auto import from //branches/cupcake_rel/...@140373
diff --git a/res/layout/compose_message_activity.xml b/res/layout/compose_message_activity.xml
index ab6ab7f..21bf1f6 100644
--- a/res/layout/compose_message_activity.xml
+++ b/res/layout/compose_message_activity.xml
@@ -166,7 +166,7 @@
                         android:layout_marginLeft="5dip"
                         android:layout_width="wrap_content"
                         android:layout_height="fill_parent"
-                        style="?android:attr/buttonStyleSmall"
+                        style="?android:attr/buttonStyle"
                         android:layout_gravity="center_vertical"
                         android:nextFocusLeft="@+id/embedded_text_editor"
                         android:text="@string/send"
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 6ca8785..45c0250 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Obnovování..."</string>
     <string name="has_draft">"Koncept"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anonymní"</string>
     <string name="no_subject_view">"(Předmět neuveden)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Přidat snímek"</string>
     <string name="add_slide_hint">"Umožňuje vytvořit nový snímek."</string>
     <string name="discard_slideshow">"Zahodit prezentaci"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Odstranit text"</string>
     <string name="add_picture">"Přidat fotografii"</string>
     <string name="remove_picture">"Odstranit fotografii"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Zpráva bude smazána."</string>
     <string name="confirm_delete_all_messages">"Celá konverzace bude smazána."</string>
     <string name="confirm_delete_all_SIM_messages">"Všechny zprávy na kartě SIM budou smazány."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Podrobnosti se nepodařilo zobrazit."</string>
     <string name="message_details_title">"Podrobnosti zprávy"</string>
     <string name="message_type_label">"Typ: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Horní text"</string>
     <string name="notification_multiple">"Nepřečtené zprávy: <xliff:g id="COUNT">%s</xliff:g>."</string>
     <string name="notification_multiple_title">"Nové zprávy"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"Paměť karty SIM je plná"</string>
     <string name="sim_full_body">"Smažte některé zprávy a vytvořte tak místo pro nové."</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index ee24574..c5f8ece 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Aktualisierung wird ausgeführt..."</string>
     <string name="has_draft">"Entwurf"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anonym"</string>
     <string name="no_subject_view">"(Kein Betreff)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Dia hinzufügen"</string>
     <string name="add_slide_hint">"Wählen Sie diese Option, um ein neues Dia zu erstellen."</string>
     <string name="discard_slideshow">"Diashow verwerfen"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Text entfernen"</string>
     <string name="add_picture">"Bild hinzufügen"</string>
     <string name="remove_picture">"Bild entfernen"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Die Nachricht wird gelöscht."</string>
     <string name="confirm_delete_all_messages">"Der gesamte Thread wird gelöscht."</string>
     <string name="confirm_delete_all_SIM_messages">"Alle Nachrichten auf der SIM werden gelöscht."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Details nicht abrufbar"</string>
     <string name="message_details_title">"Nachrichtendetails"</string>
     <string name="message_type_label">"Typ: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Text oben"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> ungelesene Nachrichten"</string>
     <string name="notification_multiple_title">"Neue Nachrichten"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM-Karte ist voll."</string>
     <string name="sim_full_body">"Löschen Sie einige Nachrichten, um Platz für weitere Nachrichten zu schaffen."</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 7673d42..33b6a0a 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Actualizando..."</string>
     <string name="has_draft">"Borrador"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anónimo"</string>
     <string name="no_subject_view">"(Sin asunto)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Añadir diapositiva"</string>
     <string name="add_slide_hint">"Selecciona esta opción para crear una diapositiva nueva."</string>
     <string name="discard_slideshow">"Descartar presentación"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Eliminar texto"</string>
     <string name="add_picture">"Añadir imagen"</string>
     <string name="remove_picture">"Eliminar imagen"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Se eliminará el mensaje."</string>
     <string name="confirm_delete_all_messages">"Se eliminará toda la cadena."</string>
     <string name="confirm_delete_all_SIM_messages">"Todos los mensajes se eliminarán de la tarjeta SIM."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"No se pueden obtener detalles."</string>
     <string name="message_details_title">"Detalles del mensaje"</string>
     <string name="message_type_label">"Tipo: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Texto arriba"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> mensajes no leídos"</string>
     <string name="notification_multiple_title">"Mensajes nuevos"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"Tarjeta SIM llena"</string>
     <string name="sim_full_body">"Elimina algunos mensajes para dejar espacio para otros."</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index ad14bb4..66b7a34 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Actualisation…"</string>
     <string name="has_draft">"Brouillon"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anonyme"</string>
     <string name="no_subject_view">"(Aucun objet)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Ajouter une diapositive"</string>
     <string name="add_slide_hint">"Sélectionner cet élément pour créer une nouvelle diapositive."</string>
     <string name="discard_slideshow">"Supprimer le diaporama"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Supprimer le texte"</string>
     <string name="add_picture">"Ajouter une image"</string>
     <string name="remove_picture">"Supprimer l\'image"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Le message va être supprimé."</string>
     <string name="confirm_delete_all_messages">"L\'intégralité du fil de discussion va être supprimée."</string>
     <string name="confirm_delete_all_SIM_messages">"Tous les messages de la carte SIM seront effacés."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Impossible de récupérer les détails"</string>
     <string name="message_details_title">"Détails du message"</string>
     <string name="message_type_label">"Type : "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Texte en haut de l\'écran"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> messages non lus."</string>
     <string name="notification_multiple_title">"Nouveaux messages"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"La carte SIM est pleine."</string>
     <string name="sim_full_body">"Supprimez des messages pour libérer de l\'espace."</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 86077a5..32d6269 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Aggiornamento..."</string>
     <string name="has_draft">"Bozza"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anonimo"</string>
     <string name="no_subject_view">"(Nessun oggetto)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Aggiungi diapositiva"</string>
     <string name="add_slide_hint">"Seleziona per creare nuova diapositiva."</string>
     <string name="discard_slideshow">"Ignora presentazione"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Rimuovi testo"</string>
     <string name="add_picture">"Aggiungi immagine"</string>
     <string name="remove_picture">"Rimuovi immagine"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Il messaggio verrà eliminato."</string>
     <string name="confirm_delete_all_messages">"Verrà eliminata l\'intera conversazione."</string>
     <string name="confirm_delete_all_SIM_messages">"Verranno eliminati tutti i messaggi nella SIM."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Impossibile ottenere i dettagli"</string>
     <string name="message_details_title">"Dettagli messaggio"</string>
     <string name="message_type_label">"Tipo: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Testo in alto"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> messaggi da leggere."</string>
     <string name="notification_multiple_title">"Nuovi messaggi"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM piena"</string>
     <string name="sim_full_body">"Elimina alcuni messaggi per liberare spazio."</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index d77f41d..0a534b2 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -18,7 +18,7 @@
     <string name="app_label">"メッセージ"</string>
     <string name="new_message">"新しいメッセージ"</string>
     <string name="create_new_message">"新しいメッセージを作成する"</string>
-    <string name="menu_call_back">"<xliff:g id="NAME">%s</xliff:g>さんに発信"</string>
+    <string name="menu_call_back">"発信 <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="menu_send_email">"<xliff:g id="NAME">%s</xliff:g>さんにメールを送信"</string>
     <string name="menu_compose_new">"作成"</string>
     <string name="menu_preferences">"設定"</string>
@@ -32,9 +32,9 @@
     <skip />
     <string name="refreshing">"更新中..."</string>
     <string name="has_draft">"下書き"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
-    <string name="anonymous_recipient">"差出人不明"</string>
+    <string name="anonymous_recipient">"非通知"</string>
     <string name="no_subject_view">"(件名なし)"</string>
     <string name="messagelist_sender_self">"自分"</string>
     <string name="view_picture">"画像を表示"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"スライドを追加"</string>
     <string name="add_slide_hint">"新しいスライドを作成します。"</string>
     <string name="discard_slideshow">"スライドショーを破棄"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"テキストを削除"</string>
     <string name="add_picture">"画像を追加"</string>
     <string name="remove_picture">"画像を削除"</string>
@@ -72,7 +74,7 @@
     <string name="add_video">"動画を追加"</string>
     <string name="remove_video">"動画を削除"</string>
     <string name="compose_title">"作成"</string>
-    <string name="to_hint">"宛先"</string>
+    <string name="to_hint">"To"</string>
     <string name="subject_hint">"件名"</string>
     <string name="add_attachment">"添付"</string>
     <string name="add_subject">"件名を追加"</string>
@@ -97,8 +99,8 @@
     <string name="forward_prefix">"Fwd: "</string>
     <string name="discard_message">"破棄"</string>
     <string name="discard_message_reason">"有効な宛先が指定されていないので、メッセージは破棄されます。"</string>
-    <string name="has_invalid_recipient">"無効な受信者:&lt;<xliff:g id="NAME">%1$s</xliff:g>&gt;"</string>
-    <string name="invalid_recipient_message">"受信者にメッセージが届くように、宛先を修正してください。"</string>
+    <string name="has_invalid_recipient">"不明な宛先: &lt;<xliff:g id="NAME">%1$s</xliff:g>&gt;"</string>
+    <string name="invalid_recipient_message">"宛先を修正してください。無効なアドレスがあります。"</string>
     <string name="cannot_send_message">"メッセージを送信できません"</string>
     <string name="cannot_send_message_reason">"メッセージに有効な宛先が指定されていません。"</string>
     <string name="cannot_forward_drm_obj">"メッセージ内のDRM対象は転送できません。"</string>
@@ -163,21 +165,23 @@
     <string name="pref_summary_mms_auto_retrieval">"メッセージを自動的に取得"</string>
     <string name="pref_title_mms_retrieval_during_roaming">"ローミングを自動的に取得"</string>
     <string name="pref_summary_mms_retrieval_during_roaming">"ローミング中にメッセージを自動的に取得する"</string>
-    <string name="to_label">"宛先 "</string>
+    <string name="to_label">"To "</string>
     <string name="confirm_dialog_title">"削除"</string>
     <string name="confirm_delete_conversation">"スレッド全体が削除されます。"</string>
     <string name="confirm_delete_all_conversations">"スレッドはすべて削除されます。"</string>
     <string name="confirm_delete_message">"メッセージを削除します。"</string>
     <string name="confirm_delete_all_messages">"スレッド全体が削除されます。"</string>
     <string name="confirm_delete_all_SIM_messages">"SIMカードのすべてのメッセージが削除されます。"</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"詳細を表示できません"</string>
     <string name="message_details_title">"メッセージの詳細"</string>
     <string name="message_type_label">"タイプ: "</string>
     <string name="text_message">"SMSメッセージ"</string>
     <string name="multimedia_message">"MMSメッセージ"</string>
     <string name="multimedia_notification">"MMS通知"</string>
-    <string name="from_label">"差出人: "</string>
-    <string name="to_address_label">"宛先: "</string>
+    <string name="from_label">"From: "</string>
+    <string name="to_address_label">"To: "</string>
     <string name="bcc_label">"Bcc: "</string>
     <string name="sent_label">"送信: "</string>
     <string name="received_label">"受信: "</string>
@@ -207,7 +211,7 @@
     <string name="status_failed">"失敗"</string>
     <string name="status_unread">"未読"</string>
     <string name="status_rejected">"拒否"</string>
-    <string name="recipient_label">"受信者: "</string>
+    <string name="recipient_label">"宛先: "</string>
     <string name="status_label">"ステータス: "</string>
     <string name="attach_image">"画像"</string>
     <string name="attach_take_photo">"写真をキャプチャ"</string>
@@ -216,13 +220,13 @@
     <string name="attach_sound">"オーディオ"</string>
     <string name="attach_record_sound">"音声録音"</string>
     <string name="attach_slideshow">"スライドショー"</string>
-    <string name="select_bottom_text">"テキストを下に表示"</string>
-    <string name="select_top_text">"テキストを上に表示"</string>
+    <string name="select_bottom_text">"テキストを下に配置"</string>
+    <string name="select_top_text">"テキストを上に配置"</string>
     <string name="notification_multiple">"未読メッセージ<xliff:g id="COUNT">%s</xliff:g>通"</string>
     <string name="notification_multiple_title">"新しいメッセージ"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIMカード空き領域なし"</string>
     <string name="sim_full_body">"空き容量を増やすにはメッセージを削除します。"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 564b08c..cbaf408 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"새로 고치는 중..."</string>
     <string name="has_draft">"임시저장"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"익명"</string>
     <string name="no_subject_view">"(제목 없음)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"슬라이드 추가"</string>
     <string name="add_slide_hint">"새 슬라이드를 만드세요."</string>
     <string name="discard_slideshow">"슬라이드쇼 삭제"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"텍스트 삭제"</string>
     <string name="add_picture">"사진 추가"</string>
     <string name="remove_picture">"사진 삭제"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"메시지가 삭제됩니다."</string>
     <string name="confirm_delete_all_messages">"전체 대화가 삭제됩니다."</string>
     <string name="confirm_delete_all_SIM_messages">"SIM에 있는 모든 메일이 삭제됩니다."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"세부정보를 가져올 수 없음"</string>
     <string name="message_details_title">"메시지 세부정보"</string>
     <string name="message_type_label">"유형: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"텍스트를 위쪽에"</string>
     <string name="notification_multiple">"읽지 않은 메시지가 <xliff:g id="COUNT">%s</xliff:g>개 있습니다."</string>
     <string name="notification_multiple_title">"새 메시지"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM 카드 용량이 가득 참"</string>
     <string name="sim_full_body">"저장 공간을 늘리려면 메시지를 일부 삭제하세요."</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index aced8f2..cc6b52e 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -30,7 +30,7 @@
     <string name="menu_view">"Vis"</string>
     <string name="refreshing">"Synkroniserer…"</string>
     <string name="has_draft">"Utkast"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anonym"</string>
     <string name="no_subject_view">"(Mangler emne)"</string>
@@ -62,6 +62,8 @@
     <string name="add_slide">"Legg til lysbilde"</string>
     <string name="add_slide_hint">"Velg for å lage nytt bilde"</string>
     <string name="discard_slideshow">"Forkast bildeserie"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Fjern tekst"</string>
     <string name="add_picture">"Legg til bilde"</string>
     <string name="remove_picture">"Fjern bilde"</string>
@@ -169,6 +171,8 @@
     <string name="confirm_delete_all_messages">"Hele tråden vil bli slettet.BREAK_0BREAK_1BREAK_265701806463341097BREAK_3Alle meldinger på SIM-kortet vil bli slettet."</string>
     <!-- no translation found for confirm_delete_all_SIM_messages (65701806463341097) -->
     <skip />
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Kan ikke hente detaljer"</string>
     <string name="message_details_title">"Meldingsdetaljer"</string>
     <string name="message_type_label">"Type: "</string>
@@ -219,9 +223,9 @@
     <string name="select_top_text">"Text på toppen"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> uleste meldinger."</string>
     <string name="notification_multiple_title">"Nye meldinger"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM-kort fullt"</string>
     <string name="sim_full_body">"Fjern noen meldinger for å gjøre plass til flere."</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index f13af37..119dc08 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Vernieuwen..."</string>
     <string name="has_draft">"Concept"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anoniem"</string>
     <string name="no_subject_view">"(Geen onderwerp)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Dia toevoegen"</string>
     <string name="add_slide_hint">"Selecteer dit om een nieuwe dia te maken."</string>
     <string name="discard_slideshow">"Diavoorstelling weggooien"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Tekst verwijderen"</string>
     <string name="add_picture">"Foto toevoegen"</string>
     <string name="remove_picture">"Foto verwijderen"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Het bericht wordt verwijderd."</string>
     <string name="confirm_delete_all_messages">"De volledige thread wordt verwijderd."</string>
     <string name="confirm_delete_all_SIM_messages">"Alle berichten op de SIM-kaart worden verwijderd."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Kan details niet ophalen"</string>
     <string name="message_details_title">"Berichtdetails"</string>
     <string name="message_type_label">"Type: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Tekst bovenaan"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> ongelezen berichten."</string>
     <string name="notification_multiple_title">"Nieuwe berichten"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM-kaart vol"</string>
     <string name="sim_full_body">"Verwijder enkele berichten om ruimte vrij te maken voor nieuwe berichten."</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index bad9870..b4abba5 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Odświeżanie..."</string>
     <string name="has_draft">"Wersja robocza"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Anonim"</string>
     <string name="no_subject_view">"(Brak tematu)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Dodaj slajd"</string>
     <string name="add_slide_hint">"Wybierz, aby utworzyć nowy slajd."</string>
     <string name="discard_slideshow">"Odrzuć pokaz slajdów"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Usuń tekst"</string>
     <string name="add_picture">"Dodaj zdjęcie"</string>
     <string name="remove_picture">"Usuń zdjęcie"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Wiadomość zostanie usunięta."</string>
     <string name="confirm_delete_all_messages">"Cały wątek zostanie usunięty."</string>
     <string name="confirm_delete_all_SIM_messages">"Wszystkie wiadomości na karcie SIM zostaną usunięte."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Nie można uzyskać szczegółów"</string>
     <string name="message_details_title">"Szczegóły wiadomości"</string>
     <string name="message_type_label">"Typ: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Tekst na górze"</string>
     <string name="notification_multiple">"Liczba nieprzeczytanych wiadomości: <xliff:g id="COUNT">%s</xliff:g>."</string>
     <string name="notification_multiple_title">"Nowe wiadomości"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"Karta SIM jest pełna"</string>
     <string name="sim_full_body">"Usuń część wiadomości, aby zwolnić miejsce dla nowych."</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index d62cadd..76ef45b 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"Идет обновление…"</string>
     <string name="has_draft">"Черновик"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"Аноним"</string>
     <string name="no_subject_view">"(Без темы)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"Добавить слайд"</string>
     <string name="add_slide_hint">"Выберите для создания слайда."</string>
     <string name="discard_slideshow">"Отменить слайд-шоу"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"Удалить текст"</string>
     <string name="add_picture">"Добавить изображение"</string>
     <string name="remove_picture">"Убрать изображение"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"Это сообщение будет удалено."</string>
     <string name="confirm_delete_all_messages">"Вся ветка будет удалена."</string>
     <string name="confirm_delete_all_SIM_messages">"Все сообщения на SIM-карте будут удалены."</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"Не удается получить сведения"</string>
     <string name="message_details_title">"Сведения о сообщении"</string>
     <string name="message_type_label">"Тип: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"Текст сверху"</string>
     <string name="notification_multiple">"Непрочитанных сообщений: <xliff:g id="COUNT">%s</xliff:g>."</string>
     <string name="notification_multiple_title">"Новые сообщения"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM-карта заполнена"</string>
     <string name="sim_full_body">"Удалите какие-нибудь сообщения, чтобы освободить место для новых."</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 9d42e8e..38274ac 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"正在刷新..."</string>
     <string name="has_draft">"草稿"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"匿名"</string>
     <string name="no_subject_view">"(无主题)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"添加幻灯片"</string>
     <string name="add_slide_hint">"选择以创建新幻灯片。"</string>
     <string name="discard_slideshow">"放弃幻灯片演示"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"删除文本"</string>
     <string name="add_picture">"添加图片"</string>
     <string name="remove_picture">"删除图片"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"会删除此信息。"</string>
     <string name="confirm_delete_all_messages">"会删除整个线程。"</string>
     <string name="confirm_delete_all_SIM_messages">"SIM 卡上的所有信息都会删除。"</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"无法获取详情"</string>
     <string name="message_details_title">"信息详情"</string>
     <string name="message_type_label">"类型: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"顶部文本"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> 条未读信息。"</string>
     <string name="notification_multiple_title">"新信息"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM 卡已满"</string>
     <string name="sim_full_body">"删除某些信息以腾出空间存储更多内容。"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index f919db3..fbfdc40 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -32,7 +32,7 @@
     <skip />
     <string name="refreshing">"重新整理中..."</string>
     <string name="has_draft">"草稿"</string>
-    <!-- no translation found for broadcast_from_to (1508520751945021904) -->
+    <!-- no translation found for broadcast_from_to (1804605929273213017) -->
     <skip />
     <string name="anonymous_recipient">"匿名"</string>
     <string name="no_subject_view">"(沒有主旨)"</string>
@@ -64,6 +64,8 @@
     <string name="add_slide">"新增投影片"</string>
     <string name="add_slide_hint">"新增投影片"</string>
     <string name="discard_slideshow">"放棄投影片"</string>
+    <!-- no translation found for slide_show_part (5077675385448696846) -->
+    <skip />
     <string name="remove_text">"移除文字"</string>
     <string name="add_picture">"新增圖片"</string>
     <string name="remove_picture">"移除圖片"</string>
@@ -170,6 +172,8 @@
     <string name="confirm_delete_message">"此簡訊將被刪除。"</string>
     <string name="confirm_delete_all_messages">"將刪除整個會話群組。"</string>
     <string name="confirm_delete_all_SIM_messages">"即將刪除 SIM 卡上的所有訊息。"</string>
+    <!-- no translation found for confirm_delete_SIM_message (767624259182679915) -->
+    <skip />
     <string name="cannot_get_details">"無法取得細節"</string>
     <string name="message_details_title">"簡訊細節"</string>
     <string name="message_type_label">"類型: "</string>
@@ -220,9 +224,9 @@
     <string name="select_top_text">"置頂文字"</string>
     <string name="notification_multiple">"<xliff:g id="COUNT">%s</xliff:g> 封未讀簡訊。"</string>
     <string name="notification_multiple_title">"新簡訊"</string>
-    <!-- no translation found for notification_failed_multiple (6548564868491846210) -->
+    <!-- no translation found for notification_failed_multiple (4081781748475686236) -->
     <skip />
-    <!-- no translation found for notification_failed_multiple_title (1781897599964634963) -->
+    <!-- no translation found for notification_failed_multiple_title (1112032024904397126) -->
     <skip />
     <string name="sim_full_title">"SIM 卡已滿"</string>
     <string name="sim_full_body">"刪除一些簡訊以釋放儲存空間。"</string>
diff --git a/src/com/android/mms/MmsApp.java b/src/com/android/mms/MmsApp.java
index 9e721ff..f2ae97d 100644
--- a/src/com/android/mms/MmsApp.java
+++ b/src/com/android/mms/MmsApp.java
@@ -29,6 +29,7 @@
 import android.preference.PreferenceManager;
 
 public class MmsApp extends Application {
+    public static final String LOG_TAG = "Mms";
 
     @Override
     public void onCreate() {
diff --git a/src/com/android/mms/model/SlideshowModel.java b/src/com/android/mms/model/SlideshowModel.java
index 83a1003..d5e11da 100644
--- a/src/com/android/mms/model/SlideshowModel.java
+++ b/src/com/android/mms/model/SlideshowModel.java
@@ -569,5 +569,18 @@
         
         return true;
     }
+    
+    /**
+     * Make sure the text in slide 0 is no longer holding onto a reference to the text
+     * in the message text box.
+    */
+    public void prepareForSend() {
+        if (size() == 1) {
+            TextModel text = get(0).getText();
+            if (text != null) {
+                text.cloneText();
+            }
+        }
+    }
 
 }
diff --git a/src/com/android/mms/model/TextModel.java b/src/com/android/mms/model/TextModel.java
index 011182e..a74b1e9 100644
--- a/src/com/android/mms/model/TextModel.java
+++ b/src/com/android/mms/model/TextModel.java
@@ -110,6 +110,10 @@
         notifyModelChanged(true);
     }
 
+    public void cloneText() {
+        mText = new String(mText.toString());
+    }
+
     public int getCharset() {
         return mCharset;
     }
diff --git a/src/com/android/mms/transaction/MessagingNotification.java b/src/com/android/mms/transaction/MessagingNotification.java
index 9014b13..4547870 100644
--- a/src/com/android/mms/transaction/MessagingNotification.java
+++ b/src/com/android/mms/transaction/MessagingNotification.java
@@ -403,15 +403,14 @@
     }
 
     public static void notifyDownloadFailed(Context context, long threadId) {
-        notifyFailed(context, true, true, threadId);
+        notifyFailed(context, true, threadId);
     }
 
-    public static void notifySendFailed(Context context, boolean isMms) {
-        notifyFailed(context, isMms, false, 0);
+    public static void notifySendFailed(Context context) {
+        notifyFailed(context, false, 0);
     }
 
-    private static void notifyFailed(Context context, boolean isMms,
-            boolean isDownload, long threadId) {
+    private static void notifyFailed(Context context, boolean isDownload, long threadId) {
         // TODO factor out common code for creating notifications
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
 
@@ -518,6 +517,8 @@
     public static void updateSendFailedNotification(Context context) {
         if (getUndeliveredMessageCount(context, null) < 1) {
             cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID);
+        } else {
+            notifySendFailed(context);      // rebuild and adjust the message count if necessary.
         }
     }
     
diff --git a/src/com/android/mms/transaction/MmsSystemEventReceiver.java b/src/com/android/mms/transaction/MmsSystemEventReceiver.java
index aa0ed4e..a23668e 100644
--- a/src/com/android/mms/transaction/MmsSystemEventReceiver.java
+++ b/src/com/android/mms/transaction/MmsSystemEventReceiver.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.Phone;
+import com.android.mms.MmsApp;
 
 /**
  * MmsSystemEventReceiver receives the
@@ -42,12 +43,10 @@
  */
 public class MmsSystemEventReceiver extends BroadcastReceiver {
     private static final String TAG = "MmsSystemEventReceiver";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
 
     private static void wakeUpService(Context context) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "TransactionService is going to be woken up.");
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+            Log.v(TAG, "wakeUpService: start transaction service ...");
         }
 
         context.startService(new Intent(context, TransactionService.class));
@@ -55,7 +54,7 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        if (LOCAL_LOGV) {
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
             Log.v(TAG, "Intent received: " + intent);
         }
 
@@ -66,7 +65,7 @@
         } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
             String state = intent.getStringExtra(Phone.STATE_KEY);
 
-            if (LOCAL_LOGV) {
+            if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                 Log.v(TAG, "ANY_DATA_STATE event received: " + state);
             }
 
diff --git a/src/com/android/mms/transaction/RetryScheduler.java b/src/com/android/mms/transaction/RetryScheduler.java
index d5a3f15..99b9f33 100644
--- a/src/com/android/mms/transaction/RetryScheduler.java
+++ b/src/com/android/mms/transaction/RetryScheduler.java
@@ -181,7 +181,7 @@
                             DownloadManager.getInstance().markState(
                                     uri, DownloadManager.STATE_PERMANENT_FAILURE);
                         } else {
-                            MessagingNotification.notifySendFailed(mContext, true);
+                            MessagingNotification.notifySendFailed(mContext);
                         }
                     }
 
diff --git a/src/com/android/mms/transaction/SmsReceiverService.java b/src/com/android/mms/transaction/SmsReceiverService.java
index eef3236..e7d7789 100644
--- a/src/com/android/mms/transaction/SmsReceiverService.java
+++ b/src/com/android/mms/transaction/SmsReceiverService.java
@@ -22,6 +22,7 @@
 
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.mms.R;
+import com.android.mms.MmsApp;
 import com.android.mms.ui.ClassZeroActivity;
 import com.android.mms.util.SendingProgressTokenManager;
 import com.google.android.mms.MmsException;
@@ -60,8 +61,6 @@
  */
 public class SmsReceiverService extends Service {
     private static final String TAG = "SmsReceiverService";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
 
     private ServiceHandler mServiceHandler;
     private Looper mServiceLooper;
@@ -97,8 +96,8 @@
 
     @Override
     public void onCreate() {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Creating SmsReceiverService");
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+            Log.v(TAG, "onCreate");
         }
 
         // Start up the thread running the service.  Note that we create a
@@ -113,8 +112,8 @@
 
     @Override
     public void onStart(Intent intent, int startId) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Starting #" + startId + ": " + intent.getExtras());
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+            Log.v(TAG, "onStart: #" + startId + ": " + intent.getExtras());
         }
 
         mResultCode = intent.getIntExtra("result", 0);
@@ -127,8 +126,8 @@
 
     @Override
     public void onDestroy() {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Destroying SmsReceiverService");
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+            Log.v(TAG, "onDestroy");
         }
         mServiceLooper.quit();
     }
@@ -150,7 +149,7 @@
          */
         @Override
         public void handleMessage(Message msg) {
-            if (LOCAL_LOGV) {
+            if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                 Log.v(TAG, "Handling incoming message: " + msg);
             }
             int serviceId = msg.arg1;
@@ -234,7 +233,7 @@
             mToastHandler.sendEmptyMessage(1);
         } else {
             Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_FAILED);
-            MessagingNotification.notifySendFailed(getApplicationContext(), false);
+            MessagingNotification.notifySendFailed(getApplicationContext());
             sendFirstQueuedMessage();
         }
     }
diff --git a/src/com/android/mms/transaction/TransactionService.java b/src/com/android/mms/transaction/TransactionService.java
index 9782f63..ed1317a 100644
--- a/src/com/android/mms/transaction/TransactionService.java
+++ b/src/com/android/mms/transaction/TransactionService.java
@@ -19,6 +19,7 @@
 
 import com.android.internal.telephony.Phone;
 import com.android.mms.R;
+import com.android.mms.MmsApp;
 import com.android.mms.util.RateController;
 import com.google.android.mms.pdu.GenericPdu;
 import com.google.android.mms.pdu.NotificationInd;
@@ -81,8 +82,6 @@
  */
 public class TransactionService extends Service implements Observer {
     private static final String TAG = "TransactionService";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
 
     /**
      * Used to identify notification intents broadcasted by the
@@ -168,7 +167,7 @@
 
     @Override
     public void onCreate() {
-        if (LOCAL_LOGV) {
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
             Log.v(TAG, "Creating TransactionService");
         }
 
@@ -188,8 +187,8 @@
 
     @Override
     public void onStart(Intent intent, int startId) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Starting #" + startId + ": " + intent.getExtras());
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+            Log.v(TAG, "onStart: #" + startId + ": " + intent.getExtras());
         }
 
         mConnMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -202,8 +201,9 @@
             if (cursor != null) {
                 try {
                     if (cursor.getCount() == 0) {
-                        if (LOCAL_LOGV) {
-                            Log.v(TAG, "No pending messages. Stopping service.");
+                        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "onStart: " +
+                                    "No pending messages. Stopping service.");
                         }
                         RetryScheduler.setRetryAlarm(this);
                         stopSelfIfIdle(startId);
@@ -251,13 +251,17 @@
                     cursor.close();
                 }
             } else {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "No pending messages. Stopping service.");
+                if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "onStart: " +
+                            "No pending messages. Stopping service.");
                 }
                 RetryScheduler.setRetryAlarm(this);
                 stopSelfIfIdle(startId);
             }
         } else {
+            if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+                Log.v(TAG, "onStart: launch transaction...");
+            }
             // For launching NotificationTransaction and test purpose.
             TransactionBundle args = new TransactionBundle(intent.getExtras());
             launchTransaction(startId, args, noNetwork);
@@ -267,6 +271,9 @@
     private void stopSelfIfIdle(int startId) {
         synchronized (mProcessing) {
             if (mProcessing.isEmpty() && mPending.isEmpty()) {
+                if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "stopSelfIfIdle: STOP!");
+                }
                 stopSelf(startId);
             }
         }
@@ -297,6 +304,7 @@
 
     private void launchTransaction(int serviceId, TransactionBundle txnBundle, boolean noNetwork) {
         if (noNetwork) {
+            Log.w(TAG, "launchTransaction: no network error!");
             onNetworkUnavailable(serviceId, txnBundle.getTransactionType());
             return;
         }
@@ -304,7 +312,7 @@
         msg.arg1 = serviceId;
         msg.obj = txnBundle;
 
-        if (LOCAL_LOGV) {
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
             Log.v(TAG, "Sending: " + msg);
         }
         mServiceHandler.sendMessage(msg);
@@ -325,11 +333,11 @@
 
     @Override
     public void onDestroy() {
-        if (LOCAL_LOGV) {
+        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
             Log.v(TAG, "Destroying TransactionService");
         }
         if (!mPending.isEmpty()) {
-            Log.i(TAG, "TransactionService exiting with transaction still pending");
+            Log.w(TAG, "TransactionService exiting with transaction still pending");
         }
 
         releaseWakeLock();
@@ -373,7 +381,7 @@
 
             switch (result) {
                 case TransactionState.SUCCESS:
-                    if (LOCAL_LOGV) {
+                    if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Transaction complete: " + serviceId);
                     }
 
@@ -392,12 +400,12 @@
                     }
                     break;
                 case TransactionState.FAILED:
-                    if (LOCAL_LOGV) {
+                    if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Transaction failed: " + serviceId);
                     }
                     break;
                 default:
-                    if (LOCAL_LOGV) {
+                    if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Transaction state unknown: " +
                                 serviceId + " " + result);
                     }
@@ -477,7 +485,7 @@
          */
         @Override
         public void handleMessage(Message msg) {
-            if (LOCAL_LOGV) {
+            if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                 Log.v(TAG, "Handling incoming message: " + msg);
             }
 
@@ -494,7 +502,7 @@
                         }
                     }
 
-                    if (LOCAL_LOGV) {
+                    if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Extending MMS connectivity - still processing txn");
                     }
 
@@ -528,7 +536,7 @@
                     }
 
                     NetworkInfo info = mConnectivityListener.getNetworkInfo();
-                    if (LOCAL_LOGV) {
+                    if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Got DATA_STATE_CHANGED event: " + info);
                     }
 
@@ -625,13 +633,11 @@
                             return;
                         }
 
-                        if (LOCAL_LOGV) {
+                        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Started processing of incoming message: " + msg);
                         }
                     } catch (Exception ex) {
-                        if (LOCAL_LOGV) {
-                            Log.v(TAG, "Exception occurred while handling message: " + msg, ex);
-                        }
+                        Log.w(TAG, "Exception occurred while handling message: " + msg, ex);
 
                         if (transaction != null) {
                             try {
@@ -651,7 +657,7 @@
                         }
                     } finally {
                         if (transaction == null) {
-                            if (LOCAL_LOGV) {
+                            if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                                 Log.v(TAG, "Transaction was null. Stopping self: " + serviceId);
                             }
                             endMmsConnectivity();
@@ -688,7 +694,7 @@
                 try {
                     int serviceId = transaction.getServiceId();
                     if (processTransaction(transaction)) {
-                        if (LOCAL_LOGV) {
+                        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Started deferred processing of transaction: "
                                     + transaction);
                         }
@@ -697,9 +703,7 @@
                         stopSelf(serviceId);
                     }
                 } catch (IOException e) {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, e.getMessage(), e);
-                    }
+                    Log.w(TAG, e.getMessage(), e);
                 }
             }
             else {
@@ -722,7 +726,7 @@
             synchronized (mProcessing) {
                 for (Transaction t : mPending) {
                     if (t.isEquivalent(transaction)) {
-                        if (LOCAL_LOGV) {
+                        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Transaction already pending: " +
                                     transaction.getServiceId());
                         }
@@ -731,7 +735,7 @@
                 }
                 for (Transaction t : mProcessing) {
                     if (t.isEquivalent(transaction)) {
-                        if (LOCAL_LOGV) {
+                        if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Duplicated transaction: " + transaction.getServiceId());
                         }
                         return true;
@@ -747,19 +751,19 @@
                 int connectivityResult = beginMmsConnectivity();
                 if (connectivityResult == Phone.APN_REQUEST_STARTED) {
                     mPending.add(transaction);
-                    if (LOCAL_LOGV) {
+                    if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Defer txn processing pending MMS connectivity");
                     }
                     return true;
                 }
 
-                if (LOCAL_LOGV) {
+                if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                     Log.v(TAG, "Adding transaction to list: " + transaction);
                 }
                 mProcessing.add(transaction);
             }
 
-            if (LOCAL_LOGV) {
+            if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                 Log.v(TAG, "Starting transaction: " + transaction);
             }
 
diff --git a/src/com/android/mms/ui/ComposeMessageActivity.java b/src/com/android/mms/ui/ComposeMessageActivity.java
index 5c0590b..2f94fee 100644
--- a/src/com/android/mms/ui/ComposeMessageActivity.java
+++ b/src/com/android/mms/ui/ComposeMessageActivity.java
@@ -69,7 +69,6 @@
 import android.content.DialogInterface.OnClickListener;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.database.ContentObserver;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteException;
@@ -151,9 +150,6 @@
  *         new message, this parameter shouldn't be present.
  * msg_uri Uri The message which should be opened for editing in the editor.
  * address String The addresses of the recipients in current conversation.
- * compose_mode boolean Setting compose_mode to true will force the activity
- *         to show the recipients editor and the attachment editor but hide
- *         the message history. By default, this flag is set to false.
  * exit_on_sent boolean Exit this activity after the message is sent.
  */
 public class ComposeMessageActivity extends Activity
@@ -186,7 +182,6 @@
     private static final int MENU_ADD_TO_CONTACTS       = 13;
 
     private static final int MENU_EDIT_MESSAGE          = 14;
-    private static final int MENU_VIEW_PICTURE          = 15;
     private static final int MENU_VIEW_SLIDESHOW        = 16;
     private static final int MENU_VIEW_MESSAGE_DETAILS  = 17;
     private static final int MENU_DELETE_MESSAGE        = 18;
@@ -212,12 +207,15 @@
     private static final int CALLER_ID_QUERY_TOKEN = 9800;
     private static final int EMAIL_CONTACT_QUERY_TOKEN = 9801;
 
-
+    private static final int MARK_AS_READ_TOKEN = 9900;
+    
     private static final int MMS_THRESHOLD = 4;
 
     private static final int CHARS_REMAINING_BEFORE_COUNTER_SHOWN = 10;
 
     private static final long NO_DATE_FOR_DIALOG = -1L;
+    
+    private static final int REFRESH_PRESENCE = 45236;
 
 
     // caller id query params
@@ -247,7 +245,6 @@
     // The parameters/states of the activity.
     private long mThreadId;                 // Database key for the current conversation
     private String mExternalAddress;        // Serialized recipients in the current conversation
-    private boolean mComposeMode;           // Should we show the recipients editor on startup?
     private boolean mExitOnSent;            // Should we finish() after sending a message?
 
     private View mTopPanel;                 // View containing the recipient and subject editors
@@ -293,10 +290,8 @@
     private AlertDialog mSmileyDialog;
     
     // Everything needed to deal with presence
-    private ContentObserver mContentObserver;
     private Cursor mContactInfoCursor;
     private int mPresenceStatus;
-    private final Handler mPresenceHandler = new Handler();
     private String[] mContactInfoSelectionArgs = new String[1];
 
 
@@ -379,6 +374,15 @@
         }
     };
 
+    private final Handler mPresencePollingHandler = new Handler() {        
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == REFRESH_PRESENCE) {
+                startQueryForContactInfo();
+            }
+        }
+    };
+
     private final OnKeyListener mSubjectKeyListener = new OnKeyListener() {
         public boolean onKey(View v, int keyCode, KeyEvent event) {
             if (event.getAction() != KeyEvent.ACTION_DOWN) {
@@ -1643,17 +1647,19 @@
             mMsgText = readTemporarySmsMessage(mThreadId);
         }
         
-        // If we are in an existing thread and we are not in "compose mode",
-        // start up the message list view.
-        boolean initRecipients = false;
-        if ((mThreadId > 0L) && !mComposeMode) {
-            MessageUtils.markAsRead(this, mThreadId);
-            initMessageList(false);
-        } else {
-            // Otherwise, show the recipients editor.
-            initRecipients = true;
-        }
-        if (initRecipients || (ConversationList.isFailedToDeliver(getIntent()) 
+
+        // Set up the message history ListAdapter
+        initMessageList();
+
+        // Mark the current thread as read.
+        markAsRead(mThreadId);
+        
+        // Show the recipients editor if we:
+        // - Don't have a valid thread OR
+        // - This conversation is marked with a failure and there is at most
+        //   one message in it (to give the user a chance to try a different
+        //   number).
+        if ((mThreadId <= 0) || (ConversationList.isFailedToDeliver(getIntent()) 
                 && mMsgListAdapter.getCount() <= 1)) {
             initRecipientsEditor();
         }
@@ -1712,7 +1718,10 @@
             if (oldIsMms) {
                 // Save the old temporary message if necessary.
                 if ((mMessageUri != null) && isPreparedForSending()) {
-                    updateTemporaryMmsMessage(false);
+                    // TODO: Do we already have the wrong mMessageUri here
+                    // from the new Intent?  Is this saving a draft to
+                    // the wrong place?
+                    asyncUpdateTemporaryMmsMessage();
                 }
             } else {
                 if (oldThreadId <= 0) {
@@ -1725,7 +1734,7 @@
             mRecipientList = RecipientList.from(mExternalAddress, this);
             updateState(RECIPIENTS_REQUIRE_MMS, recipientsRequireMms());
 
-            if (newThreadId > 0L && !mComposeMode) {
+            if (newThreadId > 0L) {
                 // If we have already initialized the recipients editor, just
                 // hide it in the display.
                 if (mRecipientsEditor != null) {
@@ -1733,8 +1742,7 @@
                     hideTopPanelIfNecessary();
                 }
 
-                MessageUtils.markAsRead(this, newThreadId);
-                initMessageList(false);
+                markAsRead(newThreadId);
             } else {
                 initRecipientsEditor();
             }
@@ -1782,10 +1790,7 @@
     protected void onRestart() {
         super.onRestart();
 
-        if (mThreadId > 0L && !mComposeMode) {
-            MessageUtils.markAsRead(this, mThreadId);
-            initMessageList(false);
-        }
+        markAsRead(mThreadId);
     }
 
     @Override
@@ -1803,6 +1808,12 @@
         updateSendFailedNotification();
     }
     
+    @Override
+    public void onResume() {
+        super.onResume();
+        startPresencePollingRequest();
+    }
+
     private void updateSendFailedNotification() {
         // updateSendFailedNotificationForThread makes a database call, so do the work off
         // of the ui thread.
@@ -1839,22 +1850,17 @@
                 if (LOCAL_LOGV) {
                     Log.v(TAG, "ONFREEZE: mMessageUri: " + mMessageUri);
                 }
-                updateTemporaryMmsMessage(false);
+                asyncUpdateTemporaryMmsMessage();
                 outState.putParcelable("msg_uri", mMessageUri);
             }
         } else {
             outState.putString("sms_body", mMsgText.toString());
             if (mThreadId <= 0) {
                 setThreadId(getOrCreateThreadId(mRecipientList.getToNumbers()));
-                initMessageList(false);
             }
             updateTemporarySmsMessage(mThreadId, mMsgText.toString());
         }
 
-        if (mComposeMode) {
-            outState.putBoolean("compose_mode", mComposeMode);
-        }
-
         if (mExitOnSent) {
             outState.putBoolean("exit_on_sent", mExitOnSent);
         }
@@ -1887,6 +1893,7 @@
     @Override
     protected void onPause() {
         super.onPause();
+        cancelPresencePollingRequests();
 
         if (isFinishing()) {
             if (hasValidRecipient()) {
@@ -1897,7 +1904,10 @@
                                     mContentResolver, mMessageUri, null, null);
                         } else {
                             setThreadId(getOrCreateThreadId(mRecipientList.getToNumbers()));
-                            updateTemporaryMmsMessage(true);
+                            asyncUpdateTemporaryMmsMessage();
+                            Toast.makeText(this, R.string.message_saved_as_draft,
+                                           Toast.LENGTH_SHORT).show();
+
                         }
                     }
                 } else {
@@ -2069,7 +2079,7 @@
     public void onAttachmentChanged(int newType, int oldType) {
         drawBottomPanel(newType);
         if (newType > AttachmentEditor.TEXT_ONLY) {
-            if (!requiresMms() && !mComposeMode) {
+            if (!requiresMms()) {
                 toastConvertInfo(true);
             }
             updateState(HAS_ATTACHMENT, true);
@@ -2103,7 +2113,7 @@
         // Only add the "View contact" menu item when there's a single recipient and that
         // recipient is someone in contacts.
         Recipient singleRecipient = mRecipientList.getSingleRecipient();
-        if (singleRecipient != null && singleRecipient.person_id != -1) {
+        if (singleRecipient != null && singleRecipient.person_id > 0) {
             menu.add(0, MENU_VIEW_CONTACT, 0, R.string.menu_view_contact).setIcon(
                     R.drawable.ic_menu_contact);
         }
@@ -2735,9 +2745,10 @@
     }
 
     private void startMsgListQuery() {
-        if (mMsgListAdapter == null) {
+        if (mThreadId <= 0) {
             return;
         }
+        
         // Cancel any pending queries
         mBackgroundQueryHandler.cancelOperation(MESSAGE_LIST_QUERY_TOKEN);
         try {
@@ -2750,11 +2761,11 @@
         }
     }
 
-    private void initMessageList(boolean startNewQuery) {
+    private void initMessageList() {
         if (mMsgListAdapter != null) {
             return;
         }
-
+        
         // Initialize the list adapter with a null cursor.
         mMsgListAdapter = new MessageListAdapter(
                 this, null, mMsgListView, true, getThreadType());
@@ -2769,10 +2780,6 @@
                 ((MessageListItem) view).onMessageListItemClick();
             }
         });
-
-        if (startNewQuery) {
-            startMsgListQuery();
-        }
     }
 
     private Uri createTemporaryMmsMessage() throws MmsException {
@@ -2785,45 +2792,35 @@
         return res;
     }
 
-    private void updateTemporaryMmsMessage(final boolean showToast) {
-        if (mMessageUri == null) {
-            try {
-                mMessageUri = createTemporaryMmsMessage();
-            } catch (MmsException e) {
-                Log.e(TAG, "updateTemporaryMmsMessage: cannot createTemporaryMmsMessage.", e);
+    private void asyncUpdateTemporaryMmsMessage() {
+        // PduPersister makes database calls and is known to ANR. Do the work on a
+        // background thread.
+        final SendReq sendReq = new SendReq();
+        fillMessageHeaders(sendReq);
+
+        new Thread(new Runnable() {
+            public void run() {
+                updateTemporaryMmsMessage(mMessageUri, mPersister,
+                        mSlideshow, sendReq);
             }
-        } else {
-            SendReq sendReq = new SendReq();
-            fillMessageHeaders(sendReq);
-            mPersister.updateHeaders(mMessageUri, sendReq);
-            final PduBody pb = mSlideshow.toPduBody();
+        }).start();
 
-            // PduPersister makes database calls and is known to ANR. Do the work on a
-            // background thread.
-            new Thread(new Runnable() {
-                public void run() {
-                    synchronized (mPersister) {
-                        try {
-                            mPersister.updateParts(mMessageUri, pb);
-                            if (showToast) {
-                                runOnUiThread(new Runnable() {
-                                    public void run() {
-                                        Toast.makeText(ComposeMessageActivity.this,
-                                                R.string.message_saved_as_draft,
-                                                Toast.LENGTH_SHORT).show();
-                                    }
-                                });
-                            }
-                        } catch (MmsException e) {
-                            Log.e(TAG, "updateTemporaryMmsMessage: cannot update message.", e);
-                        }
-                    }
-                }
-            }).run();
+        // Be paranoid and delete any SMS drafts that might be lying around.
+        asyncDeleteTemporarySmsMessage(mThreadId);
+    }
+    
+    private static void updateTemporaryMmsMessage(Uri uri, PduPersister persister,
+            SlideshowModel slideshow, SendReq sendReq) {
+        persister.updateHeaders(uri, sendReq);
+        final PduBody pb = slideshow.toPduBody();
 
-            mSlideshow.sync(pb);
+        try {
+            persister.updateParts(uri, pb);
+        } catch (MmsException e) {
+            Log.e(TAG, "updateTemporaryMmsMessage: cannot update message " + uri);
         }
-        deleteTemporarySmsMessage(mThreadId);
+
+        slideshow.sync(pb);
     }
 
     private static final String[] SMS_BODY_PROJECTION = { Sms._ID, Sms.BODY };
@@ -2900,6 +2897,12 @@
         }
     }
 
+    private void asyncDeleteTemporarySmsMessage(long threadId) {
+        mBackgroundQueryHandler.startDelete(0, null,
+                ContentUris.withAppendedId(Sms.Conversations.CONTENT_URI, threadId),
+                SMS_DRAFT_WHERE, null);
+    }
+
     private void deleteTemporarySmsMessage(long threadId) {
         SqliteWrapper.delete(this, mContentResolver,
                 ContentUris.withAppendedId(Sms.Conversations.CONTENT_URI, threadId),
@@ -2968,67 +2971,131 @@
         return hasRecipient() && (hasAttachment() || hasText());
     }
 
-    private void preSendingMessage() {
-        // If the recipients editor is visible, recalculate the thread ID we
-        // should be using.  The user could have edited it.
-        if (isRecipientsEditorVisible()) {
-            mThreadId = getOrCreateThreadId(mRecipientList.getToNumbers());
-        }
-
-        // needSaveAsMms will convert a message that is solely a Mms message because it has
-        // an empty subject back into an Sms message. Doesn't notify the user of the conversion.
-        if (!needSaveAsMms() && !requiresMms()) {
-            return;
-        }
-
-        // Update contents of the message before sending it.
-        updateTemporaryMmsMessage(false);
-    }
-
-    private void sendMessage() {
-        boolean failed = false;
-
-        preSendingMessage();
-
-        String[] dests = fillMessageHeaders(new SendReq());
-        MessageSender msgSender = requiresMms()
-                ? new MmsMessageSender(this, mMessageUri)
-                : new SmsMessageSender(this, dests, mMsgText.toString(), mThreadId);
-
-        try {
-            if (!msgSender.sendMessage(mThreadId) && (mMessageUri != null)) {
-                // The message was sent through SMS protocol, we should
-                // delete the copy which was previously saved in MMS drafts.
-                SqliteWrapper.delete(this, mContentResolver, mMessageUri, null, null);
-            }
-        } catch (MmsException e) {
-            Log.e(TAG, "Failed to send message: " + mMessageUri, e);
-            // TODO Indicate this error to user(for example, show a warning
-            // icon beside the message.
-            failed = true;
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to send message: " + mMessageUri, e);
-            // TODO Indicate this error to user(for example, show a warning
-            // icon beside the message.
-            failed = true;
-        } finally {
-            if (mExitOnSent) {
-                mMsgText = "";
-                mMessageUri = null;
-                finish();
-            } else if (!failed) {
-                postSendingMessage();
-            }
-        }
-    }
-
+    private String[] mLastRecipients;
+    private long mLastThreadId;
+    
     private long getOrCreateThreadId(String[] numbers) {
+        // Don't bother to hit the database if the recipient set has not
+        // changed since the last call.
+        if (Arrays.equals(numbers, mLastRecipients)) {
+            return mLastThreadId;
+        }
+        mLastRecipients = numbers;
         HashSet<String> recipients = new HashSet<String>();
         recipients.addAll(Arrays.asList(numbers));
-        return Threads.getOrCreateThreadId(this, recipients);
+        mLastThreadId = Threads.getOrCreateThreadId(this, recipients);
+        return mLastThreadId;
+    }
+
+
+    private void sendMessage() {
+        // Need this for both SMS and MMS.
+        final String[] dests = mRecipientList.getToNumbers();
+        
+        // needSaveAsMms will convert a message that is solely a Mms message because it has
+        // an empty subject back into an Sms message. Doesn't notify the user of the conversion.
+        if (needSaveAsMms()) {
+            // Make local copies of the bits we need for sending a message,
+            // because we will be doing it off of the main thread, which will
+            // immediately continue on to resetting some of this state.
+            final Uri mmsUri = mMessageUri;
+            final PduPersister persister = mPersister;
+            final SlideshowModel slideshow = mSlideshow;
+            final SendReq sendReq = new SendReq();
+            fillMessageHeaders(sendReq);
+            
+            // Make sure the text in slide 0 is no longer holding onto a reference to the text
+            // in the message text box.
+            slideshow.prepareForSend();
+
+            // Do the dirty work of sending the message off of the main UI thread.
+            new Thread(new Runnable() {
+                public void run() {
+                    sendMmsWorker(dests, mmsUri, persister, slideshow, sendReq);
+                }
+            }).start();
+        } else {
+            // Same rules apply as above.
+            final String msgText = mMsgText.toString();
+            new Thread(new Runnable() {
+                public void run() {
+                    sendSmsWorker(dests, msgText);
+                }
+            }).start();
+        }
+        
+        if (mExitOnSent) {
+            // If we are supposed to exit after a message is sent,
+            // clear out the text and URIs to inhibit saving of any
+            // drafts and call finish().
+            mMsgText = "";
+            mMessageUri = null;
+            finish();
+        } else {
+            // Otherwise, reset the UI to be ready for the next message.
+            resetMessage();
+        }
+    }
+    
+    /**
+     * Do the actual work of sending a message.  Runs outside of the main thread.
+     */
+    private void sendSmsWorker(String[] dests, String msgText) {
+        // Make sure we are still using the correct thread ID for our
+        // recipient set.
+        long threadId = getOrCreateThreadId(dests);
+
+        MessageSender sender = new SmsMessageSender(this, dests, msgText, threadId);
+        try {
+            sender.sendMessage(threadId);
+            setThreadId(threadId);
+            startMsgListQuery();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to send SMS message.");
+        }
+    }
+
+    private void sendMmsWorker(String[] dests, Uri mmsUri, PduPersister persister,
+                               SlideshowModel slideshow, SendReq sendReq) {
+        // Make sure we are still using the correct thread ID for our
+        // recipient set.
+        long threadId = getOrCreateThreadId(dests);
+
+        // Sync the MMS message in progress to disk.
+        updateTemporaryMmsMessage(mmsUri, persister, slideshow, sendReq);
+        // Be paranoid and clean any draft SMS up.
+        deleteTemporarySmsMessage(threadId);
+
+        MessageSender sender = new MmsMessageSender(this, mmsUri);
+        try {
+            if (!sender.sendMessage(threadId)) {
+                // The message was sent through SMS protocol, we should
+                // delete the copy which was previously saved in MMS drafts.
+                SqliteWrapper.delete(this, mContentResolver, mmsUri, null, null);
+            }
+            
+            setThreadId(threadId);
+            startMsgListQuery();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to send message: " + mmsUri);
+        }
     }
 
     private void resetMessage() {
+        // Make the attachment editor hide its view before we destroy it.
+        if (mAttachmentEditor != null) {
+            mAttachmentEditor.hideView();
+        }
+
+        // Focus to the text editor.
+        mTextEditor.requestFocus();
+
+        // We have to remove the text change listener while the text editor gets cleared and
+        // we subsequently turn the message back into SMS. When the listener is listening while
+        // doing the clearing, it's fighting to update its counts and itself try and turn
+        // the message one way or the other.
+        mTextEditor.removeTextChangedListener(mTextEditorWatcher);
+
         // RECIPIENTS_REQUIRE_MMS is the only state flag that is valid
         // when starting a new message, so preserve only that.
         mMessageState &= RECIPIENTS_REQUIRE_MMS;
@@ -3053,56 +3120,18 @@
             // Start a new message as an MMS.
             resetMmsComponents();
         }
-    }
-
-    private void postSendingMessage() {
-        if (!requiresMms()) {
-            // This should not be necessary because we delete the draft
-            // message from the database at the time we read it back,
-            // but I am paranoid.
-            deleteTemporarySmsMessage(mThreadId);
-        }
-
-        // Make the attachment editor hide its view before we destroy it.
-        if (mAttachmentEditor != null) {
-            mAttachmentEditor.hideView();
-        }
-
-        // Focus to the text editor.
-        mTextEditor.requestFocus();
-
-        // We have to remove the text change listener while the text editor gets cleared and
-        // we subsequently turn the message back into SMS. When the listener is listening while
-        // doing the clearing, it's fighting to update its counts and itself try and turn
-        // the message one way or the other.
-        mTextEditor.removeTextChangedListener(mTextEditorWatcher);
-
-        // Clear out all the debris in preparation for starting a new message. 
-        resetMessage();
-
+        
         drawBottomPanel(AttachmentEditor.TEXT_ONLY);
 
         // "Or not", in this case.
         updateSendButtonState();
-
-        String[] numbers = mRecipientList.getToNumbers();
-        long threadId = getOrCreateThreadId(numbers);
-        if (threadId > 0) {
-            if (mRecipientsEditor != null) {
-                mRecipientsEditor.setVisibility(View.GONE);
-                hideTopPanelIfNecessary();
-            }
-
-            if ((mMsgListAdapter == null) || (threadId != mThreadId)) {
-                setThreadId(threadId);
-                initMessageList(true);
-            }
-        } else {
-            Log.e(TAG, "Failed to find/create thread with: "
-                    + Arrays.toString(numbers));
-            finish();
-            return;
+        
+        // Hide the recipients editor.
+        if (mRecipientsEditor != null) {
+            mRecipientsEditor.setVisibility(View.GONE);
+            hideTopPanelIfNecessary();
         }
+
         // Our changes are done. Let the listener respond to text changes once again.
         mTextEditor.addTextChangedListener(mTextEditorWatcher);
         
@@ -3173,7 +3202,6 @@
             setThreadId(savedInstanceState.getLong("thread_id", 0));
             mMessageUri = (Uri) savedInstanceState.getParcelable("msg_uri");
             mExternalAddress = savedInstanceState.getString("address");
-            mComposeMode = savedInstanceState.getBoolean("compose_mode", false);
             mExitOnSent = savedInstanceState.getBoolean("exit_on_sent", false);
             mSubject = savedInstanceState.getString("subject");
             mMsgText = savedInstanceState.getString("sms_body");
@@ -3193,7 +3221,6 @@
                 }
             }
             mExternalAddress = intent.getStringExtra("address");
-            mComposeMode = intent.getBooleanExtra("compose_mode", false);
             mExitOnSent = intent.getBooleanExtra("exit_on_sent", false);
             mMsgText = intent.getStringExtra("sms_body");
 
@@ -3218,7 +3245,7 @@
                 // discards the message, we will clean it up later when we
                 // delete obsolete threads.
                 if (!TextUtils.isEmpty(mExternalAddress)) {
-                    setThreadId(Threads.getOrCreateThreadId(this, mExternalAddress));
+                    setThreadId(getOrCreateThreadId(new String[] { mExternalAddress }));
                 }
             }
         }
@@ -3299,6 +3326,21 @@
         }
     }
 
+    private void markAsRead(long threadId) {
+        if (threadId <= 0) {
+            return;
+        }
+        
+        Uri threadUri = ContentUris.withAppendedId(Threads.CONTENT_URI, threadId);
+        ContentValues values = new ContentValues(1);
+        values.put("read", 1);
+        String where = "read = 0";
+        Long cookie = new Long(threadId);
+
+        mBackgroundQueryHandler.startUpdate(MARK_AS_READ_TOKEN, cookie,
+                                            threadUri, values, where, null);
+    }
+    
     private final class BackgroundQueryHandler extends AsyncQueryHandler {
         public BackgroundQueryHandler(ContentResolver contentResolver) {
             super(contentResolver);
@@ -3328,7 +3370,7 @@
                 case THREAD_READ_QUERY_TOKEN:
                     boolean isRead = (cursor.moveToFirst() && (cursor.getInt(0) == 1));
                     if (!isRead) {
-                        MessageUtils.markAsRead(ComposeMessageActivity.this, mThreadId);
+                        markAsRead(mThreadId);
                     }
                     cursor.close();
                     return;
@@ -3338,6 +3380,7 @@
                     cleanupContactInfoCursor();
                     mContactInfoCursor = cursor;
                     updateContactInfo();
+                    startPresencePollingRequest();
                     return;
 
             }
@@ -3363,6 +3406,17 @@
                 ComposeMessageActivity.this.finish();
             }
         }
+        
+        @Override
+        protected void onUpdateComplete(int token, Object cookie, int result) {
+            switch(token) {
+            case MARK_AS_READ_TOKEN:
+                long threadId = (Long)cookie;
+                MessagingNotification.updateNewMessageIndicator(
+                                        ComposeMessageActivity.this, threadId);
+                break;
+            }
+        }
     }
 
     private void showSmileyDialog() {
@@ -3439,10 +3493,21 @@
         }
     }
     
+    private void cancelPresencePollingRequests() {
+        mPresencePollingHandler.removeMessages(REFRESH_PRESENCE);
+    }
+    
+    private void startPresencePollingRequest() {
+        mPresencePollingHandler.sendEmptyMessageDelayed(REFRESH_PRESENCE,
+                60 * 1000); // refresh every minute
+    }
+    
     private void startQueryForContactInfo() {
         String number = mRecipientList.getSingleRecipientNumber();
+        cancelPresencePollingRequests();    // make sure there are no outstanding polling requests
         if (TextUtils.isEmpty(number)) {
             setPresenceIcon(0);
+            startPresencePollingRequest();
             return;
         }
 
diff --git a/src/com/android/mms/ui/ConversationList.java b/src/com/android/mms/ui/ConversationList.java
index 0937245..53a7a94 100644
--- a/src/com/android/mms/ui/ConversationList.java
+++ b/src/com/android/mms/ui/ConversationList.java
@@ -343,7 +343,7 @@
         } else {
             info = cache.getContactInfo(this, address);
         }
-        if (info != null && info.person_id != -1) {
+        if (info != null && info.person_id > 0) {
             Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, info.person_id);
             Intent intent = new Intent(Intent.ACTION_VIEW, uri);
             startActivity(intent);            
diff --git a/src/com/android/mms/ui/MessageUtils.java b/src/com/android/mms/ui/MessageUtils.java
index 77a2299..07989b0 100644
--- a/src/com/android/mms/ui/MessageUtils.java
+++ b/src/com/android/mms/ui/MessageUtils.java
@@ -585,19 +585,6 @@
                         ContentUris.parseId(messageUri));
     }
 
-    public static void markAsRead(Context context, long threadId) {
-        MessageUtils.handleReadReport(context, threadId,
-                PduHeaders.READ_STATUS_READ, null);
-        
-        ContentValues values = new ContentValues(1);
-        values.put("read", READ_THREAD);
-        SqliteWrapper.update(context, context.getContentResolver(),
-                ContentUris.withAppendedId(Threads.CONTENT_URI, threadId),
-                values, "read=0", null);
-        
-        MessagingNotification.updateNewMessageIndicator(context, threadId);
-    }
-
     public static void resizeImageAsync(final Context context,
             final Uri imageUri, final Handler handler,
             final ResizeImageResultCallback cb) {
diff --git a/src/com/android/mms/ui/RecipientList.java b/src/com/android/mms/ui/RecipientList.java
index 246bcb1..12ee161 100644
--- a/src/com/android/mms/ui/RecipientList.java
+++ b/src/com/android/mms/ui/RecipientList.java
@@ -18,6 +18,7 @@
 package com.android.mms.ui;
 
 import com.android.mms.MmsConfig;
+import com.android.mms.R;
 import com.android.mms.transaction.MessageSender;
 import com.android.mms.util.ContactInfoCache;
 
@@ -222,35 +223,33 @@
                     recipient.bcc = true;
                     number = number.substring(5);
                 }
-                
-                if (!Mms.isEmailAddress(number)) {
-                    /*
-                     * TODO: Consider getting the CallerInfo object asynchronously
-                     * to help with ui responsiveness, instead of running the query
-                     * directly from the UI thread
-                     */
-                    ContactInfoCache.CacheEntry entry = cache.getContactInfo(context, number);
-                    if (TextUtils.isEmpty(entry.name)) {
-                        recipient.person_id = -1;
-                        if (MessageUtils.isLocalNumber(entry.phoneNumber)) {
-                            recipient.name = "Me";
-                        } else {
-                            recipient.name = entry.phoneNumber;
-                        }
+
+                /*
+                 * TODO: Consider getting the CallerInfo object asynchronously
+                 * to help with ui responsiveness, instead of running the query
+                 * directly from the UI thread
+                 */
+                ContactInfoCache.CacheEntry entry = cache.getContactInfo(context, number);
+                recipient.person_id = entry.person_id;
+                if (TextUtils.isEmpty(entry.name)) {
+                    if (MessageUtils.isLocalNumber(entry.phoneNumber)) {
+                        recipient.name = context.getString(R.string.messagelist_sender_self);
                     } else {
-                        recipient.person_id = entry.person_id;
-                        recipient.name = entry.name;
+                        recipient.name = entry.phoneNumber;
                     }
-                    recipient.label = entry.phoneLabel;
-                    recipient.number = (entry.phoneNumber == null) ? "" : entry.phoneNumber;
                 } else {
-                    recipient.number = number;
-                    recipient.name = cache.getDisplayName(context, number);
+                    recipient.name = entry.name;
                 }
                 
+                if (Mms.isEmailAddress(number)) {
+                    recipient.number = number;
+                    recipient.name = cache.getDisplayName(context, number);
+                } else {
+                    recipient.label = entry.phoneLabel;
+                    recipient.number = (entry.phoneNumber == null) ? "" : entry.phoneNumber;
+                }
                 recipient.nameAndNumber = Recipient.buildNameAndNumber(recipient.name,
                         recipient.number);
-
                 list.add(recipient.filter());
             }
         }
diff --git a/src/com/android/mms/util/ContactInfoCache.java b/src/com/android/mms/util/ContactInfoCache.java
index acc0e98..a6c43b2 100644
--- a/src/com/android/mms/util/ContactInfoCache.java
+++ b/src/com/android/mms/util/ContactInfoCache.java
@@ -146,11 +146,7 @@
         }
         
         public String toString() {
-            if (null == name) {
-                return "";
-            }
-
-            StringBuilder buf = new StringBuilder(name);
+            StringBuilder buf = new StringBuilder("name=" + name);
             buf.append(", phone=" + phoneNumber);
             buf.append(", pid=" + person_id);
             buf.append(", presence=" + presenceResId);
@@ -229,9 +225,12 @@
     /**
      * Returns the caller info in CacheEntry.
      */
-    // TODO: rename this function to: getContactInfoForPhoneNumber
-    public CacheEntry getContactInfo(Context context, String number) {
-        return getContactInfoForPhoneNumber(context, number, true /* allow query */);
+    public CacheEntry getContactInfo(Context context, String numberOrEmail) {
+        if (Mms.isEmailAddress(numberOrEmail)) {
+            return getContactInfoForEmailAddress(context, numberOrEmail, true /* allow query */);
+        } else {
+            return getContactInfoForPhoneNumber(context, numberOrEmail, true /* allow query */);
+        }
     }
 
     /**
@@ -432,11 +431,11 @@
                 while (cursor.moveToNext()) {
                     entry.presenceResId = getPresenceIconResourceId(
                             cursor.getInt(CONTACT_METHOD_STATUS_COLUMN));
+                    entry.person_id = cursor.getLong(CONTACT_METHOD_ID_COLUMN);
 
                     String name = cursor.getString(CONTACT_METHOD_NAME_COLUMN);
                     if (!TextUtils.isEmpty(name)) {
                         entry.name = name;
-                        entry.person_id = cursor.getLong(CONTACT_METHOD_ID_COLUMN);
                         if (LOCAL_DEBUG) {
                             log("queryEmailDisplayName: name=" + entry.name + ", email=" + email +
                                     ", presence=" + entry.presenceResId);