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

package com.android.email.provider;

import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcel;
import android.test.MoreAsserts;
import android.test.ProviderTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.email.SecurityPolicy;
import com.android.email.provider.EmailProvider.AttachmentService;
import com.android.emailcommon.AccountManagerTypes;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.EmailContent.Attachment;
import com.android.emailcommon.provider.EmailContent.AttachmentColumns;
import com.android.emailcommon.provider.EmailContent.Body;
import com.android.emailcommon.provider.EmailContent.BodyColumns;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.EmailContent.PolicyColumns;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.provider.Policy;
import com.android.emailcommon.utility.TextUtilities;
import com.android.emailcommon.utility.Utility;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Tests of the Email provider.
 *
 * You can run this entire test case with:
 *   runtest -c com.android.email.provider.ProviderTests email
 *
 * TODO: Add tests for cursor notification mechanism.  (setNotificationUri and notifyChange)
 * We can't test the entire notification mechanism with a mock content resolver, because which URI
 * to notify when notifyChange() is called is in the actual content resolver.
 * Implementing the same mechanism in a mock one is pointless.  Instead what we could do is check
 * what notification URI each cursor has, and with which URI is notified when
 * inserting/updating/deleting.  (The former require a new method from AbstractCursor)
 */
@LargeTest
public class ProviderTests extends ProviderTestCase2<EmailProvider> {

    private EmailProvider mProvider;
    private Context mMockContext;

    public ProviderTests() {
        super(EmailProvider.class, EmailContent.AUTHORITY);
    }

    // TODO: move this out to a common place. There are other places that have similar mocks.
    /**
     * Private context wrapper used to add back getPackageName() for these tests.
     */
    private static class MockContext2 extends ContextWrapper {

        private final Context mRealContext;

        public MockContext2(Context mockContext, Context realContext) {
            super(mockContext);
            mRealContext = realContext;
        }

        @Override
        public Context getApplicationContext() {
            return this;
        }

        @Override
        public String getPackageName() {
            return mRealContext.getPackageName();
        }

        @Override
        public Object getSystemService(String name) {
            return mRealContext.getSystemService(name);
        }
    }

    private static final AttachmentService MOCK_ATTACHMENT_SERVICE = new AttachmentService() {
        @Override
        public void attachmentChanged(Context context, long id, int flags) {
            // Noop. Don't download attachments.
        }
    };

    @Override
    public void setUp() throws Exception {
        super.setUp();
        mMockContext = new MockContext2(getMockContext(), getContext());
        mProvider = getProvider();
        mProvider.injectAttachmentService(MOCK_ATTACHMENT_SERVICE);
        // Invalidate all caches, since we reset the database for each test
        ContentCache.invalidateAllCaches();
    }

    @Override
    public void tearDown() throws Exception {
        super.tearDown();
        mProvider.injectAttachmentService(null);
    }

    /**
     * TODO: Database upgrade tests
     */

    //////////////////////////////////////////////////////////
    ////// Utility methods
    //////////////////////////////////////////////////////////

    /** Sets the message count of all mailboxes to {@code -1}. */
    private void setMinusOneToMessageCounts() {
        ContentValues values = new ContentValues();
        values.put(MailboxColumns.MESSAGE_COUNT, -1);

        // EmailProvider.update() doesn't allow updating messageCount, so directly use the DB.
        SQLiteDatabase db = getProvider().getDatabase(mMockContext);
        db.update(Mailbox.TABLE_NAME, values, null, null);
    }

    /** Returns the number of messages in a mailbox. */
    private int getMessageCount(long mailboxId) {
        return Utility.getFirstRowInt(mMockContext,
                ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId),
                new String[] {MailboxColumns.MESSAGE_COUNT}, null, null, null, 0);
    }

    /** Creates a new message. */
    private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read,
            int flagLoaded) {
        Message message = ProviderTestUtils.setupMessage(
                "1", b.mAccountKey, b.mId, true, false, c, starred, read);
        message.mFlagLoaded = flagLoaded;
        message.save(c);
        return message;
    }

    //////////////////////////////////////////////////////////
    ////// The tests
    //////////////////////////////////////////////////////////

    /**
     * Test simple account save/retrieve
     */
    @SmallTest
    public void testAccountSave() {
        Account account1 = ProviderTestUtils.setupAccount("account-save", true, mMockContext);
        long account1Id = account1.mId;

        Account account2 = Account.restoreAccountWithId(mMockContext, account1Id);

        ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account2);
    }

    /**
     * Test simple account save/retrieve with predefined hostauth records
     */
    @SmallTest
    public void testAccountSaveHostAuth() {
        Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
        // add hostauth data, which should be saved the first time
        account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false,
                mMockContext);
        account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false,
                mMockContext);
        account1.save(mMockContext);
        long account1Id = account1.mId;

        // Confirm account reads back correctly
        Account account1get = Account.restoreAccountWithId(mMockContext, account1Id);
        ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account1get);

        // Confirm hostauth fields can be accessed & read back correctly
        HostAuth hostAuth1get = HostAuth.restoreHostAuthWithId(mMockContext,
                account1get.mHostAuthKeyRecv);
        ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-recv",
                account1.mHostAuthRecv, hostAuth1get);
        HostAuth hostAuth2get = HostAuth.restoreHostAuthWithId(mMockContext,
                account1get.mHostAuthKeySend);
        ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-send",
                account1.mHostAuthSend, hostAuth2get);
    }

    public void testAccountGetHostAuthSend() {
        Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
        account.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false,
                mMockContext);
        account.save(mMockContext);
        HostAuth authGet;
        HostAuth authTest;

        authTest = account.mHostAuthSend;
        assertNotNull(authTest);
        assertTrue(account.mHostAuthKeySend != 0);

        // HostAuth is not changed
        authGet = account.getOrCreateHostAuthSend(mMockContext);
        assertTrue(authGet == authTest); // return the same object

        // New HostAuth; based upon mHostAuthKeyRecv
        authTest = HostAuth.restoreHostAuthWithId(mMockContext,
                account.mHostAuthKeySend);
        account.mHostAuthSend = null;
        authGet = account.getOrCreateHostAuthSend(mMockContext);
        assertNotNull(authGet);
        assertNotNull(account.mHostAuthSend);
        ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthSend-1", authTest, authGet);

        // New HostAuth; completely empty
        authTest = new HostAuth();
        account.mHostAuthSend = null;
        account.mHostAuthKeySend = 0;
        authGet = account.getOrCreateHostAuthSend(mMockContext);
        assertNotNull(authGet);
        assertNotNull(account.mHostAuthSend);
        ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthSendv-2", authTest, authGet);
    }

    public void testAccountGetHostAuthRecv() {
        Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
        account.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false,
                mMockContext);
        account.save(mMockContext);
        HostAuth authGet;
        HostAuth authTest;

        authTest = account.mHostAuthRecv;
        assertNotNull(authTest);
        assertTrue(account.mHostAuthKeyRecv != 0);

        // HostAuth is not changed
        authGet = account.getOrCreateHostAuthRecv(mMockContext);
        assertTrue(authGet == authTest); // return the same object

        // New HostAuth; based upon mHostAuthKeyRecv
        authTest = HostAuth.restoreHostAuthWithId(mMockContext,
                account.mHostAuthKeyRecv);
        account.mHostAuthRecv = null;
        authGet = account.getOrCreateHostAuthRecv(mMockContext);
        assertNotNull(authGet);
        assertNotNull(account.mHostAuthRecv);
        ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthRecv-1", authTest, authGet);

        // New HostAuth; completely empty
        authTest = new HostAuth();
        account.mHostAuthRecv = null;
        account.mHostAuthKeyRecv = 0;
        authGet = account.getOrCreateHostAuthRecv(mMockContext);
        assertNotNull(authGet);
        assertNotNull(account.mHostAuthRecv);
        ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthRecv-2", authTest, authGet);
    }

    /**
     * Simple test of account parceling.  The rather torturous path is to ensure that the
     * account is really flattened all the way down to a parcel and back.
     */
    public void testAccountParcel() {
        Account account1 = ProviderTestUtils.setupAccount("parcel", false, mMockContext);
        Bundle b = new Bundle();
        b.putParcelable("account", account1);
        Parcel p = Parcel.obtain();
        b.writeToParcel(p, 0);
        p.setDataPosition(0);       // rewind it for reading
        Bundle b2 = new Bundle(Account.class.getClassLoader());
        b2.readFromParcel(p);
        Account account2 = (Account) b2.getParcelable("account");
        p.recycle();

        ProviderTestUtils.assertAccountEqual("testAccountParcel", account1, account2);
    }

    /**
     * Test for {@link Account#getShortcutSafeUri()} and
     * {@link Account#getAccountIdFromShortcutSafeUri}.
     */
    public void testAccountShortcutSafeUri() {
        final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext);
        final Account account2 = ProviderTestUtils.setupAccount("account-2", true, mMockContext);
        final long account1Id = account1.mId;
        final long account2Id = account2.mId;

        final Uri uri1 = account1.getShortcutSafeUri();
        final Uri uri2 = account2.getShortcutSafeUri();

        // Check the path part of the URIs.
        MoreAsserts.assertEquals(new String[] {"account", account1.mCompatibilityUuid},
                uri1.getPathSegments().toArray());
        MoreAsserts.assertEquals(new String[] {"account", account2.mCompatibilityUuid},
                uri2.getPathSegments().toArray());

        assertEquals(account1Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, uri1));
        assertEquals(account2Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, uri2));

        // Test for the Eclair(2.0-2.1) style URI.
        assertEquals(account1Id, Account.getAccountIdFromShortcutSafeUri(mMockContext,
                getEclairStyleShortcutUri(account1)));
        assertEquals(account2Id, Account.getAccountIdFromShortcutSafeUri(mMockContext,
                getEclairStyleShortcutUri(account2)));
    }

    private static Uri getEclairStyleShortcutUri(Account account) {
        // We used _id instead of UUID only on Eclair(2.0-2.1).
        return Account.CONTENT_URI.buildUpon().appendEncodedPath("" + account.mId).build();
    }

    public void testGetProtocol() {
        Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
        // add hostauth data, with protocol
        account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("eas", "account-hostauth-recv",
                false, mMockContext);
        // Note that getProtocol uses the receive host auth, so the protocol here shouldn't matter
        // to the test result
        account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("foo", "account-hostauth-send",
                false, mMockContext);
        account1.save(mMockContext);
        assertEquals("eas", Account.getProtocol(mMockContext, account1.mId));
        assertEquals("eas", account1.getProtocol(mMockContext));
        Account account2 = ProviderTestUtils.setupAccount("account-nohostauth", false,
                mMockContext);
        account2.save(mMockContext);
        // Make sure that we return null when there's no host auth
        assertNull(Account.getProtocol(mMockContext, account2.mId));
        assertNull(account2.getProtocol(mMockContext));
        // And when there's no account
        assertNull(Account.getProtocol(mMockContext, 0));
    }

    public void testAccountIsValidId() {
        final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext);
        final Account account2 = ProviderTestUtils.setupAccount("account-2", true, mMockContext);

        assertTrue(Account.isValidId(mMockContext, account1.mId));
        assertTrue(Account.isValidId(mMockContext, account2.mId));

        assertFalse(Account.isValidId(mMockContext, 1234567)); // Some random ID
        assertFalse(Account.isValidId(mMockContext, -1));
        assertFalse(Account.isValidId(mMockContext, -500));
    }

    private final static String[] MAILBOX_UNREAD_COUNT_PROJECTION = new String [] {
        MailboxColumns.UNREAD_COUNT
    };
    private final static int MAILBOX_UNREAD_COUNT_COLMUN = 0;

    /**
     * Get the value of the unread count in the mailbox of the account.
     * This can be different from the actual number of unread messages in that mailbox.
     */
    private int getUnreadCount(long mailboxId) {
        String text = null;
        Cursor c = null;
        try {
            c = mMockContext.getContentResolver().query(
                    Mailbox.CONTENT_URI,
                    MAILBOX_UNREAD_COUNT_PROJECTION,
                    EmailContent.RECORD_ID + "=?",
                    new String[] { String.valueOf(mailboxId) },
                    null);
            c.moveToFirst();
            text = c.getString(MAILBOX_UNREAD_COUNT_COLMUN);
        } finally {
            c.close();
        }
        return Integer.valueOf(text);
    }

    private static String[] expectedAttachmentNames =
        new String[] {"attachment1.doc", "attachment2.xls", "attachment3"};
    // The lengths need to be kept in ascending order
    private static long[] expectedAttachmentSizes = new long[] {31415L, 97701L, 151213L};

    /*
     * Returns null if the message has no body.
     */
    private Body loadBodyForMessageId(long messageId) {
        Cursor c = null;
        try {
            c = mMockContext.getContentResolver().query(
                    EmailContent.Body.CONTENT_URI,
                    EmailContent.Body.CONTENT_PROJECTION,
                    EmailContent.Body.MESSAGE_KEY + "=?",
                    new String[] {String.valueOf(messageId)},
                    null);
            int numBodies = c.getCount();
            assertTrue("at most one body", numBodies < 2);
            return c.moveToFirst() ? EmailContent.getContent(c, Body.class) : null;
        } finally {
            c.close();
        }
    }

    /**
     * Test simple message save/retrieve
     *
     * TODO: serverId vs. serverIntId
     */
    @MediumTest
    public void testMessageSave() {
        Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;

        // Test a simple message (saved with no body)
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;
        Message message1get = EmailContent.Message.restoreMessageWithId(mMockContext, message1Id);
        ProviderTestUtils.assertMessageEqual("testMessageSave", message1, message1get);

        // Test a message saved with a body
        // Note that it will read back w/o the text & html so we must extract those
        Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
                true, mMockContext);
        long message2Id = message2.mId;
        String text2 = message2.mText;
        String html2 = message2.mHtml;
        String textReply2 = message2.mTextReply;
        String htmlReply2 = message2.mHtmlReply;
        long sourceKey2 = message2.mSourceKey;
        String introText2 = message2.mIntroText;
        message2.mText = null;
        message2.mHtml = null;
        message2.mTextReply = null;
        message2.mHtmlReply = null;
        message2.mSourceKey = 0;
        message2.mIntroText = null;
        Message message2get = EmailContent.Message.restoreMessageWithId(mMockContext, message2Id);
        ProviderTestUtils.assertMessageEqual("testMessageSave", message2, message2get);

        // Now see if there's a body saved with the right stuff
        Body body2 = loadBodyForMessageId(message2Id);
        assertEquals("body text", text2, body2.mTextContent);
        assertEquals("body html", html2, body2.mHtmlContent);
        assertEquals("reply text", textReply2, body2.mTextReply);
        assertEquals("reply html", htmlReply2, body2.mHtmlReply);
        assertEquals("source key", sourceKey2, body2.mSourceKey);
        assertEquals("intro text", introText2, body2.mIntroText);
    }

    @MediumTest
    public void testMessageWithAttachment() {
        Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;

        // Message with attachments and body
        Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, true,
                false, mMockContext);
        ArrayList<Attachment> atts = new ArrayList<Attachment>();
        for (int i = 0; i < 3; i++) {
            atts.add(ProviderTestUtils.setupAttachment(
                    -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
                    false, mMockContext));
        }
        message3.mAttachments = atts;
        message3.save(mMockContext);
        long message3Id = message3.mId;

        // Now check the attachments; there should be three and they should match name and size
        Cursor c = null;
        try {
            // Note that there is NO guarantee of the order of returned records in the general case,
            // so we specifically ask for ordering by size.  The expectedAttachmentSizes array must
            // be kept sorted by size (ascending) for this test to work properly
            c = mMockContext.getContentResolver().query(
                    Attachment.CONTENT_URI,
                    Attachment.CONTENT_PROJECTION,
                    Attachment.MESSAGE_KEY + "=?",
                    new String[] {
                            String.valueOf(message3Id)
                    },
                    Attachment.SIZE);
            int numAtts = c.getCount();
            assertEquals(3, numAtts);
            int i = 0;
            while (c.moveToNext()) {
                Attachment actual = EmailContent.getContent(c, Attachment.class);
                ProviderTestUtils.assertAttachmentEqual("save-message3", atts.get(i), actual);
                i++;
            }
        } finally {
            c.close();
        }
    }


    @MediumTest
    public void testMessageSaveWithJustAttachments() {
        Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        Cursor c = null;

        // Message with attachments but no body
        Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id, false,
                false, mMockContext);
        ArrayList<Attachment> atts = new ArrayList<Attachment>();
        for (int i = 0; i < 3; i++) {
            atts.add(ProviderTestUtils.setupAttachment(
                    -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
                    false, mMockContext));
        }
        message4.mAttachments = atts;
        message4.save(mMockContext);
        long message4Id = message4.mId;

        // Now check the attachments; there should be three and they should match name and size
        c = null;

        try {
            // Note that there is NO guarantee of the order of returned records in the general case,
            // so we specifically ask for ordering by size.  The expectedAttachmentSizes array must
            // be kept sorted by size (ascending) for this test to work properly
            c = mMockContext.getContentResolver().query(
                    Attachment.CONTENT_URI,
                    Attachment.CONTENT_PROJECTION,
                    Attachment.MESSAGE_KEY + "=?",
                    new String[] {
                            String.valueOf(message4Id)
                    },
                    Attachment.SIZE);
            int numAtts = c.getCount();
            assertEquals(3, numAtts);
            int i = 0;
            while (c.moveToNext()) {
                Attachment actual = EmailContent.getContent(c, Attachment.class);
                ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), actual);
                i++;
            }
        } finally {
            c.close();
        }

        // test EmailContent.restoreAttachmentsWitdMessageId()
        Attachment[] attachments =
            Attachment.restoreAttachmentsWithMessageId(mMockContext, message4Id);
        int size = attachments.length;
        assertEquals(3, size);
        for (int i = 0; i < size; ++i) {
            ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), attachments[i]);
        }
    }

    /**
     * Test that saving a message creates the proper snippet for that message
     */
    public void testMessageSaveAddsSnippet() {
        Account account = ProviderTestUtils.setupAccount("message-snippet", true, mMockContext);
        Mailbox box = ProviderTestUtils.setupMailbox("box1", account.mId, true, mMockContext);

        // Create a message without a body, unsaved
        Message message = ProviderTestUtils.setupMessage("message", account.mId, box.mId, false,
                false, mMockContext);
        message.mText = "This is some text";
        message.mHtml = "<html>This is some text</html>";
        message.save(mMockContext);
        Message restoredMessage = Message.restoreMessageWithId(mMockContext, message.mId);
        // We should have the plain text as the snippet
        assertEquals(restoredMessage.mSnippet,
                TextUtilities.makeSnippetFromPlainText(message.mText));

        // Start again
        message = ProviderTestUtils.setupMessage("message", account.mId, box.mId, false,
                false, mMockContext);
        message.mText = null;
        message.mHtml = "<html>This is some text</html>";
        message.save(mMockContext);
        restoredMessage = Message.restoreMessageWithId(mMockContext, message.mId);
        // We should have the plain text as the snippet
        assertEquals(restoredMessage.mSnippet,
                TextUtilities.makeSnippetFromHtmlText(message.mHtml));
    }

    /**
     * TODO: update account
     */

    /**
     * TODO: update mailbox
     */

    /**
     * TODO: update message
     */

    /**
     * Test delete account
     * TODO: hostauth
     */
    public void testAccountDelete() {
        Account account1 = ProviderTestUtils.setupAccount("account-delete-1", true, mMockContext);
        long account1Id = account1.mId;
        Account account2 = ProviderTestUtils.setupAccount("account-delete-2", true, mMockContext);
        long account2Id = account2.mId;

        // make sure there are two accounts
        int numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
        assertEquals(2, numBoxes);

        // now delete one of them
        Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there's only one account now
        numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
        assertEquals(1, numBoxes);

        // now delete the other one
        uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there are no accounts now
        numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
        assertEquals(0, numBoxes);
    }

    /**
     * Test for Body.lookupBodyIdWithMessageId()
     * Verifies that:
     * - for a message without body, -1 is returned.
     * - for a mesage with body, the id matches the one from loadBodyForMessageId.
     */
    public void testLookupBodyIdWithMessageId() {
        final ContentResolver resolver = mMockContext.getContentResolver();
        Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;

        // 1. create message with no body, check that returned bodyId is -1
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;
        long bodyId1 = Body.lookupBodyIdWithMessageId(mMockContext, message1Id);
        assertEquals(bodyId1, -1);

        // 2. create message with body, check that returned bodyId is correct
        Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
                true, mMockContext);
        long message2Id = message2.mId;
        long bodyId2 = Body.lookupBodyIdWithMessageId(mMockContext, message2Id);
        Body body = loadBodyForMessageId(message2Id);
        assertNotNull(body);
        assertEquals(body.mId, bodyId2);
    }

    /**
     * Test for Body.updateBodyWithMessageId().
     * 1. - create message without body,
     *    - update its body (set TEXT_CONTENT)
     *    - check correct updated body is read back
     *
     * 2. - create message with body,
     *    - update body (set TEXT_CONTENT)
     *    - check correct updated body is read back
     */
    public void testUpdateBodyWithMessageId() {
        Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;

        final String textContent = "foobar some odd text";
        final String htmlContent = "and some html";
        final String textReply = "plain text reply";
        final String htmlReply = "or the html reply";
        final String introText = "fred wrote:";

        ContentValues values = new ContentValues();
        values.put(BodyColumns.TEXT_CONTENT, textContent);
        values.put(BodyColumns.HTML_CONTENT, htmlContent);
        values.put(BodyColumns.TEXT_REPLY, textReply);
        values.put(BodyColumns.HTML_REPLY, htmlReply);
        values.put(BodyColumns.SOURCE_MESSAGE_KEY, 17);
        values.put(BodyColumns.INTRO_TEXT, introText);

        // 1
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;
        Body body1 = loadBodyForMessageId(message1Id);
        assertNull(body1);
        Body.updateBodyWithMessageId(mMockContext, message1Id, values);
        body1 = loadBodyForMessageId(message1Id);
        assertNotNull(body1);
        assertEquals(body1.mTextContent, textContent);
        assertEquals(body1.mHtmlContent, htmlContent);
        assertEquals(body1.mTextReply, textReply);
        assertEquals(body1.mHtmlReply, htmlReply);
        assertEquals(body1.mSourceKey, 17);
        assertEquals(body1.mIntroText, introText);

        // 2
        Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
                true, mMockContext);
        long message2Id = message2.mId;
        Body body2 = loadBodyForMessageId(message2Id);
        assertNotNull(body2);
        assertTrue(!body2.mTextContent.equals(textContent));
        Body.updateBodyWithMessageId(mMockContext, message2Id, values);
        body2 = loadBodyForMessageId(message1Id);
        assertNotNull(body2);
        assertEquals(body2.mTextContent, textContent);
        assertEquals(body2.mHtmlContent, htmlContent);
        assertEquals(body2.mTextReply, textReply);
        assertEquals(body2.mHtmlReply, htmlReply);
        assertEquals(body2.mSourceKey, 17);
        assertEquals(body2.mIntroText, introText);
    }

    /**
     * Test body retrieve methods
     */
    public void testBodyRetrieve() {
        // No account needed
        // No mailbox needed
        Message message1 = ProviderTestUtils.setupMessage("bodyretrieve", 1, 1, true,
                true, mMockContext);
        long messageId = message1.mId;

        assertEquals(message1.mText,
                Body.restoreBodyTextWithMessageId(mMockContext, messageId));
        assertEquals(message1.mHtml,
                Body.restoreBodyHtmlWithMessageId(mMockContext, messageId));
        assertEquals(message1.mTextReply,
                Body.restoreReplyTextWithMessageId(mMockContext, messageId));
        assertEquals(message1.mHtmlReply,
                Body.restoreReplyHtmlWithMessageId(mMockContext, messageId));
        assertEquals(message1.mIntroText,
                Body.restoreIntroTextWithMessageId(mMockContext, messageId));
        assertEquals(message1.mSourceKey,
                Body.restoreBodySourceKey(mMockContext, messageId));
    }

    /**
     * Test delete body.
     * 1. create message without body (message id 1)
     * 2. create message with body (message id 2. The body has _id 1 and messageKey 2).
     * 3. delete first message.
     * 4. verify that body for message 2 has not been deleted.
     * 5. delete message 2, verify body is deleted.
     */
    public void testDeleteBody() {
        final ContentResolver resolver = mMockContext.getContentResolver();

        // Create account and mailboxes
        Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;

        // 1. create message without body
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;

        // 2. create message with body
        Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
                true, mMockContext);
        long message2Id = message2.mId;
        // verify body is there
        assertNotNull(loadBodyForMessageId(message2Id));

        // 3. delete first message
        resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null);

        // 4. verify body for second message wasn't deleted
        assertNotNull(loadBodyForMessageId(message2Id));

        // 5. delete second message, check its body is deleted
        resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message2Id), null, null);
        assertNull(loadBodyForMessageId(message2Id));
    }

    /**
     * Test delete orphan bodies.
     * 1. create message without body (message id 1)
     * 2. create message with body (message id 2. Body has _id 1 and messageKey 2).
     * 3. delete first message.
     * 4. delete some other mailbox -- this triggers delete orphan bodies.
     * 5. verify that body for message 2 has not been deleted.
     */
    public void testDeleteOrphanBodies() {
        final ContentResolver resolver = mMockContext.getContentResolver();

        // Create account and two mailboxes
        Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mMockContext);
        long box2Id = box2.mId;

        // 1. create message without body
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;

        // 2. create message with body
        Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
                true, mMockContext);
        long message2Id = message2.mId;
        //verify body is there
        assertNotNull(loadBodyForMessageId(message2Id));

        // 3. delete first message
        resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null);

        // 4. delete some mailbox (because it triggers "delete orphan bodies")
        resolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id), null, null);

        // 5. verify body for second message wasn't deleted during "delete orphan bodies"
        assertNotNull(loadBodyForMessageId(message2Id));
    }

    /**
     * Note that we can't use EmailContent.count() here because it uses a projection including
     * count(*), and count(*) is incompatible with a LIMIT (i.e. the limit would be applied to the
     * single column returned with count(*), rather than to the query itself)
     */
    private int count(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor c = context.getContentResolver().query(uri, EmailContent.ID_PROJECTION, selection,
                selectionArgs, null);
        try {
            return c.getCount();
        } finally {
            c.close();
        }
    }

    public void testMessageQueryWithLimit() {
        final Context context = mMockContext;

        // Create account and two mailboxes
        Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context);
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context);

        // Create 4 messages in box1
        ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context);
        ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context);
        ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context);
        ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context);

        // Create 4 messages in box2
        ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context);
        ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context);
        ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context);
        ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context);

        // Check normal case, special case (limit 1), and arbitrary limits
        assertEquals(8, count(mMockContext, Message.CONTENT_URI, null, null));
        assertEquals(1, count(mMockContext, EmailContent.uriWithLimit(Message.CONTENT_URI, 1),
                null, null));
        assertEquals(3, count(mMockContext, EmailContent.uriWithLimit(Message.CONTENT_URI, 3),
                null, null));
        assertEquals(8, count(mMockContext, EmailContent.uriWithLimit(Message.CONTENT_URI, 100),
                null, null));

        // Check that it works with selection/selection args
        String[] args = new String[] {Long.toString(box1.mId)};
        assertEquals(4, count(mMockContext, Message.CONTENT_URI,
                MessageColumns.MAILBOX_KEY + "=?", args));
        assertEquals(1, count(mMockContext,
                EmailContent.uriWithLimit(Message.CONTENT_URI, 1),
                MessageColumns.MAILBOX_KEY + "=?", args));
    }

    /**
     * Test delete orphan messages
     * 1. create message without body (message id 1)
     * 2. create message with body (message id 2. Body has _id 1 and messageKey 2).
     * 3. delete first message.
     * 4. delete some other mailbox -- this triggers delete orphan bodies.
     * 5. verify that body for message 2 has not been deleted.
     */
     public void testDeleteOrphanMessages() {
        final ContentResolver resolver = mMockContext.getContentResolver();
        final Context context = mMockContext;

        // Create account and two mailboxes
        Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context);
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context);

        // Create 4 messages in box1
        Message msg1_1 =
            ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context);
        Message msg1_2 =
            ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context);
        Message msg1_3 =
            ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context);
        Message msg1_4 =
            ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context);

        // Create 4 messages in box2
        Message msg2_1 =
            ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context);
        Message msg2_2 =
            ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context);
        Message msg2_3 =
            ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context);
        Message msg2_4 =
            ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context);

        // Delete 2 from each mailbox
        resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_1.mId),
                null, null);
        resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_2.mId),
                null, null);
        resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_1.mId),
                null, null);
        resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_2.mId),
                null, null);

        // There should be 4 items in the deleted item table
        assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));

        // Update 2 from each mailbox
        ContentValues v = new ContentValues();
        v.put(MessageColumns.DISPLAY_NAME, "--updated--");
        resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_3.mId),
                v, null, null);
        resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_4.mId),
                v, null, null);
        resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_3.mId),
                v, null, null);
        resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_4.mId),
                v, null, null);

         // There should be 4 items in the updated item table
        assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));

        // Manually add 2 messages from a "deleted" mailbox to deleted and updated tables
        // Use a value > 2 for the deleted box id
        long delBoxId = 10;
        // Create 4 messages in the "deleted" mailbox
        Message msgX_A =
            ProviderTestUtils.setupMessage("messageA", acct.mId, delBoxId, false, false, context);
        Message msgX_B =
            ProviderTestUtils.setupMessage("messageB", acct.mId, delBoxId, false, false, context);
        Message msgX_C =
            ProviderTestUtils.setupMessage("messageC", acct.mId, delBoxId, false, false, context);
        Message msgX_D =
            ProviderTestUtils.setupMessage("messageD", acct.mId, delBoxId, false, false, context);

        ContentValues cv;
        // We have to assign id's manually because there are no autoincrement id's for these tables
        // Start with an id that won't exist, since id's in these tables must be unique
        long msgId = 10;
        // It's illegal to manually insert these, so we need to catch the exception
        // NOTE: The insert succeeds, and then throws the exception
        try {
            cv = msgX_A.toContentValues();
            cv.put(EmailContent.RECORD_ID, msgId++);
            resolver.insert(Message.DELETED_CONTENT_URI, cv);
        } catch (IllegalArgumentException e) {
        }
        try {
            cv = msgX_B.toContentValues();
            cv.put(EmailContent.RECORD_ID, msgId++);
            resolver.insert(Message.DELETED_CONTENT_URI, cv);
        } catch (IllegalArgumentException e) {
        }
        try {
            cv = msgX_C.toContentValues();
            cv.put(EmailContent.RECORD_ID, msgId++);
            resolver.insert(Message.UPDATED_CONTENT_URI, cv);
        } catch (IllegalArgumentException e) {
        }
        try {
            cv = msgX_D.toContentValues();
            cv.put(EmailContent.RECORD_ID, msgId++);
            resolver.insert(Message.UPDATED_CONTENT_URI, cv);
        } catch (IllegalArgumentException e) {
        }

        // There should be 6 items in the deleted and updated tables
        assertEquals(6, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
        assertEquals(6, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));

        // Delete the orphans
        EmailProvider.deleteMessageOrphans(EmailProvider.getReadableDatabase(context),
                Message.DELETED_TABLE_NAME);
        EmailProvider.deleteMessageOrphans(EmailProvider.getReadableDatabase(context),
                Message.UPDATED_TABLE_NAME);

        // There should now be 4 messages in each of the deleted and updated tables again
        assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
        assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
    }

    /**
     * Test delete message
     * TODO: body
     * TODO: attachments
     */
    public void testMessageDelete() {
        Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;
        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
                true, mMockContext);
        long message2Id = message2.mId;

        String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " +
                EmailContent.MessageColumns.MAILBOX_KEY + "=?";
        String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) };

        // make sure there are two messages
        int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(2, numMessages);

        // now delete one of them
        Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there's only one message now
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(1, numMessages);

        // now delete the other one
        uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there are no messages now
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(0, numMessages);
    }

    /**
     * Test delete synced message
     * TODO: body
     * TODO: attachments
     */
    public void testSyncedMessageDelete() {
        Account account1 = ProviderTestUtils.setupAccount("synced-message-delete", true,
                mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;
        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
                true, mMockContext);
        long message2Id = message2.mId;

        String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND "
                + EmailContent.MessageColumns.MAILBOX_KEY + "=?";
        String[] selArgs = new String[] {
            String.valueOf(account1Id), String.valueOf(box1Id)
        };

        // make sure there are two messages
        int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(2, numMessages);

        // make sure we start with no synced deletions
        numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
                selArgs);
        assertEquals(0, numMessages);

        // now delete one of them SYNCED
        Uri uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there's only one message now
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(1, numMessages);

        // make sure there's one synced deletion now
        numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
                selArgs);
        assertEquals(1, numMessages);

        // now delete the other one NOT SYNCED
        uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there are no messages now
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(0, numMessages);

        // make sure there's still one deletion now
        numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
                selArgs);
        assertEquals(1, numMessages);
    }

    /**
     * Test message update
     * TODO: body
     * TODO: attachments
     */
    public void testMessageUpdate() {
        Account account1 = ProviderTestUtils.setupAccount("message-update", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
                true, mMockContext);
        long message1Id = message1.mId;
        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
                true, mMockContext);
        long message2Id = message2.mId;
        ContentResolver cr = mMockContext.getContentResolver();

        String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND "
                + EmailContent.MessageColumns.MAILBOX_KEY + "=?";
        String[] selArgs = new String[] {
            String.valueOf(account1Id), String.valueOf(box1Id)
        };

        // make sure there are two messages
        int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(2, numMessages);

        // change the first one
        Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id);
        ContentValues cv = new ContentValues();
        cv.put(MessageColumns.FROM_LIST, "from-list");
        cr.update(uri, cv, null, null);

        // make sure there's no updated message
        numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
                selArgs);
        assertEquals(0, numMessages);

        // get the message back from the provider, make sure the change "stuck"
        Message restoredMessage = Message.restoreMessageWithId(mMockContext, message1Id);
        assertEquals("from-list", restoredMessage.mFrom);

        // change the second one
        uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id);
        cv = new ContentValues();
        cv.put(MessageColumns.FROM_LIST, "from-list");
        cr.update(uri, cv, null, null);

        // make sure there's one updated message
        numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
                selArgs);
        assertEquals(1, numMessages);

        // get the message back from the provider, make sure the change "stuck",
        // as before
        restoredMessage = Message.restoreMessageWithId(mMockContext, message2Id);
        assertEquals("from-list", restoredMessage.mFrom);

        // get the original message back from the provider
        Cursor c = cr.query(Message.UPDATED_CONTENT_URI, Message.CONTENT_PROJECTION, null, null,
                null);
        try {
            assertTrue(c.moveToFirst());
            Message originalMessage = EmailContent.getContent(c, Message.class);
            // make sure this has the original value
            assertEquals("from message2", originalMessage.mFrom);
            // Should only be one
            assertFalse(c.moveToNext());
        } finally {
            c.close();
        }

        // delete the second message
        cr.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id), null, null);

        // hey, presto! the change should be gone
        numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
                selArgs);
        assertEquals(0, numMessages);

        // and there should now be a deleted record
        numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
                selArgs);
        assertEquals(1, numMessages);
    }

    /**
     * TODO: cascaded delete account
     * TODO: hostauth
     * TODO: body
     * TODO: attachments
     * TODO: create other account, mailbox & messages and confirm the right objects were deleted
     */
    public void testCascadeDeleteAccount() {
        Account account1 = ProviderTestUtils.setupAccount("account-delete-cascade", true,
                mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        /* Message message1 = */ ProviderTestUtils.setupMessage("message1", account1Id, box1Id,
                false, true, mMockContext);
        /* Message message2 = */ ProviderTestUtils.setupMessage("message2", account1Id, box1Id,
                false, true, mMockContext);

        // make sure there is one account, one mailbox, and two messages
        int numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
        assertEquals(1, numAccounts);
        int numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null);
        assertEquals(1, numBoxes);
        int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
        assertEquals(2, numMessages);

        // delete the account
        Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there are no accounts, mailboxes, or messages
        numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
        assertEquals(0, numAccounts);
        numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null);
        assertEquals(0, numBoxes);
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
        assertEquals(0, numMessages);
    }

    /**
     * Test cascaded delete mailbox
     * TODO: body
     * TODO: attachments
     * TODO: create other mailbox & messages and confirm the right objects were deleted
     */
    public void testCascadeDeleteMailbox() {
        Account account1 = ProviderTestUtils.setupAccount("mailbox-delete-cascade", true,
                mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id,
                false, true, mMockContext);
        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id,
                false, true, mMockContext);
        Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id,
                false, true, mMockContext);
        Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id,
                false, true, mMockContext);
        ProviderTestUtils.setupMessage("message5", account1Id, box1Id, false, true, mMockContext);
        ProviderTestUtils.setupMessage("message6", account1Id, box1Id, false, true, mMockContext);

        String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " +
                EmailContent.MessageColumns.MAILBOX_KEY + "=?";
        String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) };

        // make sure there are six messages
        int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(6, numMessages);

        ContentValues cv = new ContentValues();
        cv.put(Message.SERVER_ID, "SERVER_ID");
        ContentResolver resolver = mMockContext.getContentResolver();

        // Update two messages
        resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1.mId),
                cv, null, null);
        resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2.mId),
                cv, null, null);
        // Delete two messages
        resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message3.mId),
                null, null);
        resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message4.mId),
                null, null);

        // There should now be two messages in updated/deleted, and 4 in messages
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(4, numMessages);
        numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
                selArgs);
        assertEquals(2, numMessages);
        numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
                selArgs);
        assertEquals(2, numMessages);

        // now delete the mailbox
        Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id);
        resolver.delete(uri, null, null);

        // there should now be zero messages in all three tables
        numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
        assertEquals(0, numMessages);
        numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
                selArgs);
        assertEquals(0, numMessages);
        numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
                selArgs);
        assertEquals(0, numMessages);
    }

    /**
     * Test cascaded delete message
     * Confirms that deleting a message will also delete its body & attachments
     */
    public void testCascadeMessageDelete() {
        Account account1 = ProviderTestUtils.setupAccount("message-cascade", true, mMockContext);
        long account1Id = account1.mId;
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
        long box1Id = box1.mId;

        // Each message has a body, and also give each 2 attachments
        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
                false, mMockContext);
        ArrayList<Attachment> atts = new ArrayList<Attachment>();
        for (int i = 0; i < 2; i++) {
            atts.add(ProviderTestUtils.setupAttachment(
                    -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
                    false, mMockContext));
        }
        message1.mAttachments = atts;
        message1.save(mMockContext);
        long message1Id = message1.mId;

        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, true,
                false, mMockContext);
        atts = new ArrayList<Attachment>();
        for (int i = 0; i < 2; i++) {
            atts.add(ProviderTestUtils.setupAttachment(
                    -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
                    false, mMockContext));
        }
        message2.mAttachments = atts;
        message2.save(mMockContext);
        long message2Id = message2.mId;

        // Set up to test total counts of bodies & attachments for our test messages
        String bodySelection = BodyColumns.MESSAGE_KEY + " IN (?,?)";
        String attachmentSelection = AttachmentColumns.MESSAGE_KEY + " IN (?,?)";
        String[] selArgs = new String[] { String.valueOf(message1Id), String.valueOf(message2Id) };

        // make sure there are two bodies
        int numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs);
        assertEquals(2, numBodies);

        // make sure there are four attachments
        int numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI,
                attachmentSelection, selArgs);
        assertEquals(4, numAttachments);

        // now delete one of the messages
        Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // there should be one body and two attachments
        numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs);
        assertEquals(1, numBodies);

        numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI,
                attachmentSelection, selArgs);
        assertEquals(2, numAttachments);

        // now delete the other message
        uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        // make sure there are no bodies or attachments
        numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs);
        assertEquals(0, numBodies);

        numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI,
                attachmentSelection, selArgs);
        assertEquals(0, numAttachments);
    }

    /**
     * Test that our unique file name algorithm works as expected.  Since this test requires an
     * SD card, we check the environment first, and return immediately if none is mounted.
     * @throws IOException
     */
    public void testCreateUniqueFile() throws IOException {
        // Delete existing files, if they exist
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return;
        }
        try {
            String fileName = "A11achm3n1.doc";
            File uniqueFile = Attachment.createUniqueFile(fileName);
            assertEquals(fileName, uniqueFile.getName());
            if (uniqueFile.createNewFile()) {
                uniqueFile = Attachment.createUniqueFile(fileName);
                assertEquals("A11achm3n1-2.doc", uniqueFile.getName());
                if (uniqueFile.createNewFile()) {
                    uniqueFile = Attachment.createUniqueFile(fileName);
                    assertEquals("A11achm3n1-3.doc", uniqueFile.getName());
                }
           }
            fileName = "A11achm3n1";
            uniqueFile = Attachment.createUniqueFile(fileName);
            assertEquals(fileName, uniqueFile.getName());
            if (uniqueFile.createNewFile()) {
                uniqueFile = Attachment.createUniqueFile(fileName);
                assertEquals("A11achm3n1-2", uniqueFile.getName());
            }
        } finally {
            File directory = Environment.getExternalStorageDirectory();
            // These are the files that should be created earlier in the test.  Make sure
            // they are deleted for the next go-around
            String[] fileNames = new String[] {"A11achm3n1.doc", "A11achm3n1-2.doc", "A11achm3n1"};
            int length = fileNames.length;
            for (int i = 0; i < length; i++) {
                File file = new File(directory, fileNames[i]);
                if (file.exists()) {
                    file.delete();
                }
            }
        }
    }

    /**
     * Test retrieving attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI)
     */
    public void testGetAttachmentByMessageIdUri() {

        // Note, we don't strictly need accounts, mailboxes or messages to run this test.
        Attachment a1 = ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext);
        Attachment a2 = ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext);
        ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext);
        ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext);

        // Now ask for the attachments of message id=1
        // Note: Using the "sort by size" trick to bring them back in expected order
        Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1);
        Cursor c = mMockContext.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION,
                null, null, Attachment.SIZE);
        assertEquals(2, c.getCount());

        try {
            c.moveToFirst();
            Attachment a1Get = EmailContent.getContent(c, Attachment.class);
            ProviderTestUtils.assertAttachmentEqual("getAttachByUri-1", a1, a1Get);
            c.moveToNext();
            Attachment a2Get = EmailContent.getContent(c, Attachment.class);
            ProviderTestUtils.assertAttachmentEqual("getAttachByUri-2", a2, a2Get);
        } finally {
            c.close();
        }
    }

    /**
     * Test deleting attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI)
     */
    public void testDeleteAttachmentByMessageIdUri() {
        ContentResolver mockResolver = mMockContext.getContentResolver();

        // Note, we don't strictly need accounts, mailboxes or messages to run this test.
        ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext);
        ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext);
        Attachment a3 = ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext);
        Attachment a4 = ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext);

        // Delete all attachments for message id=1
        Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1);
        mockResolver.delete(uri, null, null);

        // Read back all attachments and confirm that we have the expected remaining attachments
        // (the attachments that are set for message id=2).  Note order-by size to simplify test.
        Cursor c = mockResolver.query(Attachment.CONTENT_URI, Attachment.CONTENT_PROJECTION,
                null, null, Attachment.SIZE);
        assertEquals(2, c.getCount());

        try {
            c.moveToFirst();
            Attachment a3Get = EmailContent.getContent(c, Attachment.class);
            ProviderTestUtils.assertAttachmentEqual("getAttachByUri-3", a3, a3Get);
            c.moveToNext();
            Attachment a4Get = EmailContent.getContent(c, Attachment.class);
            ProviderTestUtils.assertAttachmentEqual("getAttachByUri-4", a4, a4Get);
        } finally {
            c.close();
        }
    }

    @SmallTest
    public void testGetDefaultAccountNoneExplicitlySet() {
        Account account1 = ProviderTestUtils.setupAccount("account-default-1", false, mMockContext);
        account1.mIsDefault = false;
        account1.save(mMockContext);

        // We should find account1 as default
        long defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(defaultAccountId, account1.mId);

        Account account2 = ProviderTestUtils.setupAccount("account-default-2", false, mMockContext);
        account2.mIsDefault = false;
        account2.save(mMockContext);

        Account account3 = ProviderTestUtils.setupAccount("account-default-3", false, mMockContext);
        account3.mIsDefault = false;
        account3.save(mMockContext);

        // We should find the earliest one as the default, so that it can be consistent on
        // repeated calls.
        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertTrue(defaultAccountId == account1.mId);
    }

    /**
     * Tests of default account behavior
     *
     * 1.  Simple set/get
     * 2.  Moving default between 3 accounts
     * 3.  Delete default, make sure another becomes default
     */
    public void testSetGetDefaultAccount() {
        // There should be no default account if there are no accounts
        long defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(Account.NO_ACCOUNT, defaultAccountId);

        Account account1 = ProviderTestUtils.setupAccount("account-default-1", false, mMockContext);
        account1.mIsDefault = false;
        account1.save(mMockContext);
        long account1Id = account1.mId;
        Account account2 = ProviderTestUtils.setupAccount("account-default-2", false, mMockContext);
        account2.mIsDefault = false;
        account2.save(mMockContext);
        long account2Id = account2.mId;
        Account account3 = ProviderTestUtils.setupAccount("account-default-3", false, mMockContext);
        account3.mIsDefault = false;
        account3.save(mMockContext);
        long account3Id = account3.mId;

        // With three accounts, but none marked default, confirm that the first one is the default.
        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertTrue(defaultAccountId == account1Id);

        updateIsDefault(account1, true);
        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(account1Id, defaultAccountId);

        updateIsDefault(account2, true);
        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(account2Id, defaultAccountId);

        updateIsDefault(account3, true);
        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(account3Id, defaultAccountId);

        // Now delete a non-default account and confirm no change
        Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(account3Id, defaultAccountId);

        // Now confirm deleting the default account and it switches to another one
        uri = ContentUris.withAppendedId(Account.CONTENT_URI, account3Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(account2Id, defaultAccountId);

        // Now delete the final account and confirm there are no default accounts again
        uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id);
        mMockContext.getContentResolver().delete(uri, null, null);

        defaultAccountId = Account.getDefaultAccountId(mMockContext);
        assertEquals(-1, defaultAccountId);
    }

    private void updateIsDefault(Account account, boolean newState) {
        account.setDefaultAccount(newState);
        ContentValues cv = new ContentValues();
        cv.put(AccountColumns.IS_DEFAULT, account.mIsDefault);
        account.update(mMockContext, cv);
    }

    public static Message setupUnreadMessage(String name, long accountId, long mailboxId,
            boolean addBody, boolean saveIt, Context context) {
        Message msg =
            ProviderTestUtils.setupMessage(name, accountId, mailboxId, addBody, false, context);
        msg.mFlagRead = false;
        if (saveIt) {
            msg.save(context);
        }
        return msg;
    }

    public void testUnreadCountTriggers() {
        // Start with one account and three mailboxes
        Account account = ProviderTestUtils.setupAccount("triggers", true, mMockContext);
        Mailbox boxA = ProviderTestUtils.setupMailbox("boxA", account.mId, true, mMockContext);
        Mailbox boxB = ProviderTestUtils.setupMailbox("boxB", account.mId, true, mMockContext);
        Mailbox boxC = ProviderTestUtils.setupMailbox("boxC", account.mId, true, mMockContext);

        // Make sure there are no unreads
        assertEquals(0, getUnreadCount(boxA.mId));
        assertEquals(0, getUnreadCount(boxB.mId));
        assertEquals(0, getUnreadCount(boxC.mId));

        // Create 4 unread messages (only 3 named) in boxA
        Message message1 = setupUnreadMessage("message1", account.mId, boxA.mId,
                false, true, mMockContext);
        Message message2= setupUnreadMessage("message2", account.mId, boxA.mId,
                false, true, mMockContext);
        Message message3 =  setupUnreadMessage("message3", account.mId, boxA.mId,
                false, true, mMockContext);
        setupUnreadMessage("message4", account.mId, boxC.mId, false, true, mMockContext);

        // Make sure the unreads are where we expect them
        assertEquals(3, getUnreadCount(boxA.mId));
        assertEquals(0, getUnreadCount(boxB.mId));
        assertEquals(1, getUnreadCount(boxC.mId));

        // After deleting message 1, the count in box A should be decremented (to 2)
        ContentResolver cr = mMockContext.getContentResolver();
        Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1.mId);
        cr.delete(uri, null, null);
        assertEquals(2, getUnreadCount(boxA.mId));
        assertEquals(0, getUnreadCount(boxB.mId));
        assertEquals(1, getUnreadCount(boxC.mId));

        // Move message 2 to box B, leaving 1 in box A and 1 in box B
        message2.mMailboxKey = boxB.mId;
        ContentValues cv = new ContentValues();
        cv.put(MessageColumns.MAILBOX_KEY, boxB.mId);
        cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message2.mId), cv, null, null);
        assertEquals(1, getUnreadCount(boxA.mId));
        assertEquals(1, getUnreadCount(boxB.mId));
        assertEquals(1, getUnreadCount(boxC.mId));

        // Mark message 3 (from box A) read, leaving 0 in box A
        cv.clear();
        cv.put(MessageColumns.FLAG_READ, 1);
        cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null);
        assertEquals(0, getUnreadCount(boxA.mId));
        assertEquals(1, getUnreadCount(boxB.mId));
        assertEquals(1, getUnreadCount(boxC.mId));

        // Move message 3 to box C; should be no change (it's read)
        message3.mMailboxKey = boxC.mId;
        cv.clear();
        cv.put(MessageColumns.MAILBOX_KEY, boxC.mId);
        cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null);
        assertEquals(0, getUnreadCount(boxA.mId));
        assertEquals(1, getUnreadCount(boxB.mId));
        assertEquals(1, getUnreadCount(boxC.mId));

        // Mark message 3 unread; it's now in box C, so that box's count should go up to 3
        cv.clear();
        cv.put(MessageColumns.FLAG_READ, 0);
        cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null);
        assertEquals(0, getUnreadCount(boxA.mId));
        assertEquals(1, getUnreadCount(boxB.mId));
        assertEquals(2, getUnreadCount(boxC.mId));
    }

    /**
     * Test for EmailProvider.createIndex().
     * Check that it returns exacly the same string as the one used previously for index creation.
     */
    public void testCreateIndex() {
        String oldStr = "create index message_" + MessageColumns.TIMESTAMP
            + " on " + Message.TABLE_NAME + " (" + MessageColumns.TIMESTAMP + ");";
        String newStr = EmailProvider.createIndex(Message.TABLE_NAME, MessageColumns.TIMESTAMP);
        assertEquals(newStr, oldStr);
    }

    public void testDatabaseCorruptionRecovery() {
        final ContentResolver resolver = mMockContext.getContentResolver();
        final Context context = mMockContext;

        // Create account and two mailboxes
        Account acct = ProviderTestUtils.setupAccount("acct1", true, context);
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);

        // Create 4 messages in box1 with bodies
        ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context);
        ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context);
        ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context);
        ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context);

        // Confirm there are four messages
        int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
        assertEquals(4, count);
        // Confirm there are four bodies
        count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
        assertEquals(4, count);

        // Find the EmailProvider.db file
        File dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME);
        // The EmailProvider.db database should exist (the provider creates it automatically)
        assertTrue(dbFile != null);
        assertTrue(dbFile.exists());
        // Delete it, and confirm it is gone
        assertTrue(dbFile.delete());
        assertFalse(dbFile.exists());

        // Find the EmailProviderBody.db file
        dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME);
        // The EmailProviderBody.db database should still exist
        assertTrue(dbFile != null);
        assertTrue(dbFile.exists());

        // URI to uncache the databases
        // This simulates the Provider starting up again (otherwise, it will still be pointing to
        // the already opened files)
        // Note that we only have access to the EmailProvider via the ContentResolver; therefore,
        // we cannot directly call into the provider and use a URI for this
        resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null);

        // TODO We should check for the deletion of attachment files once this is implemented in
        // the provider

        // Explanation for what happens below...
        // The next time the database is created by the provider, it will notice that there's
        // already a EmailProviderBody.db file.  In this case, it will delete that database to
        // ensure that both are in sync (and empty)

        // Confirm there are no bodies
        count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
        assertEquals(0, count);

        // Confirm there are no messages
        count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
        assertEquals(0, count);
    }

    public void testBodyDatabaseCorruptionRecovery() {
        final ContentResolver resolver = mMockContext.getContentResolver();
        final Context context = mMockContext;

        // Create account and two mailboxes
        Account acct = ProviderTestUtils.setupAccount("acct1", true, context);
        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);

        // Create 4 messages in box1 with bodies
        ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context);
        ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context);
        ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context);
        ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context);

        // Confirm there are four messages
        int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
        assertEquals(4, count);
        // Confirm there are four bodies
        count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
        assertEquals(4, count);

        // Find the EmailProviderBody.db file
        File dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME);
        // The EmailProviderBody.db database should exist (the provider creates it automatically)
        assertTrue(dbFile != null);
        assertTrue(dbFile.exists());
        // Delete it, and confirm it is gone
        assertTrue(dbFile.delete());
        assertFalse(dbFile.exists());

        // Find the EmailProvider.db file
        dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME);
        // The EmailProviderBody.db database should still exist
        assertTrue(dbFile != null);
        assertTrue(dbFile.exists());

        // URI to uncache the databases
        // This simulates the Provider starting up again (otherwise, it will still be pointing to
        // the already opened files)
        // Note that we only have access to the EmailProvider via the ContentResolver; therefore,
        // we cannot directly call into the provider and use a URI for this
        resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null);

        // TODO We should check for the deletion of attachment files once this is implemented in
        // the provider

        // Explanation for what happens below...
        // The next time the body database is created by the provider, it will notice that there's
        // already a populated EmailProvider.db file.  In this case, it will delete that database to
        // ensure that both are in sync (and empty)

        // Confirm there are no messages
        count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
        assertEquals(0, count);

        // Confirm there are no bodies
        count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
        assertEquals(0, count);
    }

    public void testAccountIsSecurityHold() {
        final Context context = mMockContext;
        Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context);

        Account acct2 = ProviderTestUtils.setupAccount("acct2", false, context);
        acct2.mFlags |= Account.FLAGS_SECURITY_HOLD;
        acct2.save(context);

        assertFalse(Account.isSecurityHold(context, acct1.mId));
        assertTrue(Account.isSecurityHold(context, acct2.mId));
        assertFalse(Account.isSecurityHold(context, 9999999)); // No such account
   }

    public void testClearAccountHoldFlags() {
        Account a1 = ProviderTestUtils.setupAccount("holdflag-1", false, mMockContext);
        a1.mFlags = Account.FLAGS_NOTIFY_NEW_MAIL;
        a1.mPolicy = new Policy();
        a1.save(mMockContext);
        Account a2 = ProviderTestUtils.setupAccount("holdflag-2", false, mMockContext);
        a2.mFlags = Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_SECURITY_HOLD;
        a2.mPolicy = new Policy();
        a2.save(mMockContext);

        // bulk clear
        Account.clearSecurityHoldOnAllAccounts(mMockContext);

        // confirm new values as expected - no hold flags; other flags unmolested
        Account a1a = Account.restoreAccountWithId(mMockContext, a1.mId);
        assertEquals(Account.FLAGS_NOTIFY_NEW_MAIL, a1a.mFlags);
        Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId);
        assertEquals(Account.FLAGS_VIBRATE_ALWAYS, a2a.mFlags);
    }

    private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read) {
        return ProviderTestUtils.setupMessage(
                "1", b.mAccountKey, b.mId, true, true, c, starred, read);
    }

    public void testAccountIsEasAccount() {
        Account account = new Account();
        // No hostauth
        assertFalse(account.isEasAccount(mMockContext));

        checkAccountIsEasAccount(null, false);
        checkAccountIsEasAccount("", false);
        checkAccountIsEasAccount("x", false);
        checkAccountIsEasAccount("eas", true);
    }

    private void checkAccountIsEasAccount(String protocol, boolean expected) {
        Account account = ProviderTestUtils.setupAccount("account", false, mMockContext);
        account.mHostAuthRecv = ProviderTestUtils.setupHostAuth(protocol, "account-hostauth-recv",
                false, mMockContext);
        account.save(mMockContext);
        assertEquals(expected, account.isEasAccount(mMockContext));
    }

    public void testGetKeyColumnLong() {
        final Context c = mMockContext;
        Account a = ProviderTestUtils.setupAccount("acct", true, c);
        Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a.mId, true, c, Mailbox.TYPE_MAIL);
        Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a.mId, true, c, Mailbox.TYPE_MAIL);
        Message m1 = createMessage(c, b1, false, false);
        Message m2 = createMessage(c, b2, false, false);
        assertEquals(a.mId, Message.getKeyColumnLong(c, m1.mId, MessageColumns.ACCOUNT_KEY));
        assertEquals(a.mId, Message.getKeyColumnLong(c, m2.mId, MessageColumns.ACCOUNT_KEY));
        assertEquals(b1.mId, Message.getKeyColumnLong(c, m1.mId, MessageColumns.MAILBOX_KEY));
        assertEquals(b2.mId, Message.getKeyColumnLong(c, m2.mId, MessageColumns.MAILBOX_KEY));
    }

    public void testGetAccountIdForMessageId() {
        final Context c = mMockContext;
        Account a1 = ProviderTestUtils.setupAccount("acct1", true, c);
        Account a2 = ProviderTestUtils.setupAccount("acct2", true, c);
        Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_MAIL);
        Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a2.mId, true, c, Mailbox.TYPE_MAIL);
        Message m1 = createMessage(c, b1, false, false);
        Message m2 = createMessage(c, b2, false, false);

        assertEquals(a1.mId, Account.getAccountIdForMessageId(c, m1.mId));
        assertEquals(a2.mId, Account.getAccountIdForMessageId(c, m2.mId));

        // message desn't exist
        assertEquals(-1, Account.getAccountIdForMessageId(c, 12345));
    }

    public void testGetAccountForMessageId() {
        final Context c = mMockContext;
        Account a = ProviderTestUtils.setupAccount("acct", true, c);
        Message m1 = ProviderTestUtils.setupMessage("1", a.mId, 1, true, true, c, false, false);
        Message m2 = ProviderTestUtils.setupMessage("1", a.mId, 2, true, true, c, false, false);
        ProviderTestUtils.assertAccountEqual("x", a, Account.getAccountForMessageId(c, m1.mId));
        ProviderTestUtils.assertAccountEqual("x", a, Account.getAccountForMessageId(c, m2.mId));
    }

    public void testGetAccountGetInboxIdTest() {
        final Context c = mMockContext;

        // Prepare some data with red-herrings.
        Account a1 = ProviderTestUtils.setupAccount("acct1", true, c);
        Account a2 = ProviderTestUtils.setupAccount("acct2", true, c);
        Mailbox b1i = ProviderTestUtils.setupMailbox("b1i", a1.mId, true, c, Mailbox.TYPE_INBOX);
        Mailbox b2a = ProviderTestUtils.setupMailbox("b2a", a2.mId, true, c, Mailbox.TYPE_MAIL);
        Mailbox b2i = ProviderTestUtils.setupMailbox("b2b", a2.mId, true, c, Mailbox.TYPE_INBOX);

        assertEquals(b2i.mId, Account.getInboxId(c, a2.mId));

        // No account found.
        assertEquals(-1, Account.getInboxId(c, 999999));
    }

    /**
     * Check if update to {@link Account#RESET_NEW_MESSAGE_COUNT_URI} resets the new message count.
     */
    public void testResetNewMessageCount() {
        final Context c = mMockContext;
        final ContentResolver cr = c.getContentResolver();

        // Prepare test data
        Account a1 = ProviderTestUtils.setupAccount("acct1", false, c);
        a1.mNewMessageCount = 1;
        a1.save(c);
        Account a2 = ProviderTestUtils.setupAccount("acct2", false, c);
        a2.mNewMessageCount = 2;
        a2.save(c);
        Account a3 = ProviderTestUtils.setupAccount("acct3", false, c);
        a3.mNewMessageCount = 3;
        a3.save(c);
        Account a4 = ProviderTestUtils.setupAccount("acct4", false, c);
        a4.mNewMessageCount = 4;
        a4.save(c);
        Account a5 = ProviderTestUtils.setupAccount("acct5", false, c);
        a5.mNewMessageCount = 5;
        a5.save(c);

        // With ID in URI, no selection
        cr.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a1.mId),
                null, null, null);
        assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
        assertEquals(2, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
        assertEquals(3, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
        assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
        assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);

        // No ID in URI, with selection
        cr.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null,
                EmailContent.ID_SELECTION, new String[] {Long.toString(a2.mId)});
        assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
        assertEquals(3, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
        assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
        assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);

        // With ID, with selection
        cr.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a3.mId), null,
                EmailContent.ID_SELECTION, new String[] {Long.toString(a3.mId)});
        assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
        assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
        assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);

        // No ID in URI, no selection
        cr.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null, null, null);
        assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
        assertEquals(0, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);
    }

    /**
     * Check if update on ACCOUNT_ID_ADD_TO_FIELD updates the cache properly.
     */
    public void testUpdateCacheAccountIdAddToField() {
        final Context c = mMockContext;
        Account a1 = ProviderTestUtils.setupAccount("a1", true, c);

        int start = Account.restoreAccountWithId(c, a1.mId).mNewMessageCount;

        // +1 to NEW_MESSAGE_COUNT
        ContentValues cv = new ContentValues();
        cv.put(EmailContent.FIELD_COLUMN_NAME, AccountColumns.NEW_MESSAGE_COUNT);
        cv.put(EmailContent.ADD_COLUMN_NAME, 1);
        mProvider.update(ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, a1.mId), cv,
                null, null);

        // Check
        assertEquals(start + 1, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
    }

    /**
     * Check if update on ACCOUNT_RESET_NEW_COUNT updates the cache properly.
     */
    public void testUpdateCacheAccountResetNewCount() {
        final Context c = mMockContext;
        Account a1 = ProviderTestUtils.setupAccount("a1", true, c);

        // precondition
        assertTrue(Account.restoreAccountWithId(c, a1.mId).mNewMessageCount > 0);

        // Reset
        mProvider.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null, null, null);

        // Check
        assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
    }

    /**
     * Check if update on ACCOUNT_RESET_NEW_COUNT_ID updates the cache properly.
     */
    public void testUpdateCacheAccountResetNewCountId() {
        final Context c = mMockContext;
        Account a1 = ProviderTestUtils.setupAccount("a1", true, c);

        // precondition
        assertTrue(Account.restoreAccountWithId(c, a1.mId).mNewMessageCount > 0);

        // Reset
        mProvider.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a1.mId),
                null, null, null);

        // Check
        assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
    }

    /**
     * Check that we're handling illegal uri's properly (by throwing an exception unless it's a
     * query for an id of -1, in which case we return a zero-length cursor)
     */
    public void testIllegalUri() {
        final ContentResolver cr = mMockContext.getContentResolver();

        ContentValues cv = new ContentValues();
        Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/fooble");
        try {
            cr.insert(uri, cv);
            fail("Insert should have thrown exception");
        } catch (IllegalArgumentException e) {
        }
        try {
            cr.update(uri, cv, null, null);
            fail("Update should have thrown exception");
        } catch (IllegalArgumentException e) {
        }
        try {
            cr.delete(uri, null, null);
            fail("Delete should have thrown exception");
        } catch (IllegalArgumentException e) {
        }
        try {
            cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
            fail("Query should have thrown exception");
        } catch (IllegalArgumentException e) {
        }
        uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/mailbox/fred");
        try {
            cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
            fail("Query should have thrown exception");
        } catch (IllegalArgumentException e) {
        }
        uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/mailbox/-1");
        Cursor c = cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
        assertNotNull(c);
        assertEquals(0, c.getCount());
        c.close();
    }

    /**
     * Verify {@link EmailProvider#recalculateMessageCount(android.database.sqlite.SQLiteDatabase)}
     */
    public void testRecalculateMessageCounts() {
        final Context c = mMockContext;

        // Create accounts
        Account a1 = ProviderTestUtils.setupAccount("holdflag-1", true, c);
        Account a2 = ProviderTestUtils.setupAccount("holdflag-2", true, c);

        // Create mailboxes for each account
        Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_INBOX);
        Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a1.mId, true, c, Mailbox.TYPE_OUTBOX);
        Mailbox b3 = ProviderTestUtils.setupMailbox("box3", a2.mId, true, c, Mailbox.TYPE_INBOX);
        Mailbox b4 = ProviderTestUtils.setupMailbox("box4", a2.mId, true, c, Mailbox.TYPE_OUTBOX);
        Mailbox bt = ProviderTestUtils.setupMailbox("boxT", a2.mId, true, c, Mailbox.TYPE_TRASH);

        // Create some messages
        // b1 (account 1, inbox): 1 message, including 1 starred
        Message m11 = createMessage(c, b1, true, false, Message.FLAG_LOADED_COMPLETE);

        // b2 (account 1, outbox): 2 message, including 1 starred
        Message m21 = createMessage(c, b2, false, false, Message.FLAG_LOADED_COMPLETE);
        Message m22 = createMessage(c, b2, true, true, Message.FLAG_LOADED_COMPLETE);

        // b3 (account 2, inbox): 3 message, including 1 starred
        Message m31 = createMessage(c, b3, false, false, Message.FLAG_LOADED_COMPLETE);
        Message m32 = createMessage(c, b3, false, false, Message.FLAG_LOADED_COMPLETE);
        Message m33 = createMessage(c, b3, true, true, Message.FLAG_LOADED_COMPLETE);

        // b4 (account 2, outbox) has no messages.

        // bt (account 2, trash) has 3 messages, including 2 starred
        Message mt1 = createMessage(c, bt, true, false, Message.FLAG_LOADED_COMPLETE);
        Message mt2 = createMessage(c, bt, true, false, Message.FLAG_LOADED_COMPLETE);
        Message mt3 = createMessage(c, bt, false, false, Message.FLAG_LOADED_COMPLETE);

        // Verifiy initial message counts
        assertEquals(1, getMessageCount(b1.mId));
        assertEquals(2, getMessageCount(b2.mId));
        assertEquals(3, getMessageCount(b3.mId));
        assertEquals(0, getMessageCount(b4.mId));
        assertEquals(3, getMessageCount(bt.mId));

        // Whew. The setup is done; now let's actually get to the test

        // First, invalidate the message counts.
        setMinusOneToMessageCounts();
        assertEquals(-1, getMessageCount(b1.mId));
        assertEquals(-1, getMessageCount(b2.mId));
        assertEquals(-1, getMessageCount(b3.mId));
        assertEquals(-1, getMessageCount(b4.mId));
        assertEquals(-1, getMessageCount(bt.mId));

        // Batch update.
        SQLiteDatabase db = getProvider().getDatabase(mMockContext);
        EmailProvider.recalculateMessageCount(db);

        // Check message counts are valid again
        assertEquals(1, getMessageCount(b1.mId));
        assertEquals(2, getMessageCount(b2.mId));
        assertEquals(3, getMessageCount(b3.mId));
        assertEquals(0, getMessageCount(b4.mId));
        assertEquals(3, getMessageCount(bt.mId));
    }

    /** Creates an account */
    private Account createAccount(Context c, String name, HostAuth recvAuth, HostAuth sendAuth) {
        Account account = ProviderTestUtils.setupAccount(name, false, c);
        if (recvAuth != null) {
            account.mHostAuthKeyRecv = recvAuth.mId;
            if (sendAuth == null) {
                account.mHostAuthKeySend = recvAuth.mId;
            }
        }
        if (sendAuth != null) {
            account.mHostAuthKeySend = sendAuth.mId;
        }
        account.save(c);
        return account;
    }

    /** Creates a mailbox; redefine as we need version 17 mailbox values */
    private Mailbox createMailbox(Context c, String displayName, String serverId, long parentKey,
            long accountId) {
        Mailbox box = new Mailbox();

        box.mDisplayName = displayName;
        box.mServerId = serverId;
        box.mParentKey = parentKey;
        box.mAccountKey = accountId;
        // Don't care about the fields below ... set them for giggles
        box.mType = Mailbox.TYPE_MAIL;
        box.mDelimiter = '/';
        box.mSyncKey = "sync-key";
        box.mSyncLookback = 2;
        box.mSyncInterval = Account.CHECK_INTERVAL_NEVER;
        box.mSyncTime = 3;
        box.mFlagVisible = true;
        box.mFlags = 5;
        box.mVisibleLimit = 6;
        box.save(c);
        return box;
    }

    /**
     * Asserts equality between two mailboxes. We define this as we don't have implementations
     * for Mailbox#equals().
     */
    private void assertEquals(Mailbox expected, Mailbox actual) {
        if (expected == null && actual == null) return;
        assertTrue(expected != null && actual != null);
        assertEqualsExceptServerId(expected, actual, expected.mServerId);
    }

    /**
     * Asserts equality between the two mailboxes EXCEPT for the server id. The given server
     * ID is the expected value.
     */
    private void assertEqualsExceptServerId(Mailbox expected, Mailbox actual, String serverId) {
        if (expected == null && actual == null) return;

        assertTrue(expected != null && actual != null);
        assertEquals(expected.mDisplayName, actual.mDisplayName);
        assertEquals(serverId, actual.mServerId);
        assertEquals(expected.mParentKey, actual.mParentKey);
        assertEquals(expected.mAccountKey, actual.mAccountKey);
    }

    /** Verifies updating the DB from v17 to v18 works as expected */
    public void testUpgradeFromVersion17ToVersion18() {
        final Context c = mMockContext;
        // Create accounts
        Account a1 = createAccount(c, "exchange",
                ProviderTestUtils.setupHostAuth("eas", "exchange.host.com", true, c),
                null);
        Account a2 = createAccount(c, "imap",
                ProviderTestUtils.setupHostAuth("imap", "imap.host.com", true, c),
                ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, c));
        Account a3 = createAccount(c, "pop3",
                ProviderTestUtils.setupHostAuth("pop3", "imap.host.com", true, c),
                ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, c));

        // Create mailboxes; some w/ valid parent IDs, others without
        Mailbox b11 = createMailbox(c, "box1", "12", 0L, a1.mId);
        Mailbox b12 = createMailbox(c, "box2", "67", -1L, a1.mId);
        Mailbox b13 = createMailbox(c, "box3", "18", b12.mId, a1.mId);

        Mailbox b21 = createMailbox(c, "box4", null, 0L, a2.mId);
        Mailbox b22 = createMailbox(c, "box4/foo/bar", "will-be-replaced", 0L, a2.mId);
        Mailbox b23 = createMailbox(c, "box5", null, -1L, a2.mId);
        Mailbox b24 = createMailbox(c, "box6", "box5/box6", b23.mId, a2.mId);

        Mailbox b31 = createMailbox(c, "box7", "12", 0L, a3.mId);
        Mailbox b32 = createMailbox(c, "box8/foo/bar", "will-be-replaced", 0L, a3.mId);
        Mailbox b33 = createMailbox(c, "box9", "box9", -1L, a3.mId);
        Mailbox b34 = createMailbox(c, "boxA", "box9/boxA", b33.mId, a3.mId);

        // Sanity check the mailboxes that were just added
        Mailbox testMailbox;
        testMailbox = Mailbox.restoreMailboxWithId(c, b11.mId);
        assertEquals(b11, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b12.mId);
        assertEquals(b12, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b13.mId);
        assertEquals(b13, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b21.mId);
        assertEqualsExceptServerId(b21, testMailbox, null);
        testMailbox = Mailbox.restoreMailboxWithId(c, b22.mId);
        assertEqualsExceptServerId(b22, testMailbox, "will-be-replaced");
        testMailbox = Mailbox.restoreMailboxWithId(c, b23.mId);
        assertEquals(b23, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b24.mId);
        assertEquals(b24, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b31.mId);
        assertEqualsExceptServerId(b31, testMailbox, "12");
        testMailbox = Mailbox.restoreMailboxWithId(c, b32.mId);
        assertEqualsExceptServerId(b32, testMailbox, "will-be-replaced");
        testMailbox = Mailbox.restoreMailboxWithId(c, b33.mId);
        assertEquals(b33, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b34.mId);
        assertEquals(b34, testMailbox);

        SQLiteDatabase db = getProvider().getDatabase(mMockContext);
        EmailProvider.upgradeFromVersion17ToVersion18(db);

        // Verify that only IMAP/POP3 mailboxes w/ a parent key of '0' are changed
        // Exchange mailboxes; none should be changed
        testMailbox = Mailbox.restoreMailboxWithId(c, b11.mId);
        assertEquals(b11, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b12.mId);
        assertEquals(b12, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b13.mId);
        assertEquals(b13, testMailbox);

        // IMAP mailboxes; only mailboxes w/ a parent id of '0' are changed
        testMailbox = Mailbox.restoreMailboxWithId(c, b21.mId);
        assertEqualsExceptServerId(b21, testMailbox, "box4");
        testMailbox = Mailbox.restoreMailboxWithId(c, b22.mId);
        assertEqualsExceptServerId(b22, testMailbox, "box4/foo/bar");
        testMailbox = Mailbox.restoreMailboxWithId(c, b23.mId);
        assertEquals(b23, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b24.mId);
        assertEquals(b24, testMailbox);

        // POP3 mailboxes; only mailboxes w/ a parent id of '0' are changed
        testMailbox = Mailbox.restoreMailboxWithId(c, b31.mId);
        assertEqualsExceptServerId(b31, testMailbox, "box7");
        testMailbox = Mailbox.restoreMailboxWithId(c, b32.mId);
        assertEqualsExceptServerId(b32, testMailbox, "box8/foo/bar");
        testMailbox = Mailbox.restoreMailboxWithId(c, b33.mId);
        assertEquals(b33, testMailbox);
        testMailbox = Mailbox.restoreMailboxWithId(c, b34.mId);
        assertEquals(b34, testMailbox);
    }

    /**
     * Determine whether a list of AccountManager accounts includes a given EmailProvider account
     * @param amAccountList a list of AccountManager accounts
     * @param account an EmailProvider account
     * @param context the caller's context (our test provider's context)
     * @return whether or not the EmailProvider account is represented in AccountManager
     */
    private boolean amAccountListHasAccount(android.accounts.Account[] amAccountList,
            Account account, Context context) {
        String email = account.mEmailAddress;
        for (android.accounts.Account amAccount: amAccountList) {
            if (amAccount.name.equals(email)) {
                return true;
            }
        }
        return false;
    }

    public void testAutoCacheNewContent() {
        Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
        // add hostauth data, which should be saved the first time
        account.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false,
                mMockContext);
        account.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false,
                mMockContext);
        account.save(mMockContext);
        assertTrue(mProvider.isCached(Account.CONTENT_URI, account.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, account.mHostAuthRecv.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, account.mHostAuthSend.mId));
    }

    /** Creates a mailbox; redefine as we need version 17 mailbox values */
    private Mailbox createTypeMailbox(Context c, long accountId, int type) {
        Mailbox box = new Mailbox();

        box.mDisplayName = "foo";
        box.mServerId = "1:1";
        box.mParentKey = 0;
        box.mAccountKey = accountId;
        // Don't care about the fields below ... set them for giggles
        box.mType = type;
        box.save(c);
        return box;
    }

    public void testAutoCacheInvalidate() {
        // Create 3 accounts with hostauth and 3 mailboxes each (2 of which are pre-cached)
        Account a = ProviderTestUtils.setupAccount("account1", false, mMockContext);
        a.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-recv", -1, false,
                mMockContext);
        a.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-send", -1, false,
                mMockContext);
        a.save(mMockContext);
        Mailbox a1 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_INBOX);
        Mailbox a2 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_MAIL);
        Mailbox a3 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_DRAFTS);
        Account b = ProviderTestUtils.setupAccount("account2", false, mMockContext);
        b.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-recv", -1, false,
                mMockContext);
        b.mHostAuthSend = ProviderTestUtils.setupHostAuth("accoun-send", -1, false,
                mMockContext);
        b.save(mMockContext);
        Mailbox b1 = createTypeMailbox(mMockContext, b.mId, Mailbox.TYPE_OUTBOX);
        Mailbox b2 = createTypeMailbox(mMockContext, b.mId, Mailbox.TYPE_MAIL);
        Mailbox b3 = createTypeMailbox(mMockContext, b.mId, Mailbox.TYPE_SENT);
        Account c = ProviderTestUtils.setupAccount("account3", false, mMockContext);
        c.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-recv", -1, false,
                mMockContext);
        c.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-send", -1, false,
                mMockContext);
        c.save(mMockContext);
        Mailbox c1 = createTypeMailbox(mMockContext, c.mId, Mailbox.TYPE_SEARCH);
        Mailbox c2 = createTypeMailbox(mMockContext, c.mId, Mailbox.TYPE_MAIL);
        Mailbox c3 = createTypeMailbox(mMockContext, c.mId, Mailbox.TYPE_TRASH);

        // Confirm expected cache state
        assertTrue(mProvider.isCached(Account.CONTENT_URI, a.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthRecv.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthSend.mId));
        assertTrue(mProvider.isCached(Account.CONTENT_URI, b.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthRecv.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthSend.mId));
        assertTrue(mProvider.isCached(Account.CONTENT_URI, c.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthRecv.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthSend.mId));

        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a1.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, a2.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a3.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, b1.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b2.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, b3.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c1.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, c2.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c3.mId));

        // Delete account b
        EmailContent.delete(mMockContext, Account.CONTENT_URI, b.mId);

        // Confirm cache state
        assertTrue(mProvider.isCached(Account.CONTENT_URI, a.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthRecv.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthSend.mId));
        assertFalse(mProvider.isCached(Account.CONTENT_URI, b.mId));
        assertFalse(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthRecv.mId));
        assertFalse(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthSend.mId));
        assertTrue(mProvider.isCached(Account.CONTENT_URI, c.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthRecv.mId));
        assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthSend.mId));

        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a1.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, a2.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a3.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b1.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b2.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b3.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c1.mId));
        assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, c2.mId));
        assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c3.mId));
    }

    /**
     * Remove a single pop/imap account from the AccountManager
     * @param accountManager our AccountManager
     * @param name the name of the test account to remove
     */
    private void removeAccountManagerAccount(AccountManager accountManager, String name) {
        try {
            accountManager.removeAccount(
                    new android.accounts.Account(name, AccountManagerTypes.TYPE_POP_IMAP),
                    null, null).getResult();
        } catch (OperationCanceledException e) {
        } catch (AuthenticatorException e) {
        } catch (IOException e) {
        }
    }

    /**
     * Remove all test accounts from the AccountManager
     * @param accountManager the AccountManager
     */
    private void cleanupTestAccountManagerAccounts(AccountManager accountManager) {
        android.accounts.Account[] amAccountList =
            accountManager.getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP);
        for (android.accounts.Account account: amAccountList) {
            if (account.name.startsWith(AccountReconciler.ACCOUNT_MANAGER_ACCOUNT_TEST_PREFIX)) {
                removeAccountManagerAccount(accountManager, account.name);
            }
        }
    }

    /** Verifies updating the DB from v21 to v22 works as expected */
    public void testUpgradeFromVersion21ToVersion22() {
        String imapTestLogin =
            AccountReconciler.ACCOUNT_MANAGER_ACCOUNT_TEST_PREFIX + "imap.host.com";
        String pop3TestLogin =
            AccountReconciler.ACCOUNT_MANAGER_ACCOUNT_TEST_PREFIX + "pop3.host.com";
        AccountManager accountManager = AccountManager.get(mContext);

        // Create provider accounts (one of each type)
        Account a1 = createAccount(mMockContext, "exchange",
                ProviderTestUtils.setupHostAuth("eas", "exchange.host.com", true, mMockContext),
                null);
        HostAuth h2 =
            ProviderTestUtils.setupHostAuth("imap", "imap.host.com", false, mMockContext);
        h2.mLogin = imapTestLogin;
        h2.save(mMockContext);
        Account a2 = createAccount(mMockContext, "imap", h2,
                ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, mMockContext));
        HostAuth h3 =
            ProviderTestUtils.setupHostAuth("pop3", "pop3.host.com", false, mMockContext);
        h3.mLogin = pop3TestLogin;
        h3.save(mMockContext);
        Account a3 = createAccount(mMockContext, "pop3", h3,
                ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, mMockContext));

        // Get the current list of AccountManager accounts (we have to use the real context here),
        // whereas we use the mock context for EmailProvider (this is because the mock context
        // doesn't implement AccountManager hooks)
        android.accounts.Account[] amAccountList =
            accountManager.getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP);
        // There shouldn't be AccountManager accounts for these
        assertFalse(amAccountListHasAccount(amAccountList, a1, mMockContext));
        assertFalse(amAccountListHasAccount(amAccountList, a2, mMockContext));
        assertFalse(amAccountListHasAccount(amAccountList, a3, mMockContext));

        amAccountList = null;
        try {
            // Upgrade the database
            SQLiteDatabase db = getProvider().getDatabase(mMockContext);
            EmailProvider.upgradeFromVersion21ToVersion22(db, getContext());

            // The pop3 and imap account should now be in account manager
            amAccountList = accountManager.getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP);
            assertFalse(amAccountListHasAccount(amAccountList, a1, mMockContext));
            assertTrue(amAccountListHasAccount(amAccountList, a2, mMockContext));
            assertTrue(amAccountListHasAccount(amAccountList, a3, mMockContext));
        } finally {
            cleanupTestAccountManagerAccounts(accountManager);
        }
    }

    public void testCleanupOrphans() {
        EmailProvider ep = getProvider();
        SQLiteDatabase db = ep.getDatabase(mMockContext);

        Account a = ProviderTestUtils.setupAccount("account1", true, mMockContext);
        // Mailbox a1 and a3 won't have a valid account
        Mailbox a1 = createTypeMailbox(mMockContext, -1, Mailbox.TYPE_INBOX);
        Mailbox a2 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_MAIL);
        Mailbox a3 = createTypeMailbox(mMockContext, -1, Mailbox.TYPE_DRAFTS);
        Mailbox a4 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_SENT);
        Mailbox a5 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_TRASH);
        // Mailbox ax isn't even saved; use an obviously invalid id
        Mailbox ax = new Mailbox();
        ax.mId = 69105;

        // Message mt2 is an orphan, as is mt4
        Message m1 = createMessage(mMockContext, a1, true, false, Message.FLAG_LOADED_COMPLETE);
        Message m2 = createMessage(mMockContext, a2, true, false, Message.FLAG_LOADED_COMPLETE);
        Message m3 = createMessage(mMockContext, a3, true, false, Message.FLAG_LOADED_COMPLETE);
        Message m4 = createMessage(mMockContext, a4, true, false, Message.FLAG_LOADED_COMPLETE);
        Message m5 = createMessage(mMockContext, a5, true, false, Message.FLAG_LOADED_COMPLETE);
        Message mx = createMessage(mMockContext, ax, true, false, Message.FLAG_LOADED_COMPLETE);

        // Two orphan policies
        Policy p1 = new Policy();
        p1.save(mMockContext);
        Policy p2 = new Policy();
        p2.save(mMockContext);
        Policy p3 = new Policy();
        SecurityPolicy.setAccountPolicy(mMockContext, a, p3, "0");

        // We don't want anything cached or the tests below won't work.  Note that
        // deleteUnlinked is only called by EmailProvider when the caches are empty
        ContentCache.invalidateAllCaches();
        // Delete orphaned mailboxes/messages/policies
        ep.deleteUnlinked(db, Mailbox.TABLE_NAME, MailboxColumns.ACCOUNT_KEY, AccountColumns.ID,
                Account.TABLE_NAME);
        ep.deleteUnlinked(db, Message.TABLE_NAME, MessageColumns.ACCOUNT_KEY, AccountColumns.ID,
                Account.TABLE_NAME);
        ep.deleteUnlinked(db, Policy.TABLE_NAME, PolicyColumns.ID, AccountColumns.POLICY_KEY,
                Account.TABLE_NAME);

        // Make sure the orphaned mailboxes are gone
        assertNull(Mailbox.restoreMailboxWithId(mMockContext, a1.mId));
        assertNotNull(Mailbox.restoreMailboxWithId(mMockContext, a2.mId));
        assertNull(Mailbox.restoreMailboxWithId(mMockContext, a3.mId));
        assertNotNull(Mailbox.restoreMailboxWithId(mMockContext, a4.mId));
        assertNotNull(Mailbox.restoreMailboxWithId(mMockContext, a5.mId));
        assertNull(Mailbox.restoreMailboxWithId(mMockContext, ax.mId));

        // Make sure orphaned messages are gone
        assertNull(Message.restoreMessageWithId(mMockContext, m1.mId));
        assertNotNull(Message.restoreMessageWithId(mMockContext, m2.mId));
        assertNull(Message.restoreMessageWithId(mMockContext, m3.mId));
        assertNotNull(Message.restoreMessageWithId(mMockContext, m4.mId));
        assertNotNull(Message.restoreMessageWithId(mMockContext, m5.mId));
        assertNull(Message.restoreMessageWithId(mMockContext, mx.mId));

        // Make sure orphaned policies are gone
        assertNull(Policy.restorePolicyWithId(mMockContext, p1.mId));
        assertNull(Policy.restorePolicyWithId(mMockContext, p2.mId));
        a = Account.restoreAccountWithId(mMockContext, a.mId);
        assertNotNull(Policy.restorePolicyWithId(mMockContext, a.mPolicyKey));
    }
}
