diff --git a/src/com/android/dialer/voicemail/VoicemailAsyncTaskUtil.java b/src/com/android/dialer/voicemail/VoicemailAsyncTaskUtil.java
new file mode 100644
index 0000000..7abf9a7
--- /dev/null
+++ b/src/com/android/dialer/voicemail/VoicemailAsyncTaskUtil.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2016 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.dialer.voicemail;
+
+import com.android.contacts.common.testing.NeededForTesting;
+import com.android.dialer.calllog.CallLogQuery;
+import com.android.dialer.database.VoicemailArchiveContract;
+import com.android.dialer.util.AsyncTaskExecutor;
+import com.android.dialer.util.AsyncTaskExecutors;
+import com.google.common.base.Preconditions;
+import com.google.common.io.ByteStreams;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.CallLog;
+import android.provider.VoicemailContract;
+import android.util.Log;
+import com.android.common.io.MoreCloseables;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.annotation.Nullable;
+
+/**
+ * Class containing asynchronous tasks for voicemails.
+ */
+@NeededForTesting
+public class VoicemailAsyncTaskUtil {
+    private static final String TAG = "VoicemailAsyncTaskUtil";
+
+    /** The enumeration of {@link AsyncTask} objects we use in this class. */
+    public enum Tasks {
+        GET_VOICEMAIL_FILE_PATH,
+        SET_VOICEMAIL_ARCHIVE_STATUS,
+        ARCHIVE_VOICEMAIL_CONTENT
+    }
+
+    @NeededForTesting
+    public interface OnArchiveVoicemailListener {
+        /**
+         * Called after the voicemail has been archived.
+         *
+         * @param archivedVoicemailUri the URI of the archived voicemail
+         */
+        void onArchiveVoicemail(@Nullable Uri archivedVoicemailUri);
+    }
+
+    @NeededForTesting
+    public interface OnSetVoicemailArchiveStatusListener {
+        /**
+         * Called after the voicemail archived_by_user column is updated.
+         *
+         * @param success whether the update was successful or not
+         */
+        void onSetVoicemailArchiveStatus(boolean success);
+    }
+
+    @NeededForTesting
+    public interface OnGetArchivedVoicemailFilePathListener {
+        /**
+         * Called after the voicemail file path is obtained.
+         *
+         * @param filePath the file path of the archived voicemail
+         */
+        void onGetArchivedVoicemailFilePath(@Nullable String filePath);
+    }
+
+    private final ContentResolver mResolver;
+    private final AsyncTaskExecutor mAsyncTaskExecutor;
+
+    @NeededForTesting
+    public VoicemailAsyncTaskUtil(ContentResolver contentResolver) {
+        mResolver = Preconditions.checkNotNull(contentResolver);
+        mAsyncTaskExecutor = AsyncTaskExecutors.createThreadPoolExecutor();
+    }
+
+    /**
+     * Returns the archived voicemail file path.
+     */
+    @NeededForTesting
+    public void getVoicemailFilePath(
+            final OnGetArchivedVoicemailFilePathListener listener,
+            final Uri voicemailUri) {
+        Preconditions.checkNotNull(listener);
+        Preconditions.checkNotNull(voicemailUri);
+        mAsyncTaskExecutor.submit(Tasks.GET_VOICEMAIL_FILE_PATH,
+                new AsyncTask<Void, Void, String>() {
+                    @Nullable
+                    @Override
+                    protected String doInBackground(Void... params) {
+                        try (Cursor cursor = mResolver.query(voicemailUri,
+                                new String[]{VoicemailArchiveContract.VoicemailArchive._DATA},
+                                null, null, null)) {
+                            if (hasContent(cursor)) {
+                                return cursor.getString(cursor.getColumnIndex(
+                                        VoicemailArchiveContract.VoicemailArchive._DATA));
+                            }
+                        }
+                        return null;
+                    }
+
+                    @Override
+                    protected void onPostExecute(String filePath) {
+                        listener.onGetArchivedVoicemailFilePath(filePath);
+                    }
+                });
+    }
+
+    /**
+     * Updates the archived_by_user flag of the archived voicemail.
+     */
+    @NeededForTesting
+    public void setVoicemailArchiveStatus(
+            final OnSetVoicemailArchiveStatusListener listener,
+            final Uri voicemailUri,
+            final boolean archivedByUser) {
+        Preconditions.checkNotNull(listener);
+        Preconditions.checkNotNull(voicemailUri);
+        mAsyncTaskExecutor.submit(Tasks.SET_VOICEMAIL_ARCHIVE_STATUS,
+                new AsyncTask<Void, Void, Boolean>() {
+                    @Override
+                    protected Boolean doInBackground(Void... params) {
+                        ContentValues values = new ContentValues(1);
+                        values.put(VoicemailArchiveContract.VoicemailArchive.ARCHIVED,
+                                archivedByUser);
+                        return mResolver.update(voicemailUri, values, null, null) > 0;
+                    }
+
+                    @Override
+                    protected void onPostExecute(Boolean success) {
+                        listener.onSetVoicemailArchiveStatus(success);
+                    }
+                });
+    }
+
+    /**
+     * Checks if a voicemail has already been archived, if so, return the previously archived URI.
+     * Otherwise, copy the voicemail information to the local dialer database. If archive was
+     * successful, archived voicemail URI is returned to listener, otherwise null.
+     */
+    @NeededForTesting
+    public void archiveVoicemailContent(
+            final OnArchiveVoicemailListener listener,
+            final Uri voicemailUri) {
+        Preconditions.checkNotNull(listener);
+        Preconditions.checkNotNull(voicemailUri);
+        mAsyncTaskExecutor.submit(Tasks.ARCHIVE_VOICEMAIL_CONTENT,
+                new AsyncTask<Void, Void, Uri>() {
+                    @Nullable
+                    @Override
+                    protected Uri doInBackground(Void... params) {
+                        Uri archivedVoicemailUri = getArchivedVoicemailUri(voicemailUri);
+
+                        // If previously archived, return uri, otherwise archive everything.
+                        if (archivedVoicemailUri != null) {
+                            return archivedVoicemailUri;
+                        }
+
+                        // Combine call log and voicemail content info.
+                        ContentValues values = getVoicemailContentValues(voicemailUri);
+                        if (values == null) {
+                            return null;
+                        }
+
+                        Uri insertedVoicemailUri = mResolver.insert(
+                                VoicemailArchiveContract.VoicemailArchive.CONTENT_URI, values);
+                        if (insertedVoicemailUri == null) {
+                            return null;
+                        }
+
+                        // Copy voicemail content to a new file.
+                        boolean copiedFile = false;
+                        try (InputStream inputStream = mResolver.openInputStream(voicemailUri);
+                             OutputStream outputStream =
+                                     mResolver.openOutputStream(insertedVoicemailUri)) {
+                            if (inputStream != null && outputStream != null) {
+                                ByteStreams.copy(inputStream, outputStream);
+                                copiedFile = true;
+                                return insertedVoicemailUri;
+                            }
+                        } catch (IOException e) {
+                            Log.w(TAG, "Failed to copy voicemail content to new file: "
+                                    + e.toString());
+                        } finally {
+                            if (!copiedFile) {
+                                // Roll back insert if the voicemail content was not copied.
+                                mResolver.delete(insertedVoicemailUri, null, null);
+                            }
+                        }
+                        return null;
+                    }
+
+                    @Override
+                    protected void onPostExecute(Uri archivedVoicemailUri) {
+                        listener.onArchiveVoicemail(archivedVoicemailUri);
+                    }
+                });
+    }
+
+    /**
+     * Helper method to get the archived URI of a voicemail.
+     *
+     * @param voicemailUri a {@link android.provider.VoicemailContract.Voicemails#CONTENT_URI} URI.
+     * @return the URI of the archived voicemail or {@code null}
+     */
+    @Nullable
+    private Uri getArchivedVoicemailUri(Uri voicemailUri) {
+        try (Cursor cursor = getArchiveExistsCursor(voicemailUri)) {
+            if (hasContent(cursor)) {
+                return VoicemailArchiveContract.VoicemailArchive
+                        .buildWithId(cursor.getInt(cursor.getColumnIndex(
+                                VoicemailArchiveContract.VoicemailArchive._ID)));
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Helper method to make a copy of all the values needed to display a voicemail.
+     *
+     * @param voicemailUri a {@link VoicemailContract.Voicemails#CONTENT_URI} URI.
+     * @return the combined call log and voicemail values for the given URI, or {@code null}
+     */
+    @Nullable
+    private ContentValues getVoicemailContentValues(Uri voicemailUri) {
+        try (Cursor callLogInfo = getCallLogInfoCursor(voicemailUri);
+             Cursor contentInfo = getContentInfoCursor(voicemailUri)) {
+
+            if (hasContent(callLogInfo) && hasContent(contentInfo)) {
+                // Create values to insert into database.
+                ContentValues values = new ContentValues();
+
+                // Insert voicemail call log info.
+                values.put(VoicemailArchiveContract.VoicemailArchive.COUNTRY_ISO,
+                        callLogInfo.getString(CallLogQuery.COUNTRY_ISO));
+                values.put(VoicemailArchiveContract.VoicemailArchive.GEOCODED_LOCATION,
+                        callLogInfo.getString(CallLogQuery.GEOCODED_LOCATION));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NAME,
+                        callLogInfo.getString(CallLogQuery.CACHED_NAME));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NUMBER_TYPE,
+                        callLogInfo.getInt(CallLogQuery.CACHED_NUMBER_TYPE));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NUMBER_LABEL,
+                        callLogInfo.getString(CallLogQuery.CACHED_NUMBER_LABEL));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_LOOKUP_URI,
+                        callLogInfo.getString(CallLogQuery.CACHED_LOOKUP_URI));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_MATCHED_NUMBER,
+                        callLogInfo.getString(CallLogQuery.CACHED_MATCHED_NUMBER));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NORMALIZED_NUMBER,
+                        callLogInfo.getString(CallLogQuery.CACHED_NORMALIZED_NUMBER));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_FORMATTED_NUMBER,
+                        callLogInfo.getString(CallLogQuery.CACHED_FORMATTED_NUMBER));
+                values.put(VoicemailArchiveContract.VoicemailArchive.NUMBER_PRESENTATION,
+                        callLogInfo.getInt(CallLogQuery.NUMBER_PRESENTATION));
+                values.put(VoicemailArchiveContract.VoicemailArchive.ACCOUNT_COMPONENT_NAME,
+                        callLogInfo.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME));
+                values.put(VoicemailArchiveContract.VoicemailArchive.ACCOUNT_ID,
+                        callLogInfo.getString(CallLogQuery.ACCOUNT_ID));
+                values.put(VoicemailArchiveContract.VoicemailArchive.FEATURES,
+                        callLogInfo.getInt(CallLogQuery.FEATURES));
+                values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_PHOTO_URI,
+                        callLogInfo.getString(CallLogQuery.CACHED_PHOTO_URI));
+
+                // Insert voicemail content info.
+                values.put(VoicemailArchiveContract.VoicemailArchive.SERVER_ID,
+                        contentInfo.getInt(contentInfo.getColumnIndex(
+                                VoicemailContract.Voicemails._ID)));
+                values.put(VoicemailArchiveContract.VoicemailArchive.NUMBER,
+                        contentInfo.getString(contentInfo.getColumnIndex(
+                                VoicemailContract.Voicemails.NUMBER)));
+                values.put(VoicemailArchiveContract.VoicemailArchive.DATE,
+                        contentInfo.getLong(contentInfo.getColumnIndex(
+                                VoicemailContract.Voicemails.DATE)));
+                values.put(VoicemailArchiveContract.VoicemailArchive.DURATION,
+                        contentInfo.getLong(contentInfo.getColumnIndex(
+                                VoicemailContract.Voicemails.DURATION)));
+                values.put(VoicemailArchiveContract.VoicemailArchive.MIME_TYPE,
+                        contentInfo.getString(contentInfo.getColumnIndex(
+                                VoicemailContract.Voicemails.MIME_TYPE)));
+                values.put(VoicemailArchiveContract.VoicemailArchive.TRANSCRIPTION,
+                        contentInfo.getString(contentInfo.getColumnIndex(
+                                VoicemailContract.Voicemails.TRANSCRIPTION)));
+
+                // Achived is false by default because it is updated after insertion.
+                values.put(VoicemailArchiveContract.VoicemailArchive.ARCHIVED, false);
+
+                return values;
+            }
+        }
+        return null;
+    }
+
+    private boolean hasContent(@Nullable Cursor cursor) {
+        return cursor != null && cursor.moveToFirst();
+    }
+
+    @Nullable
+    private Cursor getCallLogInfoCursor(Uri voicemailUri) {
+        return mResolver.query(
+                ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
+                        ContentUris.parseId(voicemailUri)),
+                CallLogQuery._PROJECTION, null, null, null);
+    }
+
+    @Nullable
+    private Cursor getContentInfoCursor(Uri voicemailUri) {
+        return mResolver.query(voicemailUri,
+                new String[] {
+                        VoicemailContract.Voicemails._ID,
+                        VoicemailContract.Voicemails.NUMBER,
+                        VoicemailContract.Voicemails.DATE,
+                        VoicemailContract.Voicemails.DURATION,
+                        VoicemailContract.Voicemails.MIME_TYPE,
+                        VoicemailContract.Voicemails.TRANSCRIPTION,
+                }, null, null, null);
+    }
+
+    @Nullable
+    private Cursor getArchiveExistsCursor(Uri voicemailUri) {
+        return mResolver.query(VoicemailArchiveContract.VoicemailArchive.CONTENT_URI,
+                new String[] {VoicemailArchiveContract.VoicemailArchive._ID},
+                VoicemailArchiveContract.VoicemailArchive.SERVER_ID + "="
+                        + ContentUris.parseId(voicemailUri),
+                null,
+                null);
+    }
+}
diff --git a/tests/src/com/android/dialer/voicemail/VoicemailAsyncTaskUtilTest.java b/tests/src/com/android/dialer/voicemail/VoicemailAsyncTaskUtilTest.java
new file mode 100644
index 0000000..d98d9fa
--- /dev/null
+++ b/tests/src/com/android/dialer/voicemail/VoicemailAsyncTaskUtilTest.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2016 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.dialer.voicemail;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.res.AssetFileDescriptor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.CallLog;
+import android.provider.VoicemailContract;
+import android.test.InstrumentationTestCase;
+import android.test.mock.MockContentResolver;
+
+import com.android.contacts.common.test.mocks.MockContentProvider;
+import com.android.contacts.common.test.mocks.MockContentProvider.Query;
+import com.android.dialer.calllog.CallLogQuery;
+import com.android.dialer.database.VoicemailArchiveContract;
+import com.android.dialer.util.AsyncTaskExecutors;
+import com.android.dialer.util.FakeAsyncTaskExecutor;
+import com.android.dialer.voicemail.VoicemailAsyncTaskUtil.OnGetArchivedVoicemailFilePathListener;
+import com.android.dialer.voicemail.VoicemailAsyncTaskUtil.OnArchiveVoicemailListener;
+import com.android.dialer.voicemail.VoicemailAsyncTaskUtil.OnSetVoicemailArchiveStatusListener;
+
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+import static org.mockito.Mockito.*;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class VoicemailAsyncTaskUtilTest extends InstrumentationTestCase {
+    private static final String TEST_MIME_TYPE = "audio/mp3";
+    private static final String TEST_NUMBER = "+1412555555";
+    private static final String TEST_FILE_PATH = "TEST_PATH";
+    private static final String TEST_TRANSCRIPTION = "TEST_TRANSCRIPTION";
+    private static final long TEST_DATE = 0;
+    private static final long TEST_DURATION = 0;
+    private static final int TEST_SERVER_ID = 1;
+    private static final int TEST_ID = 2;
+    private static final Uri ARCHIVED_VOICEMAIL_URI =
+            VoicemailArchiveContract.VoicemailArchive.buildWithId(TEST_ID);
+    private static final Uri VOICEMAIL_URI = VoicemailContract.Voicemails.CONTENT_URI
+            .buildUpon().appendPath(Integer.toString(TEST_SERVER_ID)).build();
+    private static final String[] CALLLOG_QUERY_PROJECTION = new String[] {
+            CallLog.Calls._ID,
+            CallLog.Calls.NUMBER,
+            CallLog.Calls.DATE,
+            CallLog.Calls.DURATION,
+            CallLog.Calls.TYPE,
+            CallLog.Calls.COUNTRY_ISO,
+            CallLog.Calls.VOICEMAIL_URI,
+            CallLog.Calls.GEOCODED_LOCATION,
+            CallLog.Calls.CACHED_NAME,
+            CallLog.Calls.CACHED_NUMBER_TYPE,
+            CallLog.Calls.CACHED_NUMBER_LABEL,
+            CallLog.Calls.CACHED_LOOKUP_URI,
+            CallLog.Calls.CACHED_MATCHED_NUMBER,
+            CallLog.Calls.CACHED_NORMALIZED_NUMBER,
+            CallLog.Calls.CACHED_PHOTO_ID,
+            CallLog.Calls.CACHED_FORMATTED_NUMBER,
+            CallLog.Calls.IS_READ,
+            CallLog.Calls.NUMBER_PRESENTATION,
+            CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME,
+            CallLog.Calls.PHONE_ACCOUNT_ID,
+            CallLog.Calls.FEATURES,
+            CallLog.Calls.DATA_USAGE,
+            CallLog.Calls.TRANSCRIPTION,
+            CallLog.Calls.CACHED_PHOTO_URI
+    };
+    private static final String[] VOICEMAIL_PROJECTION = new String[] {
+            VoicemailContract.Voicemails._ID,
+            VoicemailContract.Voicemails.NUMBER,
+            VoicemailContract.Voicemails.DATE,
+            VoicemailContract.Voicemails.DURATION,
+            VoicemailContract.Voicemails.MIME_TYPE,
+            VoicemailContract.Voicemails.TRANSCRIPTION,
+    };
+
+    private final MockContentResolver mContentResolver = new MockContentResolver();
+    private final MockContentProvider mArchiveContentProvider = new TestVoicemailContentProvider();
+    private final MockContentProvider mVoicemailContentProvider =
+            new TestVoicemailContentProvider();
+    private final MockContentProvider mCallLogContentProvider = new MockContentProvider();
+    @Rule
+    private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
+    private VoicemailAsyncTaskUtil mVoicemailAsyncTaskUtil;
+    private FakeAsyncTaskExecutor mFakeAsyncTaskExecutor;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mFakeAsyncTaskExecutor = new FakeAsyncTaskExecutor(getInstrumentation());
+        AsyncTaskExecutors.setFactoryForTest(mFakeAsyncTaskExecutor.getFactory());
+        mContentResolver.addProvider(VoicemailArchiveContract.AUTHORITY, mArchiveContentProvider);
+        mContentResolver.addProvider(VoicemailContract.AUTHORITY, mVoicemailContentProvider);
+        mContentResolver.addProvider(CallLog.AUTHORITY, mCallLogContentProvider);
+        mVoicemailAsyncTaskUtil = new VoicemailAsyncTaskUtil(mContentResolver);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        AsyncTaskExecutors.setFactoryForTest(null);
+        super.tearDown();
+    }
+
+    public void testGetVoicemailFilePath_VoicemailExists() throws Throwable {
+        newVoicemailArchiveQuery().withAnyProjection()
+                .returnRow(getCombinedContentValuesWithData());
+        final OnGetArchivedVoicemailFilePathListener listener =
+                mock(OnGetArchivedVoicemailFilePathListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.getVoicemailFilePath(listener, ARCHIVED_VOICEMAIL_URI);
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.GET_VOICEMAIL_FILE_PATH);
+        verify(listener).onGetArchivedVoicemailFilePath(TEST_FILE_PATH);
+        verifyQueries();
+    }
+
+    public void testGetVoicemailFilePath_VoicemailNotExists() throws Throwable {
+        newVoicemailArchiveFakeQuery().withAnyProjection().returnEmptyCursor();
+        final OnGetArchivedVoicemailFilePathListener listener =
+                mock(OnGetArchivedVoicemailFilePathListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.getVoicemailFilePath(listener, getFakeVoicemailUri());
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.GET_VOICEMAIL_FILE_PATH);
+        verify(listener).onGetArchivedVoicemailFilePath(null);
+        verifyQueries();
+    }
+
+    public void testSetVoicemailArchiveStatus_VoicemailNotExists() throws Throwable {
+        newVoicemailArchiveNotExistsUpdateQuery(true);
+        final OnSetVoicemailArchiveStatusListener listener =
+                mock(OnSetVoicemailArchiveStatusListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.setVoicemailArchiveStatus(listener,
+                        getFakeVoicemailUri(), true);
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.SET_VOICEMAIL_ARCHIVE_STATUS);
+        verify(listener).onSetVoicemailArchiveStatus(false);
+        verifyQueries();
+    }
+
+    public void testSetVoicemailArchiveStatus_VoicemailExists() throws Throwable {
+        newVoicemailArchiveExistsUpdateQuery(true);
+        final OnSetVoicemailArchiveStatusListener listener =
+                mock(OnSetVoicemailArchiveStatusListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.setVoicemailArchiveStatus(listener,
+                        ARCHIVED_VOICEMAIL_URI, true);
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.SET_VOICEMAIL_ARCHIVE_STATUS);
+        verify(listener).onSetVoicemailArchiveStatus(true);
+        verifyQueries();
+    }
+
+    public void testArchiveVoicemailContent_ArchiveNotExists() throws Throwable {
+        newVoicemailArchiveExistsQuery().returnEmptyCursor();
+        newQueryCallLogInfo().returnRow(getCallLogContentValues());
+        newVoicemailQuery().returnRow(getVoicemailContentValues());
+        newVoicemailArchiveInsert();
+        final OnArchiveVoicemailListener listener = mock(OnArchiveVoicemailListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.archiveVoicemailContent(listener, VOICEMAIL_URI);
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.ARCHIVE_VOICEMAIL_CONTENT);
+        verify(listener).onArchiveVoicemail(ARCHIVED_VOICEMAIL_URI);
+        verifyQueries();
+    }
+
+    public void testArchiveVoicemailContent_ArchiveExists() throws Throwable {
+        newVoicemailArchiveExistsQuery().returnRow(getCombinedValuesWithId());
+        final OnArchiveVoicemailListener listener = mock(OnArchiveVoicemailListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.archiveVoicemailContent(listener, VOICEMAIL_URI);
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.ARCHIVE_VOICEMAIL_CONTENT);
+        verify(listener).onArchiveVoicemail(ARCHIVED_VOICEMAIL_URI);
+        verifyQueries();
+    }
+
+    public void testArchiveVoicemailContent_CallLogInfoNotExists() throws Throwable {
+        newVoicemailArchiveExistsQuery().returnEmptyCursor();
+        newQueryCallLogInfo().returnEmptyCursor();
+        newVoicemailQuery().returnEmptyCursor();
+        final OnArchiveVoicemailListener listener = mock(OnArchiveVoicemailListener.class);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mVoicemailAsyncTaskUtil.archiveVoicemailContent(listener, VOICEMAIL_URI);
+            }
+        });
+        mFakeAsyncTaskExecutor.runTask(VoicemailAsyncTaskUtil.Tasks.ARCHIVE_VOICEMAIL_CONTENT);
+        verify(listener).onArchiveVoicemail(null);
+        verifyQueries();
+    }
+
+    private Query newVoicemailArchiveQuery() {
+        return mArchiveContentProvider.expectQuery(ARCHIVED_VOICEMAIL_URI);
+    }
+
+    private Query newVoicemailArchiveFakeQuery() {
+        return mArchiveContentProvider.expectQuery(getFakeVoicemailUri());
+    }
+
+    private Query newQueryCallLogInfo() {
+        return mCallLogContentProvider.expectQuery(ContentUris.withAppendedId(
+                CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL, ContentUris.parseId(VOICEMAIL_URI)))
+                .withProjection(CALLLOG_QUERY_PROJECTION);
+    }
+
+    private Query newVoicemailQuery() {
+        return mVoicemailContentProvider.expectQuery(VOICEMAIL_URI).withAnySelection()
+                .withProjection(VOICEMAIL_PROJECTION);
+    }
+
+    private Query newVoicemailArchiveExistsQuery() {
+        return mArchiveContentProvider.expectQuery(
+                VoicemailArchiveContract.VoicemailArchive.CONTENT_URI)
+                .withSelection(VoicemailArchiveContract.VoicemailArchive.SERVER_ID + "="
+                        + ContentUris.parseId(VOICEMAIL_URI), (String[]) null)
+                .withProjection(VoicemailArchiveContract.VoicemailArchive._ID);
+    }
+
+    private void newVoicemailArchiveInsert() {
+        mArchiveContentProvider.expectInsert(
+                VoicemailArchiveContract.VoicemailArchive.CONTENT_URI, getCombinedContentValues(),
+                ARCHIVED_VOICEMAIL_URI);
+    }
+
+    private void newVoicemailArchiveNotExistsUpdateQuery(boolean status) {
+        mArchiveContentProvider.expectUpdate(getFakeVoicemailUri(),
+                getArchiveStatusUpdateValues(status), null, null).returnRowsAffected(0);
+    }
+
+    private void newVoicemailArchiveExistsUpdateQuery(boolean status) {
+        mArchiveContentProvider.expectUpdate(ARCHIVED_VOICEMAIL_URI,
+                getArchiveStatusUpdateValues(status), null, null).returnRowsAffected(1);
+    }
+
+    private static ContentValues getCallLogContentValues() {
+        ContentValues values = new ContentValues();
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.GEOCODED_LOCATION], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_NAME], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.COUNTRY_ISO], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_NUMBER_TYPE], 0);
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_NUMBER_LABEL], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_LOOKUP_URI], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_MATCHED_NUMBER], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_NORMALIZED_NUMBER], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.CACHED_FORMATTED_NUMBER], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.NUMBER_PRESENTATION], 0);
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.ACCOUNT_COMPONENT_NAME], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.ACCOUNT_ID], "");
+        values.put(CALLLOG_QUERY_PROJECTION[CallLogQuery.FEATURES], 0);
+        values.put(CALLLOG_QUERY_PROJECTION[23], "");
+        return values;
+    }
+
+    private static ContentValues getVoicemailContentValues() {
+        ContentValues values = new ContentValues();
+        values.put(VoicemailContract.Voicemails.NUMBER, TEST_NUMBER);
+        values.put(VoicemailContract.Voicemails.DATE, TEST_DATE);
+        values.put(VoicemailContract.Voicemails.DURATION, TEST_DURATION);
+        values.put(VoicemailContract.Voicemails.MIME_TYPE, TEST_MIME_TYPE);
+        values.put(VoicemailContract.Voicemails._ID, TEST_SERVER_ID);
+        values.put(VoicemailContract.Voicemails.TRANSCRIPTION, TEST_TRANSCRIPTION);
+        values.put("_data", TEST_FILE_PATH);    // VoicemailContract.Voicemails._DATA
+        return values;
+    }
+
+    private static ContentValues getCombinedContentValues() {
+        ContentValues values = new ContentValues();
+        // Call log info
+        values.put(VoicemailArchiveContract.VoicemailArchive.GEOCODED_LOCATION, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NAME, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NUMBER_TYPE, 0);
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NUMBER_LABEL, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_LOOKUP_URI, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_MATCHED_NUMBER, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_NORMALIZED_NUMBER, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_FORMATTED_NUMBER, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.NUMBER_PRESENTATION, 0);
+        values.put(VoicemailArchiveContract.VoicemailArchive.ACCOUNT_COMPONENT_NAME, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.ACCOUNT_ID, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.FEATURES, 0);
+        values.put(VoicemailArchiveContract.VoicemailArchive.CACHED_PHOTO_URI, "");
+        values.put(VoicemailArchiveContract.VoicemailArchive.COUNTRY_ISO, "");
+
+        // Voicemail content info
+        values.put(VoicemailArchiveContract.VoicemailArchive.NUMBER, TEST_NUMBER);
+        values.put(VoicemailArchiveContract.VoicemailArchive.DATE, TEST_DATE);
+        values.put(VoicemailArchiveContract.VoicemailArchive.DURATION, TEST_DURATION);
+        values.put(VoicemailArchiveContract.VoicemailArchive.MIME_TYPE, TEST_MIME_TYPE);
+        values.put(VoicemailArchiveContract.VoicemailArchive.SERVER_ID, TEST_SERVER_ID);
+        values.put(VoicemailArchiveContract.VoicemailArchive.TRANSCRIPTION, TEST_TRANSCRIPTION);
+
+        // Custom fields
+        values.put(VoicemailArchiveContract.VoicemailArchive.ARCHIVED, false);
+        return values;
+    }
+
+    private static ContentValues getCombinedContentValuesWithData() {
+        ContentValues values = getCombinedContentValues();
+        values.put(VoicemailArchiveContract.VoicemailArchive._DATA, TEST_FILE_PATH);
+        return values;
+    }
+
+    private static ContentValues getCombinedValuesWithId() {
+        ContentValues values = getCombinedContentValuesWithData();
+        values.put(VoicemailArchiveContract.VoicemailArchive._ID, TEST_ID);
+        return values;
+    }
+
+    private static ContentValues getArchiveStatusUpdateValues(boolean status) {
+        ContentValues values = new ContentValues();
+        values.put(VoicemailArchiveContract.VoicemailArchive.ARCHIVED, status);
+        return values;
+    }
+
+    private static Uri getFakeVoicemailUri() {
+        return VoicemailArchiveContract.VoicemailArchive.buildWithId(0);
+    }
+
+    private void verifyQueries() {
+        mArchiveContentProvider.verify();
+        mCallLogContentProvider.verify();
+        mVoicemailContentProvider.verify();
+    }
+
+    private class TestVoicemailContentProvider extends MockContentProvider {
+        @Override
+        public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+            int modeBits = ParcelFileDescriptor.parseMode(mode);
+            try {
+                return ParcelFileDescriptor.open(mTemporaryFolder.newFile(), modeBits);
+            } catch (IOException e) {
+                return null;
+            }
+        }
+
+        @Override
+        public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts) {
+            try {
+                return new AssetFileDescriptor(openFile(uri, "r"), 0,
+                        AssetFileDescriptor.UNKNOWN_LENGTH);
+            } catch (FileNotFoundException e) {
+                return null;
+            }
+        }
+    }
+}
+
