am 41caac8b: Add new permissions for read/write social stream.

* commit '41caac8ba5987bab31782baa9b39ae0da74d3825':
  Add new permissions for read/write social stream.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 83c1df4..219ff67 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -46,6 +46,7 @@
     <uses-permission android:name="com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL" />
     <!-- allow broadcasting secret code intents that reboot the phone -->
     <uses-permission android:name="android.permission.REBOOT" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
     <application
         android:name="com.android.contacts.ContactsApplication"
diff --git a/res/drawable-hdpi/dial_num_0_wht.png b/res/drawable-hdpi/dial_num_0_wht.png
index 9d7fc62..c42bf4c 100644
--- a/res/drawable-hdpi/dial_num_0_wht.png
+++ b/res/drawable-hdpi/dial_num_0_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_1_wht.png b/res/drawable-hdpi/dial_num_1_wht.png
index e941c52..434fd33 100644
--- a/res/drawable-hdpi/dial_num_1_wht.png
+++ b/res/drawable-hdpi/dial_num_1_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_2_wht.png b/res/drawable-hdpi/dial_num_2_wht.png
index fc5540b..2ae20ab 100644
--- a/res/drawable-hdpi/dial_num_2_wht.png
+++ b/res/drawable-hdpi/dial_num_2_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_3_wht.png b/res/drawable-hdpi/dial_num_3_wht.png
index 45637b9..991d5f3 100644
--- a/res/drawable-hdpi/dial_num_3_wht.png
+++ b/res/drawable-hdpi/dial_num_3_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_4_wht.png b/res/drawable-hdpi/dial_num_4_wht.png
index af8c8aa..7aad3ef 100644
--- a/res/drawable-hdpi/dial_num_4_wht.png
+++ b/res/drawable-hdpi/dial_num_4_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_5_wht.png b/res/drawable-hdpi/dial_num_5_wht.png
index 20ab0b1..42a1d0b 100644
--- a/res/drawable-hdpi/dial_num_5_wht.png
+++ b/res/drawable-hdpi/dial_num_5_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_6_wht.png b/res/drawable-hdpi/dial_num_6_wht.png
index 8811b4b..b03e019 100644
--- a/res/drawable-hdpi/dial_num_6_wht.png
+++ b/res/drawable-hdpi/dial_num_6_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_7_wht.png b/res/drawable-hdpi/dial_num_7_wht.png
index ed6d749..8b72fff 100644
--- a/res/drawable-hdpi/dial_num_7_wht.png
+++ b/res/drawable-hdpi/dial_num_7_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_8_wht.png b/res/drawable-hdpi/dial_num_8_wht.png
index 6844aeb..822f21a 100644
--- a/res/drawable-hdpi/dial_num_8_wht.png
+++ b/res/drawable-hdpi/dial_num_8_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_9_wht.png b/res/drawable-hdpi/dial_num_9_wht.png
index df294be..2ee944b 100644
--- a/res/drawable-hdpi/dial_num_9_wht.png
+++ b/res/drawable-hdpi/dial_num_9_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_pound_wht.png b/res/drawable-hdpi/dial_num_pound_wht.png
index 46316e5..e10e57d 100644
--- a/res/drawable-hdpi/dial_num_pound_wht.png
+++ b/res/drawable-hdpi/dial_num_pound_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_star_wht.png b/res/drawable-hdpi/dial_num_star_wht.png
index c36e31c..1dfc111 100644
--- a/res/drawable-hdpi/dial_num_star_wht.png
+++ b/res/drawable-hdpi/dial_num_star_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png b/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png
index 60fecb2..d21cc10 100644
--- a/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png
+++ b/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_minus_disabled_holo_dark.png b/res/drawable-hdpi/ic_minus_disabled_holo_dark.png
index 0d2d93b..c2ad8dc 100644
--- a/res/drawable-hdpi/ic_minus_disabled_holo_dark.png
+++ b/res/drawable-hdpi/ic_minus_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_play_disabled_holo_dark.png b/res/drawable-hdpi/ic_play_disabled_holo_dark.png
new file mode 100644
index 0000000..e3a3853
--- /dev/null
+++ b/res/drawable-hdpi/ic_play_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_plus_disabled_holo_dark.png b/res/drawable-hdpi/ic_plus_disabled_holo_dark.png
index ed65c1c..723e362 100644
--- a/res/drawable-hdpi/ic_plus_disabled_holo_dark.png
+++ b/res/drawable-hdpi/ic_plus_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_0_wht.png b/res/drawable-mdpi/dial_num_0_wht.png
index 96a0dcd..e6e295a 100644
--- a/res/drawable-mdpi/dial_num_0_wht.png
+++ b/res/drawable-mdpi/dial_num_0_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_1_wht.png b/res/drawable-mdpi/dial_num_1_wht.png
index 56dbca3..a640e36 100644
--- a/res/drawable-mdpi/dial_num_1_wht.png
+++ b/res/drawable-mdpi/dial_num_1_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_2_wht.png b/res/drawable-mdpi/dial_num_2_wht.png
index 4c0991c..e311f4f 100644
--- a/res/drawable-mdpi/dial_num_2_wht.png
+++ b/res/drawable-mdpi/dial_num_2_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_3_wht.png b/res/drawable-mdpi/dial_num_3_wht.png
index 81bf770..f07324a 100644
--- a/res/drawable-mdpi/dial_num_3_wht.png
+++ b/res/drawable-mdpi/dial_num_3_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_4_wht.png b/res/drawable-mdpi/dial_num_4_wht.png
index 5f07476..cd8d33c 100644
--- a/res/drawable-mdpi/dial_num_4_wht.png
+++ b/res/drawable-mdpi/dial_num_4_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_5_wht.png b/res/drawable-mdpi/dial_num_5_wht.png
index 5cf9c7a..a9f27dc 100644
--- a/res/drawable-mdpi/dial_num_5_wht.png
+++ b/res/drawable-mdpi/dial_num_5_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_6_wht.png b/res/drawable-mdpi/dial_num_6_wht.png
index ceffb29..2bdf08e 100644
--- a/res/drawable-mdpi/dial_num_6_wht.png
+++ b/res/drawable-mdpi/dial_num_6_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_7_wht.png b/res/drawable-mdpi/dial_num_7_wht.png
index 022ef9c..6c1c599 100644
--- a/res/drawable-mdpi/dial_num_7_wht.png
+++ b/res/drawable-mdpi/dial_num_7_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_8_wht.png b/res/drawable-mdpi/dial_num_8_wht.png
index c470e68..db0694c 100644
--- a/res/drawable-mdpi/dial_num_8_wht.png
+++ b/res/drawable-mdpi/dial_num_8_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_9_wht.png b/res/drawable-mdpi/dial_num_9_wht.png
index 27d94ef..692fdb0 100644
--- a/res/drawable-mdpi/dial_num_9_wht.png
+++ b/res/drawable-mdpi/dial_num_9_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_pound_wht.png b/res/drawable-mdpi/dial_num_pound_wht.png
index 68908c3..f216d05 100644
--- a/res/drawable-mdpi/dial_num_pound_wht.png
+++ b/res/drawable-mdpi/dial_num_pound_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_star_wht.png b/res/drawable-mdpi/dial_num_star_wht.png
index cb8aa28..f7e8e9f 100644
--- a/res/drawable-mdpi/dial_num_star_wht.png
+++ b/res/drawable-mdpi/dial_num_star_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png b/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png
index 1f32576..d8cec25 100644
--- a/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png
+++ b/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_minus_disabled_holo_dark.png b/res/drawable-mdpi/ic_minus_disabled_holo_dark.png
index 76ef6e8..fb0103c 100644
--- a/res/drawable-mdpi/ic_minus_disabled_holo_dark.png
+++ b/res/drawable-mdpi/ic_minus_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_play_disabled_holo_dark.png b/res/drawable-mdpi/ic_play_disabled_holo_dark.png
new file mode 100644
index 0000000..64bed72
--- /dev/null
+++ b/res/drawable-mdpi/ic_play_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_plus_disabled_holo_dark.png b/res/drawable-mdpi/ic_plus_disabled_holo_dark.png
index 2a5947c..70c9a3d 100644
--- a/res/drawable-mdpi/ic_plus_disabled_holo_dark.png
+++ b/res/drawable-mdpi/ic_plus_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_0_wht.png b/res/drawable-xhdpi/dial_num_0_wht.png
index f6f96cc..dca0aea 100644
--- a/res/drawable-xhdpi/dial_num_0_wht.png
+++ b/res/drawable-xhdpi/dial_num_0_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_1_wht.png b/res/drawable-xhdpi/dial_num_1_wht.png
index 8333aba..d1535c1 100644
--- a/res/drawable-xhdpi/dial_num_1_wht.png
+++ b/res/drawable-xhdpi/dial_num_1_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_2_wht.png b/res/drawable-xhdpi/dial_num_2_wht.png
index 02f8fdf..12c4ab9 100644
--- a/res/drawable-xhdpi/dial_num_2_wht.png
+++ b/res/drawable-xhdpi/dial_num_2_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_3_wht.png b/res/drawable-xhdpi/dial_num_3_wht.png
index 44383b5..4353e8a 100644
--- a/res/drawable-xhdpi/dial_num_3_wht.png
+++ b/res/drawable-xhdpi/dial_num_3_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_4_wht.png b/res/drawable-xhdpi/dial_num_4_wht.png
index f90cb73..ccee5cc 100644
--- a/res/drawable-xhdpi/dial_num_4_wht.png
+++ b/res/drawable-xhdpi/dial_num_4_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_5_wht.png b/res/drawable-xhdpi/dial_num_5_wht.png
index c41c615..f27f153 100644
--- a/res/drawable-xhdpi/dial_num_5_wht.png
+++ b/res/drawable-xhdpi/dial_num_5_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_6_wht.png b/res/drawable-xhdpi/dial_num_6_wht.png
index 4c7a235..8966d13 100644
--- a/res/drawable-xhdpi/dial_num_6_wht.png
+++ b/res/drawable-xhdpi/dial_num_6_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_7_wht.png b/res/drawable-xhdpi/dial_num_7_wht.png
index fabca99..b018810 100644
--- a/res/drawable-xhdpi/dial_num_7_wht.png
+++ b/res/drawable-xhdpi/dial_num_7_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_8_wht.png b/res/drawable-xhdpi/dial_num_8_wht.png
index 7bd70b0..7c7b4f8 100644
--- a/res/drawable-xhdpi/dial_num_8_wht.png
+++ b/res/drawable-xhdpi/dial_num_8_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_9_wht.png b/res/drawable-xhdpi/dial_num_9_wht.png
index 207276c..23984f0 100644
--- a/res/drawable-xhdpi/dial_num_9_wht.png
+++ b/res/drawable-xhdpi/dial_num_9_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_pound_wht.png b/res/drawable-xhdpi/dial_num_pound_wht.png
index b2cac17..be21af8 100644
--- a/res/drawable-xhdpi/dial_num_pound_wht.png
+++ b/res/drawable-xhdpi/dial_num_pound_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_star_wht.png b/res/drawable-xhdpi/dial_num_star_wht.png
index 2862c45..061a494 100644
--- a/res/drawable-xhdpi/dial_num_star_wht.png
+++ b/res/drawable-xhdpi/dial_num_star_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png b/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png
index 4a45288..9e12338 100644
--- a/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png
+++ b/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_minus_disabled_holo_dark.png b/res/drawable-xhdpi/ic_minus_disabled_holo_dark.png
index 1f09cf8..ae6bce7 100644
--- a/res/drawable-xhdpi/ic_minus_disabled_holo_dark.png
+++ b/res/drawable-xhdpi/ic_minus_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_play_disabled_holo_dark.png b/res/drawable-xhdpi/ic_play_disabled_holo_dark.png
new file mode 100644
index 0000000..9537351
--- /dev/null
+++ b/res/drawable-xhdpi/ic_play_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_plus_disabled_holo_dark.png b/res/drawable-xhdpi/ic_plus_disabled_holo_dark.png
index 5728d50..169da3e 100644
--- a/res/drawable-xhdpi/ic_plus_disabled_holo_dark.png
+++ b/res/drawable-xhdpi/ic_plus_disabled_holo_dark.png
Binary files differ
diff --git a/res/drawable/ic_hold_pause.xml b/res/drawable/ic_hold_pause.xml
index b99689c..19902ae 100644
--- a/res/drawable/ic_hold_pause.xml
+++ b/res/drawable/ic_hold_pause.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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_enabled="false"
             android:drawable="@drawable/ic_hold_pause_disabled_holo_dark" />
diff --git a/res/drawable/ic_minus.xml b/res/drawable/ic_minus.xml
index 1fa9210..9750127 100644
--- a/res/drawable/ic_minus.xml
+++ b/res/drawable/ic_minus.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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_enabled="false" android:drawable="@drawable/ic_minus_disabled_holo_dark" />
     <item android:drawable="@drawable/ic_minus_holo_dark" />
diff --git a/res/drawable/ic_play.xml b/res/drawable/ic_play.xml
new file mode 100644
index 0000000..1c43a55
--- /dev/null
+++ b/res/drawable/ic_play.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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_enabled="false"
+        android:drawable="@drawable/ic_play_disabled_holo_dark" />
+    <item android:drawable="@drawable/ic_play_holo_dark" />
+</selector>
diff --git a/res/drawable/ic_plus.xml b/res/drawable/ic_plus.xml
index d5aa2e7..176b21a 100644
--- a/res/drawable/ic_plus.xml
+++ b/res/drawable/ic_plus.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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_enabled="false" android:drawable="@drawable/ic_plus_disabled_holo_dark" />
     <item android:drawable="@drawable/ic_plus_holo_dark" />
diff --git a/res/drawable/ic_speakerphone_off.xml b/res/drawable/ic_speakerphone_off.xml
index 85cf810..6a8a0a1 100644
--- a/res/drawable/ic_speakerphone_off.xml
+++ b/res/drawable/ic_speakerphone_off.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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_enabled="false" android:drawable="@drawable/ic_sound_off_speakerphone_disabled_holo_dark" />
     <item android:drawable="@drawable/ic_sound_off_speakerphone_holo_dark" />
diff --git a/res/drawable/ic_speakerphone_on.xml b/res/drawable/ic_speakerphone_on.xml
index eb79f71..4bcd5c6 100644
--- a/res/drawable/ic_speakerphone_on.xml
+++ b/res/drawable/ic_speakerphone_on.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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_enabled="false" android:drawable="@drawable/ic_sound_speakerphone_disabled_holo_dark" />
     <item android:drawable="@drawable/ic_sound_speakerphone_holo_dark" />
diff --git a/res/drawable/seek_bar_thumb.xml b/res/drawable/seek_bar_thumb.xml
index 61884bb..c0cffcc 100644
--- a/res/drawable/seek_bar_thumb.xml
+++ b/res/drawable/seek_bar_thumb.xml
@@ -1,34 +1,55 @@
 <?xml version="1.0" encoding="utf-8"?>
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- First item is the outer transparent sphere. -->
-    <item>
-        <shape
-            android:shape="oval"
-        >
-            <size
-                android:width="16dip"
-                android:height="16dip"
-            />
-            <solid
-                android:color="@color/voicemail_playback_seek_bar_yet_to_play"
-            />
-        </shape>
+<!-- Copyright (C) 2011 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_enabled="true">
+        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+            <!-- First item is the outer transparent sphere. -->
+            <item>
+                <shape
+                    android:shape="oval"
+                >
+                    <size
+                        android:width="16dip"
+                        android:height="16dip"
+                    />
+                    <solid
+                        android:color="@color/voicemail_playback_seek_bar_yet_to_play"
+                    />
+                </shape>
+            </item>
+            <!-- Second item is the inner almost-opaque sphere.
+                 Seems to derive its size from the outer, a size element doesn't change anything.
+                 Looks like using left, right, top and bottom on the item is best to fix inner sphere. -->
+            <item
+                android:left="3dip"
+                android:right="3dip"
+                android:top="3dip"
+                android:bottom="3dip"
+            >
+                <shape
+                    android:shape="oval"
+                >
+                    <solid
+                        android:color="@color/voicemail_playback_seek_bar_already_played"
+                    />
+                </shape>
+            </item>
+        </layer-list>
     </item>
-    <!-- Second item is the inner almost-opaque sphere.
-         Seems to derive its size from the outer, a size element doesn't change anything.
-         Looks like using left, right, top and bottom on the item is best to fix inner sphere. -->
-    <item
-        android:left="3dip"
-        android:right="3dip"
-        android:top="3dip"
-        android:bottom="3dip"
-    >
-        <shape
-            android:shape="oval"
-        >
-            <solid
-                android:color="@color/voicemail_playback_seek_bar_already_played"
-            />
-        </shape>
-    </item>
-</layer-list>
+
+    <!-- Do not show the thumb when disabled -->
+    <item android:drawable="@android:color/transparent" />
+</selector>
\ No newline at end of file
diff --git a/res/drawable/seekbar_drawable.xml b/res/drawable/seekbar_drawable.xml
index 2533b7f..96bbee3 100644
--- a/res/drawable/seekbar_drawable.xml
+++ b/res/drawable/seekbar_drawable.xml
@@ -1,22 +1,63 @@
 <?xml version="1.0" encoding="utf-8"?>
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:id="@android:id/background">
-    <shape android:shape="line">
-      <stroke
-        android:width="2dip"
-        android:color="@color/voicemail_playback_seek_bar_yet_to_play"
-        />
-    </shape>
-  </item>
-  <!-- I am not defining a secondary progress colour - we don't use it. -->
-  <item android:id="@android:id/progress">
-    <clip>
-      <shape android:shape="line">
-        <stroke
-          android:width="2dip"
-          android:color="@color/voicemail_playback_seek_bar_already_played"
-          />
-      </shape>
-    </clip>
-  </item>
-</layer-list>
+<!-- Copyright (C) 2011 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_enabled="true">
+        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+          <item android:id="@android:id/background">
+            <shape android:shape="line">
+              <stroke
+                android:width="2dip"
+                android:color="@color/voicemail_playback_seek_bar_yet_to_play"
+                />
+            </shape>
+          </item>
+          <!-- I am not defining a secondary progress colour - we don't use it. -->
+          <item android:id="@android:id/progress">
+            <clip>
+              <shape android:shape="line">
+                <stroke
+                  android:width="2dip"
+                  android:color="@color/voicemail_playback_seek_bar_already_played"
+                  />
+              </shape>
+            </clip>
+          </item>
+        </layer-list>
+    </item>
+    <item>
+        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+          <item android:id="@android:id/background">
+            <shape android:shape="line">
+              <stroke
+                android:width="2dip"
+                android:color="@color/voicemail_playback_seek_bar_yet_to_play"
+                />
+            </shape>
+          </item>
+          <!-- I am not defining a secondary progress colour - we don't use it. -->
+          <item android:id="@android:id/progress">
+            <clip>
+              <shape android:shape="line">
+                <stroke
+                  android:width="2dip"
+                  android:color="@color/voicemail_playback_seek_bar_yet_to_play"
+                  />
+              </shape>
+            </clip>
+          </item>
+        </layer-list>
+    </item>
+</selector>
diff --git a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
index 0d94622..de6cd97 100644
--- a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
+++ b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
@@ -18,26 +18,26 @@
 -->
 
 <!-- Note: padding might be controlled programatically -->
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:minHeight="@dimen/detail_min_line_item_height">
+    android:paddingLeft="16dip">
 
-    <!-- Note: padding might be controlled programatically -->
-    <com.android.contacts.detail.PrimaryActionViewContainer
-        android:id="@+id/primary_action_view_container"
-        android:layout_width="0dip"
-        android:layout_weight="1"
+    <com.android.contacts.detail.ActionsViewContainer
+        android:id="@+id/actions_view_container"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="@dimen/detail_min_line_item_height"
+        android:gravity="center_vertical"
         android:orientation="horizontal"
-        android:layout_gravity="center_vertical"
         android:focusable="true"
-        android:background="?android:attr/selectableItemBackground">
+        android:background="?android:attr/selectableItemBackground"
+        android:nextFocusRight="@+id/secondary_action_view_container">
 
+        <!-- Note: padding might be controlled programatically -->
         <LinearLayout
+            android:id="@+id/primary_action_view"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
@@ -80,7 +80,7 @@
             android:id="@+id/type"
             style="@style/ContactDetailItemType"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
             android:paddingRight="16dip" />
 
@@ -92,33 +92,34 @@
             android:layout_gravity="center_vertical"
             android:background="@drawable/ic_menu_mark" />
 
-    </com.android.contacts.detail.PrimaryActionViewContainer>
 
-    <View
-        android:id="@+id/vertical_divider"
-        android:layout_width="1px"
-        android:layout_height="match_parent"
-        android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
-        android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
-        android:background="?android:attr/dividerVertical" />
-
-    <!-- Note: padding might be controlled programatically -->
-    <FrameLayout
-        android:id="@+id/secondary_action_view_container"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:paddingLeft="@dimen/detail_item_icon_margin"
-        android:paddingRight="@dimen/detail_item_icon_margin"
-        android:duplicateParentState="false"
-        android:focusable="true"
-        android:background="?android:attr/selectableItemBackground">
-        <ImageView
-            android:id="@+id/secondary_action_button"
-            android:layout_width="32dip"
+        <View
+            android:id="@+id/vertical_divider"
+            android:layout_width="1px"
             android:layout_height="match_parent"
-            android:layout_centerVertical="true"
-            android:gravity="center"
-            android:scaleType="center"
-            android:duplicateParentState="false" />
-    </FrameLayout>
-</LinearLayout>
+            android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
+            android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
+            android:background="?android:attr/dividerVertical" />
+
+        <!-- Note: padding might be controlled programatically -->
+        <FrameLayout
+            android:id="@+id/secondary_action_view_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="@dimen/detail_item_icon_margin"
+            android:paddingRight="@dimen/detail_item_icon_margin"
+            android:duplicateParentState="false"
+            android:focusable="true"
+            android:background="?android:attr/selectableItemBackground"
+            android:nextFocusLeft="@id/actions_view_container">
+            <ImageView
+                android:id="@+id/secondary_action_button"
+                android:layout_width="32dip"
+                android:layout_height="match_parent"
+                android:layout_centerVertical="true"
+                android:gravity="center"
+                android:scaleType="center"
+                android:duplicateParentState="false" />
+        </FrameLayout>
+    </com.android.contacts.detail.ActionsViewContainer>
+</FrameLayout>
diff --git a/res/layout-sw580dp/group_source_button.xml b/res/layout-sw580dp/group_source_button.xml
index a058990..e0fe4a9 100644
--- a/res/layout-sw580dp/group_source_button.xml
+++ b/res/layout-sw580dp/group_source_button.xml
@@ -29,12 +29,12 @@
     android:padding="10dip" >
 
     <TextView
+        android:id="@android:id/title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:duplicateParentState="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:text="@string/view_updates_from_group"/>
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
 
     <ImageView
         android:id="@android:id/icon"
diff --git a/res/layout-w470dp/group_source_button.xml b/res/layout-w470dp/group_source_button.xml
index 1acd510..af62c2c 100644
--- a/res/layout-w470dp/group_source_button.xml
+++ b/res/layout-w470dp/group_source_button.xml
@@ -34,12 +34,12 @@
         android:orientation="horizontal">
 
         <TextView
+            android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:textColor="@color/action_bar_button_text_color"
-            android:text="@string/view_updates_from_group"
             style="@android:style/Widget.Holo.ActionBar.TabText"/>
 
         <ImageView
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
index a890ddf..13124f2 100644
--- a/res/layout/call_detail.xml
+++ b/res/layout/call_detail.xml
@@ -79,16 +79,6 @@
             android:background="@android:color/holo_blue_light"
             android:layout_below="@+id/contact_background_sizer"
         />
-        <LinearLayout
-            android:id="@+id/voicemail_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingBottom="@dimen/call_detail_button_spacing"
-            android:layout_below="@id/blue_separator"
-            android:background="@android:color/black"
-        >
-            <!-- The voicemail fragment will be put here. -->
-        </LinearLayout>
         <View
             android:id="@+id/photo_text_bar"
             android:layout_width="match_parent"
@@ -132,6 +122,16 @@
             android:layout_alignBottom="@id/contact_background_sizer"
             android:background="?android:attr/selectableItemBackground"
         />
+        <LinearLayout
+            android:id="@+id/voicemail_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="@dimen/call_detail_button_spacing"
+            android:layout_below="@id/blue_separator"
+            android:background="@android:color/black"
+        >
+            <!-- The voicemail fragment will be put here. -->
+        </LinearLayout>
         <FrameLayout android:id="@+id/call_and_sms_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index 852b6f7..4735d03 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 
+<!-- Layout parameters are set programmatically. -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/res/layout/call_log_incoming_call_icon.xml b/res/layout/call_log_incoming_call_icon.xml
index 7bb7054..8361655 100644
--- a/res/layout/call_log_incoming_call_icon.xml
+++ b/res/layout/call_log_incoming_call_icon.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/call_log_incoming_call_icon"
     android:layout_width="wrap_content"
diff --git a/res/layout/call_log_missed_call_icon.xml b/res/layout/call_log_missed_call_icon.xml
index 4a37229..49177cd 100644
--- a/res/layout/call_log_missed_call_icon.xml
+++ b/res/layout/call_log_missed_call_icon.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/call_log_missed_call_icon"
     android:layout_width="wrap_content"
diff --git a/res/layout/call_log_outgoing_call_icon.xml b/res/layout/call_log_outgoing_call_icon.xml
index 67841be..f109eb4 100644
--- a/res/layout/call_log_outgoing_call_icon.xml
+++ b/res/layout/call_log_outgoing_call_icon.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/call_log_outgoing_call_icon"
     android:layout_width="wrap_content"
diff --git a/res/layout/call_log_voicemail_icon.xml b/res/layout/call_log_voicemail_icon.xml
index cfd6a2d..4fddcf0 100644
--- a/res/layout/call_log_voicemail_icon.xml
+++ b/res/layout/call_log_voicemail_icon.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/call_log_voicemail_icon"
     android:layout_width="wrap_content"
diff --git a/res/layout/contact_detail_list_item.xml b/res/layout/contact_detail_list_item.xml
index 99f027f..a410dc9 100644
--- a/res/layout/contact_detail_list_item.xml
+++ b/res/layout/contact_detail_list_item.xml
@@ -18,27 +18,25 @@
 -->
 
 <!-- Note: padding might be controlled programatically -->
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:paddingTop="8dip"
-    android:paddingBottom="8dip"
-    android:minHeight="@dimen/detail_min_line_item_height">
+    android:paddingLeft="16dip">
 
-    <!-- Note: padding might be controlled programatically -->
-    <com.android.contacts.detail.PrimaryActionViewContainer
-        android:id="@+id/primary_action_view_container"
-        android:layout_width="0dip"
-        android:layout_weight="1"
+    <com.android.contacts.detail.ActionsViewContainer
+        android:id="@+id/actions_view_container"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:focusable="true"
-        android:background="?android:attr/selectableItemBackground">
+        android:background="?android:attr/selectableItemBackground"
+        android:nextFocusRight="@+id/secondary_action_view_container"
+        android:minHeight="@dimen/detail_min_line_item_height">
 
+        <!-- Note: padding might be controlled programatically -->
         <LinearLayout
+            android:id="@+id/primary_action_view"
             android:layout_width="0dip"
             android:layout_height="wrap_content"
             android:layout_weight="1"
@@ -93,30 +91,31 @@
                 android:visibility="gone" />
 
         </LinearLayout>
-    </com.android.contacts.detail.PrimaryActionViewContainer>
 
-    <View
-        android:id="@+id/vertical_divider"
-        android:layout_width="1dip"
-        android:layout_height="match_parent"
-        android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
-        android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
-        android:background="?android:attr/dividerVertical" />
+        <View
+            android:id="@+id/vertical_divider"
+            android:layout_width="1dip"
+            android:layout_height="match_parent"
+            android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
+            android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
+            android:background="?android:attr/dividerVertical" />
 
-    <!-- Note: padding might be controlled programatically -->
-    <FrameLayout
-        android:id="@+id/secondary_action_view_container"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:paddingLeft="@dimen/detail_item_icon_margin"
-        android:paddingRight="@dimen/detail_item_icon_margin"
-        android:focusable="true"
-        android:background="?android:attr/selectableItemBackground">
-        <ImageView
-            android:id="@+id/secondary_action_button"
-            android:layout_width="32dip"
-            android:layout_height="32dip"
-            android:layout_gravity="center_vertical"
-            android:duplicateParentState="false" />
-    </FrameLayout>
-</LinearLayout>
+        <!-- Note: padding might be controlled programatically -->
+        <FrameLayout
+            android:id="@+id/secondary_action_view_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:paddingLeft="@dimen/detail_item_icon_margin"
+            android:paddingRight="@dimen/detail_item_icon_margin"
+            android:focusable="true"
+            android:background="?android:attr/selectableItemBackground"
+            android:nextFocusLeft="@id/actions_view_container">
+            <ImageView
+                android:id="@+id/secondary_action_button"
+                android:layout_width="32dip"
+                android:layout_height="32dip"
+                android:layout_gravity="center_vertical"
+                android:duplicateParentState="false" />
+        </FrameLayout>
+    </com.android.contacts.detail.ActionsViewContainer>
+</FrameLayout>
diff --git a/res/layout/contact_detail_network_title_entry_view.xml b/res/layout/contact_detail_network_title_entry_view.xml
index bc0d3f1..1907a7a 100644
--- a/res/layout/contact_detail_network_title_entry_view.xml
+++ b/res/layout/contact_detail_network_title_entry_view.xml
@@ -17,31 +17,38 @@
  */
 -->
 
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="@dimen/detail_item_side_margin"
-    android:paddingRight="@dimen/detail_item_side_margin"
-    android:paddingTop="@dimen/detail_item_vertical_margin"
-    android:paddingBottom="@dimen/detail_item_vertical_margin"
-    android:orientation="horizontal"
-    android:gravity="center_vertical">
-
-    <ImageView
-        android:id="@+id/network_icon"
-        android:layout_width="@dimen/detail_network_icon_size"
-        android:layout_height="@dimen/detail_network_icon_size"
-        android:layout_marginLeft="@dimen/detail_item_icon_margin"
-        android:layout_marginRight="@dimen/detail_item_icon_margin"
-        android:layout_gravity="center_vertical"
-        android:scaleType="centerInside" />
-
-    <TextView
-        android:id="@+id/network_title"
-        android:layout_width="wrap_content"
+    android:paddingRight="@dimen/detail_item_side_margin">
+    <LinearLayout
+        android:id="@+id/primary_action_view"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
+        android:paddingTop="@dimen/detail_item_vertical_margin"
+        android:paddingBottom="@dimen/detail_item_vertical_margin"
+        android:focusable="true"
+        android:background="?android:attr/selectableItemBackground"
+        android:minHeight="@dimen/detail_min_line_item_height"
+        android:orientation="horizontal"
+        android:gravity="center_vertical">
 
-</LinearLayout>
+        <ImageView
+            android:id="@+id/network_icon"
+            android:layout_width="@dimen/detail_network_icon_size"
+            android:layout_height="@dimen/detail_network_icon_size"
+            android:layout_marginLeft="@dimen/detail_item_icon_margin"
+            android:layout_marginRight="@dimen/detail_item_icon_margin"
+            android:layout_gravity="center_vertical"
+            android:scaleType="centerInside" />
+
+        <TextView
+            android:id="@+id/network_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+    </LinearLayout>
+</FrameLayout>
diff --git a/res/layout/contact_tile_frequent.xml b/res/layout/contact_tile_frequent.xml
index 43bbe9d..5b51c78 100644
--- a/res/layout/contact_tile_frequent.xml
+++ b/res/layout/contact_tile_frequent.xml
@@ -18,9 +18,7 @@
     class="com.android.contacts.list.ContactTileView"
     android:focusable="true"
     android:background="?android:attr/selectableItemBackground"
-    android:nextFocusRight="@+id/contact_tile_quick"
-    android:paddingRight="16dip"
-    android:paddingLeft="16dip" >
+    android:nextFocusRight="@+id/contact_tile_quick">
 
     <RelativeLayout
         android:layout_width="match_parent"
diff --git a/res/layout/contact_tile_frequent_phone.xml b/res/layout/contact_tile_frequent_phone.xml
index 26c221c..5bd82cd 100644
--- a/res/layout/contact_tile_frequent_phone.xml
+++ b/res/layout/contact_tile_frequent_phone.xml
@@ -13,15 +13,15 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
+<!-- Layout parameters are set programmatically. -->
 <view
-    android:id="@+id/contact_tile_frequent_phone"
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_tile_frequent_phone"
     class="com.android.contacts.list.ContactTileDarkFrequentView"
     android:focusable="true"
     android:background="?android:attr/selectableItemBackground"
-    android:nextFocusLeft="@+id/contact_tile_quick"
-    android:paddingRight="16dip"
-    android:paddingLeft="16dip" >
+    android:nextFocusLeft="@+id/contact_tile_quick">
 
     <RelativeLayout
         android:layout_width="match_parent"
@@ -55,31 +55,38 @@
             android:fadingEdgeLength="3dip"
             android:ellipsize="marquee" />
 
-        <TextView
-            android:id="@+id/contact_tile_phone_number"
-            android:layout_width="wrap_content"
+        <LinearLayout
+            android:orientation="horizontal"
             android:layout_height="wrap_content"
-            android:textSize="14sp"
-            android:textColor="@color/dialtacts_secondary_text_color"
-            android:layout_marginLeft="8dip"
-            android:singleLine="true"
-            android:maxLength="18"
+            android:layout_width="match_parent"
+            android:layout_below="@id/contact_tile_name"
             android:layout_toRightOf="@id/image_container"
-            android:layout_below="@id/contact_tile_name" />
+            android:gravity="center_vertical">
 
-        <TextView
-            android:id="@+id/contact_tile_phone_type"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textSize="14sp"
-            android:ellipsize="end"
-            android:singleLine="true"
-            android:textAllCaps="true"
-            android:textColor="@color/dialtacts_secondary_text_color"
-            android:layout_marginLeft="12dip"
-            android:maxLength="8"
-            android:layout_alignParentRight="true"
-            android:layout_alignTop="@id/contact_tile_phone_number" />
+            <TextView
+                android:id="@+id/contact_tile_phone_number"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="5"
+                android:textSize="14sp"
+                android:textColor="@color/dialtacts_secondary_text_color"
+                android:layout_marginLeft="8dip"
+                android:singleLine="true"/>
+
+            <TextView
+                android:id="@+id/contact_tile_phone_type"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="3"
+                android:textSize="12sp"
+                android:ellipsize="end"
+                android:singleLine="true"
+                android:textAllCaps="true"
+                android:textColor="@color/dialtacts_secondary_text_color"
+                android:layout_marginLeft="8dip"
+                android:gravity="right" />
+
+        </LinearLayout>
 
         <View
             android:id="@+id/contact_tile_horizontal_divider"
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
index 6484d87..af85bba 100644
--- a/res/layout/dialtacts_activity.xml
+++ b/res/layout/dialtacts_activity.xml
@@ -19,7 +19,7 @@
     android:layout_height="match_parent"
     android:layout_marginTop="?android:attr/actionBarSize">
 
-    <android.support.v4.view.ViewPager
+    <com.android.contacts.activities.DialtactsViewPager
         android:id="@+id/pager"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
diff --git a/res/layout/editor_account_header.xml b/res/layout/editor_account_header.xml
index ff33cf1..c255209 100644
--- a/res/layout/editor_account_header.xml
+++ b/res/layout/editor_account_header.xml
@@ -26,7 +26,7 @@
     android:paddingBottom="8dip"
     android:gravity="center_vertical"
     android:paddingLeft="@dimen/account_container_left_padding"
-    android:paddingRight="32dip">
+    android:paddingRight="28dip">
 
     <LinearLayout
         android:id="@+id/account"
@@ -38,18 +38,20 @@
 
         <TextView
             android:id="@+id/account_type"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:singleLine="true" />
+            android:singleLine="true"
+            android:ellipsize="end" />
 
         <TextView
              android:id="@+id/account_name"
-             android:layout_width="wrap_content"
+             android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textAppearance="?android:attr/textAppearanceSmall"
              android:textColor="?android:attr/textColorTertiary"
-             android:singleLine="true" />
+             android:singleLine="true"
+             android:ellipsize="end" />
 
     </LinearLayout>
 
diff --git a/res/layout/editor_account_header_with_dropdown.xml b/res/layout/editor_account_header_with_dropdown.xml
index 001eaae..311a783 100644
--- a/res/layout/editor_account_header_with_dropdown.xml
+++ b/res/layout/editor_account_header_with_dropdown.xml
@@ -24,42 +24,40 @@
     android:orientation="horizontal"
     android:gravity="center_vertical"
     android:paddingLeft="@dimen/account_container_left_padding"
-    android:paddingRight="32dip">
+    android:paddingRight="28dip">
 
     <LinearLayout
         android:id="@+id/account"
         android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
+        android:layout_width="0dip"
+        android:layout_weight="1"
         android:orientation="vertical"
         style="?android:attr/spinnerStyle">
 
         <TextView
             android:id="@+id/account_type"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:singleLine="true" />
+            android:singleLine="true"
+            android:ellipsize="end" />
 
         <TextView
              android:id="@+id/account_name"
-             android:layout_width="wrap_content"
+             android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:paddingRight="8dip"
              android:textAppearance="?android:attr/textAppearanceSmall"
              android:textColor="?android:attr/textColorTertiary"
-             android:singleLine="true" />
+             android:singleLine="true"
+             android:ellipsize="end" />
 
     </LinearLayout>
 
-    <!-- Spacer between the account type / name dropdown and the account icon -->
-    <View
-        android:layout_width="0dip"
-        android:layout_height="match_parent"
-        android:layout_weight="1"/>
-
     <FrameLayout
         android:layout_width="wrap_content"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent"
+        android:layout_marginLeft="10dip">
 
         <ImageView
              android:id="@+id/account_icon"
diff --git a/res/layout/group_detail_fragment.xml b/res/layout/group_detail_fragment.xml
index d95a6db..2b020c9 100644
--- a/res/layout/group_detail_fragment.xml
+++ b/res/layout/group_detail_fragment.xml
@@ -40,7 +40,8 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:fadingEdge="none"
-            android:scrollbarStyle="outsideOverlay"/>
+            android:scrollbarStyle="outsideOverlay"
+            android:divider="@null"/>
 
         <!--
           Shadow overlay over the list of group members (since we have a fake stacked
diff --git a/res/layout/group_source_button.xml b/res/layout/group_source_button.xml
index 49aa2db..8d09033 100644
--- a/res/layout/group_source_button.xml
+++ b/res/layout/group_source_button.xml
@@ -30,6 +30,7 @@
     android:paddingRight="16dip" >
 
     <TextView
+        android:id="@android:id/title"
         android:layout_width="0dip"
         android:layout_height="wrap_content"
         android:layout_weight="1"
@@ -37,7 +38,6 @@
         android:duplicateParentState="true"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="@color/action_bar_button_text_color"
-        android:text="@string/view_updates_from_group"
         style="@android:style/Widget.Holo.ActionBar.TabText"/>
 
     <FrameLayout
diff --git a/res/layout/playback_layout.xml b/res/layout/playback_layout.xml
index 711ebf8..2dfcb4d 100644
--- a/res/layout/playback_layout.xml
+++ b/res/layout/playback_layout.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
diff --git a/res/layout/quickcontact_list_item.xml b/res/layout/quickcontact_list_item.xml
index 7929718..c018eea 100755
--- a/res/layout/quickcontact_list_item.xml
+++ b/res/layout/quickcontact_list_item.xml
@@ -16,22 +16,23 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/actions_view_container"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
     android:orientation="horizontal"
-    android:background="@drawable/quickcontact_list_item_background"
-    android:gravity="center_vertical">
+    android:gravity="center_vertical"
+    android:background="?android:attr/selectableItemBackground"
+    android:nextFocusRight="@+id/secondary_action_button">
     <LinearLayout
-        android:id="@+id/primary_action_view_container"
         android:layout_width="0dip"
         android:layout_height="wrap_content"
-        android:minHeight="?android:attr/listPreferredItemHeight"
         android:layout_weight="1"
-        android:orientation="vertical"
         android:paddingLeft="16dip"
         android:paddingRight="16dip"
         android:gravity="center_vertical"
-        android:background="?android:attr/selectableItemBackground">
+        android:orientation="vertical"
+    >
         <TextView
             android:id="@android:id/text1"
             android:layout_width="wrap_content"
@@ -61,5 +62,6 @@
         android:paddingLeft="@dimen/detail_item_icon_margin"
         android:paddingRight="@dimen/detail_item_icon_margin"
         android:background="?android:attr/selectableItemBackground"
-        android:duplicateParentState="false" />
+        android:duplicateParentState="false"
+        android:nextFocusLeft="@id/actions_view_container" />
 </LinearLayout>
diff --git a/res/layout/select_dialog_item.xml b/res/layout/select_dialog_item.xml
index ea671dd..d49ae10 100644
--- a/res/layout/select_dialog_item.xml
+++ b/res/layout/select_dialog_item.xml
@@ -23,7 +23,7 @@
     android:id="@android:id/text1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="48dip"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textColor="?android:attr/textColorAlertDialogListItem"
     android:gravity="center_vertical"
diff --git a/res/layout/user_profile_header.xml b/res/layout/user_profile_header.xml
index ff01a11..6867dea 100644
--- a/res/layout/user_profile_header.xml
+++ b/res/layout/user_profile_header.xml
@@ -40,6 +40,7 @@
             android:ellipsize="end"
             android:gravity="left|center_vertical"
             android:layout_weight="1"
+            android:textAllCaps="true"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:paddingLeft="?attr/list_item_text_indent"
             android:textColor="@color/people_app_theme_color" />
@@ -52,7 +53,7 @@
             android:ellipsize="end"
             android:layout_gravity="right|center_vertical"
             android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textSize="12dip"
+            android:textSize="12sp"
             android:textColor="@color/contact_count_text_color" />
     </LinearLayout>
 
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4584ff5..e9cbfa9 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Beskikbaar"</string>
     <string name="status_away" msgid="1838861100379804730">"Weg"</string>
     <string name="status_busy" msgid="9147992455450257136">"Besig"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Bel nommer"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Speel stemboodskap"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Inkomende oproep"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Uitgaande oproep"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index c1a62f6..a47a129 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"የሚገኝ"</string>
     <string name="status_away" msgid="1838861100379804730">"ወጣ ብሏል"</string>
     <string name="status_busy" msgid="9147992455450257136">"ተይዟ ል"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"ቁጥር ደውል።"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"የድምፅ መልዕክት አጫውት"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"ገቢ ጥሪ"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"ወጪ ጥሪ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 47475f1..2ca44d9 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"متوفر"</string>
     <string name="status_away" msgid="1838861100379804730">"بعيد"</string>
     <string name="status_busy" msgid="9147992455450257136">"مشغول"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"اتصال برقم"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"تشغيل البريد الصوتي"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"مكالمة واردة"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"مكالمة صادرة"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"الاحتفاظ بها محليًا"</string>
     <string name="add_account" msgid="8201790677994503186">"إضافة حساب"</string>
     <string name="add_new_account" msgid="5748627740680940264">"إضافة حساب جديد"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"لم يتم إرسال الاتصال."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"لم يتم إرسال المكالمة."</string>
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 8abad0a..35a2cd3 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Налице"</string>
     <string name="status_away" msgid="1838861100379804730">"Отсъства"</string>
     <string name="status_busy" msgid="9147992455450257136">"Зает/а"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Обадете се на номер"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Пускане на гласовата поща"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Входящо обаждане"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Изходящо обаждане"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 1f41d60..8e86e04 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponible"</string>
     <string name="status_away" msgid="1838861100379804730">"Absent"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ocupat"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Truca al número"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Reprodueix el missatge de veu"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Trucada entrant"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Trucada sortint"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index d543bcf..59e4ceb 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"K dispozici"</string>
     <string name="status_away" msgid="1838861100379804730">"Pryč"</string>
     <string name="status_busy" msgid="9147992455450257136">"Nemám čas"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Volat číslo"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Přehrát hlasovou schránku"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Příchozí hovor"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Odchozí hovor"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index d974b18..94a2e33 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Tilgængelig"</string>
     <string name="status_away" msgid="1838861100379804730">"Ikke til stede"</string>
     <string name="status_busy" msgid="9147992455450257136">"Optaget"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Ring til nummer"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Afspil telefonsvarerbesked"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Indgående opkald"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Udgående opkald"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c331231..cb6a7ed 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Verfügbar"</string>
     <string name="status_away" msgid="1838861100379804730">"Abwesend"</string>
     <string name="status_busy" msgid="9147992455450257136">"Beschäftigt"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Nummer anrufen"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Mailbox abhören"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Eingehender Anruf"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Ausgehender Anruf"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Lokal speichern"</string>
     <string name="add_account" msgid="8201790677994503186">"Konto hinzufügen"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Neues Konto hinzufügen"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Anruf nicht verbunden."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"Anruf nicht verbunden"</string>
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 4a7b3e2..495fbc3 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Διαθέσιμος"</string>
     <string name="status_away" msgid="1838861100379804730">"Απουσιάζω"</string>
     <string name="status_busy" msgid="9147992455450257136">"Απασχολημένος"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Κλήση αριθμού"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Αναπαραγωγή μηνύματος αυτόματου τηλεφωνητή"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Εισερχόμενη κλήση"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Εξερχόμενη κλήση"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index d16051b..2db4cba 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Available"</string>
     <string name="status_away" msgid="1838861100379804730">"Away"</string>
     <string name="status_busy" msgid="9147992455450257136">"Busy"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Call number"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Play voicemail"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Incoming call"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Outgoing call"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index d8dbb48..a2debdb 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponible"</string>
     <string name="status_away" msgid="1838861100379804730">"Ausente"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ocupado"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Llamar al número"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Reproducir mensaje de voz"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Llamada entrante"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Llamada saliente"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Guardar localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Agregar una cuenta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Agregar una cuenta nueva"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Llamada no enviada."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"No se realizó la llamada."</string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 11c1001..e05396c 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponible"</string>
     <string name="status_away" msgid="1838861100379804730">"Ausente"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ocupado"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Llamar al número"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Reproducir mensaje de voz"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Llamada entrante"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Llamada saliente"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Guardar localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Añadir cuenta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Añadir una cuenta nueva"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"La llamada no se ha enviado."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"No se ha enviado la llamada."</string>
 </resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 62929a0..262fedc 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"در دسترس"</string>
     <string name="status_away" msgid="1838861100379804730">"غایب"</string>
     <string name="status_busy" msgid="9147992455450257136">"مشغول"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"تماس با شماره"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"پخش پست صوتی"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"تماس ورودی"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"تماس خروجی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 634fd17..736adef 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Tavoitettavissa"</string>
     <string name="status_away" msgid="1838861100379804730">"Poissa"</string>
     <string name="status_busy" msgid="9147992455450257136">"Varattu"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Soita numeroon"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Toista vastaajaviesti"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Saapuva puhelu"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Lähtevä puhelu"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index bf2102c..87349ee 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -161,12 +161,12 @@
     <string name="simContacts_title" msgid="27341688347689769">"Contacts de carte SIM"</string>
     <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Vous n\'avez aucun contact à afficher. Si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes."</string>
     <string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Vous n\'avez aucun contact à afficher."</string>
-    <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:560 in java.io.StringReader@4d546e25)  -->
-    <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:567 in java.io.StringReader@620b66cc)  -->
+    <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:560 in java.io.StringReader@431b9fb1)  -->
+    <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:567 in java.io.StringReader@4a913fe2)  -->
     <string name="noContactsHelpTextWithSync" product="tablet" msgid="2364665535969139880">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", puis sur :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts vers la tablette ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier les paramètres de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SIM ou SD."\n</li></string>
     <string name="noContactsHelpTextWithSync" product="default" msgid="3017521127042216243">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" et sélectionnez :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts sur le téléphone ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier le paramètre de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SIM ou SD."\n</li></string>
-    <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:565 in java.io.StringReader@5a8a0d5d)  -->
-    <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:571 in java.io.StringReader@1d73831b)  -->
+    <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:565 in java.io.StringReader@5f934ad)  -->
+    <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:571 in java.io.StringReader@2bf14ceb)  -->
     <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="6222739731808897565">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", puis sur :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts vers la tablette ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier les paramètres de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SD."\n</li></string>
     <string name="noContactsNoSimHelpTextWithSync" product="default" msgid="9040060730467973050">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" et sélectionnez :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts sur le téléphone ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier le paramètre de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SD."\n</li></string>
     <string name="noFavoritesHelpText" msgid="3744655776704833277">"Vous ne disposez d\'aucun favoris."\n\n"Pour ajouter un contact à la liste de favoris :"\n\n"        "<li>"Appuyez sur l\'onglet "<b>"Contacts"</b>"."\n</li>" "\n<li>"Appuyez sur le contact à ajouter à vos favoris."\n</li>" "\n<li>"Appuyez sur l\'étoile en regard du nom du contact."\n</li></string>
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponible"</string>
     <string name="status_away" msgid="1838861100379804730">"Absent"</string>
     <string name="status_busy" msgid="9147992455450257136">"Occupé"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Appeler le numéro"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Écouter le message vocal"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Appel entrant"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Appel sortant"</string>
@@ -557,10 +556,10 @@
     <string name="external_profile_title" msgid="8034998767621359438">"Mon profil <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g>"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Affichage de tous les contacts"</string>
     <string name="no_account_prompt" msgid="7061052512446855192">"Tirez le meilleur parti de l\'application Contacts en utilisant un compte Google."\n\n"• Accédez-y depuis n\'importe quel navigateur Web."\n"• Sauvegardez vos contacts en toute sécurité."</string>
-    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Votre nouveau contact ne sera pas sauvegardé. Ajouter un compte qui sauvegarde les contacts en ligne ?"</string>
+    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Votre nouveau contact ne sera pas sauvegardé. Ajouter un compte permettant de sauvegarder les contacts en ligne ?"</string>
     <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"Votre nouveau contact va être synchronisé avec <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
     <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Vous pouvez synchroniser votre nouveau contact avec l\'un des comptes suivants. Lequel souhaitez-vous utiliser ?"</string>
-    <string name="keep_local" msgid="1258761699192993322">"Enreg. copie locale"</string>
+    <string name="keep_local" msgid="1258761699192993322">"Enregistrer localement"</string>
     <string name="add_account" msgid="8201790677994503186">"Ajouter un compte"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Ajouter un nouveau compte"</string>
     <string name="phone_call_prohibited" msgid="4329551585931067534">"L\'appel n\'a pas été effectué."</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 65e2c6a..2bf57cb 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Dostupan"</string>
     <string name="status_away" msgid="1838861100379804730">"Odsutan"</string>
     <string name="status_busy" msgid="9147992455450257136">"Zauzet"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Nazovi broj"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Reprodukcija govorne pošte"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Dolazni poziv"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Odlazni poziv"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 722dba6..6f2c9aa 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Elérhető"</string>
     <string name="status_away" msgid="1838861100379804730">"Nincs a gépnél"</string>
     <string name="status_busy" msgid="9147992455450257136">"Elfoglalt"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Szám hívása"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Hangposta lejátszása"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Bejövő hívás"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Kimenő hívás"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 362b7f0..534c359 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Tersedia"</string>
     <string name="status_away" msgid="1838861100379804730">"Tidak di Tempat"</string>
     <string name="status_busy" msgid="9147992455450257136">"Sibuk"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Nomor panggilan"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Putar pesan suara"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Panggilan masuk"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Panggilan keluar"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 023e310..e3f1025 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -412,7 +412,7 @@
     <string name="display_options_sort_list_by" msgid="6080091755852211076">"Ordina elenco per"</string>
     <string name="display_options_sort_by_given_name" msgid="184916793466387067">"Nome"</string>
     <string name="display_options_sort_by_family_name" msgid="7857986975275712622">"Cognome"</string>
-    <string name="display_options_view_names_as" msgid="18022868169627979">"Visualizz. nomi contatti"</string>
+    <string name="display_options_view_names_as" msgid="18022868169627979">"Visualizza nomi contatti con"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Prima il nome"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Prima il cognome"</string>
     <string name="search_bar_hint" msgid="1012756309632856553">"Cerca contatti"</string>
@@ -505,7 +505,7 @@
     <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g> "</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Imposta il mio profilo"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Digita il nome della persona"</string>
-    <string name="view_updates_from_group" msgid="1782685984905600034">"Visualizza aggiornam."</string>
+    <string name="view_updates_from_group" msgid="1782685984905600034">"Visualizza aggiornamenti"</string>
   <plurals name="notification_voicemail_title">
     <item quantity="one" msgid="1746619685488504230">"Segreteria"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> messaggi vocali"</item>
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponibile"</string>
     <string name="status_away" msgid="1838861100379804730">"Assente"</string>
     <string name="status_busy" msgid="9147992455450257136">"Occupato"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Chiama numero"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Riproduci messaggio vocale"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Chiamata in arrivo"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Chiamata in uscita"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 4c56572..3ed48a7 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"זמין"</string>
     <string name="status_away" msgid="1838861100379804730">"לא נמצא"</string>
     <string name="status_busy" msgid="9147992455450257136">"עסוק"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"התקשר למספר"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"הפעל דואר קולי"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"שיחה נכנסת"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"שיחה יוצאת"</string>
@@ -563,5 +562,7 @@
     <string name="keep_local" msgid="1258761699192993322">"שמור באופן מקומי"</string>
     <string name="add_account" msgid="8201790677994503186">"הוסף חשבון"</string>
     <string name="add_new_account" msgid="5748627740680940264">"הוסף חשבון חדש"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"השיחה לא נשלחה."</string>
+    <!-- no translation found for phone_call_prohibited (4329551585931067534) -->
+    <!-- no translation found for phone_call_prohibited (4313552620858880999) -->
+    <skip />
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 43b275c..4647615 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"オンライン"</string>
     <string name="status_away" msgid="1838861100379804730">"不在"</string>
     <string name="status_busy" msgid="9147992455450257136">"取り込み中"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"電話番号"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"ボイスメールを再生"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"着信"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"発信"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index ea5110e..871c63c 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"대화 가능"</string>
     <string name="status_away" msgid="1838861100379804730">"자리 비움"</string>
     <string name="status_busy" msgid="9147992455450257136">"다른 용무 중"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"전화 걸기"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"음성사서함 재생"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"수신 전화"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"발신 전화"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index afdca2b..0e7da8e 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Pasiekiamas"</string>
     <string name="status_away" msgid="1838861100379804730">"Pasišalinęs"</string>
     <string name="status_busy" msgid="9147992455450257136">"Užsiėmęs"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Skambinti numeriu"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Paleisti balso pašto pranešimus"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Gaunamasis skambutis"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Išsiunčiamasis skambutis"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 883d265..f917550 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Pieejama"</string>
     <string name="status_away" msgid="1838861100379804730">"Prombūtnē"</string>
     <string name="status_busy" msgid="9147992455450257136">"Aizņemts"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Zvanīt uz numuru"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Atskaņot balss pasta ziņojumu"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Ienākošs zvans"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Izejošs zvans"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index dd84dea..7dfe0a4 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -539,7 +539,6 @@
     <string name="status_available" msgid="5586870015822828392">"Ada"</string>
     <string name="status_away" msgid="1838861100379804730">"Tiada"</string>
     <string name="status_busy" msgid="9147992455450257136">"Sibuk"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Memanggil nombor"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Mainkan mel suara"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Panggilan masuk"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Panggilan keluar"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index ff1af24..b7012c6 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -161,12 +161,12 @@
     <string name="simContacts_title" msgid="27341688347689769">"Kontakter på SIM-kort"</string>
     <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Du har ingen kontakter å vise. (Hvis du nettopp har lagt til en konto, kan det ta noen minutter å synkronisere kontaktene.)"</string>
     <string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Du har ingen kontakter å vise."</string>
-    <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:292 in java.io.StringReader@6727734f)  -->
-    <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:293 in java.io.StringReader@4f037c71)  -->
+    <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:292 in java.io.StringReader@3e34a1fc)  -->
+    <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:293 in java.io.StringReader@7176c74b)  -->
     <string name="noContactsHelpTextWithSync" product="tablet" msgid="2364665535969139880">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>", og trykk deretter på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer"</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til nettbrettet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt fra grunnen av"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Eksporter"</b></font>" for å importere kontakter fra SIM- eller SD-kort"\n</li></string>
     <string name="noContactsHelpTextWithSync" product="default" msgid="3017521127042216243">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" og trykk deretter på: "\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer "</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til telefonen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importér/Eksportér"</b></font>" for å importere kontakter fra SIM- eller SD-kort"\n</li></string>
-    <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@6ddf073d)  -->
-    <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@4d546e25)  -->
+    <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@2d16471f)  -->
+    <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@11975b59)  -->
     <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="6222739731808897565">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>", og trykk deretter på: "\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer"</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til nettbrettet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt fra grunnen av"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/eksporter"</b></font>" for å importere kontakter fra SD-kortet"\n</li></string>
     <string name="noContactsNoSimHelpTextWithSync" product="default" msgid="9040060730467973050">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" og trykk deretter på: "\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer "</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til telefonen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importér/eksportér"</b></font>" for å importere kontakter fra SD-kortet"\n</li></string>
     <string name="noFavoritesHelpText" msgid="3744655776704833277">"Du har ingen favoritter."\n\n"Slik legger du til en kontakt i favorittlisten:"\n\n" "<li>"Trykk på fanen "<b>"Kontakter"</b>" "\n</li>" "\n<li>"Trykk på kontakten du vil legge til i favoritter"\n</li>" "\n<li>"Trykk på stjernen ved siden av kontaktnavnet"\n</li></string>
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Tilgjengelig"</string>
     <string name="status_away" msgid="1838861100379804730">"Borte"</string>
     <string name="status_busy" msgid="9147992455450257136">"Opptatt"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Ring nummer"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Spill av talemelding"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Innkommende samtale"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Utgående samtale"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Behold lokalt"</string>
     <string name="add_account" msgid="8201790677994503186">"Legg til konto"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Legg til ny konto"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Samtalen ble ikke opprettet."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"Anrop ikke foretatt."</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 9ce5b0d..c5cb310 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Beschikbaar"</string>
     <string name="status_away" msgid="1838861100379804730">"Afwezig"</string>
     <string name="status_busy" msgid="9147992455450257136">"Bezet"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Nummer bellen"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Voicemail afspelen"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Inkomende oproep"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Uitgaande oproep"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 0198ddf..576d2f5 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Dostępny"</string>
     <string name="status_away" msgid="1838861100379804730">"Nieobecny"</string>
     <string name="status_busy" msgid="9147992455450257136">"Zajęty"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Zadzwoń pod numer"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Odtwórz pocztę głosową"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Połączenie przychodzące"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Połączenie wychodzące"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 961ecc1..850272a 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Available"</string>
     <string name="status_away" msgid="1838861100379804730">"Ausente"</string>
     <string name="status_busy" msgid="9147992455450257136">"ocupado"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Número da chamada"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Reproduzir mensagem de correio de voz"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Chamada recebida"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Chamada efetuada"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Manter localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Adicionar conta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Adicionar nova conta"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Chamada não efectuada."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"Chamada não efetuada."</string>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index a52827b..4e4e475 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponível"</string>
     <string name="status_away" msgid="1838861100379804730">"Ausente"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ocupado"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Número de chamada"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Reproduzir mensagem de voz"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Chamada recebida"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Chamada realizada"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Manter localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Adicionar conta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Adicionar nova conta"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Chamada não completada."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"Chamada não enviada."</string>
 </resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 96e0400..354934c 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -688,8 +688,6 @@
     <skip />
     <!-- no translation found for status_busy (9147992455450257136) -->
     <skip />
-    <!-- no translation found for description_call_log_call_button (8207201401459528442) -->
-    <skip />
     <!-- no translation found for description_call_log_play_button (651182125650429846) -->
     <skip />
     <!-- no translation found for description_call_log_incoming_call (4485427487637250143) -->
@@ -741,5 +739,7 @@
     <skip />
     <!-- no translation found for add_new_account (5748627740680940264) -->
     <skip />
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Il clom n\'è betg vegnì exequì."</string>
+    <!-- no translation found for phone_call_prohibited (4329551585931067534) -->
+    <!-- no translation found for phone_call_prohibited (4313552620858880999) -->
+    <skip />
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index efb87c3..ae7e913 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Disponibil(ă)"</string>
     <string name="status_away" msgid="1838861100379804730">"Plecat(ă)"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ocupat(ă)"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Apelaţi numărul"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Redaţi mesajul vocal"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Apel de intrare"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Apel de ieşire"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 84c43af..50adc7f 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -517,7 +517,7 @@
     <string name="voicemail_fetching_content" msgid="877911315738258780">"Получение голосовой почты..."</string>
     <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Не удалось получить голосовую почту."</string>
     <string name="call_log_new_header" msgid="846546437517724715">"Новые"</string>
-    <string name="call_log_old_header" msgid="6262205894314263629">"Предыдущие"</string>
+    <string name="call_log_old_header" msgid="6262205894314263629">"Раньше"</string>
     <string name="voicemail_status_voicemail_not_available" msgid="3164200979671881947">"Нет подключения к серверу гол. почты"</string>
     <string name="voicemail_status_messages_waiting" msgid="2970301042310727909">"Нет подключения к серверу гол. почты. Имеются новые сообщения."</string>
     <string name="voicemail_status_configure_voicemail" msgid="3940240432123700974">"Настройте голосовую почту."</string>
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"На месте"</string>
     <string name="status_away" msgid="1838861100379804730">"Отсутствует"</string>
     <string name="status_busy" msgid="9147992455450257136">"Не беспокоить"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Позвонить"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Прослушать голосовую почту"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Входящий вызов"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Исходящий вызов"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 8d291a8..7d4113f 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"K dispozícii"</string>
     <string name="status_away" msgid="1838861100379804730">"Preč"</string>
     <string name="status_busy" msgid="9147992455450257136">"Zaneprázdnený"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Volať číslo"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Prehrať hlasovú správu"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Prichádzajúci hovor"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Odchádzajúci hovor"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index edbeb90..b571fbc 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Dosegljiv"</string>
     <string name="status_away" msgid="1838861100379804730">"Odsoten"</string>
     <string name="status_busy" msgid="9147992455450257136">"Zaseden"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Kliči številko"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Predvajanje sporočil glasovne pošte"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Dohodni klic"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Odhodni klic"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Ohrani lokalno"</string>
     <string name="add_account" msgid="8201790677994503186">"Dodaj račun"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Dodaj nov račun"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Klic ni bil poslan."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"Klic ni uspel."</string>
 </resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 12aecf7..e2dbee3 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Доступан/на"</string>
     <string name="status_away" msgid="1838861100379804730">"Одсутан/на"</string>
     <string name="status_busy" msgid="9147992455450257136">"Заузет/а"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Позивање броја"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Пуштање говорне поште"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Долазни позив"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Одлазни позив"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index a3ea088..34f7a12 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Tillgänglig"</string>
     <string name="status_away" msgid="1838861100379804730">"Borta"</string>
     <string name="status_busy" msgid="9147992455450257136">"Upptagen"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Ring upp nummer"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Spela upp röstmeddelande"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Inkommande samtal"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Utgående samtal"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index a8d6b40..199e227 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -169,7 +169,7 @@
     <string name="noContactsNoSimHelpText" product="default" msgid="467658807711582876">"Huna anwani zozote za kuonyesha."\n\n"Ili kuongeza anwani, bonyeza "<font fgcolor="#ffffffff"><b>"Menyu"</b></font>" na gusa:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akaunti"</b></font>" ili kuongeza au kusanidi akaunti ya anwani unaweza kupatanisha katika simu"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Mawasiliano mapya"</b></font>" ili kuunda anwani mpya kuanzia mwanzo"</li>" "\n\n<li><font fgcolor="#ffffffff"><b>"Leta/Hamisha"</b></font>"ili kuleta anwani kutoka kwa kadi yako ya SD"\n</li></string>
     <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="6222739731808897565">"Huna anwani zozote za kuonyesha. (Kama uliongeza akaunti, inaweza kuchukua dakika chache kusawazisha anwani.)"\n\n"Kuongeza anwani, bonyeza "<font fgcolor="#ffffffff"><b>"Menyu"</b></font>" na uguse:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akaunti"</b></font>" ili kuongeza au kusanidi akaunti na anwani unazoweza kusawazisha kwenye kompyuta ndogo"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Chaguo za onyesha"</b></font>" ili kubadilisha ni anwani gani zinazoonekana"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Anwani mpya"</b></font>" ili kuunda anwani mpya kutoka mwanzo"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Leta/Hamisha"</b></font>" ili kuleta anwani kutoka kwa kadi yako ya SD"\n</li></string>
     <string name="noContactsNoSimHelpTextWithSync" product="default" msgid="9040060730467973050">"Hauna anwani zozote za kuonyesha. (Kama umeongeza tu akaunti, inaweza kuchukua dadika chache ili kupatanisha anwani.)"\n\n"Ili kuongeza anwani, bonyeza "<font fgcolor="#ffffffff"><b>"Menyu"</b></font>" na gusa:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akaunti"</b></font>" ili kuongeza au kusanidi anwani unayoweza kupatanisha katika simu"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Onyesha Machaguo"</b></font>"ili kubadilisha anwani zinazoonekana"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Anwani mpya"</b></font>" ili kuunda anwani mpya kuanzia mwanzo"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Leta/Hamisha"</b></font>"ili kuleta anwani kutoka kwa kadi yako ya SD"\n</li></string>
-    <!-- syntax error in translation for noFavoritesHelpText (3744655776704833277) org.xmlpull.v1.XmlPullParserException: expected: /string read: b (position:END_TAG </b>@1:167 in java.io.StringReader@5a8a0d5d)  -->
+    <!-- syntax error in translation for noFavoritesHelpText (3744655776704833277) org.xmlpull.v1.XmlPullParserException: expected: /string read: b (position:END_TAG </b>@1:167 in java.io.StringReader@3e60420f)  -->
     <string name="liveFolder_all_label" msgid="5961411940473276616">"Anwani zote"</string>
     <string name="liveFolder_favorites_label" msgid="2674341514070517105">"Yenye nyota"</string>
     <string name="liveFolder_phones_label" msgid="1709786878793436245">"Simu"</string>
@@ -539,7 +539,6 @@
     <string name="status_available" msgid="5586870015822828392">"Anapatikana"</string>
     <string name="status_away" msgid="1838861100379804730">"Mbali"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ana shughuli"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Pigia nambari"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Cheza barua ya sauti"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Simu inayoingia"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Simu inayotoka"</string>
@@ -552,7 +551,7 @@
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"Barua sauti ambayo haijasikizwa"</string>
     <string name="description_send_message" msgid="6046623392322890962">"Tuma ujumba kwa <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_dial_phone_number" msgid="8831647331642648637">"Piga simu <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="description_quick_contact_for" msgid="6737516415168327789">"Mwasiliani wa haraka wa <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="description_quick_contact_for" msgid="6737516415168327789">"Mawasiliano ya haraka ya <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="call_log_empty_gecode" msgid="5588904744812100846">"-"</string>
     <string name="user_profile_contacts_list_header" msgid="5582421742835006940">"Mimi"</string>
     <string name="local_profile_title" msgid="2021416826991393684">"Maelezo yangu mafupi ya ndani."</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 8f2cc85..f9093b2 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"ว่าง"</string>
     <string name="status_away" msgid="1838861100379804730">"ไม่อยู่"</string>
     <string name="status_busy" msgid="9147992455450257136">"ไม่ว่าง"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"โทรออกหมายเลขนี้"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"เล่นข้อความเสียง"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"สายเรียกเข้า"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"สายโทรออก"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"จัดเก็บในตัวเครื่อง"</string>
     <string name="add_account" msgid="8201790677994503186">"เพิ่มบัญชี"</string>
     <string name="add_new_account" msgid="5748627740680940264">"เพิ่มบัญชีใหม่"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"ไม่ได้โทรออก"</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"ไม่สามารถโทรออก"</string>
 </resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index c07eb19..27515ef 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Available"</string>
     <string name="status_away" msgid="1838861100379804730">"Malayo"</string>
     <string name="status_busy" msgid="9147992455450257136">"Busy"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Tawagan ang numero"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"I-play ang voicemail"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"May tumatawag"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Papalabas na tawag"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 68c47f3..deaa0f5 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Uygun"</string>
     <string name="status_away" msgid="1838861100379804730">"Dışarıda"</string>
     <string name="status_busy" msgid="9147992455450257136">"Meşgul"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Numarayı sesli ara"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Sesli mesajı oynat"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Gelen çağrı"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Giden çağrı"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 57799e8..2bba0da 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Доступний"</string>
     <string name="status_away" msgid="1838861100379804730">"Не на місці"</string>
     <string name="status_busy" msgid="9147992455450257136">"Зайнятий"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Дзвонити на номер"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Відтворити голосову пошту"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Вхідний дзвінок"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Вихідний дзвінок"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"Зберегти локально"</string>
     <string name="add_account" msgid="8201790677994503186">"Додати обліковий запис"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Додати новий обліковий запис"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"Виклик не надісл."</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"Виклик не здійснено."</string>
 </resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 5eed192..fa972c7 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Có mặt"</string>
     <string name="status_away" msgid="1838861100379804730">"Vắng mặt"</string>
     <string name="status_busy" msgid="9147992455450257136">"Bận"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Số cuộc gọi"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Phát thư thoại"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Cuộc gọi đến"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Cuộc gọi đi"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index ca39736..41dc994 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"在线"</string>
     <string name="status_away" msgid="1838861100379804730">"离开"</string>
     <string name="status_busy" msgid="9147992455450257136">"忙碌"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"拨打号码"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"播放语音邮件"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"来电"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"去电"</string>
@@ -563,5 +562,5 @@
     <string name="keep_local" msgid="1258761699192993322">"本地保存"</string>
     <string name="add_account" msgid="8201790677994503186">"添加帐户"</string>
     <string name="add_new_account" msgid="5748627740680940264">"添加新帐户"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"拨号未送出。"</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"通话未拨出。"</string>
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 64a62ce..219dfdb 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"線上"</string>
     <string name="status_away" msgid="1838861100379804730">"離開"</string>
     <string name="status_busy" msgid="9147992455450257136">"忙碌"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"撥打號碼"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"播放語音留言"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"來電"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"已撥電話"</string>
@@ -549,7 +548,7 @@
     <string name="description_send_text_message" msgid="7803126439934046891">"傳送簡訊給<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"未聽取的語音留言"</string>
     <string name="description_send_message" msgid="6046623392322890962">"傳送訊息給<xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="description_dial_phone_number" msgid="8831647331642648637">"<xliff:g id="NAME">%1$s</xliff:g>的電話號碼"</string>
+    <string name="description_dial_phone_number" msgid="8831647331642648637">"撥打 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_quick_contact_for" msgid="6737516415168327789">"<xliff:g id="NAME">%1$s</xliff:g>的快速聯絡人相片"</string>
     <string name="call_log_empty_gecode" msgid="5588904744812100846">"-"</string>
     <string name="user_profile_contacts_list_header" msgid="5582421742835006940">"我自己"</string>
@@ -557,11 +556,11 @@
     <string name="external_profile_title" msgid="8034998767621359438">"我的 <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g> 個人資料"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"顯示所有聯絡人"</string>
     <string name="no_account_prompt" msgid="7061052512446855192">"透過「Google 帳戶」使用「Google 人物搜尋」可獲得更佳的效益。"\n\n"• 透過任何瀏覽器都可存取。"\n"• 安全備份您的聯絡人。"</string>
-    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"您的新聯絡人資料不會備份。要新增可在線上備份聯絡人資料的帳戶嗎?"</string>
-    <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"您的聯絡人資料將與 <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g> 同步處理。"</string>
-    <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"您可以透過下列其中一個帳戶同步處理您的新聯絡人資料。要使用那個帳戶?"</string>
+    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"系統不會備份您新增的聯絡人資料。您是否要新建一個帳戶,將您的聯絡人資料另存在線上?"</string>
+    <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"您新增的聯絡人資料將會同步儲存在 <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g> 的帳戶中。"</string>
+    <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"您可以將新增的聯絡人資料同步儲存在下列其中一個帳戶中。您要選擇哪一個帳戶?"</string>
     <string name="keep_local" msgid="1258761699192993322">"儲存在本機中"</string>
     <string name="add_account" msgid="8201790677994503186">"新增帳戶"</string>
     <string name="add_new_account" msgid="5748627740680940264">"新增帳戶"</string>
-    <string name="phone_call_prohibited" msgid="4329551585931067534">"撥號未送出。"</string>
+    <string name="phone_call_prohibited" msgid="4329551585931067534">"無法傳送通話。"</string>
 </resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 5e18de4..518e089 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -537,7 +537,6 @@
     <string name="status_available" msgid="5586870015822828392">"Yatholakala"</string>
     <string name="status_away" msgid="1838861100379804730">"Akekho"</string>
     <string name="status_busy" msgid="9147992455450257136">"Matasa"</string>
-    <string name="description_call_log_call_button" msgid="8207201401459528442">"Shayela inombolo"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Dlala i-imeyli yezwi"</string>
     <string name="description_call_log_incoming_call" msgid="4485427487637250143">"Ikholi engenayo"</string>
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Ikholi eliphumayo"</string>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 561eefc..2fa7005 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -74,4 +74,6 @@
     <!--  Color of the vertical stripe that goes on the left of a block quote inside a stream item -->
     <color name="stream_item_stripe_color">#CCCCCC</color>
 
+    <!-- Color of image view placeholder. -->
+    <color name="image_placeholder">#DDDDDD</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 5a94324..4decc19 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -156,8 +156,12 @@
     <dimen name="contact_browser_list_item_text_indent">8dip</dimen>
     <dimen name="contact_browser_list_top_margin">8dip</dimen>
 
-    <!--  ContactTile Layouts -->
-    <dimen name="contact_tile_shadowbox_height">48dip</dimen>
+    <!-- ContactTile Layouts -->
+    <!--
+      Use sp instead of dip so that the shadowbox heights can all scale uniformly
+      when the font size is scaled for accessibility purposes
+    -->
+    <dimen name="contact_tile_shadowbox_height">48sp</dimen>
 
     <!-- Call Log -->
     <dimen name="call_log_call_action_size">32dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aa99d21..e33debb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1579,7 +1579,7 @@
     <!-- Label to instruct the user to type in a contact's name to add the contact as a member of the current group. [CHAR LIMIT=64] -->
     <string name="enter_contact_name">Type person\'s name</string>
 
-    <!-- Button to view the updates from the current group on the group detail page [CHAR LIMIT=20] -->
+    <!-- Button to view the updates from the current group on the group detail page [CHAR LIMIT=25] -->
     <string name="view_updates_from_group">View updates</string>
 
     <!-- Title of the notification of new voicemails. [CHAR LIMIT=30] -->
@@ -1676,13 +1676,6 @@
     <!--  Used to display as default status when the contact is busy or Do not disturb for chat [CHAR LIMIT=19] -->
     <string name="status_busy">Busy</string>
 
-    <!-- String describing the icon in the call log used to place a call.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_call_log_call_button">Call number</string>
-
     <!-- String describing the icon in the call log used to play a voicemail.
 
         Note: AccessibilityServices use this attribute to announce what the view represents.
@@ -1818,7 +1811,15 @@
     <!-- Button label to prompt the user to add another account (when there are already existing accounts on the device) [CHAR LIMIT=30] -->
     <string name="add_new_account">Add new account</string>
 
-    <!-- Dialog message which is shown when the user tries to make a phone call
-         to prohibited phone numbers [CHAR LIMIT=NONE] -->
-    <string name="phone_call_prohibited" msgid="4313552620858880999">Call not sent.</string>
+    <!-- Dialog title which is shown when the user tries to make a phone call
+         to prohibited phone numbers [CHAR LIMIT=40] -->
+    <string name="dialog_phone_call_prohibited_title" msgid="4313552620858880999">Call not sent</string>
+
+    <!-- Dialog title which is shown when the user tries to check voicemail
+         while the system isn't ready for the access. [CHAR LIMIT=40] -->
+    <string name="dialog_voicemail_not_ready_title">Voicemail number unavailable</string>
+
+    <!-- Dialog message which is shown when the user tries to check voicemail
+         while the system isn't ready for the access. [CHAR LIMIT=NONE] -->
+    <string name="dialog_voicemail_not_ready_message">To configure voicemail, go to Menu &gt; Settings.</string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 690ab04..5e7d9e2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -46,7 +46,7 @@
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
         <item name="contact_browser_list_padding_left">16dip</item>
         <item name="contact_browser_list_padding_right">0dip</item>
-        <item name="contact_browser_background">@android:color/black</item>
+        <item name="contact_browser_background">@android:color/transparent</item>
         <item name="list_item_text_indent">@dimen/contact_browser_list_item_text_indent</item>
         <!-- CallLog -->
         <item name="call_log_primary_text_color">#FFFFFF</item>
@@ -142,7 +142,7 @@
         <item name="list_item_profile_photo_size">70dip</item>
         <item name="list_item_prefix_highlight_color">#99cc00</item>
         <item name="list_item_header_text_color">@color/people_app_theme_color</item>
-        <item name="list_item_header_text_size">14dip</item>
+        <item name="list_item_header_text_size">14sp</item>
         <item name="list_item_header_height">26dip</item>
         <item name="list_item_header_underline_height">1dip</item>
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml
index 17ef37f..949ec36 100644
--- a/res/xml/searchable.xml
+++ b/res/xml/searchable.xml
@@ -25,6 +25,7 @@
     android:searchMode="queryRewriteFromText"
 
     android:includeInGlobalSearch="true"
+    android:queryAfterZeroResults="true"
     android:searchSuggestAuthority="com.android.contacts"
     android:searchSuggestIntentAction="android.provider.Contacts.SEARCH_SUGGESTION_CLICKED"
     android:searchSuggestIntentData="content://com.android.contacts/contacts/lookup"
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index b7ccffc..113a18b 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -96,6 +96,7 @@
     private PhoneNumberHelper mPhoneNumberHelper;
     private PhoneCallDetailsHelper mPhoneCallDetailsHelper;
     private TextView mHeaderTextView;
+    private View mHeaderOverlayView;
     private ImageView mMainActionView;
     private ImageButton mMainActionPushLayerView;
     private ImageView mContactBackgroundView;
@@ -240,6 +241,7 @@
         mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
         mAsyncQueryHandler = new CallDetailActivityQueryHandler(this);
         mHeaderTextView = (TextView) findViewById(R.id.header_text);
+        mHeaderOverlayView = findViewById(R.id.photo_text_bar);
         mStatusMessageView = findViewById(R.id.voicemail_status);
         mStatusMessageText = (TextView) findViewById(R.id.voicemail_status_message);
         mStatusMessageAction = (TextView) findViewById(R.id.voicemail_status_action);
@@ -454,6 +456,8 @@
                 if (mainActionIntent == null) {
                     mMainActionView.setVisibility(View.INVISIBLE);
                     mMainActionPushLayerView.setVisibility(View.GONE);
+                    mHeaderTextView.setVisibility(View.INVISIBLE);
+                    mHeaderOverlayView.setVisibility(View.INVISIBLE);
                 } else {
                     mMainActionView.setVisibility(View.VISIBLE);
                     mMainActionView.setImageResource(mainActionIcon);
@@ -465,6 +469,8 @@
                         }
                     });
                     mMainActionPushLayerView.setContentDescription(mainActionDescription);
+                    mHeaderTextView.setVisibility(View.VISIBLE);
+                    mHeaderOverlayView.setVisibility(View.VISIBLE);
                 }
 
                 // This action allows to call the number that places the call.
@@ -507,22 +513,31 @@
                 ListView historyList = (ListView) findViewById(R.id.history);
                 historyList.setAdapter(
                         new CallDetailHistoryAdapter(CallDetailActivity.this, mInflater,
-                                mCallTypeHelper, details, hasVoicemail(), canPlaceCallsTo));
+                                mCallTypeHelper, details, hasVoicemail(), canPlaceCallsTo,
+                                findViewById(R.id.controls)));
                 BackScrollManager.bind(
                         new ScrollableHeader() {
-                            private View controls = findViewById(R.id.controls);
-                            private View photo = findViewById(R.id.contact_background_sizer);
-                            private View nameHeader = findViewById(R.id.photo_text_bar);
+                            private View mControls = findViewById(R.id.controls);
+                            private View mPhoto = findViewById(R.id.contact_background_sizer);
+                            private View mHeader = findViewById(R.id.photo_text_bar);
+                            private View mSeparator = findViewById(R.id.blue_separator);
 
                             @Override
                             public void setOffset(int offset) {
-                                controls.setY(-offset);
+                                mControls.setY(-offset);
                             }
 
                             @Override
                             public int getMaximumScrollableHeaderOffset() {
-                                // We can scroll the photo out, but we should keep the header.
-                                return photo.getHeight() - nameHeader.getHeight();
+                                // We can scroll the photo out, but we should keep the header if
+                                // present.
+                                if (mHeader.getVisibility() == View.VISIBLE) {
+                                    return mPhoto.getHeight() - mHeader.getHeight();
+                                } else {
+                                    // If the header is not present, we should also scroll out the
+                                    // separator line.
+                                    return mPhoto.getHeight() + mSeparator.getHeight();
+                                }
                             }
                         },
                         historyList);
@@ -719,7 +734,6 @@
 
     private StatusMessage getStatusMessage(Cursor statusCursor) {
         List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor);
-        Log.d(TAG, "Num status messages: " + messages.size());
         if (messages.size() == 0) {
             return null;
         }
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index 57defcf..007c1e0 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -73,8 +73,8 @@
 public class ContactLoader extends Loader<ContactLoader.Result> {
     private static final String TAG = "ContactLoader";
 
-    private Uri mLookupUri;
     private final Uri mRequestedUri;
+    private Uri mLookupUri;
     private boolean mLoadGroupMetaData;
     private boolean mLoadStreamItems;
     private final boolean mLoadInvitableAccountTypes;
@@ -91,10 +91,14 @@
      * The result of a load operation. Contains all data necessary to display the contact.
      */
     public static final class Result {
-        /**
-         * Singleton instance that represents "No Contact Found"
-         */
-        public static final Result NOT_FOUND = new Result((Exception) null);
+        private enum Status {
+            /** Contact is successfully loaded */
+            LOADED,
+            /** There was an error loading the contact */
+            ERROR,
+            /** Contact is not found */
+            NOT_FOUND,
+        }
 
         private final Uri mRequestedUri;
         private final Uri mLookupUri;
@@ -130,13 +134,19 @@
         private final String mCustomRingtone;
         private final boolean mIsUserProfile;
 
+        private final Status mStatus;
         private final Exception mException;
 
         /**
          * Constructor for special results, namely "no contact found" and "error".
          */
-        private Result(Exception exception) {
-            mRequestedUri = null;
+        private Result(Uri requestedUri, Status status, Exception exception) {
+            if (status == Status.ERROR && exception == null) {
+                throw new IllegalArgumentException("ERROR result must have exception");
+            }
+            mStatus = status;
+            mException = exception;
+            mRequestedUri = requestedUri;
             mLookupUri = null;
             mUri = null;
             mDirectoryId = -1;
@@ -158,11 +168,14 @@
             mSendToVoicemail = false;
             mCustomRingtone = null;
             mIsUserProfile = false;
-            mException = exception;
         }
 
-        private static Result forError(Exception exception) {
-            return new Result(exception);
+        private static Result forError(Uri requestedUri, Exception exception) {
+            return new Result(requestedUri, Status.ERROR, exception);
+        }
+
+        private static Result forNotFound(Uri requestedUri) {
+            return new Result(requestedUri, Status.NOT_FOUND, null);
         }
 
         /**
@@ -173,6 +186,7 @@
                 String photoUri, String displayName, String altDisplayName, String phoneticName,
                 boolean starred, Integer presence, boolean sendToVoicemail, String customRingtone,
                 boolean isUserProfile) {
+            mStatus = Status.LOADED;
             mException = null;
             mRequestedUri = requestedUri;
             mLookupUri = lookupUri;
@@ -199,6 +213,7 @@
         }
 
         private Result(Result from) {
+            mStatus = from.mStatus;
             mException = from.mException;
             mRequestedUri = from.mRequestedUri;
             mLookupUri = from.mLookupUri;
@@ -293,15 +308,36 @@
         /**
          * @return true when an exception happened during loading, in which case
          *     {@link #getException} returns the actual exception object.
+         *     Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
+         *     {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
+         *     and vice versa.
          */
         public boolean isError() {
-            return mException != null;
+            return mStatus == Status.ERROR;
         }
 
         public Exception getException() {
             return mException;
         }
 
+        /**
+         * @return true when the specified contact is not found.
+         *     Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
+         *     {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
+         *     and vice versa.
+         */
+        public boolean isNotFound() {
+            return mStatus == Status.NOT_FOUND;
+        }
+
+        /**
+         * @return true if the specified contact is successfully loaded.
+         *     i.e. neither {@link #isError()} nor {@link #isNotFound()}.
+         */
+        public boolean isLoaded() {
+            return mStatus == Status.LOADED;
+        }
+
         public long getNameRawContactId() {
             return mNameRawContactId;
         }
@@ -647,7 +683,7 @@
                 final ContentResolver resolver = getContext().getContentResolver();
                 final Uri uriCurrentFormat = ensureIsContactUri(resolver, mLookupUri);
                 Result result = loadContactEntity(resolver, uriCurrentFormat);
-                if (result != Result.NOT_FOUND) {
+                if (!result.isNotFound()) {
                     if (result.isDirectoryEntry()) {
                         loadDirectoryMetaData(result);
                     } else if (mLoadGroupMetaData) {
@@ -666,7 +702,7 @@
                 return result;
             } catch (Exception e) {
                 Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
-                return Result.forError(e);
+                return Result.forError(mRequestedUri, e);
             }
         }
 
@@ -717,13 +753,13 @@
                     Contacts.Entity.RAW_CONTACT_ID);
             if (cursor == null) {
                 Log.e(TAG, "No cursor returned in loadContactEntity");
-                return Result.NOT_FOUND;
+                return Result.forNotFound(mRequestedUri);
             }
 
             try {
                 if (!cursor.moveToFirst()) {
                     cursor.close();
-                    return Result.NOT_FOUND;
+                    return Result.forNotFound(mRequestedUri);
                 }
 
                 long currentRawContactId = -1;
@@ -1143,7 +1179,7 @@
 
             mContact = result;
 
-            if (!result.isError() && result != Result.NOT_FOUND) {
+            if (result.isLoaded()) {
                 mLookupUri = result.getLookupUri();
 
                 if (!result.isDirectoryEntry()) {
diff --git a/src/com/android/contacts/ContactPhotoManager.java b/src/com/android/contacts/ContactPhotoManager.java
index b2ceffa..e04a07a 100644
--- a/src/com/android/contacts/ContactPhotoManager.java
+++ b/src/com/android/contacts/ContactPhotoManager.java
@@ -28,6 +28,8 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Handler.Callback;
@@ -67,6 +69,35 @@
         return R.drawable.ic_contact_picture_holo_light;
     }
 
+    public static abstract class DefaultImageProvider {
+        public abstract void applyDefaultImage(ImageView view, boolean hires, boolean darkTheme);
+    }
+
+    private static class AvatarDefaultImageProvider extends DefaultImageProvider {
+        @Override
+        public void applyDefaultImage(ImageView view, boolean hires, boolean darkTheme) {
+            view.setImageResource(getDefaultAvatarResId(hires, darkTheme));
+        }
+    }
+
+    private static class BlankDefaultImageProvider extends DefaultImageProvider {
+        private static Drawable sDrawable;
+
+        @Override
+        public void applyDefaultImage(ImageView view, boolean hires, boolean darkTheme) {
+            if (sDrawable == null) {
+                Context context = view.getContext();
+                sDrawable = new ColorDrawable(context.getResources().getColor(
+                        R.color.image_placeholder));
+            }
+            view.setImageDrawable(sDrawable);
+        }
+    }
+
+    public static final DefaultImageProvider DEFAULT_AVATER = new AvatarDefaultImageProvider();
+
+    public static final DefaultImageProvider DEFAULT_BLANK = new BlankDefaultImageProvider();
+
     /**
      * Requests the singleton instance of {@link AccountTypeManager} with data bound from
      * the available authenticators. This method can safely be called from the UI thread.
@@ -91,14 +122,32 @@
      * it is displayed immediately.  Otherwise a request is sent to load the photo
      * from the database.
      */
-    public abstract void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme);
+    public abstract void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme,
+            DefaultImageProvider defaultProvider);
+
+    /**
+     * Calls {@link #loadPhoto(ImageView, long, boolean, boolean, DefaultImageProvider)} with
+     * {@link #DEFAULT_AVATER}.
+     */
+    public final void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme) {
+        loadPhoto(view, photoId, hires, darkTheme, DEFAULT_AVATER);
+    }
 
     /**
      * Load photo into the supplied image view.  If the photo is already cached,
      * it is displayed immediately.  Otherwise a request is sent to load the photo
      * from the location specified by the URI.
      */
-    public abstract void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme);
+    public abstract void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme,
+            DefaultImageProvider defaultProvider);
+
+    /**
+     * Calls {@link #loadPhoto(ImageView, Uri, boolean, boolean, DefaultImageProvider)} with
+     * {@link #DEFAULT_AVATER}.
+     */
+    public final void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme) {
+        loadPhoto(view, photoUri, hires, darkTheme, DEFAULT_AVATER);
+    }
 
     /**
      * Remove photo from the supplied image view. This also cancels current pending load request
@@ -236,24 +285,28 @@
     }
 
     @Override
-    public void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme) {
+    public void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme,
+            DefaultImageProvider defaultProvider) {
         if (photoId == 0) {
             // No photo is needed
-            view.setImageResource(getDefaultAvatarResId(hires, darkTheme));
+            defaultProvider.applyDefaultImage(view, hires, darkTheme);
             mPendingRequests.remove(view);
         } else {
-            loadPhotoByIdOrUri(view, Request.createFromId(photoId, hires, darkTheme));
+            loadPhotoByIdOrUri(view, Request.createFromId(photoId, hires, darkTheme,
+                    defaultProvider));
         }
     }
 
     @Override
-    public void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme) {
+    public void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme,
+            DefaultImageProvider defaultProvider) {
         if (photoUri == null) {
             // No photo is needed
-            view.setImageResource(getDefaultAvatarResId(hires, darkTheme));
+            defaultProvider.applyDefaultImage(view, hires, darkTheme);
             mPendingRequests.remove(view);
         } else {
-            loadPhotoByIdOrUri(view, Request.createFromUri(photoUri, hires, darkTheme));
+            loadPhotoByIdOrUri(view, Request.createFromUri(photoUri, hires, darkTheme,
+                    defaultProvider));
         }
     }
 
@@ -292,12 +345,12 @@
         BitmapHolder holder = mBitmapHolderCache.get(request.getKey());
         if (holder == null) {
             // The bitmap has not been loaded - should display the placeholder image.
-            view.setImageResource(getDefaultAvatarResId(request.isHires(), request.isDarkTheme()));
+            request.applyDefaultImage(view);
             return false;
         }
 
         if (holder.bytes == null) {
-            view.setImageResource(getDefaultAvatarResId(request.isHires(), request.isDarkTheme()));
+            request.applyDefaultImage(view);
             return holder.fresh;
         }
 
@@ -791,20 +844,25 @@
         private final Uri mUri;
         private final boolean mDarkTheme;
         private final boolean mHires;
+        private final DefaultImageProvider mDefaultProvider;
 
-        private Request(long id, Uri uri, boolean hires, boolean darkTheme) {
+        private Request(long id, Uri uri, boolean hires, boolean darkTheme,
+                DefaultImageProvider defaultProvider) {
             mId = id;
             mUri = uri;
             mDarkTheme = darkTheme;
             mHires = hires;
+            mDefaultProvider = defaultProvider;
         }
 
-        public static Request createFromId(long id, boolean hires, boolean darkTheme) {
-            return new Request(id, null /* no URI */, hires, darkTheme);
+        public static Request createFromId(long id, boolean hires, boolean darkTheme,
+                DefaultImageProvider defaultProvider) {
+            return new Request(id, null /* no URI */, hires, darkTheme, defaultProvider);
         }
 
-        public static Request createFromUri(Uri uri, boolean hires, boolean darkTheme) {
-            return new Request(0 /* no ID */, uri, hires, darkTheme);
+        public static Request createFromUri(Uri uri, boolean hires, boolean darkTheme,
+                DefaultImageProvider defaultProvider) {
+            return new Request(0 /* no ID */, uri, hires, darkTheme, defaultProvider);
         }
 
         public boolean isDarkTheme() {
@@ -841,5 +899,9 @@
         public Object getKey() {
             return mUri == null ? mId : mUri;
         }
+
+        public void applyDefaultImage(ImageView view) {
+            mDefaultProvider.applyDefaultImage(view, mHires, mDarkTheme);
+        }
     }
 }
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index e465772..be84cc4 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -79,6 +79,7 @@
     public static final String EXTRA_CONTACT_STATE = "state";
     public static final String EXTRA_SAVE_MODE = "saveMode";
     public static final String EXTRA_SAVE_IS_PROFILE = "saveIsProfile";
+    public static final String EXTRA_SAVE_SUCCEEDED = "saveSucceeded";
 
     public static final String ACTION_CREATE_GROUP = "createGroup";
     public static final String ACTION_RENAME_GROUP = "renameGroup";
@@ -331,10 +332,11 @@
                             new String[] {Contacts._ID, Contacts.LOOKUP_KEY},
                             null, null, null);
                     try {
-                        c.moveToFirst();
-                        final long contactId = c.getLong(0);
-                        final String lookupKey = c.getString(1);
-                        lookupUri = Contacts.getLookupUri(contactId, lookupKey);
+                        if (c.moveToFirst()) {
+                            final long contactId = c.getLong(0);
+                            final String lookupKey = c.getString(1);
+                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);
+                        }
                     } finally {
                         c.close();
                     }
@@ -344,6 +346,10 @@
                     lookupUri = RawContacts.getContactLookupUri(resolver, rawContactUri);
                 }
                 Log.v(TAG, "Saved contact. New URI: " + lookupUri);
+                // Mark the intent to indicate that the save was successful (even if the lookup URI
+                // is now null).  For local contacts or the local profile, it's possible that the
+                // save triggered removal of the contact, so no lookup URI would exist..
+                callbackIntent.putExtra(EXTRA_SAVE_SUCCEEDED, true);
                 break;
 
             } catch (RemoteException e) {
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 4007916..eb8ffa9 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -22,6 +22,7 @@
 import com.google.common.annotations.VisibleForTesting;
 
 import android.app.Application;
+import android.app.FragmentManager;
 import android.app.LoaderManager;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -109,10 +110,11 @@
         Context context = getApplicationContext();
         PreferenceManager.getDefaultSharedPreferences(context);
         AccountTypeManager.getInstance(context);
-        LoaderManager.enableDebugLogging(true);
 
-        StrictMode.setThreadPolicy(
-                new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
+        if (Log.isLoggable(Constants.STRICT_MODE_TAG, Log.DEBUG)) {
+            StrictMode.setThreadPolicy(
+                    new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
+        }
 
         if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
             Log.d(Constants.PERFORMANCE_TAG, "ContactsApplication.onCreate finish");
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 6603da8..9a3f2ef 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -103,8 +103,8 @@
      * considered equal for collapsing in the GUI. For caller-id, use
      * {@link PhoneNumberUtils#compare(Context, String, String)} instead
      */
-    public static final boolean shouldCollapse(Context context, CharSequence mimetype1,
-            CharSequence data1, CharSequence mimetype2, CharSequence data2) {
+    public static final boolean shouldCollapse(CharSequence mimetype1, CharSequence data1,
+            CharSequence mimetype2, CharSequence data2) {
         // different mimetypes? don't collapse
         if (!TextUtils.equals(mimetype1, mimetype2)) return false;
 
diff --git a/src/com/android/contacts/GroupMemberLoader.java b/src/com/android/contacts/GroupMemberLoader.java
index 9605747..a75da48 100644
--- a/src/com/android/contacts/GroupMemberLoader.java
+++ b/src/com/android/contacts/GroupMemberLoader.java
@@ -16,6 +16,7 @@
 package com.android.contacts;
 
 import com.android.contacts.list.ContactListAdapter;
+import com.android.contacts.preference.ContactsPreferences;
 
 import android.content.Context;
 import android.content.CursorLoader;
@@ -81,7 +82,13 @@
         setProjection(PROJECTION_DATA);
         setSelection(createSelection());
         setSelectionArgs(createSelectionArgs());
-        setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
+
+        ContactsPreferences prefs = new ContactsPreferences(context);
+        if (prefs.getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+            setSortOrder(Contacts.SORT_KEY_PRIMARY);
+        } else {
+            setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
+        }
     }
 
     private Uri createUri() {
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index abdde87..07f340e 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.activities;
 
+import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
 import com.android.contacts.editor.ContactEditorFragment;
@@ -115,6 +116,7 @@
         } else if (ACTION_SAVE_COMPLETED.equals(action)) {
             mFragment.onSaveCompleted(true,
                     intent.getIntExtra(ContactEditorFragment.SAVE_MODE_EXTRA_KEY, SaveMode.CLOSE),
+                    intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false),
                     intent.getData());
         } else if (ACTION_JOIN_COMPLETED.equals(action)) {
             mFragment.onJoinCompleted(intent.getData());
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 50d6f17..baa4b4b 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -84,6 +84,13 @@
             "com.android.phone.CallFeaturesSetting";
 
     /**
+     * Copied from PhoneApp. See comments in Phone app for more detail.
+     */
+    public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
+    public static final String CALL_ORIGIN_DIALTACTS =
+            "com.android.contacts.activities.DialtactsActivity";
+
+    /**
      * Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}.
      */
     private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";
@@ -697,7 +704,8 @@
         @Override
         public void onContactSelected(Uri contactUri) {
             PhoneNumberInteraction.startInteractionForPhoneCall(
-                    DialtactsActivity.this, contactUri);
+                    DialtactsActivity.this, contactUri,
+                    CALL_ORIGIN_DIALTACTS);
         }
     };
 
diff --git a/src/com/android/contacts/activities/DialtactsViewPager.java b/src/com/android/contacts/activities/DialtactsViewPager.java
new file mode 100644
index 0000000..fb869a9
--- /dev/null
+++ b/src/com/android/contacts/activities/DialtactsViewPager.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 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.contacts.activities;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+
+public class DialtactsViewPager extends ViewPager {
+    public DialtactsViewPager(Context context) {
+        super(context);
+    }
+
+    public DialtactsViewPager(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * ViewPager inherits ViewGroup's default behavior of delayed clicks
+     * on its children, but in order to make the dialpad more responsive we
+     * disable that here. The Call Log and Favorites tabs are both
+     * ListViews which delay their children anyway, as desired to prevent
+     * seeing pressed states flashing while scrolling lists
+     */
+    public boolean shouldDelayChildPressedState() {
+        return false;
+    }
+}
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index 2708d5d..b0355fc 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -105,7 +105,9 @@
 
         @Override
         public void onContactSelected(Uri contactUri) {
-            startActivity(new Intent(Intent.ACTION_VIEW, contactUri));
+            Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
+            intent.putExtra(ContactDetailActivity.INTENT_KEY_IGNORE_DEFAULT_UP_BEHAVIOR, true);
+            startActivity(intent);
         }
 
     };
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 6de297a..b088b89 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -954,9 +954,7 @@
             }
 
             TabState tab = mActionBarAdapter.getCurrentTab();
-            if (tab == TabState.GROUPS) {
-                mGroupsFragment.setAddAccountsVisibility(!areGroupWritableAccountsAvailable());
-            }
+            showEmptyStateForTab(tab);
         }
 
         invalidateOptionsMenuIfNeeded();
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
index ed9c2e0..22b85d7 100644
--- a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
+++ b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
@@ -45,16 +45,30 @@
     private final boolean mShowVoicemail;
     /** Whether the call and SMS controls are shown. */
     private final boolean mShowCallAndSms;
+    /** The controls that are shown on top of the history list. */
+    private final View mControls;
+    /** The listener to changes of focus of the header. */
+    private View.OnFocusChangeListener mHeaderFocusChangeListener =
+            new View.OnFocusChangeListener() {
+        @Override
+        public void onFocusChange(View v, boolean hasFocus) {
+            // When the header is focused, focus the controls above it instead.
+            if (hasFocus) {
+                mControls.requestFocus();
+            }
+        }
+    };
 
     public CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater,
             CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails,
-            boolean showVoicemail, boolean showCallAndSms) {
+            boolean showVoicemail, boolean showCallAndSms, View controls) {
         mContext = context;
         mLayoutInflater = layoutInflater;
         mCallTypeHelper = callTypeHelper;
         mPhoneCallDetails = phoneCallDetails;
         mShowVoicemail = showVoicemail;
         mShowCallAndSms = showCallAndSms;
+        mControls = controls;
     }
 
     @Override
@@ -103,6 +117,8 @@
             // Call and SMS controls are only shown in the main UI if there is a known number.
             View callAndSmsContainer = header.findViewById(R.id.header_call_and_sms_container);
             callAndSmsContainer.setVisibility(mShowCallAndSms ? View.VISIBLE : View.GONE);
+            header.setFocusable(true);
+            header.setOnFocusChangeListener(mHeaderFocusChangeListener);
             return header;
         }
 
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
index 0bbf53c..d54a47e 100644
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ b/src/com/android/contacts/calllog/CallLogAdapter.java
@@ -400,7 +400,15 @@
         // Determine the contact info.
         if (PhoneNumberUtils.isUriNumber(number)) {
             // This "number" is really a SIP address.
-            info = queryContactInfoForSipAddress(number);
+            ContactInfo sipInfo = queryContactInfoForSipAddress(number);
+            if (sipInfo == null || sipInfo == ContactInfo.EMPTY) {
+                // Check whether the username is actually a phone number of contact.
+                String username = number.substring(0, number.indexOf('@'));
+                if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
+                    sipInfo = queryContactInfoForPhoneNumber(username);
+                }
+            }
+            info = sipInfo;
         } else {
             info = queryContactInfoForPhoneNumber(number);
         }
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 2d93a98..c9a4b5b 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -121,7 +121,6 @@
         updateVoicemailStatusMessage(statusCursor);
 
         int activeSources = mVoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor);
-        Log.d(TAG, "Num active sources: " + activeSources);
         setVoicemailSourcesAvailable(activeSources != 0);
         MoreCloseables.closeQuietly(statusCursor);
     }
@@ -337,7 +336,15 @@
 
     @Override
     public void onVisibilityChanged(boolean visible) {
-        mShowOptionsMenu = visible;
+        if (mShowOptionsMenu != visible) {
+            mShowOptionsMenu = visible;
+            // Invalidate the options menu since we are changing the list of options shown in it.
+            Activity activity = getActivity();
+            if (activity != null) {
+                activity.invalidateOptionsMenu();
+            }
+        }
+
         if (visible && isResumed()) {
             refreshData();
         }
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index 602c283..6378c5e 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -22,6 +22,7 @@
 
 import android.content.res.Resources;
 import android.provider.CallLog.Calls;
+import android.text.TextUtils;
 import android.view.View;
 
 /**
@@ -68,7 +69,7 @@
             views.dividerView.setVisibility(View.VISIBLE);
         } else if (canCall) {
             // Call is the secondary action.
-            configureCallSecondaryAction(views);
+            configureCallSecondaryAction(views, details);
             views.dividerView.setVisibility(View.VISIBLE);
         } else {
             // No action available.
@@ -78,17 +79,29 @@
     }
 
     /** Sets the secondary action to correspond to the call button. */
-    private void configureCallSecondaryAction(CallLogListItemViews views) {
+    private void configureCallSecondaryAction(CallLogListItemViews views,
+            PhoneCallDetails details) {
         views.secondaryActionView.setVisibility(View.VISIBLE);
         views.secondaryActionView.setImageResource(R.drawable.ic_ab_dialer_holo_dark);
-        views.secondaryActionView.setContentDescription(
-                mResources.getString(R.string.description_call_log_call_button));
+        views.secondaryActionView.setContentDescription(getCallActionDescription(details));
+    }
+
+    /** Returns the description used by the call action for this phone call. */
+    private CharSequence getCallActionDescription(PhoneCallDetails details) {
+        final CharSequence recipient;
+        if (!TextUtils.isEmpty(details.name)) {
+            recipient = details.name;
+        } else {
+            recipient = mPhoneNumberHelper.getDisplayNumber(
+                    details.number, details.formattedNumber);
+        }
+        return mResources.getString(R.string.description_call, recipient);
     }
 
     /** Sets the secondary action to correspond to the play button. */
     private void configurePlaySecondaryAction(CallLogListItemViews views) {
         views.secondaryActionView.setVisibility(View.VISIBLE);
-        views.secondaryActionView.setImageResource(R.drawable.ic_play_holo_dark);
+        views.secondaryActionView.setImageResource(R.drawable.ic_play);
         views.secondaryActionView.setContentDescription(
                 mResources.getString(R.string.description_call_log_play_button));
     }
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
index f795a9c..c4fb36c 100644
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
@@ -161,14 +161,12 @@
         final Intent contentIntent;
         if (newCalls.length == 1) {
             // Open the voicemail directly.
-            Log.d(TAG, "Opening voicemail directly on select");
             contentIntent = new Intent(mContext, CallDetailActivity.class);
             contentIntent.setData(newCalls[0].callsUri);
             contentIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
                     newCalls[0].voicemailUri);
         } else {
             // Open the call log.
-            Log.d(TAG, "Opening call log on select");
             contentIntent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
         }
         notification.contentIntent = PendingIntent.getActivity(mContext, 0, contentIntent, 0);
@@ -250,7 +248,6 @@
                 while (cursor.moveToNext()) {
                     newCalls[cursor.getPosition()] = createNewCallsFromCursor(cursor);
                 }
-                Log.d(TAG, "DefaultNewCallsQuery: " + newCalls.length + " new calls");
                 return newCalls;
             } finally {
                 MoreCloseables.closeQuietly(cursor);
diff --git a/src/com/android/contacts/detail/PrimaryActionViewContainer.java b/src/com/android/contacts/detail/ActionsViewContainer.java
similarity index 79%
rename from src/com/android/contacts/detail/PrimaryActionViewContainer.java
rename to src/com/android/contacts/detail/ActionsViewContainer.java
index a342884..05382eb 100644
--- a/src/com/android/contacts/detail/PrimaryActionViewContainer.java
+++ b/src/com/android/contacts/detail/ActionsViewContainer.java
@@ -25,21 +25,21 @@
 
 /**
  * Custom {@link LinearLayout} which remembers its position in the {@link ListView}. Should be
- * used for primary touch targets in {@link ContactDetailFragment}.
+ * used for action touch targets in {@link ContactDetailFragment}.
  */
-/* package */ class PrimaryActionViewContainer extends LinearLayout {
+/* package */ class ActionsViewContainer extends LinearLayout {
 
     private ContextMenuInfo mContextMenuInfo;
 
-    public PrimaryActionViewContainer(Context context) {
+    public ActionsViewContainer(Context context) {
         super(context);
     }
 
-    public PrimaryActionViewContainer(Context context, AttributeSet attrs) {
+    public ActionsViewContainer(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public PrimaryActionViewContainer(Context context, AttributeSet attrs, int defStyle) {
+    public ActionsViewContainer(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
     }
 
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index bdcd6b0..b81cebf 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -249,7 +249,8 @@
         setDataOrHideIfNone(snippet, statusView);
         if (photoUri != null) {
             ContactPhotoManager.getInstance(context).loadPhoto(
-                    statusPhotoView, Uri.parse(photoUri), true, false);
+                    statusPhotoView, Uri.parse(photoUri), true, false,
+                    ContactPhotoManager.DEFAULT_BLANK);
             statusPhotoView.setVisibility(View.VISIBLE);
         } else {
             statusPhotoView.setVisibility(View.GONE);
@@ -339,7 +340,7 @@
             pushLayerView.setEnabled(false);
         }
         contactPhotoManager.loadPhoto(imageView, Uri.parse(streamItemPhoto.getPhotoUri()), true,
-                false);
+                false, ContactPhotoManager.DEFAULT_BLANK);
     }
 
     @VisibleForTesting
@@ -349,15 +350,16 @@
                 R.id.stream_item_attribution);
         TextView commentsView = (TextView) rootView.findViewById(R.id.stream_item_comments);
         ImageGetter imageGetter = new DefaultImageGetter(context.getPackageManager());
-        htmlView.setText(HtmlUtils.fromHtml(context, streamItem.getText(), imageGetter, null));
-        attributionView.setText(ContactBadgeUtil.getSocialDate(streamItem, context));
-        if (streamItem.getComments() != null) {
-            commentsView.setText(HtmlUtils.fromHtml(context, streamItem.getComments(), imageGetter,
-                    null));
-            commentsView.setVisibility(View.VISIBLE);
-        } else {
-            commentsView.setVisibility(View.GONE);
-        }
+
+        // Stream item text
+        setDataOrHideIfNone(HtmlUtils.fromHtml(context, streamItem.getText(), imageGetter, null),
+                htmlView);
+        // Attribution
+        setDataOrHideIfNone(ContactBadgeUtil.getSocialDate(streamItem, context),
+                attributionView);
+        // Comments
+        setDataOrHideIfNone(HtmlUtils.fromHtml(context, streamItem.getComments(), imageGetter,
+                null), commentsView);
         return rootView;
     }
 
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index d4bff5c..767d366 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -39,6 +39,7 @@
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.DataStatus;
 import com.android.contacts.util.DateUtils;
+import com.android.contacts.util.StructuredPostalUtils;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.widget.TransitionAnimationView;
 import com.android.internal.telephony.ITelephony;
@@ -634,8 +635,7 @@
                 } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build postal entries
                     entry.maxLines = POSTAL_ADDRESS_MAX_LINES;
-                    entry.intent = new Intent(
-                            Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + Uri.encode(entry.data)));
+                    entry.intent = StructuredPostalUtils.getViewPostalAddressIntent(entry.data);
                     mPostalEntries.add(entry);
                 } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build IM entries
@@ -1161,7 +1161,7 @@
             this.mIcon = icon;
             this.mLabel = label;
             this.mOnClickListener = onClickListener;
-            this.isEnabled = onClickListener != null;
+            this.isEnabled = false;
         }
 
         public static NetworkTitleViewEntry fromAccountType(Context context, AccountType type) {
@@ -1342,8 +1342,7 @@
                 return false;
             }
 
-            if (!ContactsUtils.shouldCollapse(context, mimetype, data, entry.mimetype,
-                    entry.data)) {
+            if (!ContactsUtils.shouldCollapse(mimetype, data, entry.mimetype, entry.data)) {
                 return false;
             }
 
@@ -1406,7 +1405,8 @@
         public final TextView footer;
         public final ImageView presenceIcon;
         public final ImageView secondaryActionButton;
-        public final View primaryActionViewContainer;
+        public final View actionsViewContainer;
+        public final View primaryActionView;
         public final View secondaryActionViewContainer;
         public final View secondaryActionDivider;
         public final View primaryIndicator;
@@ -1420,8 +1420,9 @@
             primaryIndicator = view.findViewById(R.id.primary_indicator);
             presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
 
-            primaryActionViewContainer = view.findViewById(R.id.primary_action_view_container);
-            primaryActionViewContainer.setOnClickListener(primaryActionClickListener);
+            actionsViewContainer = view.findViewById(R.id.actions_view_container);
+            actionsViewContainer.setOnClickListener(primaryActionClickListener);
+            primaryActionView = view.findViewById(R.id.primary_action_view);
 
             secondaryActionViewContainer = view.findViewById(
                     R.id.secondary_action_view_container);
@@ -1553,6 +1554,8 @@
                         parent, false);
                 viewCache = new NetworkTitleViewCache(result);
                 result.setTag(viewCache);
+                result.findViewById(R.id.primary_action_view).setOnClickListener(
+                        entry.mOnClickListener);
             }
 
             viewCache.name.setText(entry.getLabel());
@@ -1620,11 +1623,11 @@
                 presenceIconView.setVisibility(View.GONE);
             }
 
-            final PrimaryActionViewContainer primaryActionButtonContainer =
-                    (PrimaryActionViewContainer) views.primaryActionViewContainer;
-            primaryActionButtonContainer.setTag(entry);
-            primaryActionButtonContainer.setPosition(position);
-            registerForContextMenu(primaryActionButtonContainer);
+            final ActionsViewContainer actionsButtonContainer =
+                    (ActionsViewContainer) views.actionsViewContainer;
+            actionsButtonContainer.setTag(entry);
+            actionsButtonContainer.setPosition(position);
+            registerForContextMenu(actionsButtonContainer);
 
             // Set the secondary action button
             final ImageView secondaryActionView = views.secondaryActionButton;
@@ -1650,14 +1653,18 @@
                 views.secondaryActionDivider.setVisibility(View.GONE);
             }
 
-            // Right padding should not have "pressed" effect.
-            view.setPadding(0, 0, mViewEntryDimensions.getPaddingRight(), 0);
-            // Top, left, and bottom paddings should have "pressed" effect.
-            primaryActionButtonContainer.setPadding(entry.isInSubSection() ?
-                    mViewEntryDimensions.getWidePaddingLeft() :
-                            mViewEntryDimensions.getPaddingLeft(),
+            // Right and left padding should not have "pressed" effect.
+            view.setPadding(
+                    entry.isInSubSection()
+                            ? mViewEntryDimensions.getWidePaddingLeft()
+                            : mViewEntryDimensions.getPaddingLeft(),
+                    0, mViewEntryDimensions.getPaddingRight(), 0);
+            // Top and bottom padding should have "pressed" effect.
+            final View primaryActionView = views.primaryActionView;
+            primaryActionView.setPadding(
+                    primaryActionView.getPaddingLeft(),
                     mViewEntryDimensions.getPaddingTop(),
-                    0,
+                    primaryActionView.getPaddingRight(),
                     mViewEntryDimensions.getPaddingBottom());
             secondaryActionViewContainer.setPadding(
                     secondaryActionViewContainer.getPaddingLeft(),
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index 9417ee7..692c2ea 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -191,7 +191,7 @@
                 // This shouldn't ever happen, so throw an exception. The {@link ContactLoader}
                 // should log the actual exception.
                 throw new IllegalStateException("Failed to load contact", data.getException());
-            } else if (data == ContactLoader.Result.NOT_FOUND) {
+            } else if (data.isNotFound()) {
                 Log.i(TAG, "No contact found: " + ((ContactLoader)loader).getLookupUri());
                 mContactData = null;
             } else {
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index e9fbbbb..1790b9e 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -132,7 +132,6 @@
 
     private boolean mShowOptionsMenu;
 
-    private boolean mHasVoicemail = false;
 
     // Last number dialed, retrieved asynchronously from the call DB
     // in onCreate. This number is displayed when the user hits the
@@ -271,8 +270,6 @@
 
         mAdditionalButtonsRow = fragmentView.findViewById(R.id.dialpadAdditionalButtons);
 
-        initVoicemailButton();
-
         mSearchButton = mAdditionalButtonsRow.findViewById(R.id.searchButton);
         if (mSearchButton != null) {
             mSearchButton.setOnClickListener(this);
@@ -790,8 +787,15 @@
                 return true;
             }
             case R.id.one: {
-                if (mHasVoicemail && isDigitsEmpty()) {
-                    callVoicemail();
+                if (isDigitsEmpty()) {
+                    if (isVoicemailAvailable()) {
+                        callVoicemail();
+                    } else if (getActivity() != null) {
+                        DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
+                                R.string.dialog_voicemail_not_ready_title,
+                                R.string.dialog_voicemail_not_ready_message);
+                        dialogFragment.show(getFragmentManager(), "voicemail_not_ready");
+                    }
                     return true;
                 }
                 return false;
@@ -810,23 +814,57 @@
         getActivity().finish();
     }
 
-    public static class CallProhibitedDialogFragment extends DialogFragment {
-        public static CallProhibitedDialogFragment newInstance() {
-            return new CallProhibitedDialogFragment();
+    public static class ErrorDialogFragment extends DialogFragment {
+        private int mTitleResId;
+        private Integer mMessageResId;  // can be null
+
+        private static final String ARG_TITLE_RES_ID = "argTitleResId";
+        private static final String ARG_MESSAGE_RES_ID = "argMessageResId";
+
+        public static ErrorDialogFragment newInstance(int titleResId) {
+            return newInstanceInter(titleResId, null);
+        }
+
+        public static ErrorDialogFragment newInstance(int titleResId, int messageResId) {
+            return newInstanceInter(titleResId, messageResId);
+        }
+
+        private static ErrorDialogFragment newInstanceInter(
+                int titleResId, Integer messageResId) {
+            final ErrorDialogFragment fragment = new ErrorDialogFragment();
+            final Bundle args = new Bundle();
+            args.putInt(ARG_TITLE_RES_ID, titleResId);
+            if (messageResId != null) {
+                args.putInt(ARG_MESSAGE_RES_ID, messageResId);
+            }
+            fragment.setArguments(args);
+            return fragment;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID);
+            if (getArguments().containsKey(ARG_MESSAGE_RES_ID)) {
+                mMessageResId = getArguments().getInt(ARG_MESSAGE_RES_ID);
+            }
         }
 
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
-            return new AlertDialog.Builder(getActivity())
-                    .setTitle(R.string.phone_call_prohibited)
+            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+            builder.setTitle(mTitleResId)
                     .setPositiveButton(android.R.string.ok,
                             new DialogInterface.OnClickListener() {
                                 @Override
                                 public void onClick(DialogInterface dialog, int which) {
                                     dismiss();
                                 }
-                            })
-                    .create();
+                            });
+            if (mMessageResId != null) {
+                builder.setMessage(mMessageResId);
+            }
+            return builder.create();
         }
     }
 
@@ -892,14 +930,20 @@
                     && (SystemProperties.getInt("persist.radio.otaspdial", 0) != 1)) {
                 Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
                 if (getActivity() != null) {
-                    DialogFragment dialogFragment = CallProhibitedDialogFragment.newInstance();
+                    DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
+                                    R.string.dialog_phone_call_prohibited_title);
                     dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
                 }
 
                 // Clear the digits just in case.
                 mDigits.getText().clear();
             } else {
-                startActivity(newDialNumberIntent(number));
+                final Intent intent = newDialNumberIntent(number);
+                if (getActivity() instanceof DialtactsActivity) {
+                    intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN,
+                            DialtactsActivity.CALL_ORIGIN_DIALTACTS);
+                }
+                startActivity(intent);
                 mDigits.getText().clear();  // TODO: Fix bug 1745781
                 getActivity().finish();
             }
@@ -1285,13 +1329,19 @@
 
     /**
      * Check if voicemail is enabled/accessible.
+     *
+     * @return true if voicemail is enabled and accessibly. Note that this can be false
+     * "temporarily" after the app boot.
+     * @see TelephonyManager#getVoiceMailNumber()
      */
-    private void initVoicemailButton() {
+    private boolean isVoicemailAvailable() {
         try {
-            mHasVoicemail = TelephonyManager.getDefault().getVoiceMailNumber() != null;
+            return (TelephonyManager.getDefault().getVoiceMailNumber() != null);
         } catch (SecurityException se) {
             // Possibly no READ_PHONE_STATE privilege.
+            Log.w(TAG, "SecurityException is thrown. Maybe privilege isn't sufficient.");
         }
+        return false;
     }
 
     /**
diff --git a/src/com/android/contacts/dialpad/DigitsEditText.java b/src/com/android/contacts/dialpad/DigitsEditText.java
index 753afd4..68335da 100644
--- a/src/com/android/contacts/dialpad/DigitsEditText.java
+++ b/src/com/android/contacts/dialpad/DigitsEditText.java
@@ -59,9 +59,22 @@
     @Override
     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
         if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
-            // AsYouTypeFormatter frequently replaces digits with formatted ones, which makes
-            // tts too verbose. Let's ignore the whole event.
-            return;
+            // Since we're replacing the text every time we add or remove a
+            // character, only read the difference. (issue 5337550)
+            final int added = event.getAddedCount();
+            final int removed = event.getRemovedCount();
+            final int length = event.getBeforeText().length();
+            if (added > removed) {
+                event.setRemovedCount(0);
+                event.setAddedCount(1);
+                event.setFromIndex(length);
+            } else if (removed > added) {
+                event.setRemovedCount(1);
+                event.setAddedCount(0);
+                event.setFromIndex(length - 1);
+            } else {
+                return;
+            }
         } else if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
             // The parent EditText class lets tts read "edit box" when this View has a focus, which
             // confuses users on app launch (issue 5275935).
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index b341f83..844f892 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -398,7 +398,7 @@
         mAutoAddToDefaultGroup = mIntentExtras != null
                 && mIntentExtras.containsKey(INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY);
         mNewLocalProfile = mIntentExtras != null
-            && mIntentExtras.getBoolean(INTENT_EXTRA_NEW_LOCAL_PROFILE);
+                && mIntentExtras.getBoolean(INTENT_EXTRA_NEW_LOCAL_PROFILE);
     }
 
     public void setListener(Listener value) {
@@ -1033,7 +1033,7 @@
 
         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
         if (!EntityModifier.hasChanges(mState, accountTypes)) {
-            onSaveCompleted(false, saveMode, mLookupUri);
+            onSaveCompleted(false, saveMode, mLookupUri != null, mLookupUri);
             return true;
         }
 
@@ -1099,14 +1099,14 @@
     }
 
     public void onJoinCompleted(Uri uri) {
-        onSaveCompleted(false, SaveMode.RELOAD, uri);
+        onSaveCompleted(false, SaveMode.RELOAD, uri != null, uri);
     }
 
-    public void onSaveCompleted(boolean hadChanges, int saveMode, Uri contactLookupUri) {
-        boolean success = contactLookupUri != null;
+    public void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded,
+            Uri contactLookupUri) {
         Log.d(TAG, "onSaveCompleted(" + saveMode + ", " + contactLookupUri);
         if (hadChanges) {
-            if (success) {
+            if (saveSucceeded) {
                 if (saveMode != SaveMode.JOIN) {
                     Toast.makeText(mContext, R.string.contactSavedToast, Toast.LENGTH_SHORT).show();
                 }
@@ -1118,7 +1118,7 @@
             case SaveMode.CLOSE:
             case SaveMode.HOME:
                 final Intent resultIntent;
-                if (success && contactLookupUri != null) {
+                if (saveSucceeded && contactLookupUri != null) {
                     final String requestAuthority =
                             mLookupUri == null ? null : mLookupUri.getAuthority();
 
@@ -1149,7 +1149,7 @@
 
             case SaveMode.RELOAD:
             case SaveMode.JOIN:
-                if (success && contactLookupUri != null) {
+                if (saveSucceeded && contactLookupUri != null) {
                     // If it was a JOIN, we are now ready to bring up the join activity.
                     if (saveMode == SaveMode.JOIN) {
                         showJoinAggregateActivity(contactLookupUri);
@@ -1710,7 +1710,7 @@
         public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
             final long loaderCurrentTime = SystemClock.elapsedRealtime();
             Log.v(TAG, "Time needed for loading: " + (loaderCurrentTime-mLoaderStartTime));
-            if (data == ContactLoader.Result.NOT_FOUND || data.isError()) {
+            if (!data.isLoaded()) {
                 // Item has been deleted
                 Log.i(TAG, "No contact found. Closing activity");
                 if (mListener != null) mListener.onContactNotFound();
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 118ca26..3a40a0f 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -195,8 +195,12 @@
                 accountType = mContext.getString(R.string.account_phone);
             }
             if (!TextUtils.isEmpty(accountName)) {
+                mAccountNameTextView.setVisibility(View.VISIBLE);
                 mAccountNameTextView.setText(
                         mContext.getString(R.string.from_account_format, accountName));
+            } else {
+                // Hide this view so the other text view will be centered vertically
+                mAccountNameTextView.setVisibility(View.GONE);
             }
             mAccountTypeTextView.setText(
                     mContext.getString(R.string.account_type_format, accountType));
@@ -278,6 +282,7 @@
                             // collapse them again.
                             addOrganizationButton.setVisibility(View.GONE);
                             organizationSectionViewContainer.setVisibility(View.VISIBLE);
+                            organizationSectionViewContainer.requestFocus();
                         }
                     });
 
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index 9e1085d..2cc5d98 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -148,8 +148,12 @@
                 accountType = mContext.getString(R.string.account_phone);
             }
             if (!TextUtils.isEmpty(mAccountName)) {
+                mAccountNameTextView.setVisibility(View.VISIBLE);
                 mAccountNameTextView.setText(
                         mContext.getString(R.string.from_account_format, mAccountName));
+            } else {
+                // Hide this view so the other text view will be centered vertically
+                mAccountNameTextView.setVisibility(View.GONE);
             }
             mAccountTypeTextView.setText(mContext.getString(R.string.account_type_format,
                     accountType));
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 5a2ffd3..6911628 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -77,18 +77,18 @@
         if (!isFieldChanged(column, value)) {
             return;
         }
+        super.onFieldChanged(column, value);
 
         mChanged = true;
 
+        // Make sure the display name and the structured name are synced
         if (hasShortAndLongForms()) {
             if (areOptionalFieldsVisible()) {
-                eraseFullName(getValues());
+                rebuildFullName(getValues());
             } else {
-                eraseStructuredName(getValues());
+                rebuildStructuredName(getValues());
             }
         }
-
-        super.onFieldChanged(column, value);
     }
 
     @Override
@@ -165,12 +165,28 @@
         values.putNull(StructuredName.DISPLAY_NAME);
     }
 
+    private void rebuildFullName(ValuesDelta values) {
+        Map<String, String> structuredNameMap = valuesToStructuredNameMap(values);
+        String displayName = NameConverter.structuredNameToDisplayName(getContext(),
+                structuredNameMap);
+        values.put(StructuredName.DISPLAY_NAME, displayName);
+    }
+
     private void eraseStructuredName(ValuesDelta values) {
         for (String field : NameConverter.STRUCTURED_NAME_FIELDS) {
             values.putNull(field);
         }
     }
 
+    private void rebuildStructuredName(ValuesDelta values) {
+        String displayName = values.getAsString(StructuredName.DISPLAY_NAME);
+        Map<String, String> structuredNameMap = NameConverter.displayNameToStructuredName(
+                getContext(), displayName);
+        for (String field : structuredNameMap.keySet()) {
+            values.put(field, structuredNameMap.get(field));
+        }
+    }
+
     private static void appendQueryParameter(Uri.Builder builder, String field, String value) {
         if (!TextUtils.isEmpty(value)) {
             builder.appendQueryParameter(field, value);
diff --git a/src/com/android/contacts/group/GroupDetailDisplayUtils.java b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
index bb4cd5c..da5e0e9 100644
--- a/src/com/android/contacts/group/GroupDetailDisplayUtils.java
+++ b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
@@ -24,6 +24,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 public class GroupDetailDisplayUtils {
 
@@ -39,13 +40,21 @@
 
     public static void bindGroupSourceView(Context context, View view, String accountTypeString,
             String dataSet) {
-        ImageView accountIcon = (ImageView) view.findViewById(android.R.id.icon);
-        if (accountIcon == null) {
-            throw new IllegalStateException("Group source view must contain view with id"
-                    + "android.R.id.icon");
-        }
         AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context);
         AccountType accountType = accountTypeManager.getAccountType(accountTypeString, dataSet);
+
+        TextView label = (TextView) view.findViewById(android.R.id.title);
+        if (label == null) {
+            throw new IllegalStateException("Group source view must contain a TextView with id"
+                    + "android.R.id.label");
+        }
+        label.setText(accountType.getViewGroupLabel(context));
+
+        ImageView accountIcon = (ImageView) view.findViewById(android.R.id.icon);
+        if (accountIcon == null) {
+            throw new IllegalStateException("Group source view must contain an ImageView with id"
+                    + "android.R.id.icon");
+        }
         accountIcon.setImageDrawable(accountType.getDisplayIcon(context));
     }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
index 078f63e..e0b617c 100644
--- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
@@ -71,11 +71,11 @@
 
         // Adapter that shows a list of string resources
         final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(getActivity(),
-                android.R.layout.select_dialog_item) {
+                R.layout.select_dialog_item) {
             @Override
             public View getView(int position, View convertView, ViewGroup parent) {
                 final TextView result = (TextView)(convertView != null ? convertView :
-                        dialogInflater.inflate(android.R.layout.select_dialog_item, parent, false));
+                        dialogInflater.inflate(R.layout.select_dialog_item, parent, false));
 
                 final int resId = getItem(position);
                 result.setText(resId);
@@ -127,7 +127,6 @@
         };
         return new AlertDialog.Builder(getActivity())
                 .setTitle(R.string.dialog_import_export)
-                .setNegativeButton(android.R.string.cancel, null)
                 .setSingleChoiceItems(adapter, -1, clickListener)
                 .create();
     }
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 918dac0..d10ec06 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -19,15 +19,13 @@
 import com.android.contacts.Collapser;
 import com.android.contacts.Collapser.Collapsible;
 import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
+import com.android.contacts.activities.DialtactsActivity;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountType.StringInflater;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.DataKind;
-import com.android.i18n.phonenumbers.NumberParseException;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
-import com.android.i18n.phonenumbers.PhoneNumberUtil.MatchType;
-import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
 import com.google.common.annotations.VisibleForTesting;
 
 import android.app.Activity;
@@ -52,7 +50,6 @@
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
-import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -123,18 +120,8 @@
         }
 
         public boolean shouldCollapseWith(PhoneItem phoneItem) {
-            try {
-                PhoneNumberUtil util = PhoneNumberUtil.getInstance();
-                PhoneNumber phoneNumber1 = util.parse(phoneNumber, "ZZ" /* Unknown */);
-                PhoneNumber phoneNumber2 = util.parse(phoneItem.phoneNumber, "ZZ" /* Unknown */);
-                MatchType matchType = util.isNumberMatch(phoneNumber1, phoneNumber2);
-                if (matchType == MatchType.SHORT_NSN_MATCH) {
-                    return true;
-                }
-            } catch (NumberParseException e) {
-                return TextUtils.equals(phoneNumber, phoneItem.phoneNumber);
-            }
-            return false;
+            return ContactsUtils.shouldCollapse(Phone.CONTENT_ITEM_TYPE, phoneNumber,
+                    Phone.CONTENT_ITEM_TYPE, phoneItem.phoneNumber);
         }
 
         @Override
@@ -206,17 +193,21 @@
 
         private static final String ARG_PHONE_LIST = "phoneList";
         private static final String ARG_INTERACTION_TYPE = "interactionType";
+        private static final String ARG_CALL_ORIGIN = "callOrigin";
 
         private InteractionType mInteractionType;
         private ListAdapter mPhonesAdapter;
         private List<PhoneItem> mPhoneList;
+        private String mCallOrigin;
 
         public static void show(FragmentManager fragmentManager,
-                ArrayList<PhoneItem> phoneList, InteractionType interactionType) {
+                ArrayList<PhoneItem> phoneList, InteractionType interactionType,
+                String callOrigin) {
             PhoneDisambiguationDialogFragment fragment = new PhoneDisambiguationDialogFragment();
             Bundle bundle = new Bundle();
             bundle.putParcelableArrayList(ARG_PHONE_LIST, phoneList);
             bundle.putSerializable(ARG_INTERACTION_TYPE, interactionType);
+            bundle.putString(ARG_CALL_ORIGIN, callOrigin);
             fragment.setArguments(bundle);
             fragment.show(fragmentManager, TAG);
         }
@@ -227,6 +218,8 @@
             mPhoneList = getArguments().getParcelableArrayList(ARG_PHONE_LIST);
             mInteractionType =
                     (InteractionType) getArguments().getSerializable(ARG_INTERACTION_TYPE);
+            mCallOrigin = getArguments().getString(ARG_CALL_ORIGIN);
+
             mPhonesAdapter = new PhoneItemAdapter(activity, mPhoneList, mInteractionType);
             final LayoutInflater inflater = activity.getLayoutInflater();
             final View setPrimaryView = inflater.inflate(R.layout.set_primary_checkbox, null);
@@ -251,7 +244,7 @@
                 }
 
                 PhoneNumberInteraction.performAction(getActivity(), phoneItem.phoneNumber,
-                        mInteractionType);
+                        mInteractionType, mCallOrigin);
             } else {
                 dialog.dismiss();
             }
@@ -275,22 +268,31 @@
     private final OnDismissListener mDismissListener;
     private final InteractionType mInteractionType;
 
+    private final String mCallOrigin;
+
     private CursorLoader mLoader;
 
     @VisibleForTesting
     /* package */ PhoneNumberInteraction(Context context, InteractionType interactionType,
             DialogInterface.OnDismissListener dismissListener) {
+        this(context, interactionType, dismissListener, null);
+    }
+
+    private PhoneNumberInteraction(Context context, InteractionType interactionType,
+            DialogInterface.OnDismissListener dismissListener, String callOrigin) {
         mContext = context;
         mInteractionType = interactionType;
         mDismissListener = dismissListener;
+        mCallOrigin = callOrigin;
     }
 
     private void performAction(String phoneNumber) {
-        PhoneNumberInteraction.performAction(mContext, phoneNumber, mInteractionType);
+        PhoneNumberInteraction.performAction(mContext, phoneNumber, mInteractionType, mCallOrigin);
     }
 
     private static void performAction(
-            Context context, String phoneNumber, InteractionType interactionType) {
+            Context context, String phoneNumber, InteractionType interactionType,
+            String callOrigin) {
         Intent intent;
         switch (interactionType) {
             case SMS:
@@ -300,6 +302,9 @@
             default:
                 intent = new Intent(
                         Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", phoneNumber, null));
+                if (callOrigin != null) {
+                    intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin);
+                }
                 break;
         }
         context.startActivity(intent);
@@ -411,6 +416,17 @@
     }
 
     /**
+     * @param callOrigin If non null, {@link DialtactsActivity#EXTRA_CALL_ORIGIN} will be
+     * appended to the Intent initiating phone call. See comments in Phone package (PhoneApp)
+     * for more detail.
+     */
+    public static void startInteractionForPhoneCall(Activity activity, Uri uri,
+            String callOrigin) {
+        (new PhoneNumberInteraction(activity, InteractionType.PHONE_CALL, null, callOrigin))
+                .startInteraction(uri);
+    }
+
+    /**
      * Start text messaging (a.k.a SMS) action using given contact Uri. If there are multiple
      * candidates for the phone call, dialog is automatically shown and the user is asked to choose
      * one.
@@ -431,6 +447,6 @@
     @VisibleForTesting
     /* package */ void showDisambiguationDialog(ArrayList<PhoneItem> phoneList) {
         PhoneDisambiguationDialogFragment.show(((Activity)mContext).getFragmentManager(),
-                phoneList, mInteractionType);
+                phoneList, mInteractionType, mCallOrigin);
     }
 }
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index 304b109..a12b127 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -513,9 +513,16 @@
                 contactTile = (ContactTileView) inflate(mContext, mLayoutResId, null);
                 // Note: the layoutparam set here is only actually used for FREQUENT.
                 // We override onMeasure() for STARRED and we don't care the layout param there.
-                contactTile.setLayoutParams(new FrameLayout.LayoutParams(
+                Resources resources = mContext.getResources();
+                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                         ViewGroup.LayoutParams.WRAP_CONTENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT));
+                        ViewGroup.LayoutParams.WRAP_CONTENT);
+                params.setMargins(
+                        resources.getDimensionPixelSize(R.dimen.detail_item_side_margin),
+                        0,
+                        resources.getDimensionPixelSize(R.dimen.detail_item_side_margin),
+                        0);
+                contactTile.setLayoutParams(params);
                 contactTile.setPhotoManager(mPhotoManager);
                 contactTile.setListener(mContactTileListener);
                 addView(contactTile);
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index 608d3ad..30c3c48 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -49,7 +49,7 @@
     private View mProfileHeader;
     private Button mProfileMessage;
     private FrameLayout mMessageContainer;
-    private View mProfileTitle;
+    private TextView mProfileTitle;
 
     private View mPaddingView;
 
@@ -273,7 +273,8 @@
         mProfileHeaderContainer = new FrameLayout(inflater.getContext());
         mProfileHeader = inflater.inflate(R.layout.user_profile_header, null, false);
         mCounterHeaderView = (TextView) mProfileHeader.findViewById(R.id.contacts_count);
-        mProfileTitle = mProfileHeader.findViewById(R.id.profile_title);
+        mProfileTitle = (TextView) mProfileHeader.findViewById(R.id.profile_title);
+        mProfileTitle.setAllCaps(true);
         mProfileHeaderContainer.addView(mProfileHeader);
         list.addHeaderView(mProfileHeaderContainer, null, false);
 
diff --git a/src/com/android/contacts/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index 938d43a..015a364 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -55,6 +55,9 @@
 
     private static final String KEY_FILTER = "filter";
 
+    /** true if the loader has started at least once. */
+    private boolean mLoaderStarted;
+
     // A complete copy from DefaultContactBrowserListFragment
     // TODO: should be able to share logic around filter header.
     private class FilterHeaderClickListener implements OnClickListener {
@@ -204,6 +207,12 @@
     }
 
     @Override
+    protected void startLoading() {
+        mLoaderStarted = true;
+        super.startLoading();
+    }
+
+    @Override
     protected ContactEntryListAdapter createListAdapter() {
         if (!isLegacyCompatibilityMode()) {
             PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
@@ -272,7 +281,11 @@
             ContactListFilter.storeToPreferences(mPrefs, mFilter);
         }
 
-        reloadData();
+        // This method can be called before {@link #onStart} where we start the loader.  In that
+        // case we shouldn't start the loader yet, as we haven't done all initialization yet.
+        if (mLoaderStarted) {
+            reloadData();
+        }
         updateFilterHeaderView();
     }
 }
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/AccountType.java
index 21e17bd..15158dc 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/AccountType.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.model;
 
+import com.android.contacts.R;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 import com.google.common.annotations.VisibleForTesting;
@@ -148,7 +149,14 @@
     /**
      * @return resource ID for the "invite contact" action label, or -1 if not defined.
      */
-    protected int getInviteContactActionResId(Context context) {
+    protected int getInviteContactActionResId() {
+        return -1;
+    }
+
+    /**
+     * @return resource ID for the "view group" label, or -1 if not defined.
+     */
+    protected int getViewGroupLabelResId() {
         return -1;
     }
 
@@ -174,8 +182,20 @@
      * the contact card.  (If not defined, returns null.)
      */
     public CharSequence getInviteContactActionLabel(Context context) {
-        return getResourceText(context, summaryResPackageName, getInviteContactActionResId(context),
-                "");
+        return getResourceText(context, summaryResPackageName, getInviteContactActionResId(), "");
+    }
+
+    /**
+     * Returns a label for the "view group" action. If not defined, this falls back to our
+     * own "View Updates" string
+     */
+    public CharSequence getViewGroupLabel(Context context) {
+        final CharSequence customTitle =
+                getResourceText(context, summaryResPackageName, getViewGroupLabelResId(), null);
+
+        return customTitle == null
+                ? context.getText(R.string.view_updates_from_group)
+                : customTitle;
     }
 
     /**
diff --git a/src/com/android/contacts/model/DataKind.java b/src/com/android/contacts/model/DataKind.java
index 40f6f99..b0b3f38 100644
--- a/src/com/android/contacts/model/DataKind.java
+++ b/src/com/android/contacts/model/DataKind.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2011 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.contacts.model;
 
 import com.android.contacts.R;
diff --git a/src/com/android/contacts/model/ExternalAccountType.java b/src/com/android/contacts/model/ExternalAccountType.java
index ca064c7..0518ea5 100644
--- a/src/com/android/contacts/model/ExternalAccountType.java
+++ b/src/com/android/contacts/model/ExternalAccountType.java
@@ -57,6 +57,7 @@
     private static final String ATTR_INVITE_CONTACT_ACTION_LABEL = "inviteContactActionLabel";
     private static final String ATTR_VIEW_CONTACT_NOTIFY_SERVICE = "viewContactNotifyService";
     private static final String ATTR_VIEW_GROUP_ACTIVITY = "viewGroupActivity";
+    private static final String ATTR_VIEW_GROUP_ACTION_LABEL = "viewGroupActionLabel";
     private static final String ATTR_VIEW_STREAM_ITEM_ACTIVITY = "viewStreamItemActivity";
     private static final String ATTR_VIEW_STREAM_ITEM_PHOTO_ACTIVITY =
             "viewStreamItemPhotoActivity";
@@ -75,12 +76,14 @@
     private String mCreateContactActivityClassName;
     private String mInviteContactActivity;
     private String mInviteActionLabelAttribute;
+    private int mInviteActionLabelResId;
     private String mViewContactNotifyService;
     private String mViewGroupActivity;
+    private String mViewGroupLabelAttribute;
+    private int mViewGroupLabelResId;
     private String mViewStreamItemActivity;
     private String mViewStreamItemPhotoActivity;
     private List<String> mExtensionPackageNames;
-    private int mInviteActionLabelResId;
     private String mAccountTypeLabelAttribute;
     private String mAccountTypeIconAttribute;
     private boolean mInitSuccessful;
@@ -111,6 +114,8 @@
         mExtensionPackageNames = new ArrayList<String>();
         mInviteActionLabelResId = resolveExternalResId(context, mInviteActionLabelAttribute,
                 summaryResPackageName, ATTR_INVITE_CONTACT_ACTION_LABEL);
+        mViewGroupLabelResId = resolveExternalResId(context, mViewGroupLabelAttribute,
+                summaryResPackageName, ATTR_VIEW_GROUP_ACTION_LABEL);
         titleRes = resolveExternalResId(context, mAccountTypeLabelAttribute,
                 this.resPackageName, ATTR_ACCOUNT_LABEL);
         iconRes = resolveExternalResId(context, mAccountTypeIconAttribute,
@@ -167,7 +172,7 @@
     }
 
     @Override
-    protected int getInviteContactActionResId(Context context) {
+    protected int getInviteContactActionResId() {
         return mInviteActionLabelResId;
     }
 
@@ -182,6 +187,11 @@
     }
 
     @Override
+    protected int getViewGroupLabelResId() {
+        return mViewGroupLabelResId;
+    }
+
+    @Override
     public String getViewStreamItemActivity() {
         return mViewStreamItemActivity;
     }
@@ -242,6 +252,8 @@
                     mViewContactNotifyService = value;
                 } else if (ATTR_VIEW_GROUP_ACTIVITY.equals(attr)) {
                     mViewGroupActivity = value;
+                } else if (ATTR_VIEW_GROUP_ACTION_LABEL.equals(attr)) {
+                    mViewGroupLabelAttribute = value;
                 } else if (ATTR_VIEW_STREAM_ITEM_ACTIVITY.equals(attr)) {
                     mViewStreamItemActivity = value;
                 } else if (ATTR_VIEW_STREAM_ITEM_PHOTO_ACTIVITY.equals(attr)) {
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 2066997..84a34bd 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
 
 import com.android.contacts.ContactsUtils;
@@ -5,6 +21,7 @@
 import com.android.contacts.model.AccountType.EditType;
 import com.android.contacts.model.DataKind;
 import com.android.contacts.util.Constants;
+import com.android.contacts.util.StructuredPostalUtils;
 import com.android.contacts.util.PhoneCapabilityTester;
 
 import android.content.ContentUris;
@@ -19,6 +36,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.CommonDataKinds.Website;
 import android.provider.ContactsContract.Data;
 import android.text.TextUtils;
@@ -186,6 +204,11 @@
                     }
                 }
             }
+        } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            final String postalAddress = getAsString(cursor, StructuredPostal.FORMATTED_ADDRESS);
+            if (!TextUtils.isEmpty(postalAddress)) {
+                mIntent = StructuredPostalUtils.getViewPostalAddressIntent(postalAddress);
+            }
         }
 
         if (mIntent == null) {
@@ -294,8 +317,7 @@
             return false;
         }
         DataAction that = (DataAction)t;
-        if (!ContactsUtils.shouldCollapse(mContext, mMimeType, mBody, that.mMimeType,
-                that.mBody)) {
+        if (!ContactsUtils.shouldCollapse(mMimeType, mBody, that.mMimeType, that.mBody)) {
             return false;
         }
         if (!TextUtils.equals(mMimeType, that.mMimeType)
diff --git a/src/com/android/contacts/quickcontact/QuickContactListFragment.java b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
index cd899fa..962f07f 100644
--- a/src/com/android/contacts/quickcontact/QuickContactListFragment.java
+++ b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
@@ -25,8 +25,6 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -100,14 +98,14 @@
                         android.R.id.text1);
                 final TextView text2 = (TextView) resultView.findViewById(
                         android.R.id.text2);
-                final View primaryActionContainer = resultView.findViewById(
-                        R.id.primary_action_view_container);
+                final View actionsContainer = resultView.findViewById(
+                        R.id.actions_view_container);
                 final ImageView alternateActionButton = (ImageView) resultView.findViewById(
                         R.id.secondary_action_button);
                 final View alternateActionDivider = resultView.findViewById(R.id.vertical_divider);
 
-                primaryActionContainer.setOnClickListener(mPrimaryActionClickListener);
-                primaryActionContainer.setTag(action);
+                actionsContainer.setOnClickListener(mPrimaryActionClickListener);
+                actionsContainer.setTag(action);
                 alternateActionButton.setOnClickListener(mSecondaryActionClickListener);
                 alternateActionButton.setTag(action);
 
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index 9f7e18f..2ce15ff 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -133,7 +133,7 @@
         final RemoteViews views = new RemoteViews(context.getPackageName(),
                 R.layout.social_widget);
 
-        if (contactData.isError() || contactData == ContactLoader.Result.NOT_FOUND) {
+        if (!contactData.isLoaded()) {
             setDisplayNameAndSnippet(context, views,
                     context.getString(R.string.invalidContactMessage), null, null, null);
             setPhoto(views, ContactBadgeUtil.loadDefaultAvatarPhoto(context, false, false));
diff --git a/src/com/android/contacts/util/Constants.java b/src/com/android/contacts/util/Constants.java
index d79f029..3a43c40 100644
--- a/src/com/android/contacts/util/Constants.java
+++ b/src/com/android/contacts/util/Constants.java
@@ -25,7 +25,27 @@
     public static final String SCHEME_IMTO = "imto";
     public static final String SCHEME_SIP = "sip";
 
-    // Log tag for performance measurement.
-    // To enable: adb shell setprop log.tag.ContactsPerf VERBOSE
+    /**
+     * Log tag for performance measurement.
+     * To enable: adb shell setprop log.tag.ContactsPerf VERBOSE
+     */
     public static final String PERFORMANCE_TAG = "ContactsPerf";
+
+    /**
+     * Log tag for enabling/disabling LoaderManager log.
+     * To enable: adb shell setprop log.tag.ContactsLoaderManager DEBUG
+     */
+    public static final String LOADER_MANAGER_TAG = "ContactsLoaderManager";
+
+    /**
+     * Log tag for enabling/disabling FragmentManager log.
+     * To enable: adb shell setprop log.tag.ContactsFragmentManager DEBUG
+     */
+    public static final String FRAGMENT_MANAGER_TAG = "ContactsFragmentManager";
+
+    /**
+     * Log tag for enabling/disabling StrictMode violation log.
+     * To enable: adb shell setprop log.tag.ContactsStrictMode DEBUG
+     */
+    public static final String STRICT_MODE_TAG = "ContactsStrictMode";
 }
diff --git a/src/com/android/contacts/util/HtmlUtils.java b/src/com/android/contacts/util/HtmlUtils.java
index faaa9c2..a3c9c64 100644
--- a/src/com/android/contacts/util/HtmlUtils.java
+++ b/src/com/android/contacts/util/HtmlUtils.java
@@ -1,5 +1,24 @@
+/*
+ * Copyright (C) 2011 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.contacts.util;
 
+import com.android.contacts.R;
+import com.google.common.annotations.VisibleForTesting;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.text.Html;
@@ -11,8 +30,6 @@
 import android.text.style.ImageSpan;
 import android.text.style.QuoteSpan;
 
-import com.android.contacts.R;
-
 /**
  * Provides static functions to perform custom HTML to text conversions.
  * Specifically, it adjusts the color and padding of the vertical
@@ -21,43 +38,53 @@
 public class HtmlUtils {
 
     /**
-     * Converts HTML string to a {@link Spanned} text, adjusting formatting.
+     * Converts HTML string to a {@link Spanned} text, adjusting formatting. Any extra new line
+     * characters at the end of the text will be trimmed.
      */
     public static Spanned fromHtml(Context context, String text) {
         if (TextUtils.isEmpty(text)) {
             return null;
         }
         Spanned spanned = Html.fromHtml(text);
-        postprocess(context, spanned);
-        return spanned;
+        return postprocess(context, spanned);
     }
 
     /**
      * Converts HTML string to a {@link Spanned} text, adjusting formatting and using a custom
-     * image getter.
+     * image getter. Any extra new line characters at the end of the text will be trimmed.
      */
     public static CharSequence fromHtml(Context context, String text, ImageGetter imageGetter,
             TagHandler tagHandler) {
         if (TextUtils.isEmpty(text)) {
             return null;
         }
-        Spanned spanned = Html.fromHtml(text, imageGetter, tagHandler);
-        postprocess(context, spanned);
-        return spanned;
+        return postprocess(context, Html.fromHtml(text, imageGetter, tagHandler));
     }
 
     /**
-     * Replaces some spans with custom versions of those.
+     * Replaces some spans with custom versions of those. Any extra new line characters at the end
+     * of the text will be trimmed.
      */
-    private static void postprocess(Context context, Spanned spanned) {
-        if (!(spanned instanceof SpannableStringBuilder)) {
-            return;
+    @VisibleForTesting
+    static Spanned postprocess(Context context, Spanned original) {
+        if (original == null) {
+            return null;
+        }
+        final int length = original.length();
+        if (length == 0) {
+            return original; // Bail early.
         }
 
-        int length = spanned.length();
+        // If it's a SpannableStringBuilder, just use it.  Otherwise, create a new
+        // SpannableStringBuilder based on the passed Spanned.
+        final SpannableStringBuilder builder;
+        if (original instanceof SpannableStringBuilder) {
+            builder = (SpannableStringBuilder) original;
+        } else {
+            builder = new SpannableStringBuilder(original);
+        }
 
-        SpannableStringBuilder builder = (SpannableStringBuilder)spanned;
-        QuoteSpan[] quoteSpans = spanned.getSpans(0, length, QuoteSpan.class);
+        final QuoteSpan[] quoteSpans = builder.getSpans(0, length, QuoteSpan.class);
         if (quoteSpans != null && quoteSpans.length != 0) {
             Resources resources = context.getResources();
             int color = resources.getColor(R.color.stream_item_stripe_color);
@@ -67,7 +94,7 @@
             }
         }
 
-        ImageSpan[] imageSpans = spanned.getSpans(0, length, ImageSpan.class);
+        final ImageSpan[] imageSpans = builder.getSpans(0, length, ImageSpan.class);
         if (imageSpans != null) {
             for (int i = 0; i < imageSpans.length; i++) {
                 ImageSpan span = imageSpans[i];
@@ -75,6 +102,25 @@
                         ImageSpan.ALIGN_BASELINE));
             }
         }
+
+        // Trim the trailing new line characters at the end of the text (which can be added
+        // when HTML block quote tags are turned into new line characters).
+        int end = length;
+        for (int i = builder.length() - 1; i >= 0; i--) {
+            if (builder.charAt(i) != '\n') {
+                break;
+            }
+            end = i;
+        }
+
+        // If there's no trailing newlines, just return it.
+        if (end == length) {
+            return builder;
+        }
+
+        // Otherwise, Return a substring of the original {@link Spanned} text
+        // from the start index (inclusive) to the end index (exclusive).
+        return new SpannableStringBuilder(builder, 0, end);
     }
 
     /**
diff --git a/src/com/android/contacts/util/PhoneNumberFormatter.java b/src/com/android/contacts/util/PhoneNumberFormatter.java
index 6e63aac..204ac69 100644
--- a/src/com/android/contacts/util/PhoneNumberFormatter.java
+++ b/src/com/android/contacts/util/PhoneNumberFormatter.java
@@ -49,9 +49,7 @@
             if (watcher == null || isCancelled()) {
                 return; // May happen if we cancel the task.
             }
-            if (mTextView.getHandler() == null) {
-                return; // View is already detached.
-            }
+            // Setting a text changed listener is safe even after the view is detached.
             mTextView.addTextChangedListener(watcher);
 
             // Note changes the user made before onPostExecute() will not be formatted, but
diff --git a/src/com/android/contacts/util/StructuredPostalUtils.java b/src/com/android/contacts/util/StructuredPostalUtils.java
new file mode 100644
index 0000000..59d38ea
--- /dev/null
+++ b/src/com/android/contacts/util/StructuredPostalUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 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.contacts.util;
+
+import android.content.Intent;
+import android.net.Uri;
+
+public class StructuredPostalUtils {
+    private StructuredPostalUtils() {
+    }
+
+    public static Intent getViewPostalAddressIntent(String postalAddress) {
+        return new Intent(Intent.ACTION_VIEW, getPostalAddressUri(postalAddress));
+    }
+
+    public static Uri getPostalAddressUri(String postalAddress) {
+        return Uri.parse("geo:0,0?q=" + Uri.encode(postalAddress));
+    }
+}
diff --git a/src/com/android/contacts/util/ThemeUtils.java b/src/com/android/contacts/util/ThemeUtils.java
index d1784b6..d8326d5 100644
--- a/src/com/android/contacts/util/ThemeUtils.java
+++ b/src/com/android/contacts/util/ThemeUtils.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2011 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.contacts.util;
 
 import android.content.res.Resources.Theme;
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java b/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
index df4d9af..8912a74 100644
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
+++ b/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
@@ -266,7 +266,7 @@
 
         @Override
         public void playbackStopped() {
-            mStartStopButton.setImageResource(R.drawable.ic_play_holo_dark);
+            mStartStopButton.setImageResource(R.drawable.ic_play);
         }
 
         @Override
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
index becc133..9a84f7c 100644
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
+++ b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
@@ -555,9 +555,11 @@
             public void run() {
                 int currentPosition = 0;
                 synchronized (mLock) {
-                    if (mScheduledFuture != null) {
-                        currentPosition = mPlayer.getCurrentPosition();
+                    if (mScheduledFuture == null) {
+                        // This task has been canceled. Just stop now.
+                        return;
                     }
+                    currentPosition = mPlayer.getCurrentPosition();
                 }
                 mView.setClipPosition(currentPosition, mDuration.get());
             }
diff --git a/tests/res/xml/iconset.xml b/tests/res/xml/iconset.xml
index d910815..d1207e7 100644
--- a/tests/res/xml/iconset.xml
+++ b/tests/res/xml/iconset.xml
@@ -1,3 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
 <icon-set
     xmlns:android="http://schemas.android.com/apk/res/android">
 
diff --git a/tests/src/com/android/contacts/ContactDetailTest.java b/tests/src/com/android/contacts/ContactDetailTest.java
index 0b850b7..e8d1550 100644
--- a/tests/src/com/android/contacts/ContactDetailTest.java
+++ b/tests/src/com/android/contacts/ContactDetailTest.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 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.contacts;
 
 import com.android.contacts.activities.ContactDetailActivity;
diff --git a/tests/src/com/android/contacts/ContactsUtilsTests.java b/tests/src/com/android/contacts/ContactsUtilsTests.java
index 97a2c8e..82d0cb0 100644
--- a/tests/src/com/android/contacts/ContactsUtilsTests.java
+++ b/tests/src/com/android/contacts/ContactsUtilsTests.java
@@ -160,9 +160,9 @@
     private void assertCollapses(String message, boolean expected, CharSequence mimetype1,
             CharSequence data1, CharSequence mimetype2, CharSequence data2) {
         assertEquals(message, expected,
-                ContactsUtils.shouldCollapse(mContext, mimetype1, data1, mimetype2, data2));
+                ContactsUtils.shouldCollapse(mimetype1, data1, mimetype2, data2));
         assertEquals(message, expected,
-                ContactsUtils.shouldCollapse(mContext, mimetype2, data2, mimetype1, data1));
+                ContactsUtils.shouldCollapse(mimetype2, data2, mimetype1, data1));
 
         if (data1 == data2 && data1 != null) {
             // make sure we also do a test where object equality is not given
@@ -173,10 +173,10 @@
 
             // we have two different instances, now make sure we get the same result as before
             assertEquals(message, expected,
-                    ContactsUtils.shouldCollapse(mContext, mimetype1, data1, mimetype2,
+                    ContactsUtils.shouldCollapse(mimetype1, data1, mimetype2,
                     data2_newref));
             assertEquals(message, expected,
-                    ContactsUtils.shouldCollapse(mContext, mimetype2, data2_newref, mimetype1,
+                    ContactsUtils.shouldCollapse(mimetype2, data2_newref, mimetype1,
                     data1));
         }
     }
diff --git a/tests/src/com/android/contacts/model/AccountTypeTest.java b/tests/src/com/android/contacts/model/AccountTypeTest.java
index 9f7e7a2..42fe200 100644
--- a/tests/src/com/android/contacts/model/AccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/AccountTypeTest.java
@@ -69,7 +69,7 @@
                 resPackageName = packageName;
                 summaryResPackageName = packageName;
             }
-            @Override protected int getInviteContactActionResId(Context conext) {
+            @Override protected int getInviteContactActionResId() {
                 return externalResID;
             }
 
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
index a98b365..51c665f 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
@@ -27,13 +27,15 @@
  */
 public class MockContactPhotoManager extends ContactPhotoManager {
     @Override
-    public void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme) {
-        view.setImageResource(getDefaultAvatarResId(hires, darkTheme));
+    public void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme,
+            DefaultImageProvider defaultProvider) {
+        defaultProvider.applyDefaultImage(view, hires, darkTheme);
     }
 
     @Override
-    public void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme) {
-        view.setImageResource(getDefaultAvatarResId(hires, darkTheme));
+    public void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme,
+            DefaultImageProvider defaultProvider) {
+        defaultProvider.applyDefaultImage(view, hires, darkTheme);
     }
 
     @Override
diff --git a/tests/src/com/android/contacts/util/HtmlUtilsTest.java b/tests/src/com/android/contacts/util/HtmlUtilsTest.java
new file mode 100644
index 0000000..115f289
--- /dev/null
+++ b/tests/src/com/android/contacts/util/HtmlUtilsTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011 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.contacts.util;
+
+import com.android.contacts.util.HtmlUtils.StreamItemQuoteSpan;
+
+import android.graphics.drawable.ColorDrawable;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.SpannedString;
+import android.text.style.ImageSpan;
+import android.text.style.QuoteSpan;
+
+/**
+ * Tests for {@link HtmlUtils}.
+ *
+ * adb shell am instrument -w -e class com.android.contacts.util.HtmlUtilsTest \
+       com.android.contacts.tests/android.test.InstrumentationTestRunner
+ */
+@SmallTest
+public class HtmlUtilsTest extends AndroidTestCase {
+    /**
+     * Test for {@link HtmlUtils#postprocess} specifically about trimming newlines.
+     */
+    public void testPostProcess_trimNewLines() {
+        checkTrimNewLines("", "");
+        checkTrimNewLines("", "\n");
+        checkTrimNewLines("", "\n\n");
+        checkTrimNewLines("a", "a");
+        checkTrimNewLines("abc", "abc");
+        checkTrimNewLines("abc", "abc\n");
+        checkTrimNewLines("abc", "abc\n\n\n");
+        checkTrimNewLines("ab\nc", "ab\nc\n");
+
+        assertNull(HtmlUtils.postprocess(getContext(), null));
+    }
+
+    private final void checkTrimNewLines(String expectedString, CharSequence text) {
+        // Test with both SpannedString and SpannableStringBuilder.
+        assertEquals(expectedString,
+                HtmlUtils.postprocess(getContext(), new SpannedString(text)).toString());
+
+        assertEquals(expectedString,
+                HtmlUtils.postprocess(getContext(), new SpannableStringBuilder(text)).toString());
+    }
+
+    public void testPostProcess_with_newlines() {
+        final SpannableStringBuilder builder = new SpannableStringBuilder("01234\n\n");
+
+        setSpans(builder);
+
+        // First test with a SpannableStringBuilder, as opposed to SpannedString
+        checkPostProcess(HtmlUtils.postprocess(getContext(), builder));
+
+        // Then pass a SpannedString, which is immutable, but the method should still work.
+        checkPostProcess(HtmlUtils.postprocess(getContext(), new SpannedString(builder)));
+    }
+
+    /**
+     * Same as {@link #testPostProcess_with_newlines}, but text has no newlines.
+     * (The internal code path is slightly different.)
+     */
+    public void testPostProcess_no_newlines() {
+        final SpannableStringBuilder builder = new SpannableStringBuilder("01234");
+
+        setSpans(builder);
+
+        // First test with a SpannableStringBuilder, as opposed to SpannedString
+        checkPostProcess(HtmlUtils.postprocess(getContext(), builder));
+
+        // Then pass a SpannedString, which is immutable, but the method should still work.
+        checkPostProcess(HtmlUtils.postprocess(getContext(), new SpannedString(builder)));
+    }
+
+    private void setSpans(SpannableStringBuilder builder) {
+        builder.setSpan(new ImageSpan(new ColorDrawable(), ImageSpan.ALIGN_BOTTOM), 0, 2, 0);
+        builder.setSpan(new QuoteSpan(), 2, 4, 0);
+        builder.setSpan(new CustomSpan(), 4, builder.length(), 0);
+    }
+
+    private void checkPostProcess(Spanned ret) {
+        // Newlines should be trimmed.
+        assertEquals("01234", ret.toString());
+
+        // First, check the image span.
+        // - Vertical alignment should be changed to ALIGN_BASELINE
+        // - Drawable shouldn't be changed.
+        ImageSpan[] imageSpans = ret.getSpans(0, ret.length(), ImageSpan.class);
+        assertEquals(1, imageSpans.length);
+        assertEquals(ImageSpan.ALIGN_BASELINE, imageSpans[0].getVerticalAlignment());
+        assertEquals(ColorDrawable.class, imageSpans[0].getDrawable().getClass());
+
+        // QuoteSpans should be replaced with StreamItemQuoteSpans.
+        QuoteSpan[] quoteSpans = ret.getSpans(0, ret.length(), QuoteSpan.class);
+        assertEquals(1, quoteSpans.length);
+        assertEquals(StreamItemQuoteSpan.class, quoteSpans[0].getClass());
+
+        // Other spans should be preserved.
+        CustomSpan[] customSpans = ret.getSpans(0, ret.length(), CustomSpan.class);
+        assertEquals(1, customSpans.length);
+    }
+
+    /** Custom span class used in {@link #testPostProcess} */
+    private static class CustomSpan {
+    }
+}