/*
 * Copyright (C) 2012 Google Inc.
 * Licensed to The Android Open Source Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mail.ui;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
import android.support.v4.text.BidiFormatter;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.webkit.ConsoleMessage;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;

import com.android.emailcommon.mail.Address;
import com.android.mail.FormattedDateBuilder;
import com.android.mail.R;
import com.android.mail.analytics.Analytics;
import com.android.mail.analytics.AnalyticsTimer;
import com.android.mail.browse.ConversationContainer;
import com.android.mail.browse.ConversationContainer.OverlayPosition;
import com.android.mail.browse.ConversationFooterView.ConversationFooterCallbacks;
import com.android.mail.browse.ConversationMessage;
import com.android.mail.browse.ConversationOverlayItem;
import com.android.mail.browse.ConversationViewAdapter;
import com.android.mail.browse.ConversationViewAdapter.ConversationFooterItem;
import com.android.mail.browse.ConversationViewAdapter.MessageFooterItem;
import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem;
import com.android.mail.browse.ConversationViewAdapter.SuperCollapsedBlockItem;
import com.android.mail.browse.ConversationViewHeader;
import com.android.mail.browse.ConversationWebView;
import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreator;
import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreatorHolder;
import com.android.mail.browse.MailWebView.ContentSizeChangeListener;
import com.android.mail.browse.MessageCursor;
import com.android.mail.browse.MessageFooterView;
import com.android.mail.browse.MessageHeaderView;
import com.android.mail.browse.ScrollIndicatorsView;
import com.android.mail.browse.SuperCollapsedBlock;
import com.android.mail.browse.WebViewContextMenu;
import com.android.mail.compose.ComposeActivity;
import com.android.mail.content.ObjectCursor;
import com.android.mail.print.PrintUtils;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Message;
import com.android.mail.providers.Settings;
import com.android.mail.providers.UIProvider;
import com.android.mail.ui.ConversationViewState.ExpansionState;
import com.android.mail.utils.ConversationViewUtils;
import com.android.mail.utils.KeyboardUtils;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.android.mail.utils.ViewUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * The conversation view UI component.
 */
public class ConversationViewFragment extends AbstractConversationViewFragment implements
        SuperCollapsedBlock.OnClickListener, OnLayoutChangeListener,
        MessageHeaderView.MessageHeaderViewCallbacks, MessageFooterView.MessageFooterCallbacks,
        WebViewContextMenu.Callbacks, ConversationFooterCallbacks, View.OnKeyListener {

    private static final String LOG_TAG = LogTag.getLogTag();
    public static final String LAYOUT_TAG = "ConvLayout";

    /**
     * Difference in the height of the message header whose details have been expanded/collapsed
     */
    private int mDiff = 0;

    /**
     * Default value for {@link #mLoadWaitReason}. Conversation load will happen immediately.
     */
    private final int LOAD_NOW = 0;
    /**
     * Value for {@link #mLoadWaitReason} that means we are offscreen and waiting for the visible
     * conversation to finish loading before beginning our load.
     * <p>
     * When this value is set, the fragment should register with {@link ConversationListCallbacks}
     * to know when the visible conversation is loaded. When it is unset, it should unregister.
     */
    private final int LOAD_WAIT_FOR_INITIAL_CONVERSATION = 1;
    /**
     * Value for {@link #mLoadWaitReason} used when a conversation is too heavyweight to load at
     * all when not visible (e.g. requires network fetch, or too complex). Conversation load will
     * wait until this fragment is visible.
     */
    private final int LOAD_WAIT_UNTIL_VISIBLE = 2;

    // Default scroll distance when the user tries to scroll with up/down
    private final int DEFAULT_VERTICAL_SCROLL_DISTANCE_PX = 50;

    // Keyboard navigation
    private KeyboardNavigationController mNavigationController;
    // Since we manually control navigation for most of the conversation view due to problems
    // with two-pane layout but still rely on the system for SOME navigation, we need to keep track
    // of the view that had focus when KeyEvent.ACTION_DOWN was fired. This is because we only
    // manually change focus on KeyEvent.ACTION_UP (to prevent holding down the DOWN button and
    // lagging the app), however, the view in focus might have changed between ACTION_UP and
    // ACTION_DOWN since the system might have handled the ACTION_DOWN and moved focus.
    private View mOriginalKeyedView;
    private int mMaxScreenHeight;
    private int mTopOfVisibleScreen;

    protected ConversationContainer mConversationContainer;

    protected ConversationWebView mWebView;

    private ViewGroup mTopmostOverlay;

    private ConversationViewProgressController mProgressController;

    private ActionableToastBar mNewMessageBar;
    private ActionableToastBar.ActionClickedListener mNewMessageBarActionListener;

    protected HtmlConversationTemplates mTemplates;

    private final MailJsBridge mJsBridge = new MailJsBridge();

    protected ConversationViewAdapter mAdapter;

    protected boolean mViewsCreated;
    // True if we attempted to render before the views were laid out
    // We will render immediately once layout is done
    private boolean mNeedRender;

    /**
     * Temporary string containing the message bodies of the messages within a super-collapsed
     * block, for one-time use during block expansion. We cannot easily pass the body HTML
     * into JS without problematic escaping, so hold onto it momentarily and signal JS to fetch it
     * using {@link MailJsBridge}.
     */
    private String mTempBodiesHtml;

    private int  mMaxAutoLoadMessages;

    protected int mSideMarginPx;

    /**
     * If this conversation fragment is not visible, and it's inappropriate to load up front,
     * this is the reason we are waiting. This flag should be cleared once it's okay to load
     * the conversation.
     */
    private int mLoadWaitReason = LOAD_NOW;

    private boolean mEnableContentReadySignal;

    private ContentSizeChangeListener mWebViewSizeChangeListener;

    private float mWebViewYPercent;

    /**
     * Has loadData been called on the WebView yet?
     */
    private boolean mWebViewLoadedData;

    private long mWebViewLoadStartMs;

    private final Map<String, String> mMessageTransforms = Maps.newHashMap();

    private final DataSetObserver mLoadedObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            getHandler().post(new FragmentRunnable("delayedConversationLoad",
                    ConversationViewFragment.this) {
                @Override
                public void go() {
                    LogUtils.d(LOG_TAG, "CVF load observer fired, this=%s",
                            ConversationViewFragment.this);
                    handleDelayedConversationLoad();
                }
            });
        }
    };

    private final Runnable mOnProgressDismiss = new FragmentRunnable("onProgressDismiss", this) {
        @Override
        public void go() {
            LogUtils.d(LOG_TAG, "onProgressDismiss go() - isUserVisible() = %b", isUserVisible());
            if (isUserVisible()) {
                onConversationSeen();
            }
            mWebView.onRenderComplete();
        }
    };

    private static final boolean DEBUG_DUMP_CONVERSATION_HTML = false;
    private static final boolean DISABLE_OFFSCREEN_LOADING = false;
    private static final boolean DEBUG_DUMP_CURSOR_CONTENTS = false;

    private static final String BUNDLE_KEY_WEBVIEW_Y_PERCENT =
            ConversationViewFragment.class.getName() + "webview-y-percent";

    private BidiFormatter mBidiFormatter;

    /**
     * Contains a mapping between inline image attachments and their local message id.
     */
    private Map<String, String> mUrlToMessageIdMap;

    /**
     * Constructor needs to be public to handle orientation changes and activity lifecycle events.
     */
    public ConversationViewFragment() {}

    /**
     * Creates a new instance of {@link ConversationViewFragment}, initialized
     * to display a conversation with other parameters inherited/copied from an existing bundle,
     * typically one created using {@link #makeBasicArgs}.
     */
    public static ConversationViewFragment newInstance(Bundle existingArgs,
            Conversation conversation) {
        ConversationViewFragment f = new ConversationViewFragment();
        Bundle args = new Bundle(existingArgs);
        args.putParcelable(ARG_CONVERSATION, conversation);
        f.setArguments(args);
        return f;
    }

    @Override
    public void onAccountChanged(Account newAccount, Account oldAccount) {
        // if overview mode has changed, re-render completely (no need to also update headers)
        if (isOverviewMode(newAccount) != isOverviewMode(oldAccount)) {
            setupOverviewMode();
            final MessageCursor c = getMessageCursor();
            if (c != null) {
                renderConversation(c);
            } else {
                // Null cursor means this fragment is either waiting to load or in the middle of
                // loading. Either way, a future render will happen anyway, and the new setting
                // will take effect when that happens.
            }
            return;
        }

        // settings may have been updated; refresh views that are known to
        // depend on settings
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        LogUtils.d(LOG_TAG, "IN CVF.onActivityCreated, this=%s visible=%s", this, isUserVisible());
        super.onActivityCreated(savedInstanceState);

        if (mActivity == null || mActivity.isFinishing()) {
            // Activity is finishing, just bail.
            return;
        }

        Context context = getContext();
        mTemplates = new HtmlConversationTemplates(context);

        final FormattedDateBuilder dateBuilder = new FormattedDateBuilder(context);

        mNavigationController = mActivity.getKeyboardNavigationController();

        mAdapter = new ConversationViewAdapter(mActivity, this,
                getLoaderManager(), this, this, getContactInfoSource(), this, this,
                getListController(), this, mAddressCache, dateBuilder, mBidiFormatter, this);
        mConversationContainer.setOverlayAdapter(mAdapter);

        // set up snap header (the adapter usually does this with the other ones)
        mConversationContainer.getSnapHeader().initialize(
                this, mAddressCache, this, getContactInfoSource(),
                mActivity.getAccountController().getVeiledAddressMatcher());

        final Resources resources = getResources();
        mMaxAutoLoadMessages = resources.getInteger(R.integer.max_auto_load_messages);

        mSideMarginPx = resources.getDimensionPixelOffset(
                R.dimen.conversation_message_content_margin_side);

        mUrlToMessageIdMap = new ArrayMap<String, String>();
        final InlineAttachmentViewIntentBuilderCreator creator =
                InlineAttachmentViewIntentBuilderCreatorHolder.
                getInlineAttachmentViewIntentCreator();
        final WebViewContextMenu contextMenu = new WebViewContextMenu(getActivity(),
                creator.createInlineAttachmentViewIntentBuilder(mAccount,
                mConversation != null ? mConversation.id : -1));
        contextMenu.setCallbacks(this);
        mWebView.setOnCreateContextMenuListener(contextMenu);

        // set this up here instead of onCreateView to ensure the latest Account is loaded
        setupOverviewMode();

        // Defer the call to initLoader with a Handler.
        // We want to wait until we know which fragments are present and their final visibility
        // states before going off and doing work. This prevents extraneous loading from occurring
        // as the ViewPager shifts about before the initial position is set.
        //
        // e.g. click on item #10
        // ViewPager.setAdapter() actually first loads #0 and #1 under the assumption that #0 is
        // the initial primary item
        // Then CPC immediately sets the primary item to #10, which tears down #0/#1 and sets up
        // #9/#10/#11.
        getHandler().post(new FragmentRunnable("showConversation", this) {
            @Override
            public void go() {
                showConversation();
            }
        });

        if (mConversation != null && mConversation.conversationBaseUri != null &&
                !Utils.isEmpty(mAccount.accountCookieQueryUri)) {
            // Set the cookie for this base url
            new SetCookieTask(getContext(), mConversation.conversationBaseUri.toString(),
                    mAccount.accountCookieQueryUri).execute();
        }

        // Find the height of the screen for manually scrolling the webview via keyboard.
        final Rect screen = new Rect();
        mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(screen);
        mMaxScreenHeight = screen.bottom;
        mTopOfVisibleScreen = screen.top + mActivity.getSupportActionBar().getHeight();
    }

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        mWebViewClient = createConversationWebViewClient();

        if (savedState != null) {
            mWebViewYPercent = savedState.getFloat(BUNDLE_KEY_WEBVIEW_Y_PERCENT);
        }

        mBidiFormatter = BidiFormatter.getInstance();
    }

    protected ConversationWebViewClient createConversationWebViewClient() {
        return new ConversationWebViewClient(mAccount);
    }

    @Override
    public View onCreateView(LayoutInflater inflater,
            ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.conversation_view, container, false);
        mConversationContainer = (ConversationContainer) rootView
                .findViewById(R.id.conversation_container);
        mConversationContainer.setAccountController(this);

        mTopmostOverlay =
                (ViewGroup) mConversationContainer.findViewById(R.id.conversation_topmost_overlay);
        mTopmostOverlay.setOnKeyListener(this);
        inflateSnapHeader(mTopmostOverlay, inflater);
        mConversationContainer.setupSnapHeader();

        setupNewMessageBar();

        mProgressController = new ConversationViewProgressController(this, getHandler());
        mProgressController.instantiateProgressIndicators(rootView);

        mWebView = (ConversationWebView)
                mConversationContainer.findViewById(R.id.conversation_webview);

        mWebView.addJavascriptInterface(mJsBridge, "mail");
        // On JB or newer, we use the 'webkitAnimationStart' DOM event to signal load complete
        // Below JB, try to speed up initial render by having the webview do supplemental draws to
        // custom a software canvas.
        // TODO(mindyp):
        //PAGE READINESS SIGNAL FOR JELLYBEAN AND NEWER
        // Notify the app on 'webkitAnimationStart' of a simple dummy element with a simple no-op
        // animation that immediately runs on page load. The app uses this as a signal that the
        // content is loaded and ready to draw, since WebView delays firing this event until the
        // layers are composited and everything is ready to draw.
        // This signal does not seem to be reliable, so just use the old method for now.
        final boolean isJBOrLater = Utils.isRunningJellybeanOrLater();
        final boolean isUserVisible = isUserVisible();
        mWebView.setUseSoftwareLayer(!isJBOrLater);
        mEnableContentReadySignal = isJBOrLater && isUserVisible;
        mWebView.onUserVisibilityChanged(isUserVisible);
        mWebView.setWebViewClient(mWebViewClient);
        final WebChromeClient wcc = new WebChromeClient() {
            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                if (consoleMessage.messageLevel() == ConsoleMessage.MessageLevel.ERROR) {
                    LogUtils.e(LOG_TAG, "JS: %s (%s:%d) f=%s", consoleMessage.message(),
                            consoleMessage.sourceId(), consoleMessage.lineNumber(),
                            ConversationViewFragment.this);
                } else {
                    LogUtils.i(LOG_TAG, "JS: %s (%s:%d) f=%s", consoleMessage.message(),
                            consoleMessage.sourceId(), consoleMessage.lineNumber(),
                            ConversationViewFragment.this);
                }
                return true;
            }
        };
        mWebView.setWebChromeClient(wcc);

        final WebSettings settings = mWebView.getSettings();

        final ScrollIndicatorsView scrollIndicators =
                (ScrollIndicatorsView) rootView.findViewById(R.id.scroll_indicators);
        scrollIndicators.setSourceView(mWebView);

        settings.setJavaScriptEnabled(true);

        ConversationViewUtils.setTextZoom(getResources(), settings);

        mViewsCreated = true;
        mWebViewLoadedData = false;

        return rootView;
    }

    protected void inflateSnapHeader(ViewGroup topmostOverlay, LayoutInflater inflater) {
        inflater.inflate(R.layout.conversation_topmost_overlay_items, topmostOverlay, true);
    }

    protected void setupNewMessageBar() {
        mNewMessageBar = (ActionableToastBar) mConversationContainer.findViewById(
                R.id.new_message_notification_bar);
        mNewMessageBarActionListener = new ActionableToastBar.ActionClickedListener() {
            @Override
            public void onActionClicked(Context context) {
                onNewMessageBarClick();
            }
        };
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mWebView != null) {
            mWebView.onResume();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mWebView != null) {
            mWebView.onPause();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mConversationContainer.setOverlayAdapter(null);
        mAdapter = null;
        resetLoadWaiting(); // be sure to unregister any active load observer
        mViewsCreated = false;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putFloat(BUNDLE_KEY_WEBVIEW_Y_PERCENT, calculateScrollYPercent());
    }

    private float calculateScrollYPercent() {
        final float p;
        if (mWebView == null) {
            // onCreateView hasn't been called, return 0 as the user hasn't scrolled the view.
            return 0;
        }

        final int scrollY = mWebView.getScrollY();
        final int viewH = mWebView.getHeight();
        final int webH = (int) (mWebView.getContentHeight() * mWebView.getScale());

        if (webH == 0 || webH <= viewH) {
            p = 0;
        } else if (scrollY + viewH >= webH) {
            // The very bottom is a special case, it acts as a stronger anchor than the scroll top
            // at that point.
            p = 1.0f;
        } else {
            p = (float) scrollY / webH;
        }
        return p;
    }

    private void resetLoadWaiting() {
        if (mLoadWaitReason == LOAD_WAIT_FOR_INITIAL_CONVERSATION) {
            getListController().unregisterConversationLoadedObserver(mLoadedObserver);
        }
        mLoadWaitReason = LOAD_NOW;
    }

    @Override
    protected void markUnread() {
        super.markUnread();
        // Ignore unsafe calls made after a fragment is detached from an activity
        final ControllableActivity activity = (ControllableActivity) getActivity();
        if (activity == null) {
            LogUtils.w(LOG_TAG, "ignoring markUnread for conv=%s", mConversation.id);
            return;
        }

        if (mViewState == null) {
            LogUtils.i(LOG_TAG, "ignoring markUnread for conv with no view state (%d)",
                    mConversation.id);
            return;
        }
        activity.getConversationUpdater().markConversationMessagesUnread(mConversation,
                mViewState.getUnreadMessageUris(), mViewState.getConversationInfo());
    }

    @Override
    public void onUserVisibleHintChanged() {
        final boolean userVisible = isUserVisible();
        LogUtils.d(LOG_TAG, "ConversationViewFragment#onUserVisibleHintChanged(), userVisible = %b",
                userVisible);

        if (!userVisible) {
            mProgressController.dismissLoadingStatus();
        } else if (mViewsCreated) {
            String loadTag = null;
            final boolean isInitialLoading;
            if (mActivity != null) {
                isInitialLoading = mActivity.getConversationUpdater()
                    .isInitialConversationLoading();
            } else {
                isInitialLoading = true;
            }

            if (getMessageCursor() != null) {
                LogUtils.d(LOG_TAG, "Fragment is now user-visible, onConversationSeen: %s", this);
                if (!isInitialLoading) {
                    loadTag = "preloaded";
                }
                onConversationSeen();
            } else if (isLoadWaiting()) {
                LogUtils.d(LOG_TAG, "Fragment is now user-visible, showing conversation: %s", this);
                if (!isInitialLoading) {
                    loadTag = "load_deferred";
                }
                handleDelayedConversationLoad();
            }

            if (loadTag != null) {
                // pager swipes are visibility transitions to 'visible' except during initial
                // pager load on A) enter conversation mode B) rotate C) 2-pane conv-mode list-tap
              Analytics.getInstance().sendEvent("pager_swipe", loadTag,
                      getCurrentFolderTypeDesc(), 0);
            }
        }

        if (mWebView != null) {
            mWebView.onUserVisibilityChanged(userVisible);
        }
    }

    /**
     * Will either call initLoader now to begin loading, or set {@link #mLoadWaitReason} and do
     * nothing (in which case you should later call {@link #handleDelayedConversationLoad()}).
     */
    private void showConversation() {
        final int reason;

        if (isUserVisible()) {
            LogUtils.i(LOG_TAG,
                    "SHOWCONV: CVF is user-visible, immediately loading conversation (%s)", this);
            reason = LOAD_NOW;
            timerMark("CVF.showConversation");
        } else {
            final boolean disableOffscreenLoading = DISABLE_OFFSCREEN_LOADING
                    || Utils.isLowRamDevice(getContext())
                    || (mConversation != null && (mConversation.isRemote
                            || mConversation.getNumMessages() > mMaxAutoLoadMessages));

            // When not visible, we should not immediately load if either this conversation is
            // too heavyweight, or if the main/initial conversation is busy loading.
            if (disableOffscreenLoading) {
                reason = LOAD_WAIT_UNTIL_VISIBLE;
                LogUtils.i(LOG_TAG, "SHOWCONV: CVF waiting until visible to load (%s)", this);
            } else if (getListController().isInitialConversationLoading()) {
                reason = LOAD_WAIT_FOR_INITIAL_CONVERSATION;
                LogUtils.i(LOG_TAG, "SHOWCONV: CVF waiting for initial to finish (%s)", this);
                getListController().registerConversationLoadedObserver(mLoadedObserver);
            } else {
                LogUtils.i(LOG_TAG,
                        "SHOWCONV: CVF is not visible, but no reason to wait. loading now. (%s)",
                        this);
                reason = LOAD_NOW;
            }
        }

        mLoadWaitReason = reason;
        if (mLoadWaitReason == LOAD_NOW) {
            startConversationLoad();
        }
    }

    private void handleDelayedConversationLoad() {
        resetLoadWaiting();
        startConversationLoad();
    }

    private void startConversationLoad() {
        mWebView.setVisibility(View.VISIBLE);
        loadContent();
        // TODO(mindyp): don't show loading status for a previously rendered
        // conversation. Ielieve this is better done by making sure don't show loading status
        // until XX ms have passed without loading completed.
        mProgressController.showLoadingStatus(isUserVisible());
    }

    /**
     * Can be overridden in case a subclass needs to load something other than
     * the messages of a conversation.
     */
    protected void loadContent() {
        getLoaderManager().initLoader(MESSAGE_LOADER, Bundle.EMPTY, getMessageLoaderCallbacks());
    }

    private void revealConversation() {
        timerMark("revealing conversation");
        mProgressController.dismissLoadingStatus(mOnProgressDismiss);
        if (isUserVisible()) {
            AnalyticsTimer.getInstance().logDuration(AnalyticsTimer.OPEN_CONV_VIEW_FROM_LIST,
                    true /* isDestructive */, "open_conversation", "from_list", null);
        }
    }

    private boolean isLoadWaiting() {
        return mLoadWaitReason != LOAD_NOW;
    }

    private void renderConversation(MessageCursor messageCursor) {
        final String convHtml = renderMessageBodies(messageCursor, mEnableContentReadySignal);
        timerMark("rendered conversation");

        if (DEBUG_DUMP_CONVERSATION_HTML) {
            java.io.FileWriter fw = null;
            try {
                fw = new java.io.FileWriter(getSdCardFilePath());
                fw.write(convHtml);
            } catch (java.io.IOException e) {
                e.printStackTrace();
            } finally {
                if (fw != null) {
                    try {
                        fw.close();
                    } catch (java.io.IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        // save off existing scroll position before re-rendering
        if (mWebViewLoadedData) {
            mWebViewYPercent = calculateScrollYPercent();
        }

        mWebView.loadDataWithBaseURL(mBaseUri, convHtml, "text/html", "utf-8", null);
        mWebViewLoadedData = true;
        mWebViewLoadStartMs = SystemClock.uptimeMillis();
    }

    protected String getSdCardFilePath() {
        return "/sdcard/conv" + mConversation.id + ".html";
    }

    /**
     * Populate the adapter with overlay views (message headers, super-collapsed blocks, a
     * conversation header), and return an HTML document with spacer divs inserted for all overlays.
     *
     */
    protected String renderMessageBodies(MessageCursor messageCursor,
            boolean enableContentReadySignal) {
        int pos = -1;

        LogUtils.d(LOG_TAG, "IN renderMessageBodies, fragment=%s", this);
        boolean allowNetworkImages = false;

        // TODO: re-use any existing adapter item state (expanded, details expanded, show pics)

        // Walk through the cursor and build up an overlay adapter as you go.
        // Each overlay has an entry in the adapter for easy scroll handling in the container.
        // Items are not necessarily 1:1 in cursor and adapter because of super-collapsed blocks.
        // When adding adapter items, also add their heights to help the container later determine
        // overlay dimensions.

        // When re-rendering, prevent ConversationContainer from laying out overlays until after
        // the new spacers are positioned by WebView.
        mConversationContainer.invalidateSpacerGeometry();

        mAdapter.clear();

        // re-evaluate the message parts of the view state, since the messages may have changed
        // since the previous render
        final ConversationViewState prevState = mViewState;
        mViewState = new ConversationViewState(prevState);

        // N.B. the units of height for spacers are actually dp and not px because WebView assumes
        // a pixel is an mdpi pixel, unless you set device-dpi.

        // add a single conversation header item
        final int convHeaderPos = mAdapter.addConversationHeader(mConversation);
        final int convHeaderPx = measureOverlayHeight(convHeaderPos);

        mTemplates.startConversation(mWebView.getViewportWidth(),
                mWebView.screenPxToWebPx(mSideMarginPx), mWebView.screenPxToWebPx(convHeaderPx));

        int collapsedStart = -1;
        ConversationMessage prevCollapsedMsg = null;

        final boolean alwaysShowImages = shouldAlwaysShowImages();

        boolean prevSafeForImages = alwaysShowImages;

        boolean hasDraft = false;
        while (messageCursor.moveToPosition(++pos)) {
            final ConversationMessage msg = messageCursor.getMessage();

            final boolean safeForImages = alwaysShowImages ||
                    msg.alwaysShowImages || prevState.getShouldShowImages(msg);
            allowNetworkImages |= safeForImages;

            final Integer savedExpanded = prevState.getExpansionState(msg);
            final int expandedState;
            if (savedExpanded != null) {
                if (ExpansionState.isSuperCollapsed(savedExpanded) && messageCursor.isLast()) {
                    // override saved state when this is now the new last message
                    // this happens to the second-to-last message when you discard a draft
                    expandedState = ExpansionState.EXPANDED;
                } else {
                    expandedState = savedExpanded;
                }
            } else {
                // new messages that are not expanded default to being eligible for super-collapse
                if (msg.starred || !msg.read || messageCursor.isLast()) {
                    expandedState = ExpansionState.EXPANDED;
                } else if (messageCursor.isFirst()) {
                    expandedState = ExpansionState.COLLAPSED;
                } else {
                    expandedState = ExpansionState.SUPER_COLLAPSED;
                    hasDraft |= msg.isDraft();
                }
            }
            mViewState.setShouldShowImages(msg, prevState.getShouldShowImages(msg));
            mViewState.setExpansionState(msg, expandedState);

            // save off "read" state from the cursor
            // later, the view may not match the cursor (e.g. conversation marked read on open)
            // however, if a previous state indicated this message was unread, trust that instead
            // so "mark unread" marks all originally unread messages
            mViewState.setReadState(msg, msg.read && !prevState.isUnread(msg));

            // We only want to consider this for inclusion in the super collapsed block if
            // 1) The we don't have previous state about this message  (The first time that the
            //    user opens a conversation)
            // 2) The previously saved state for this message indicates that this message is
            //    in the super collapsed block.
            if (ExpansionState.isSuperCollapsed(expandedState)) {
                // contribute to a super-collapsed block that will be emitted just before the
                // next expanded header
                if (collapsedStart < 0) {
                    collapsedStart = pos;
                }
                prevCollapsedMsg = msg;
                prevSafeForImages = safeForImages;

                // This line puts the from address in the address cache so that
                // we get the sender image for it if it's in a super-collapsed block.
                getAddress(msg.getFrom());
                continue;
            }

            // resolve any deferred decisions on previous collapsed items
            if (collapsedStart >= 0) {
                if (pos - collapsedStart == 1) {
                    // Special-case for a single collapsed message: no need to super-collapse it.
                    renderMessage(prevCollapsedMsg, false /* expanded */, prevSafeForImages);
                } else {
                    renderSuperCollapsedBlock(collapsedStart, pos - 1, hasDraft);
                }
                hasDraft = false; // reset hasDraft
                prevCollapsedMsg = null;
                collapsedStart = -1;
            }

            renderMessage(msg, ExpansionState.isExpanded(expandedState), safeForImages);
        }

        final MessageHeaderItem lastHeaderItem = getLastMessageHeaderItem();
        final int convFooterPos = mAdapter.addConversationFooter(lastHeaderItem);
        final int convFooterPx = measureOverlayHeight(convFooterPos);

        mWebView.getSettings().setBlockNetworkImage(!allowNetworkImages);

        final boolean applyTransforms = shouldApplyTransforms();

        // If the conversation has specified a base uri, use it here, otherwise use mBaseUri
        return mTemplates.endConversation(mWebView.screenPxToWebPx(convFooterPx), mBaseUri,
                mConversation.getBaseUri(mBaseUri),
                mWebView.getViewportWidth(), mWebView.getWidthInDp(mSideMarginPx),
                enableContentReadySignal, isOverviewMode(mAccount), applyTransforms,
                applyTransforms);
    }

    private MessageHeaderItem getLastMessageHeaderItem() {
        int pos = mAdapter.getCount();
        while (--pos >= 0) {
            final ConversationOverlayItem item = mAdapter.getItem(pos);
            if (item instanceof MessageHeaderItem) {
                return (MessageHeaderItem) item;
            }
        }
        LogUtils.wtf(LOG_TAG, "No message header found");
        return null;
    }

    private void renderSuperCollapsedBlock(int start, int end, boolean hasDraft) {
        final int blockPos = mAdapter.addSuperCollapsedBlock(start, end, hasDraft);
        final int blockPx = measureOverlayHeight(blockPos);
        mTemplates.appendSuperCollapsedHtml(start, mWebView.screenPxToWebPx(blockPx));
    }

    private void renderMessage(ConversationMessage msg, boolean expanded, boolean safeForImages) {

        final int headerPos = mAdapter.addMessageHeader(msg, expanded,
                mViewState.getShouldShowImages(msg));
        final MessageHeaderItem headerItem = (MessageHeaderItem) mAdapter.getItem(headerPos);

        final int footerPos = mAdapter.addMessageFooter(headerItem);

        // Measure item header and footer heights to allocate spacers in HTML
        // But since the views themselves don't exist yet, render each item temporarily into
        // a host view for measurement.
        final int headerPx = measureOverlayHeight(headerPos);
        final int footerPx = measureOverlayHeight(footerPos);

        mTemplates.appendMessageHtml(msg, expanded, safeForImages,
                mWebView.screenPxToWebPx(headerPx), mWebView.screenPxToWebPx(footerPx));
        timerMark("rendered message");
    }

    private String renderCollapsedHeaders(MessageCursor cursor,
            SuperCollapsedBlockItem blockToReplace) {
        final List<ConversationOverlayItem> replacements = Lists.newArrayList();

        mTemplates.reset();

        final boolean alwaysShowImages = (mAccount != null) &&
                (mAccount.settings.showImages == Settings.ShowImages.ALWAYS);

        // In devices with non-integral density multiplier, screen pixels translate to non-integral
        // web pixels. Keep track of the error that occurs when we cast all heights to int
        float error = 0f;
        boolean first = true;
        for (int i = blockToReplace.getStart(), end = blockToReplace.getEnd(); i <= end; i++) {
            cursor.moveToPosition(i);
            final ConversationMessage msg = cursor.getMessage();

            final MessageHeaderItem header = ConversationViewAdapter.newMessageHeaderItem(
                    mAdapter, mAdapter.getDateBuilder(), msg, false /* expanded */,
                    alwaysShowImages || mViewState.getShouldShowImages(msg));
            final MessageFooterItem footer = mAdapter.newMessageFooterItem(mAdapter, header);

            final int headerPx = measureOverlayHeight(header);
            final int footerPx = measureOverlayHeight(footer);
            error += mWebView.screenPxToWebPxError(headerPx)
                    + mWebView.screenPxToWebPxError(footerPx);

            // When the error becomes greater than 1 pixel, make the next header 1 pixel taller
            int correction = 0;
            if (error >= 1) {
                correction = 1;
                error -= 1;
            }

            mTemplates.appendMessageHtml(msg, false /* expanded */,
                    alwaysShowImages || msg.alwaysShowImages,
                    mWebView.screenPxToWebPx(headerPx) + correction,
                    mWebView.screenPxToWebPx(footerPx));
            replacements.add(header);
            replacements.add(footer);

            mViewState.setExpansionState(msg, ExpansionState.COLLAPSED);
        }

        mAdapter.replaceSuperCollapsedBlock(blockToReplace, replacements);
        mAdapter.notifyDataSetChanged();

        return mTemplates.emit();
    }

    protected int measureOverlayHeight(int position) {
        return measureOverlayHeight(mAdapter.getItem(position));
    }

    /**
     * Measure the height of an adapter view by rendering an adapter item into a temporary
     * host view, and asking the view to immediately measure itself. This method will reuse
     * a previous adapter view from {@link ConversationContainer}'s scrap views if one was generated
     * earlier.
     * <p>
     * After measuring the height, this method also saves the height in the
     * {@link ConversationOverlayItem} for later use in overlay positioning.
     *
     * @param convItem adapter item with data to render and measure
     * @return height of the rendered view in screen px
     */
    private int measureOverlayHeight(ConversationOverlayItem convItem) {
        final int type = convItem.getType();

        final View convertView = mConversationContainer.getScrapView(type);
        final View hostView = mAdapter.getView(convItem, convertView, mConversationContainer,
                true /* measureOnly */);
        if (convertView == null) {
            mConversationContainer.addScrapView(type, hostView);
        }

        final int heightPx = mConversationContainer.measureOverlay(hostView);
        convItem.setHeight(heightPx);
        convItem.markMeasurementValid();

        return heightPx;
    }

    @Override
    public void onConversationViewHeaderHeightChange(int newHeight) {
        final int h = mWebView.screenPxToWebPx(newHeight);

        mWebView.loadUrl(String.format("javascript:setConversationHeaderSpacerHeight(%s);", h));
    }

    // END conversation header callbacks

    // START conversation footer callbacks

    @Override
    public void onConversationFooterHeightChange(int newHeight) {
        final int h = mWebView.screenPxToWebPx(newHeight);

        mWebView.loadUrl(String.format("javascript:setConversationFooterSpacerHeight(%s);", h));
    }

    // END conversation footer callbacks

    // START message header callbacks
    @Override
    public void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeightPx) {
        mConversationContainer.invalidateSpacerGeometry();

        // update message HTML spacer height
        final int h = mWebView.screenPxToWebPx(newSpacerHeightPx);
        LogUtils.i(LAYOUT_TAG, "setting HTML spacer h=%dwebPx (%dscreenPx)", h,
                newSpacerHeightPx);
        mWebView.loadUrl(String.format("javascript:setMessageHeaderSpacerHeight('%s', %s);",
                mTemplates.getMessageDomId(item.getMessage()), h));
    }

    @Override
    public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeightPx) {
        mConversationContainer.invalidateSpacerGeometry();

        // show/hide the HTML message body and update the spacer height
        final int h = mWebView.screenPxToWebPx(newSpacerHeightPx);
        LogUtils.i(LAYOUT_TAG, "setting HTML spacer expanded=%s h=%dwebPx (%dscreenPx)",
                item.isExpanded(), h, newSpacerHeightPx);
        mWebView.loadUrl(String.format("javascript:setMessageBodyVisible('%s', %s, %s);",
                mTemplates.getMessageDomId(item.getMessage()), item.isExpanded(), h));

        mViewState.setExpansionState(item.getMessage(),
                item.isExpanded() ? ExpansionState.EXPANDED : ExpansionState.COLLAPSED);
    }

    @Override
    public void showExternalResources(final Message msg) {
        mViewState.setShouldShowImages(msg, true);
        mWebView.getSettings().setBlockNetworkImage(false);
        mWebView.loadUrl("javascript:unblockImages(['" + mTemplates.getMessageDomId(msg) + "']);");
    }

    @Override
    public void showExternalResources(final String senderRawAddress) {
        mWebView.getSettings().setBlockNetworkImage(false);

        final Address sender = getAddress(senderRawAddress);
        if (sender == null) {
            // Don't need to unblock any images
            return;
        }
        final MessageCursor cursor = getMessageCursor();

        final List<String> messageDomIds = new ArrayList<>();

        int pos = -1;
        while (cursor.moveToPosition(++pos)) {
            final ConversationMessage message = cursor.getMessage();
            if (sender.equals(getAddress(message.getFrom()))) {
                message.alwaysShowImages = true;

                mViewState.setShouldShowImages(message, true);
                messageDomIds.add(mTemplates.getMessageDomId(message));
            }
        }

        final String url = String.format(
                "javascript:unblockImages(['%s']);", TextUtils.join("','", messageDomIds));
        mWebView.loadUrl(url);
    }

    @Override
    public boolean supportsMessageTransforms() {
        return true;
    }

    @Override
    public String getMessageTransforms(final Message msg) {
        final String domId = mTemplates.getMessageDomId(msg);
        return (domId == null) ? null : mMessageTransforms.get(domId);
    }

    @Override
    public boolean isSecure() {
        return false;
    }

    // END message header callbacks

    @Override
    public void showUntransformedConversation() {
        super.showUntransformedConversation();
        final MessageCursor cursor = getMessageCursor();
        if  (cursor != null) {
            renderConversation(cursor);
        }
    }

    @Override
    public void onSuperCollapsedClick(SuperCollapsedBlockItem item) {
        MessageCursor cursor = getMessageCursor();
        if (cursor == null || !mViewsCreated) {
            return;
        }

        mTempBodiesHtml = renderCollapsedHeaders(cursor, item);
        mWebView.loadUrl("javascript:replaceSuperCollapsedBlock(" + item.getStart() + ")");
        mConversationContainer.focusFirstMessageHeader();
    }

    private void showNewMessageNotification(NewMessagesInfo info) {
        mNewMessageBar.show(mNewMessageBarActionListener, info.getNotificationText(), R.string.show,
                true /* replaceVisibleToast */, false /* autohide */, null /* ToastBarOperation */);
    }

    private void onNewMessageBarClick() {
        mNewMessageBar.hide(true, true);

        renderConversation(getMessageCursor()); // mCursor is already up-to-date
                                                // per onLoadFinished()
    }

    private static OverlayPosition[] parsePositions(final int[] topArray, final int[] bottomArray) {
        final int len = topArray.length;
        final OverlayPosition[] positions = new OverlayPosition[len];
        for (int i = 0; i < len; i++) {
            positions[i] = new OverlayPosition(topArray[i], bottomArray[i]);
        }
        return positions;
    }

    protected @Nullable Address getAddress(String rawFrom) {
        return Utils.getAddress(mAddressCache, rawFrom);
    }

    private void ensureContentSizeChangeListener() {
        if (mWebViewSizeChangeListener == null) {
            mWebViewSizeChangeListener = new ContentSizeChangeListener() {
                @Override
                public void onHeightChange(int h) {
                    // When WebKit says the DOM height has changed, re-measure
                    // bodies and re-position their headers.
                    // This is separate from the typical JavaScript DOM change
                    // listeners because cases like NARROW_COLUMNS text reflow do not trigger DOM
                    // events.
                    mWebView.loadUrl("javascript:measurePositions();");
                }
            };
        }
        mWebView.setContentSizeChangeListener(mWebViewSizeChangeListener);
    }

    public static boolean isOverviewMode(Account acct) {
        return acct.settings.isOverviewMode();
    }

    private void setupOverviewMode() {
        // for now, overview mode means use the built-in WebView zoom and disable custom scale
        // gesture handling
        final boolean overviewMode = isOverviewMode(mAccount);
        final WebSettings settings = mWebView.getSettings();
        final WebSettings.LayoutAlgorithm layout;
        settings.setUseWideViewPort(overviewMode);
        settings.setSupportZoom(overviewMode);
        settings.setBuiltInZoomControls(overviewMode);
        settings.setLoadWithOverviewMode(overviewMode);
        if (overviewMode) {
            settings.setDisplayZoomControls(false);
            layout = WebSettings.LayoutAlgorithm.NORMAL;
        } else {
            layout = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
        }
        settings.setLayoutAlgorithm(layout);
    }

    @Override
    public ConversationMessage getMessageForClickedUrl(String url) {
        final String domMessageId = mUrlToMessageIdMap.get(url);
        if (domMessageId == null) {
            return null;
        }
        final MessageCursor messageCursor = getMessageCursor();
        if (messageCursor == null) {
            return null;
        }
        final String messageId = mTemplates.getMessageIdForDomId(domMessageId);
        return messageCursor.getMessageForId(Long.parseLong(messageId));
    }

    /**
     * Determines if we should intercept the left/right key event generated by the hardware
     * keyboard so the framework won't handle directional navigation for us.
     */
    private boolean shouldInterceptLeftRightEvents(@IdRes int id, boolean isLeft, boolean isRight,
            boolean twoPaneLand) {
        return twoPaneLand && (id == R.id.conversation_topmost_overlay ||
                id == R.id.upper_header ||
                id == R.id.super_collapsed_block ||
                id == R.id.message_footer ||
                (id == R.id.overflow && isRight) ||
                (id == R.id.reply_button && isLeft) ||
                (id == R.id.forward_button && isRight));
    }

    /**
     * Indicates if the direction with the provided id should navigate away from the conversation
     * view. Note that this is only applicable in two-pane landscape mode.
     */
    private boolean shouldNavigateAway(@IdRes int id, boolean isLeft, boolean twoPaneLand) {
        return twoPaneLand && isLeft && (id == R.id.conversation_topmost_overlay ||
                id == R.id.upper_header ||
                id == R.id.super_collapsed_block ||
                id == R.id.message_footer ||
                id == R.id.reply_button);
    }

    @Override
    public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
        if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
            mOriginalKeyedView = view;
        }

        if (mOriginalKeyedView != null) {
            final int id = mOriginalKeyedView.getId();
            final boolean isRtl = ViewUtils.isViewRtl(mOriginalKeyedView);
            final boolean isActionUp = keyEvent.getAction() == KeyEvent.ACTION_UP;
            final boolean isStart = KeyboardUtils.isKeycodeDirectionStart(keyCode, isRtl);
            final boolean isEnd = KeyboardUtils.isKeycodeDirectionEnd(keyCode, isRtl);
            final boolean isUp = keyCode == KeyEvent.KEYCODE_DPAD_UP;
            final boolean isDown = keyCode == KeyEvent.KEYCODE_DPAD_DOWN;

            // First we run the event by the controller
            // We manually check if the view+direction combination should shift focus away from the
            // conversation view to the thread list in two-pane landscape mode.
            final boolean isTwoPaneLand = mNavigationController.isTwoPaneLandscape();
            final boolean navigateAway = shouldNavigateAway(id, isStart, isTwoPaneLand);
            if (mNavigationController.onInterceptKeyFromCV(keyCode, keyEvent, navigateAway)) {
                return true;
            }

            // If controller didn't handle the event, check directional interception.
            if ((isStart || isEnd) && shouldInterceptLeftRightEvents(
                    id, isStart, isEnd, isTwoPaneLand)) {
                return true;
            } else if (isUp || isDown) {
                // We don't do anything on up/down for overlay
                if (id == R.id.conversation_topmost_overlay) {
                    return true;
                }

                // We manually handle up/down navigation through the overlay items because the
                // system's default isn't optimal for two-pane landscape since it's not a real list.
                final View next = mConversationContainer.getNextOverlayView(mOriginalKeyedView,
                        isDown);
                if (next != null) {
                    focusAndScrollToView(next);
                } else if (!isActionUp) {
                    // Scroll in the direction of the arrow if next view isn't found.
                    final int currentY = mWebView.getScrollY();
                    if (isUp && currentY > 0) {
                        mWebView.scrollBy(0,
                                -Math.min(currentY, DEFAULT_VERTICAL_SCROLL_DISTANCE_PX));
                    } else if (isDown) {
                        final int webviewEnd = (int) (mWebView.getContentHeight() *
                                mWebView.getScale());
                        final int currentEnd = currentY + mWebView.getHeight();
                        if (currentEnd < webviewEnd) {
                            mWebView.scrollBy(0, Math.min(webviewEnd - currentEnd,
                                    DEFAULT_VERTICAL_SCROLL_DISTANCE_PX));
                        }
                    }
                }
                return true;
            }

            // Finally we handle the special keys
            if (keyCode == KeyEvent.KEYCODE_BACK && id != R.id.conversation_topmost_overlay) {
                if (isActionUp) {
                    mTopmostOverlay.requestFocus();
                }
                return true;
            } else if (keyCode == KeyEvent.KEYCODE_ENTER &&
                    id == R.id.conversation_topmost_overlay) {
                if (isActionUp) {
                    mWebView.scrollTo(0, 0);
                    mConversationContainer.focusFirstMessageHeader();
                }
                return true;
            }
        }
        return false;
    }

    private void focusAndScrollToView(View v) {
        // Make sure that v is in view
        final int[] coords = new int[2];
        v.getLocationOnScreen(coords);
        final int bottom = coords[1] + v.getHeight();
        if (bottom > mMaxScreenHeight) {
            mWebView.scrollBy(0, bottom - mMaxScreenHeight);
        } else if (coords[1] < mTopOfVisibleScreen) {
            mWebView.scrollBy(0, coords[1] - mTopOfVisibleScreen);
        }
        v.requestFocus();
    }

    public class ConversationWebViewClient extends AbstractConversationWebViewClient {
        public ConversationWebViewClient(Account account) {
            super(account);
        }

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            // try to locate the message associated with the url
            final ConversationMessage cm = getMessageForClickedUrl(url);
            if (cm != null) {
                // try to load the url assuming it is a cid url
                final Uri uri = Uri.parse(url);
                final WebResourceResponse response = loadCIDUri(uri, cm);
                if (response != null) {
                    return response;
                }
            }

            // otherwise, attempt the default handling
            return super.shouldInterceptRequest(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            // Ignore unsafe calls made after a fragment is detached from an activity.
            // This method needs to, for example, get at the loader manager, which needs
            // the fragment to be added.
            if (!isAdded() || !mViewsCreated) {
                LogUtils.d(LOG_TAG, "ignoring CVF.onPageFinished, url=%s fragment=%s", url,
                        ConversationViewFragment.this);
                return;
            }

            LogUtils.d(LOG_TAG, "IN CVF.onPageFinished, url=%s fragment=%s wv=%s t=%sms", url,
                    ConversationViewFragment.this, view,
                    (SystemClock.uptimeMillis() - mWebViewLoadStartMs));

            ensureContentSizeChangeListener();

            if (!mEnableContentReadySignal) {
                revealConversation();
            }

            final Set<String> emailAddresses = Sets.newHashSet();
            final List<Address> cacheCopy;
            synchronized (mAddressCache) {
                cacheCopy = ImmutableList.copyOf(mAddressCache.values());
            }
            for (Address addr : cacheCopy) {
                emailAddresses.add(addr.getAddress());
            }
            final ContactLoaderCallbacks callbacks = getContactInfoSource();
            callbacks.setSenders(emailAddresses);
            getLoaderManager().restartLoader(CONTACT_LOADER, Bundle.EMPTY, callbacks);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return mViewsCreated && super.shouldOverrideUrlLoading(view, url);
        }
    }

    /**
     * NOTE: all public methods must be listed in the proguard flags so that they can be accessed
     * via reflection and not stripped.
     *
     */
    private class MailJsBridge {
        @JavascriptInterface
        public void onWebContentGeometryChange(final int[] overlayTopStrs,
                final int[] overlayBottomStrs) {
            try {
                getHandler().post(new FragmentRunnable("onWebContentGeometryChange",
                        ConversationViewFragment.this) {
                    @Override
                    public void go() {
                        if (!mViewsCreated) {
                            LogUtils.d(LOG_TAG, "ignoring webContentGeometryChange because views"
                                    + " are gone, %s", ConversationViewFragment.this);
                            return;
                        }
                        mConversationContainer.onGeometryChange(
                                parsePositions(overlayTopStrs, overlayBottomStrs));
                        if (mDiff != 0) {
                            // SCROLL!
                            int scale = (int) (mWebView.getScale() / mWebView.getInitialScale());
                            if (scale > 1) {
                                mWebView.scrollBy(0, (mDiff * (scale - 1)));
                            }
                            mDiff = 0;
                        }
                    }
                });
            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onWebContentGeometryChange");
            }
        }

        @JavascriptInterface
        public String getTempMessageBodies() {
            try {
                if (!mViewsCreated) {
                    return "";
                }

                final String s = mTempBodiesHtml;
                mTempBodiesHtml = null;
                return s;
            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.getTempMessageBodies");
                return "";
            }
        }

        @JavascriptInterface
        public String getMessageBody(String domId) {
            try {
                final MessageCursor cursor = getMessageCursor();
                if (!mViewsCreated || cursor == null) {
                    return "";
                }

                int pos = -1;
                while (cursor.moveToPosition(++pos)) {
                    final ConversationMessage msg = cursor.getMessage();
                    if (TextUtils.equals(domId, mTemplates.getMessageDomId(msg))) {
                        return HtmlConversationTemplates.wrapMessageBody(msg.getBodyAsHtml());
                    }
                }

                return "";

            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.getMessageBody");
                return "";
            }
        }

        @JavascriptInterface
        public String getMessageSender(String domId) {
            try {
                final MessageCursor cursor = getMessageCursor();
                if (!mViewsCreated || cursor == null) {
                    return "";
                }

                int pos = -1;
                while (cursor.moveToPosition(++pos)) {
                    final ConversationMessage msg = cursor.getMessage();
                    if (TextUtils.equals(domId, mTemplates.getMessageDomId(msg))) {
                        final Address address = getAddress(msg.getFrom());
                        if (address != null) {
                            return address.getAddress();
                        } else {
                            // Fall through to return an empty string
                            break;
                        }
                    }
                }

                return "";

            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.getMessageSender");
                return "";
            }
        }

        @JavascriptInterface
        public void onContentReady() {
            try {
                getHandler().post(new FragmentRunnable("onContentReady",
                        ConversationViewFragment.this) {
                    @Override
                    public void go() {
                        try {
                            if (mWebViewLoadStartMs != 0) {
                                LogUtils.i(LOG_TAG, "IN CVF.onContentReady, f=%s vis=%s t=%sms",
                                        ConversationViewFragment.this,
                                        isUserVisible(),
                                        (SystemClock.uptimeMillis() - mWebViewLoadStartMs));
                            }
                            revealConversation();
                        } catch (Throwable t) {
                            LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onContentReady");
                            // Still try to show the conversation.
                            revealConversation();
                        }
                    }
                });
            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onContentReady");
            }
        }

        @JavascriptInterface
        public float getScrollYPercent() {
            try {
                return mWebViewYPercent;
            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.getScrollYPercent");
                return 0f;
            }
        }

        @JavascriptInterface
        public void onMessageTransform(String messageDomId, String transformText) {
            try {
                LogUtils.i(LOG_TAG, "TRANSFORM: (%s) %s", messageDomId, transformText);
                mMessageTransforms.put(messageDomId, transformText);
                onConversationTransformed();
            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onMessageTransform");
            }
        }

        @JavascriptInterface
        public void onInlineAttachmentsParsed(final String[] urls, final String[] messageIds) {
            try {
                getHandler().post(new FragmentRunnable("onInlineAttachmentsParsed",
                        ConversationViewFragment.this) {
                    @Override
                    public void go() {
                        try {
                            for (int i = 0, size = urls.length; i < size; i++) {
                                mUrlToMessageIdMap.put(urls[i], messageIds[i]);
                            }
                        } catch (ArrayIndexOutOfBoundsException e) {
                            LogUtils.e(LOG_TAG, e,
                                    "Number of urls does not match number of message ids - %s:%s",
                                    urls.length, messageIds.length);
                        }
                    }
                });
            } catch (Throwable t) {
                LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onInlineAttachmentsParsed");
            }
        }
    }

    private class NewMessagesInfo {
        int count;
        int countFromSelf;

        /**
         * Return the display text for the new message notification overlay. It will be formatted
         * appropriately for a single new message vs. multiple new messages.
         *
         * @return display text
         */
        public String getNotificationText() {
            return getResources().getQuantityString(R.plurals.new_incoming_messages, count, count);
        }
    }

    @Override
    public void onMessageCursorLoadFinished(Loader<ObjectCursor<ConversationMessage>> loader,
            MessageCursor newCursor, MessageCursor oldCursor) {
        /*
         * what kind of changes affect the MessageCursor? 1. new message(s) 2.
         * read/unread state change 3. deleted message, either regular or draft
         * 4. updated message, either from self or from others, updated in
         * content or state or sender 5. star/unstar of message (technically
         * similar to #1) 6. other label change Use MessageCursor.hashCode() to
         * sort out interesting vs. no-op cursor updates.
         */

        if (oldCursor != null && !oldCursor.isClosed()) {
            final NewMessagesInfo info = getNewIncomingMessagesInfo(newCursor);

            if (info.count > 0) {
                // don't immediately render new incoming messages from other
                // senders
                // (to avoid a new message from losing the user's focus)
                LogUtils.i(LOG_TAG, "CONV RENDER: conversation updated"
                        + ", holding cursor for new incoming message (%s)", this);
                showNewMessageNotification(info);
                return;
            }

            final int oldState = oldCursor.getStateHashCode();
            final boolean changed = newCursor.getStateHashCode() != oldState;

            if (!changed) {
                final boolean processedInPlace = processInPlaceUpdates(newCursor, oldCursor);
                if (processedInPlace) {
                    LogUtils.i(LOG_TAG, "CONV RENDER: processed update(s) in place (%s)", this);
                } else {
                    LogUtils.i(LOG_TAG, "CONV RENDER: uninteresting update"
                            + ", ignoring this conversation update (%s)", this);
                }
                return;
            } else if (info.countFromSelf == 1) {
                // Special-case the very common case of a new cursor that is the same as the old
                // one, except that there is a new message from yourself. This happens upon send.
                final boolean sameExceptNewLast = newCursor.getStateHashCode(1) == oldState;
                if (sameExceptNewLast) {
                    LogUtils.i(LOG_TAG, "CONV RENDER: update is a single new message from self"
                            + " (%s)", this);
                    newCursor.moveToLast();
                    processNewOutgoingMessage(newCursor.getMessage());
                    return;
                }
            }
            // cursors are different, and not due to an incoming message. fall
            // through and render.
            LogUtils.i(LOG_TAG, "CONV RENDER: conversation updated"
                    + ", but not due to incoming message. rendering. (%s)", this);

            if (DEBUG_DUMP_CURSOR_CONTENTS) {
                LogUtils.i(LOG_TAG, "old cursor: %s", oldCursor.getDebugDump());
                LogUtils.i(LOG_TAG, "new cursor: %s", newCursor.getDebugDump());
            }
        } else {
            LogUtils.i(LOG_TAG, "CONV RENDER: initial render. (%s)", this);
            timerMark("message cursor load finished");
        }

        renderContent(newCursor);
    }

    protected void renderContent(MessageCursor messageCursor) {
        // if layout hasn't happened, delay render
        // This is needed in addition to the showConversation() delay to speed
        // up rotation and restoration.
        if (mConversationContainer.getWidth() == 0) {
            mNeedRender = true;
            mConversationContainer.addOnLayoutChangeListener(this);
        } else {
            renderConversation(messageCursor);
        }
    }

    private NewMessagesInfo getNewIncomingMessagesInfo(MessageCursor newCursor) {
        final NewMessagesInfo info = new NewMessagesInfo();

        int pos = -1;
        while (newCursor.moveToPosition(++pos)) {
            final Message m = newCursor.getMessage();
            if (!mViewState.contains(m)) {
                LogUtils.i(LOG_TAG, "conversation diff: found new msg: %s", m.uri);

                final Address from = getAddress(m.getFrom());
                // distinguish ours from theirs
                // new messages from the account owner should not trigger a
                // notification
                if (from == null || mAccount.ownsFromAddress(from.getAddress())) {
                    LogUtils.i(LOG_TAG, "found message from self: %s", m.uri);
                    info.countFromSelf++;
                    continue;
                }

                info.count++;
            }
        }
        return info;
    }

    private boolean processInPlaceUpdates(MessageCursor newCursor, MessageCursor oldCursor) {
        final Set<String> idsOfChangedBodies = Sets.newHashSet();
        final List<Integer> changedOverlayPositions = Lists.newArrayList();

        boolean changed = false;

        int pos = 0;
        while (true) {
            if (!newCursor.moveToPosition(pos) || !oldCursor.moveToPosition(pos)) {
                break;
            }

            final ConversationMessage newMsg = newCursor.getMessage();
            final ConversationMessage oldMsg = oldCursor.getMessage();

            // We are going to update the data in the adapter whenever any input fields change.
            // This ensures that the Message object that ComposeActivity uses will be correctly
            // aligned with the most up-to-date data.
            if (!newMsg.isEqual(oldMsg)) {
                mAdapter.updateItemsForMessage(newMsg, changedOverlayPositions);
                LogUtils.i(LOG_TAG, "msg #%d (%d): detected field(s) change. sendingState=%s",
                        pos, newMsg.id, newMsg.sendingState);
            }

            // update changed message bodies in-place
            if (!TextUtils.equals(newMsg.bodyHtml, oldMsg.bodyHtml) ||
                    !TextUtils.equals(newMsg.bodyText, oldMsg.bodyText)) {
                // maybe just set a flag to notify JS to re-request changed bodies
                idsOfChangedBodies.add('"' + mTemplates.getMessageDomId(newMsg) + '"');
                LogUtils.i(LOG_TAG, "msg #%d (%d): detected body change", pos, newMsg.id);
            }

            pos++;
        }


        if (!changedOverlayPositions.isEmpty()) {
            // notify once after the entire adapter is updated
            mConversationContainer.onOverlayModelUpdate(changedOverlayPositions);
            changed = true;
        }

        final ConversationFooterItem footerItem = mAdapter.getFooterItem();
        if (footerItem != null) {
            footerItem.invalidateMeasurement();
        }
        if (!idsOfChangedBodies.isEmpty()) {
            mWebView.loadUrl(String.format("javascript:replaceMessageBodies([%s]);",
                    TextUtils.join(",", idsOfChangedBodies)));
            changed = true;
        }

        return changed;
    }

    private void processNewOutgoingMessage(ConversationMessage msg) {
        // Temporarily remove the ConversationFooterItem and its view.
        // It will get re-added right after the new message is added.
        final ConversationFooterItem footerItem = mAdapter.removeFooterItem();
        // if no footer, just skip the work for it. The rest should be fine to do.
        if (footerItem != null) {
            mConversationContainer.removeViewAtAdapterIndex(footerItem.getPosition());
        }

        mTemplates.reset();
        // this method will add some items to mAdapter, but we deliberately want to avoid notifying
        // adapter listeners (i.e. ConversationContainer) until onWebContentGeometryChange is next
        // called, to prevent N+1 headers rendering with N message bodies.
        renderMessage(msg, true /* expanded */, msg.alwaysShowImages);
        mTempBodiesHtml = mTemplates.emit();

        if (footerItem != null) {
            footerItem.setLastMessageHeaderItem(getLastMessageHeaderItem());
            footerItem.invalidateMeasurement();
            mAdapter.addItem(footerItem);
        }

        mViewState.setExpansionState(msg, ExpansionState.EXPANDED);
        // FIXME: should the provider set this as initial state?
        mViewState.setReadState(msg, false /* read */);

        // From now until the updated spacer geometry is returned, the adapter items are mismatched
        // with the existing spacers. Do not let them layout.
        mConversationContainer.invalidateSpacerGeometry();

        mWebView.loadUrl("javascript:appendMessageHtml();");
    }

    private static class SetCookieTask extends AsyncTask<Void, Void, Void> {
        private final Context mContext;
        private final String mUri;
        private final Uri mAccountCookieQueryUri;
        private final ContentResolver mResolver;

        /* package */ SetCookieTask(Context context, String baseUri, Uri accountCookieQueryUri) {
            mContext = context;
            mUri = baseUri;
            mAccountCookieQueryUri = accountCookieQueryUri;
            mResolver = context.getContentResolver();
        }

        @Override
        public Void doInBackground(Void... args) {
            // First query for the cookie string from the UI provider
            final Cursor cookieCursor = mResolver.query(mAccountCookieQueryUri,
                    UIProvider.ACCOUNT_COOKIE_PROJECTION, null, null, null);
            if (cookieCursor == null) {
                return null;
            }

            try {
                if (cookieCursor.moveToFirst()) {
                    final String cookie = cookieCursor.getString(
                            cookieCursor.getColumnIndex(UIProvider.AccountCookieColumns.COOKIE));

                    if (cookie != null) {
                        final CookieSyncManager csm =
                                CookieSyncManager.createInstance(mContext);
                        CookieManager.getInstance().setCookie(mUri, cookie);
                        csm.sync();
                    }
                }

            } finally {
                cookieCursor.close();
            }


            return null;
        }
    }

    @Override
    public void onConversationUpdated(Conversation conv) {
        final ConversationViewHeader headerView = (ConversationViewHeader) mConversationContainer
                .findViewById(R.id.conversation_header);
        mConversation = conv;
        if (headerView != null) {
            headerView.onConversationUpdated(conv);
        }
    }

    @Override
    public void onLayoutChange(View v, int left, int top, int right,
            int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        boolean sizeChanged = mNeedRender
                && mConversationContainer.getWidth() != 0;
        if (sizeChanged) {
            mNeedRender = false;
            mConversationContainer.removeOnLayoutChangeListener(this);
            renderConversation(getMessageCursor());
        }
    }

    @Override
    public void setMessageDetailsExpanded(MessageHeaderItem i, boolean expanded, int heightBefore) {
        mDiff = (expanded ? 1 : -1) * Math.abs(i.getHeight() - heightBefore);
    }

    /**
     * @return {@code true} because either the Print or Print All menu item is shown in GMail
     */
    @Override
    protected boolean shouldShowPrintInOverflow() {
        return true;
    }

    @Override
    protected void printConversation() {
        PrintUtils.printConversation(mActivity.getActivityContext(), getMessageCursor(),
                mAddressCache, mConversation.getBaseUri(mBaseUri), true /* useJavascript */);
    }

    @Override
    protected void handleReply() {
        final MessageHeaderItem item = getLastMessageHeaderItem();
        if (item != null) {
            final ConversationMessage msg = item.getMessage();
            if (msg != null) {
                ComposeActivity.reply(getActivity(), mAccount, msg);
            }
        }
    }

    @Override
    protected void handleReplyAll() {
        final MessageHeaderItem item = getLastMessageHeaderItem();
        if (item != null) {
            final ConversationMessage msg = item.getMessage();
            if (msg != null) {
                ComposeActivity.replyAll(getActivity(), mAccount, msg);
            }
        }
    }
}
