Merge "Import translations. DO NOT MERGE" into jb-ub-mail
diff --git a/res/layout/account_switch_spinner_item.xml b/res/layout/account_switch_spinner_item.xml
index 41ecff7..b3418df 100644
--- a/res/layout/account_switch_spinner_item.xml
+++ b/res/layout/account_switch_spinner_item.xml
@@ -30,13 +30,21 @@
         android:layout_marginLeft="4dp"
         style="@style/UnreadCountActionBar" />
 
-    <LinearLayout
+    <!-- This spacer is here just to soak up horizontal space. -->
+    <!-- If this is omitted, the spinner triangle is too far from the text. -->
+    <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:gravity="center_vertical"
-        android:layout_toLeftOf="@id/unread"
-        android:background="@drawable/spinner_ab_holo_light">
+        android:layout_alignParentLeft="true"
+        android:layout_toLeftOf="@id/unread">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:gravity="center_vertical"
+            android:background="@drawable/spinner_ab_holo_light">
+
             <TextView
                 android:id="@+id/account_spinner_first"
                 style="@style/AccountSpinnerAnchorTextPrimary"
@@ -54,5 +62,8 @@
                 android:layout_marginRight="4dp"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent" />
-    </LinearLayout>
+
+        </LinearLayout>
+
+    </FrameLayout>
 </RelativeLayout>
diff --git a/res/layout/conversation_item_view_normal.xml b/res/layout/conversation_item_view_normal.xml
index 48a7d90..89faa36 100644
--- a/res/layout/conversation_item_view_normal.xml
+++ b/res/layout/conversation_item_view_normal.xml
@@ -35,7 +35,7 @@
             android:layout_width="24dp"
             android:layout_height="24dp"
             />
-        <com.android.mail.browse.SendersView
+        <TextView
             android:id="@+id/senders"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/res/layout/conversation_item_view_wide.xml b/res/layout/conversation_item_view_wide.xml
index d272602..8fab037 100644
--- a/res/layout/conversation_item_view_wide.xml
+++ b/res/layout/conversation_item_view_wide.xml
@@ -35,7 +35,7 @@
         android:layout_marginRight="16dip"
         android:layout_gravity="center_vertical"
         android:src="@drawable/btn_check_on_normal_holo_light" />
-    <com.android.mail.browse.SendersView
+    <TextView
         android:id="@+id/senders"
         android:layout_width="224dip"
         android:layout_height="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f98d4c3..a402ac7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -770,4 +770,6 @@
     <!-- Token used to space out message count, draft text, and senders -->
     <string translatable="false" name="message_count_spacer">\u00A0\u00A0</string>
     <string translatable="false" name="ellipsis">\u2026</string>
+
+    <string translatable="false" name="quote_begin">&lt;div class=\"quote\"&gt;</string>
 </resources>
diff --git a/src/com/android/mail/browse/ConversationCursor.java b/src/com/android/mail/browse/ConversationCursor.java
index 7bb1d3d..41f35a7 100644
--- a/src/com/android/mail/browse/ConversationCursor.java
+++ b/src/com/android/mail/browse/ConversationCursor.java
@@ -35,6 +35,7 @@
 import android.os.Bundle;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.android.mail.providers.Conversation;
 import com.android.mail.providers.UIProvider;
@@ -281,7 +282,9 @@
         long time = System.currentTimeMillis();
 
         Wrapper result = new Wrapper(sResolver.query(uri, qProjection, null, null, null), uri);
-        if (DEBUG) {
+        if (result.getWrappedCursor() == null) {
+            Log.w(TAG, "doQuery returning null cursor, uri: " + uri);
+        } else if (DEBUG) {
             time = System.currentTimeMillis() - time;
             LogUtils.i(TAG, "ConversationCursor query: %s, %dms, %d results",
                     uri, time, result.getCount());
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index cf64c90..fa7b4a8 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -565,7 +565,7 @@
                     mHeader.conversation.conversationInfo, mHeader.messageInfoString.toString(),
                     maxChars);
         } else {
-            mCoordinates.sendersView.formatSenders(mHeader, isUnread, mMode, getContext());
+            SendersView.formatSenders(mHeader, getContext());
         }
 
         pauseTimer(PERF_TAG_CALCULATE_SENDER_SUBJECT);
@@ -938,7 +938,7 @@
         // Old style senders; apply text colors/ sizes/ styling.
         if (mHeader.senderFragments.size() > 0) {
             sPaint.setTextSize(mCoordinates.sendersFontSize);
-            sPaint.setTypeface(mCoordinates.sendersView.getTypeface(isUnread));
+            sPaint.setTypeface(SendersView.getTypeface(isUnread));
             int sendersColor = getFontColor(isUnread ? sSendersTextColorUnread
                     : sSendersTextColorRead);
             sPaint.setColor(sendersColor);
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index 85097e5..95cdfaf 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -109,7 +109,7 @@
 
     // Minimum height of this view; used for animating.
     int minHeight;
-    SendersView sendersView;
+    TextView sendersView;
 
 
     // Cache to save Coordinates based on view width.
@@ -351,7 +351,7 @@
                 coordinates.showPersonalLevel = false;
             }
 
-            SendersView senders = (SendersView) view.findViewById(R.id.senders);
+            TextView senders = (TextView) view.findViewById(R.id.senders);
             coordinates.sendersView = senders;
             coordinates.sendersX = getX(senders);
             coordinates.sendersY = getY(senders);
diff --git a/src/com/android/mail/browse/SendersView.java b/src/com/android/mail/browse/SendersView.java
index e4ff155..65e578a 100644
--- a/src/com/android/mail/browse/SendersView.java
+++ b/src/com/android/mail/browse/SendersView.java
@@ -17,7 +17,11 @@
 
 package com.android.mail.browse;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.text.Html;
@@ -46,7 +50,7 @@
 
 import java.util.regex.Pattern;
 
-public class SendersView extends TextView {
+public class SendersView {
     public static final int DEFAULT_FORMATTING = 0;
     public static final int MERGED_FORMATTING = 1;
     private static final Integer DOES_NOT_EXIST = -5;
@@ -66,33 +70,24 @@
     private static String sMessageCountSpacerString;
     public static CharSequence sElidedString;
     private static Map<Integer, Integer> sPriorityToLength;
+    private static BroadcastReceiver sConfigurationChangedReceiver;
 
-    public SendersView(Context context) {
-        this(context, null);
-    }
-
-    public SendersView(Context context, AttributeSet attrs) {
-        this(context, attrs, -1);
-    }
-
-    public SendersView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public Typeface getTypeface(boolean isUnread) {
+    public static Typeface getTypeface(boolean isUnread) {
         return isUnread ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT;
     }
 
-    public void formatSenders(ConversationItemViewModel header, boolean isUnread, int mode,
-            Context context) {
-        String senders = header.conversation.senders;
-        if (TextUtils.isEmpty(senders)) {
-            return;
-        }
-        formatDefault(header, senders, context);
-    }
-
     private static void getSenderResources(Context context) {
+        if (sConfigurationChangedReceiver == null) {
+            sConfigurationChangedReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    sDraftSingularString = null;
+                    getSenderResources(context);
+                }
+            };
+            context.registerReceiver(sConfigurationChangedReceiver, new IntentFilter(
+                    Intent.ACTION_CONFIGURATION_CHANGED));
+        }
         if (sDraftSingularString == null) {
             Resources res = context.getResources();
             sSendersSplitToken = res.getString(R.string.senders_split_token);
@@ -143,7 +138,9 @@
                 messageInfo.append(draftString);
             }
             if (sendingStatus == UIProvider.ConversationSendingState.SENDING) {
-                if (count > 0 ||draftCount > 0) {
+                // If we are showing a message count or any draft text, prepend
+                // the sending state text with a comma.
+                if (count > 1 ||draftCount > 0) {
                     messageInfo.append(sSendersSplitToken);
                 }
                 SpannableStringBuilder sending = new SpannableStringBuilder();
@@ -272,8 +269,8 @@
         return sMeString;
     }
 
-    private void formatDefault(ConversationItemViewModel header,
-            String sendersString, Context context) {
+    private static void formatDefault(ConversationItemViewModel header, String sendersString,
+            Context context) {
         getSenderResources(context);
         // Clear any existing sender fragments; we must re-make all of them.
         header.senderFragments.clear();
@@ -294,8 +291,12 @@
         generateSenderFragments(header, namesOnly);
     }
 
-    private void generateSenderFragments(ConversationItemViewModel header, String[] names) {
+    private static void generateSenderFragments(ConversationItemViewModel header, String[] names) {
         header.sendersText = TextUtils.join(Address.ADDRESS_DELIMETER + " ", names);
         header.addSenderFragment(0, header.sendersText.length(), getReadStyleSpan(), true);
     }
+
+    public static void formatSenders(ConversationItemViewModel header, Context context) {
+        formatDefault(header, header.conversation.senders, context);
+    }
 }
diff --git a/src/com/android/mail/compose/QuotedTextView.java b/src/com/android/mail/compose/QuotedTextView.java
index 4531dca..d89263e 100644
--- a/src/com/android/mail/compose/QuotedTextView.java
+++ b/src/com/android/mail/compose/QuotedTextView.java
@@ -51,8 +51,6 @@
     private static final String BLOCKQUOTE_BEGIN = "<blockquote class=\"quote\" style=\""
             + "margin:0 0 0 .8ex;" + "border-left:1px #ccc solid;" + "padding-left:1ex\">";
     private static final String BLOCKQUOTE_END = "</blockquote>";
-    // HTML tags used to quote replies & forwards
-    /* package for testing */static final String QUOTE_BEGIN = "<div class=\"quote\">";
     private static final String QUOTE_END = "</div>";
 
     // Separates the attribution headers (Subject, To, etc) from the body in
@@ -67,6 +65,7 @@
     private boolean mIncludeText = true;
     private Button mRespondInlineButton;
     private RespondInlineListener mRespondInlineListener;
+    private static String sQuoteBegin;
 
     public QuotedTextView(Context context) {
         this(context, null);
@@ -89,6 +88,7 @@
         mShowHideCheckBox = (CheckBox) findViewById(R.id.hide_quoted_text);
         mShowHideCheckBox.setChecked(true);
         mShowHideCheckBox.setOnClickListener(this);
+        sQuoteBegin = context.getResources().getString(R.string.quote_begin);
         findViewById(R.id.hide_quoted_text_label).setOnClickListener(this);
 
 
@@ -256,7 +256,7 @@
         Date date = new Date(refMessage.dateReceivedMs);
         Resources resources = getContext().getResources();
         if (action == ComposeActivity.REPLY || action == ComposeActivity.REPLY_ALL) {
-            quotedText.append(QUOTE_BEGIN);
+            quotedText.append(sQuoteBegin);
             quotedText
                     .append(String.format(
                             resources.getString(R.string.reply_attribution),
@@ -269,7 +269,7 @@
             quotedText.append(BLOCKQUOTE_END);
             quotedText.append(QUOTE_END);
         } else if (action == ComposeActivity.FORWARD) {
-            quotedText.append(QUOTE_BEGIN);
+            quotedText.append(sQuoteBegin);
             quotedText
                     .append(String.format(resources.getString(R.string.forward_attribution), Utils
                             .cleanUpString(refMessage.from,
@@ -323,7 +323,7 @@
     }
 
     public static boolean containsQuotedText(String text) {
-        int pos = text.indexOf(QuotedTextView.QUOTE_BEGIN);
+        int pos = text.indexOf(sQuoteBegin);
         return pos >= 0;
     }
 
@@ -341,6 +341,6 @@
             return -1;
         }
         String textString = htmlText.toString();
-        return textString.indexOf(QUOTE_BEGIN);
+        return textString.indexOf(sQuoteBegin);
     }
 }
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index fbe3ffe..e4039cd 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -800,8 +800,9 @@
 
     public static final class ConversationSendingState {
         public static final int OTHER = 0;
-        public static final int SENDING = 1;
-        public static final int SENT = 2;
+        public static final int QUEUED = 1;
+        public static final int SENDING = 2;
+        public static final int SENT = 3;
         public static final int SEND_ERROR = -1;
     }
 
diff --git a/src/com/android/mail/ui/TwoPaneController.java b/src/com/android/mail/ui/TwoPaneController.java
index 0482ddc..444fe0a 100644
--- a/src/com/android/mail/ui/TwoPaneController.java
+++ b/src/com/android/mail/ui/TwoPaneController.java
@@ -368,10 +368,14 @@
         } else if (mode == ViewMode.SEARCH_RESULTS_CONVERSATION) {
             mViewMode.enterSearchResultsListMode();
         } else {
-            if (mode == ViewMode.CONVERSATION_LIST && getFolderListFragment().showingHierarchy()) {
+            // The Folder List fragment can be null for monkeys where we get a back before the
+            // folder list has had a chance to initialize.
+            final FolderListFragment folderList = getFolderListFragment();
+            if (mode == ViewMode.CONVERSATION_LIST && folderList != null
+                    && folderList.showingHierarchy()) {
                 // If the user navigated via the left folders list into a child folder,
                 // back should take the user up to the parent folder's conversation list.
-                Folder hierarchyFolder = getHierarchyFolder();
+                final Folder hierarchyFolder = getHierarchyFolder();
                 if (hierarchyFolder.parent != null) {
                     goUpFolderHierarchy(hierarchyFolder);
                 } else  {