diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
index de6f198..83d098f 100644
--- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
@@ -22,14 +22,16 @@
 import android.database.MatrixCursor;
 import android.net.Uri;
 import android.provider.CallLog.Calls;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.VoicemailContract;
 import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.telephony.PhoneNumberUtils;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.LargeTest;
 import android.text.TextUtils;
 import android.view.View;
-import android.widget.LinearLayout;
 
 import com.android.dialer.contactinfo.ContactInfoCache;
 import com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener;
@@ -42,24 +44,32 @@
 
 /**
  * Unit tests for {@link CallLogAdapter}.
+ *
+ * adb shell am instrument \
+ *     -e com.android.dialer.calllog.CallLogAdapterTest \
+ *     -w com.android.dialer.tests/android.test.InstrumentationTestRunner
  */
-@SmallTest
 public class CallLogAdapterTest extends AndroidTestCase {
+    private static final String EMPTY_STRING = "";
     private static final int NO_VALUE_SET = -1;
 
+    private static final String TEST_CACHED_NAME = "name";
+    private static final String TEST_CACHED_NUMBER_LABEL = "label";
+    private static final int TEST_CACHED_NUMBER_TYPE = 1;
+    private static final String TEST_COUNTRY_ISO = "US";
+    private static final String TEST_DEFAULT_CUSTOM_LABEL = "myLabel";
+    private static final Uri TEST_LOOKUP_URI = Uri.parse("content://contacts/2");
+
+    private static final String TEST_NUMBER = "12125551000";
     private static final String TEST_NUMBER_1 = "12345678";
     private static final String TEST_NUMBER_2 = "87654321";
     private static final String TEST_NUMBER_3 = "18273645";
-    private static final String TEST_NAME = "name";
-    private static final String TEST_NUMBER_LABEL = "label";
-    private static final int TEST_NUMBER_TYPE = 1;
-    private static final String TEST_COUNTRY_ISO = "US";
+    private static final String TEST_FORMATTED_NUMBER = "1 212-555-1000";
 
     // The object under test.
     private TestCallLogAdapter mAdapter;
 
     private MatrixCursor mCursor;
-    private int mCursorSize;
 
     private View mView;
     private CallLogListItemViewHolder mViewHolder;
@@ -88,117 +98,188 @@
                 };
 
         mAdapter = new TestCallLogAdapter(getContext(), fakeCallFetcher, fakeContactInfoHelper);
+
         // The cursor used in the tests to store the entries to display.
         mCursor = new MatrixCursor(CallLogQuery._PROJECTION);
         mCursor.moveToFirst();
+
         // The views into which to store the data.
-        mView = new LinearLayout(getContext());
         mViewHolder = CallLogListItemViewHolder.createForTest(getContext());
-        mView.setTag(mViewHolder);
     }
 
     @Override
     protected void tearDown() throws Exception {
         mAdapter = null;
         mCursor = null;
-        mView = null;
         super.tearDown();
     }
 
     @MediumTest
     public void testBindView_NumberOnlyNoCache() {
         createCallLogEntry();
-        mAdapter.changeCursor(mCursor);
 
+        mAdapter.changeCursor(mCursor);
         mAdapter.onBindViewHolder(mViewHolder, 0);
-        assertNameIs(mViewHolder, TEST_NUMBER_1);
+
+        assertNameIs(mViewHolder, TEST_NUMBER);
     }
 
     @MediumTest
     public void testBindView_PrivateCall() {
         createPrivateCallLogEntry();
-        mAdapter.changeCursor(mCursor);
 
+        mAdapter.changeCursor(mCursor);
         mAdapter.onBindViewHolder(mViewHolder, 0);
+
         assertEquals(Calls.PRESENTATION_RESTRICTED, mViewHolder.numberPresentation);
+        assertNull(mViewHolder.primaryActionButtonView.getTag());
+    }
+
+    @MediumTest
+    public void testBindView_UnknownCall() {
+        createUnknownCallLogEntry();
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertEquals(Calls.PRESENTATION_UNKNOWN, mViewHolder.numberPresentation);
+        assertNull(mViewHolder.primaryActionButtonView.getTag());
     }
 
     @MediumTest
     public void testBindView_WithoutQuickContactBadge() {
         createCallLogEntry();
-        mAdapter.changeCursor(mCursor);
 
+        mAdapter.changeCursor(mCursor);
         mAdapter.onBindViewHolder(mViewHolder, 0);
+
         assertFalse(mViewHolder.quickContactView.isEnabled());
     }
 
     @MediumTest
     public void testBindView_CallButton() {
         createCallLogEntry();
-        mAdapter.changeCursor(mCursor);
 
+        mAdapter.changeCursor(mCursor);
         mAdapter.onBindViewHolder(mViewHolder, 0);
 
         // The primaryActionView tag is set when the ViewHolder is binded. If it is possible
         // to place a call to the phone number, a call intent will have been created which
         // starts a phone call to the entry's number.
-        IntentProvider intentProvider =
-                (IntentProvider) mViewHolder.primaryActionButtonView.getTag();
-        Intent intent = intentProvider.getIntent(getContext());
-        assertEquals(TestConstants.CALL_INTENT_ACTION, intent.getAction());
-        assertEquals(Uri.parse("tel:" + TEST_NUMBER_1), intent.getData());
+        assertHasCallAction(mViewHolder);
     }
 
     @MediumTest
     public void testBindView_VoicemailUri() {
         createVoicemailCallLogEntry();
-        mAdapter.changeCursor(mCursor);
 
+        mAdapter.changeCursor(mCursor);
         mAdapter.onBindViewHolder(mViewHolder, 0);
+
         assertEquals(Uri.parse(mViewHolder.voicemailUri),
                 ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, 0));
+        assertNull(mViewHolder.primaryActionButtonView.getTag());
     }
 
-    public void testBindView_NoCallLogCacheNorMemoryCache_EnqueueRequest() {
-        createCallLogEntry();
+    @MediumTest
+    public void testPresentationAfterRebindingViewHolders() {
+        final int increment = 10;
+        final int size = increment * 4;
 
-        // Bind the views of a single row.
+        // Instantiate list of ViewHolders.
+        CallLogListItemViewHolder[] holders = new CallLogListItemViewHolder[size];
+        for (int i = 0; i < size; i++) {
+            holders[i] = CallLogListItemViewHolder.createForTest(getContext());
+        }
+
+        // Add first set of entries to the cursor.
+        for (int i = 0; i < increment; i++) {
+            createCallLogEntry();
+            createPrivateCallLogEntry();
+            createCallLogEntry();
+            createUnknownCallLogEntry();
+        }
+
         mAdapter.changeCursor(mCursor);
-        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        // Verify correct appearance for presentation.
+        for (int i = 0; i < size; i++) {
+            mAdapter.onBindViewHolder(holders[i], i);
+            if (holders[i].numberPresentation == Calls.PRESENTATION_ALLOWED) {
+                assertHasCallAction(holders[i]);
+            } else {
+                assertNull(holders[i].primaryActionButtonView.getTag());
+                assertEquals(holders[i].number, EMPTY_STRING);
+            }
+        }
+
+        // Append the rest of the entries to the cursor. Keep the first set of ViewHolders
+        // so they are updated and not buitl from scratch. This checks for bugs which may
+        // be evident only after the call log is updated.
+        for (int i = 0; i < increment; i++) {
+            createPrivateCallLogEntry();
+            createCallLogEntry();
+            createUnknownCallLogEntry();
+            createCallLogEntry();
+        }
+
+        mCursor.move(size);
+
+        // Verify correct appearnce for presentation.
+        for (int i = 0; i < size; i++) {
+            mAdapter.onBindViewHolder(holders[i], i + size);
+            if (holders[i].numberPresentation == Calls.PRESENTATION_ALLOWED) {
+                assertHasCallAction(holders[i]);
+            } else {
+                assertNull(holders[i].primaryActionButtonView.getTag());
+                assertEquals(holders[i].number, EMPTY_STRING);
+            }
+        }
+    }
+
+   @MediumTest
+   public void testBindView_NoCallLogCacheNorMemoryCache_EnqueueRequest() {
+       createCallLogEntry();
+
+       // Bind the views of a single row.
+       mAdapter.changeCursor(mCursor);
+       mAdapter.onBindViewHolder(mViewHolder, 0);
+
+       // There is one request for contact details.
+       assertEquals(1, mAdapter.getContactInfoCache().requests.size());
+
+       TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0);
+       // It is for the number we need to show.
+       assertEquals(TEST_NUMBER, request.number);
+       // It has the right country.
+       assertEquals(TEST_COUNTRY_ISO, request.countryIso);
+       // Since there is nothing in the cache, it is an immediate request.
+       assertTrue("should be immediate", request.immediate);
+   }
+
+   @MediumTest
+   public void testBindView_CallLogCacheButNoMemoryCache_EnqueueRequest() {
+       createCallLogEntryWithCachedValues(false);
+
+       // Bind the views of a single row.
+       mAdapter.changeCursor(mCursor);
+       mAdapter.onBindViewHolder(mViewHolder, 0);
 
         // There is one request for contact details.
         assertEquals(1, mAdapter.getContactInfoCache().requests.size());
 
         TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0);
-        // It is for the number we need to show.
-        assertEquals(TEST_NUMBER_1, request.number);
-        // It has the right country.
-        assertEquals(TEST_COUNTRY_ISO, request.countryIso);
-        // Since there is nothing in the cache, it is an immediate request.
-        assertTrue("should be immediate", request.immediate);
-    }
 
-    public void testBindView_CallLogCacheButNoMemoryCache_EnqueueRequest() {
-        mCursor.addRow(createCallLogEntryWithCachedValues());
-
-        // Bind the views of a single row.
-        mAdapter.changeCursor(mCursor);
-        mAdapter.onBindViewHolder(mViewHolder, 0);
-
-        // There is one request for contact details.
-        assertEquals(1, mAdapter.getContactInfoCache().requests.size());
-
-        TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0);
         // The values passed to the request, match the ones in the call log cache.
-        assertEquals(TEST_NAME, request.callLogInfo.name);
-        assertEquals(1, request.callLogInfo.type);
-        assertEquals(TEST_NUMBER_LABEL, request.callLogInfo.label);
+        assertEquals(TEST_CACHED_NAME, request.callLogInfo.name);
+        assertEquals(TEST_CACHED_NUMBER_TYPE, request.callLogInfo.type);
+        assertEquals(TEST_CACHED_NUMBER_LABEL, request.callLogInfo.label);
     }
 
-
+    @MediumTest
     public void testBindView_NoCallLogButMemoryCache_EnqueueRequest() {
         createCallLogEntry();
-        mAdapter.injectContactInfoForTest(TEST_NUMBER_1, TEST_COUNTRY_ISO, createContactInfo());
+        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
 
         // Bind the views of a single row.
         mAdapter.changeCursor(mCursor);
@@ -212,9 +293,9 @@
         assertFalse("should not be immediate", request.immediate);
     }
 
+    @MediumTest
     public void testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest() {
-        mCursor.addRow(createCallLogEntryWithCachedValues());
-        mAdapter.injectContactInfoForTest(TEST_NUMBER_1, TEST_COUNTRY_ISO, createContactInfo());
+        createCallLogEntryWithCachedValues(true);
 
         // Bind the views of a single row.
         mAdapter.changeCursor(mCursor);
@@ -224,13 +305,14 @@
         assertEquals(0, mAdapter.getContactInfoCache().requests.size());
     }
 
-    public void testBindView_MismatchBetwenCallLogAndMemoryCache_EnqueueRequest() {
-        mCursor.addRow(createCallLogEntryWithCachedValues());
+    @MediumTest
+    public void testBindView_MismatchBetweenCallLogAndMemoryCache_EnqueueRequest() {
+        createCallLogEntryWithCachedValues(false);
 
         // Contact info contains a different name.
         ContactInfo info = createContactInfo();
         info.name = "new name";
-        mAdapter.injectContactInfoForTest(TEST_NUMBER_1, TEST_COUNTRY_ISO, info);
+        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, info);
 
         // Bind the views of a single row.
         mAdapter.changeCursor(mCursor);
@@ -244,6 +326,98 @@
         assertFalse("should not be immediate", request.immediate);
     }
 
+    @MediumTest
+    public void testBindView_WithCachedName() {
+        createCallLogEntryWithCachedValues(
+                "John Doe",
+                Phone.TYPE_HOME,
+                TEST_CACHED_NUMBER_LABEL);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertNameIs(mViewHolder, "John Doe");
+        assertLabel(mViewHolder, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
+    }
+
+    @MediumTest
+    public void testBindView_UriNumber() {
+        createCallLogEntryWithCachedValues(
+                "sip:johndoe@gmail.com",
+                Calls.INCOMING_TYPE,
+                "John Doe",
+                Phone.TYPE_HOME,
+                TEST_DEFAULT_CUSTOM_LABEL,
+                EMPTY_STRING,
+                false /* inject */);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertNameIs(mViewHolder, "John Doe");
+        assertLabel(mViewHolder, "sip:johndoe@gmail.com", "sip:johndoe@gmail.com");
+    }
+
+    @MediumTest
+    public void testBindView_HomeLabel() {
+        createCallLogEntryWithCachedValues(
+                "John Doe",
+                Phone.TYPE_HOME,
+                TEST_CACHED_NUMBER_LABEL);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertNameIs(mViewHolder, "John Doe");
+        assertLabel(mViewHolder, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
+    }
+
+    @MediumTest
+    public void testBindView_WorkLabel() {
+        createCallLogEntryWithCachedValues(
+                "John Doe",
+                Phone.TYPE_WORK,
+                TEST_CACHED_NUMBER_LABEL);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertNameIs(mViewHolder, "John Doe");
+        assertLabel(mViewHolder, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_WORK));
+    }
+
+    @MediumTest
+    public void testBindView_CustomLabel() {
+        createCallLogEntryWithCachedValues(
+                "John Doe",
+                Phone.TYPE_CUSTOM,
+                TEST_DEFAULT_CUSTOM_LABEL);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertNameIs(mViewHolder, "John Doe");
+        assertLabel(mViewHolder, TEST_FORMATTED_NUMBER, TEST_DEFAULT_CUSTOM_LABEL);
+    }
+
+    @MediumTest
+    public void testBindView_NumberOnlyDbCachedFormattedNumber() {
+        createCallLogEntryWithCachedValues(
+                TEST_NUMBER,
+                Calls.INCOMING_TYPE,
+                EMPTY_STRING,
+                TEST_CACHED_NUMBER_TYPE,
+                TEST_CACHED_NUMBER_LABEL,
+                TEST_FORMATTED_NUMBER,
+                false /* inject */);
+
+        mAdapter.changeCursor(mCursor);
+        mAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertNameIs(mViewHolder, TEST_FORMATTED_NUMBER);
+    }
+
+    @MediumTest
     public void testBindVoicemailPromoCard() {
         createCallLogEntry(TEST_NUMBER_1);
         createCallLogEntry(TEST_NUMBER_1);
@@ -271,51 +445,106 @@
         assertEquals(TEST_NUMBER_3, mViewHolder.number);
     }
 
-    /** Returns a contact info with default values. */
-    private ContactInfo createContactInfo() {
-        ContactInfo info = new ContactInfo();
-        info.number = TEST_NUMBER_1;
-        info.name = TEST_NAME;
-        info.type = TEST_NUMBER_TYPE;
-        info.label = TEST_NUMBER_LABEL;
-        return info;
-    }
-
-    /** Returns a call log entry without cached values. */
     private void createCallLogEntry() {
-        createCallLogEntry(TEST_NUMBER_1);
+        createCallLogEntry(TEST_NUMBER);
     }
 
-    private void  createCallLogEntry(String testNumber) {
-        createCallLogEntry(testNumber, NO_VALUE_SET, NO_VALUE_SET, NO_VALUE_SET, NO_VALUE_SET);
+    private void createCallLogEntry(String testNumber) {
+        createCallLogEntry(testNumber, NO_VALUE_SET, NO_VALUE_SET);
     }
 
     private void createPrivateCallLogEntry() {
-        createCallLogEntry("", Calls.PRESENTATION_RESTRICTED, NO_VALUE_SET, 0, Calls.INCOMING_TYPE);
+        createCallLogEntry(EMPTY_STRING, Calls.PRESENTATION_RESTRICTED, Calls.INCOMING_TYPE);
+    }
+
+    private void createUnknownCallLogEntry() {
+        createCallLogEntry(EMPTY_STRING, Calls.PRESENTATION_UNKNOWN, Calls.INCOMING_TYPE);
     }
 
     private void createVoicemailCallLogEntry() {
-        createCallLogEntry(TEST_NUMBER_1, NO_VALUE_SET, NO_VALUE_SET, NO_VALUE_SET,
-                Calls.VOICEMAIL_TYPE, true /* isVoicemail */);
+        createCallLogEntry(TEST_NUMBER, NO_VALUE_SET, Calls.VOICEMAIL_TYPE);
     }
 
-    private void createCallLogEntry(
-            String number, int presentation, long date, int duration, int type) {
-        createCallLogEntry(number, presentation, date, duration, type, false /* isVoicemail */);
+    private void createCallLogEntry(String number, int presentation, int type) {
+        Object[] values = getValues(number, presentation, type);
+        mCursor.addRow(values);
     }
 
-    private void createCallLogEntry(
+    private void createCallLogEntryWithCachedValues(boolean inject) {
+        createCallLogEntryWithCachedValues(
+                TEST_NUMBER,
+                NO_VALUE_SET,
+                TEST_CACHED_NAME,
+                TEST_CACHED_NUMBER_TYPE,
+                TEST_CACHED_NUMBER_LABEL,
+                EMPTY_STRING,
+                inject);
+    }
+
+    private void createCallLogEntryWithCachedValues(
+            String cachedName, int cachedNumberType, String cachedNumberLabel) {
+        createCallLogEntryWithCachedValues(
+                TEST_NUMBER,
+                NO_VALUE_SET,
+                cachedName,
+                cachedNumberType,
+                cachedNumberLabel,
+                EMPTY_STRING,
+                false /* inject */);
+    }
+
+    /**
+     * Inserts a new call log entry
+     *
+     * It includes the values for the cached contact associated with the number.
+     *
+     * @param number The phone number.
+     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
+     * @param cachedName The name of the contact with this number
+     * @param cachedNumberType The type of the number, from the contact with this number.
+     * @param cachedNumberLabel The label of the number, from the contact with this number.
+     * @param cachedFormattedNumber The formatted number, from the contact with this number.
+     * @param inject Whether to inject the contact info into the adapter's ContactInfoCache.
+    */
+    private void createCallLogEntryWithCachedValues(
+            String number,
+            int type,
+            String cachedName,
+            int cachedNumberType,
+            String cachedNumberLabel,
+            String cachedFormattedNumber,
+            boolean inject) {
+        Object[] values = getValues(number, NO_VALUE_SET, type);
+        values[CallLogQuery.CACHED_NAME] = cachedName;
+        values[CallLogQuery.CACHED_NUMBER_TYPE] = cachedNumberType;
+        values[CallLogQuery.CACHED_NUMBER_LABEL] = cachedNumberLabel;
+        values[CallLogQuery.CACHED_FORMATTED_NUMBER] = cachedFormattedNumber;
+
+        mCursor.addRow(values);
+
+        if (inject) {
+            ContactInfo contactInfo =
+                    createContactInfo(cachedName, cachedNumberType, cachedNumberLabel);
+            mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo);
+        }
+    }
+
+    /**
+     * @param number The phone number.
+     * @param presentation Number representing display rules for "allowed",
+     *               "payphone", "restricted", or "unknown".
+     * @param date In millisec since epoch. Use NOW to use the current time.
+     */
+    private Object[] getValues(
             String number,
             int presentation,
-            long date,
-            int duration,
-            int type,
-            boolean isVoicemail) {
+            int type) {
         Object[] values = CallLogQueryTestUtils.createTestValues();
 
-        values[CallLogQuery.ID] = mCursorSize;
+        values[CallLogQuery.ID] = mCursor.getCount();
         values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
-        values[CallLogQuery.DATE] = date != NO_VALUE_SET ? date : new Date().getTime();
+        values[CallLogQuery.DATE] = new Date().getTime();
+        values[CallLogQuery.DURATION] = mRandom.nextInt(10 * 60);
 
         if (!TextUtils.isEmpty(number)) {
             values[CallLogQuery.NUMBER] = number;
@@ -323,38 +552,68 @@
         if (presentation != NO_VALUE_SET) {
             values[CallLogQuery.NUMBER_PRESENTATION] = presentation;
         }
-        if (duration != NO_VALUE_SET) {
-            values[CallLogQuery.DURATION] = (duration < 0) ? mRandom.nextInt(10 * 60) : duration;
-        }
         if (type != NO_VALUE_SET) {
             values[CallLogQuery.CALL_TYPE] = type;
         }
-        if (isVoicemail) {
-            values[CallLogQuery.VOICEMAIL_URI] =
-                ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, mCursorSize);
+        if (type == Calls.VOICEMAIL_TYPE) {
+            values[CallLogQuery.VOICEMAIL_URI] = ContentUris.withAppendedId(
+                    VoicemailContract.Voicemails.CONTENT_URI, mCursor.getCount());
         }
 
-        mCursor.addRow(values);
-        mCursorSize++;
-    }
-
-    // Returns a call log entry with a cached values.
-    private Object[] createCallLogEntryWithCachedValues() {
-        Object[] values = CallLogQueryTestUtils.createTestValues();
-        values[CallLogQuery.NUMBER] = TEST_NUMBER_1;
-        values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
-        values[CallLogQuery.CACHED_NAME] = TEST_NAME;
-        values[CallLogQuery.CACHED_NUMBER_TYPE] = TEST_NUMBER_TYPE;
-        values[CallLogQuery.CACHED_NUMBER_LABEL] = TEST_NUMBER_LABEL;
         return values;
     }
 
-    // Asserts that the name text view is shown and contains the given text./
+    private ContactInfo createContactInfo() {
+        return createContactInfo(
+                TEST_CACHED_NAME,
+                TEST_CACHED_NUMBER_TYPE,
+                TEST_CACHED_NUMBER_LABEL);
+    }
+
+    /** Returns a contact info with default values. */
+    private ContactInfo createContactInfo(String name, int type, String label) {
+        ContactInfo info = new ContactInfo();
+        info.number = TEST_NUMBER;
+        info.name = name;
+        info.type = type;
+        info.label = label;
+        info.formattedNumber = TEST_FORMATTED_NUMBER;
+        info.normalizedNumber = TEST_NUMBER;
+        info.lookupUri = TEST_LOOKUP_URI;
+        return info;
+    }
+
+    // Asserts that the name text view is shown and contains the given text.
     private void assertNameIs(CallLogListItemViewHolder viewHolder, String name) {
         assertEquals(View.VISIBLE, viewHolder.phoneCallDetailsViews.nameView.getVisibility());
         assertEquals(name, viewHolder.phoneCallDetailsViews.nameView.getText());
     }
 
+    // Asserts that the label text view contains the given text.
+    private void assertLabel(
+            CallLogListItemViewHolder viewHolder, CharSequence number, CharSequence label) {
+        if (label != null) {
+            assertTrue(viewHolder.phoneCallDetailsViews.callLocationAndDate.getText()
+                    .toString().contains(label));
+        }
+    }
+
+    private void assertHasCallAction(CallLogListItemViewHolder viewHolder) {
+        // The primaryActionView tag is set when the ViewHolder is binded. If it is possible
+        // to place a call to the phone number, a call intent will have been created which
+        // starts a phone call to the entry's number.
+        IntentProvider intentProvider =
+                (IntentProvider) viewHolder.primaryActionButtonView.getTag();
+        Intent intent = intentProvider.getIntent(getContext());
+        assertEquals(TestConstants.CALL_INTENT_ACTION, intent.getAction());
+        assertEquals(Uri.parse("tel:" + TEST_NUMBER), intent.getData());
+    }
+
+    /** Returns the label associated with a given phone type. */
+    private CharSequence getTypeLabel(int phoneType) {
+        return Phone.getTypeLabel(getContext().getResources(), phoneType, "");
+    }
+
     /// Subclass of {@link CallLogAdapter} used in tests to intercept certain calls.
     private static final class TestCallLogAdapter extends CallLogAdapter {
         public TestCallLogAdapter(Context context, CallFetcher callFetcher,
diff --git a/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java b/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
deleted file mode 100644
index aa4ad80..0000000
--- a/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * 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.dialer.calllog;
-
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.VoicemailContract;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.util.Log;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.contacts.common.test.FragmentTestActivity;
-import com.android.dialer.CallDetailActivity;
-import com.android.dialer.R;
-import com.android.dialer.util.TestConstants;
-
-import java.util.Date;
-import java.util.Formatter;
-import java.util.HashMap;
-import java.util.Random;
-
-/**
- * Tests for the contact call list activity.
- *
- * Running all tests:
- *
- *   runtest contacts
- * or
- *   adb shell am instrument \
- *     -w com.android.dialer.tests/android.test.InstrumentationTestRunner
- */
-@LargeTest
-public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
-    private static final int RAND_DURATION = -1;
-    private static final long NOW = -1L;
-
-    /** A test value for the URI of a contact. */
-    private static final Uri TEST_LOOKUP_URI = Uri.parse("content://contacts/2");
-    /** A test value for the country ISO of the phone number in the call log. */
-    private static final String TEST_COUNTRY_ISO = "US";
-    /** A phone number to be used in tests. */
-    private static final String TEST_NUMBER = "12125551000";
-    /** The formatted version of {@link #TEST_NUMBER}. */
-    private static final String TEST_FORMATTED_NUMBER = "1 212-555-1000";
-
-    private static final String TEST_DEFAULT_CUSTOM_LABEL = "myLabel";
-
-    /** The activity in which we are hosting the fragment. */
-    private FragmentTestActivity mActivity;
-    private CallLogFragment mFragment;
-    private FrameLayout mParentView;
-    /**
-     * The adapter used by the fragment to build the rows in the call log. We use it with our own in
-     * memory database.
-     */
-    private CallLogAdapter mAdapter;
-    private String mVoicemail;
-
-    // In memory array to hold the rows corresponding to the 'calls' table.
-    private MatrixCursor mCursor;
-    private int mIndex;  // Of the next row.
-
-    private Random mRnd;
-
-    // An item in the call list. All the methods performing checks use it.
-    private CallLogListItemViewHolder mItem;
-
-    // The list of view holderss representing the data in the DB, in reverse order from the DB.
-    private CallLogListItemViewHolder[] mList;
-
-    public CallLogFragmentTest() {
-        super(FragmentTestActivity.class);
-        mIndex = 1;
-        mRnd = new Random();
-    }
-
-    @Override
-    public void setUp() {
-        mActivity = getActivity();
-        // Needed by the CallLogFragment.
-        mActivity.setTheme(R.style.DialtactsTheme);
-
-        // Create the fragment and load it into the activity.
-        mFragment = new CallLogFragment();
-        FragmentManager fragmentManager = mActivity.getFragmentManager();
-        FragmentTransaction transaction = fragmentManager.beginTransaction();
-        transaction.add(FragmentTestActivity.LAYOUT_ID, mFragment);
-        transaction.commitAllowingStateLoss();
-        // Wait for the fragment to be loaded.
-        getInstrumentation().waitForIdleSync();
-
-        final TelephonyManager telephonyManager =
-                (TelephonyManager) mActivity.getSystemService(Context.TELEPHONY_SERVICE);
-        mVoicemail = telephonyManager.getVoiceMailNumber();
-        mAdapter = mFragment.getAdapter();
-        // Do not process requests for details during tests. This would start a background thread,
-        // which makes the tests flaky.
-        mAdapter.disableRequestProcessingForTest();
-        mAdapter.pauseCache();
-        mParentView = new FrameLayout(mActivity);
-        mCursor = new MatrixCursor(CallLogQuery._PROJECTION);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                mAdapter.changeCursor(mCursor);
-            }
-        });
-        getInstrumentation().waitForIdleSync();
-    }
-
-    /**
-     * Checks that the call icon is not visible for private and
-     * unknown numbers.
-     * Use 2 passes, one where new viewHolder are created and one where
-     * half of the total viewHolder are updated and the other half created.
-     */
-    @MediumTest
-    public void testCallViewIsNotVisibleForPrivateAndUnknownNumbers() {
-        final int SIZE = 50;
-        mList = new CallLogListItemViewHolder[SIZE];
-
-        // Insert the first batch of entries.
-        mCursor.moveToFirst();
-        insertRandomEntries(SIZE / 2);
-        int startOfSecondBatch = mCursor.getPosition();
-
-        buildViewListFromDb();
-        checkCallStatus();
-
-        // Append the rest of the entries. We keep the first set of
-        // viewHolder around so they get updated and not built from
-        // scratch, this exposes some bugs that are not there when the
-        // call log is launched for the 1st time but show up when the
-        // call log gets updated afterwards.
-        mCursor.move(startOfSecondBatch);
-        insertRandomEntries(SIZE / 2);
-
-        buildViewListFromDb();
-        checkCallStatus();
-    }
-
-    @MediumTest
-    public void testBindView_NumberOnlyDbCachedFormattedNumber() {
-        mCursor.moveToFirst();
-        Object[] values = getValuesToInsert(TEST_NUMBER,
-                Calls.PRESENTATION_ALLOWED, NOW, 0, Calls.INCOMING_TYPE);
-        values[CallLogQuery.CACHED_FORMATTED_NUMBER] = TEST_FORMATTED_NUMBER;
-        insertValues(values);
-        CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder)
-                mAdapter.onCreateViewHolder(mParentView, /* viewType */ 0);
-        bindViewForTest(viewHolder);
-
-        assertNameIs(viewHolder, TEST_FORMATTED_NUMBER);
-    }
-
-    @MediumTest
-    public void testBindView_WithCachedName() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, TEST_DEFAULT_CUSTOM_LABEL);
-        CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder)
-                mAdapter.onCreateViewHolder(mParentView, /* viewType */ 0);
-        bindViewForTest(viewHolder);
-
-        assertNameIs(viewHolder, "John Doe");
-        assertLabel(viewHolder, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
-    }
-
-    @MediumTest
-    public void testBindView_UriNumber() {
-        mCursor.moveToFirst();
-        insertWithCachedValues("sip:johndoe@gmail.com", NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, TEST_DEFAULT_CUSTOM_LABEL);
-        CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder)
-                mAdapter.onCreateViewHolder(mParentView, /* viewType */ 0);
-        bindViewForTest(viewHolder);
-
-        assertNameIs(viewHolder, "John Doe");
-        assertLabel(viewHolder, "sip:johndoe@gmail.com", "sip:johndoe@gmail.com");
-    }
-
-    @MediumTest
-    public void testBindView_HomeLabel() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, TEST_DEFAULT_CUSTOM_LABEL);
-        CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder)
-                mAdapter.onCreateViewHolder(mParentView, /* viewType */ 0);
-        bindViewForTest(viewHolder);
-
-        assertNameIs(viewHolder, "John Doe");
-        assertLabel(viewHolder, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
-    }
-
-    @MediumTest
-    public void testBindView_WorkLabel() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_WORK, TEST_DEFAULT_CUSTOM_LABEL);
-        CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder)
-                mAdapter.onCreateViewHolder(mParentView, /* viewType */ 0);
-        bindViewForTest(viewHolder);
-
-        assertNameIs(viewHolder, "John Doe");
-        assertLabel(viewHolder, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_WORK));
-    }
-
-    @MediumTest
-    public void testBindView_CustomLabel() {
-        mCursor.moveToFirst();
-        String numberLabel = "My label";
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_CUSTOM, numberLabel);
-        CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder)
-                mAdapter.onCreateViewHolder(mParentView, /* viewType */ 0);
-        bindViewForTest(viewHolder);
-
-        assertNameIs(viewHolder, "John Doe");
-        assertLabel(viewHolder, TEST_FORMATTED_NUMBER, numberLabel);
-    }
-
-
-    /** Returns the label associated with a given phone type. */
-    private CharSequence getTypeLabel(int phoneType) {
-        return Phone.getTypeLabel(getActivity().getResources(), phoneType, "");
-    }
-
-    //
-    // HELPERS to check conditions on the DB/viewHolder
-    //
-    /**
-     * Go over the viewHolder in the list and check to ensure that
-     * callable numbers have an associated call intent, where numbers
-     * which are not callable have a null intent.
-     */
-    private void checkCallStatus() {
-        for (int i = 0; i < mList.length; i++) {
-            if (null == mList[i]) {
-                break;
-            }
-            mItem = (CallLogListItemViewHolder) mList[i];
-            int presentation = getPhoneNumberPresentationForListEntry(i);
-            if (presentation == Calls.PRESENTATION_RESTRICTED ||
-                    presentation == Calls.PRESENTATION_UNKNOWN) {
-                //If number is not callable, the primary action view should have a null tag.
-                assertNull(mItem.primaryActionButtonView.getTag());
-            } else {
-                //If the number is callable, the primary action view should have a non-null tag.
-                assertNotNull(mItem.primaryActionButtonView.getTag());
-
-                IntentProvider intentProvider =
-                        (IntentProvider) mItem.primaryActionButtonView.getTag();
-                Intent callIntent = intentProvider.getIntent(mActivity);
-
-                //The intent should be to make the call
-                assertEquals(TestConstants.CALL_INTENT_ACTION, callIntent.getAction());
-            }
-        }
-    }
-
-    //
-    // HELPERS to setup the tests.
-    //
-
-    /**
-     * Get the Bitmap from the icons in the contacts package.
-     */
-    private Bitmap getBitmap(String resName) {
-        Resources r = mActivity.getResources();
-        int resid = r.getIdentifier(resName, "drawable",
-                getInstrumentation().getTargetContext().getPackageName());
-        BitmapDrawable d = (BitmapDrawable) r.getDrawable(resid);
-        assertNotNull(d);
-        return d.getBitmap();
-    }
-
-    //
-    // HELPERS to build/update the call entries (viewHolder) from the DB.
-    //
-
-    /**
-     * Read the DB and foreach call either update the existing view if
-     * one exists already otherwise create one.
-     * The list is build from a DESC view of the DB (last inserted entry is first).
-     */
-    private void buildViewListFromDb() {
-        int i = 0;
-        mCursor.moveToLast();
-        while (!mCursor.isBeforeFirst()) {
-            if (null == mList[i]) {
-                mList[i] = (CallLogListItemViewHolder)
-                        mAdapter.onCreateViewHolder(mParentView, /* itemType */ 0);
-            }
-            // Bind to the proper position, despite iterating in reverse.
-            bindViewForTest(mList[i], mCursor.getCount() - i - 1);
-            mCursor.moveToPrevious();
-            i++;
-        }
-    }
-
-    /** Returns the number presentation associated with the given entry in {{@link #mList}. */
-    private int getPhoneNumberPresentationForListEntry(int index) {
-        // The entries are added backward, so count from the end of the cursor.
-        mCursor.moveToPosition(mCursor.getCount() - index - 1);
-        return mCursor.getInt(CallLogQuery.NUMBER_PRESENTATION);
-    }
-
-    //
-    // HELPERS to insert numbers in the call log DB.
-    //
-
-    /**
-     * Bind a call log entry view for testing purposes.  Also inflates the action view stub so
-     * unit tests can access the buttons contained within.
-     *
-     * @param view The current call log row.
-     * @param position The position of the item.
-     */
-    private void bindViewForTest(final CallLogListItemViewHolder viewHolder, int position) {
-        mAdapter.onBindViewHolder(viewHolder, position);
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                viewHolder.inflateActionViewStub();
-            }
-        });
-        getInstrumentation().waitForIdleSync();
-    }
-
-    private void bindViewForTest(CallLogListItemViewHolder viewHolder) {
-        bindViewForTest(viewHolder, /* position */ 0);
-    }
-
-    /**
-     * Insert a certain number of random numbers in the DB. Makes sure
-     * there is at least one private and one unknown number in the DB.
-     * @param num Of entries to be inserted.
-     */
-    private void insertRandomEntries(int num) {
-        if (num < 10) {
-            throw new IllegalArgumentException("num should be >= 10");
-        }
-        boolean privateOrUnknownOrVm[];
-        privateOrUnknownOrVm = insertRandomRange(0, num - 2);
-
-        if (privateOrUnknownOrVm[0] && privateOrUnknownOrVm[1]) {
-            insertRandomRange(num - 2, num);
-        } else {
-            insertPrivate(NOW, RAND_DURATION);
-            insertUnknown(NOW, RAND_DURATION);
-        }
-    }
-
-    /**
-     * Insert a new call entry in the test DB.
-     *
-     * It includes the values for the cached contact associated with the number.
-     *
-     * @param number The phone number.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
-     * @param cachedName the name of the contact with this number
-     * @param cachedNumberType the type of the number, from the contact with this number
-     * @param cachedNumberLabel the label of the number, from the contact with this number
-     */
-    private void insertWithCachedValues(String number, long date, int duration, int type,
-            String cachedName, int cachedNumberType, String cachedNumberLabel) {
-        insert(number, Calls.PRESENTATION_ALLOWED, date, duration, type);
-        ContactInfo contactInfo = new ContactInfo();
-        contactInfo.lookupUri = TEST_LOOKUP_URI;
-        contactInfo.name = cachedName;
-        contactInfo.type = cachedNumberType;
-        contactInfo.label = cachedNumberLabel;
-        String formattedNumber = PhoneNumberUtils.formatNumber(number, TEST_COUNTRY_ISO);
-        if (formattedNumber == null) {
-            formattedNumber = number;
-        }
-        contactInfo.formattedNumber = formattedNumber;
-        contactInfo.normalizedNumber = number;
-        contactInfo.photoId = 0;
-        mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo);
-    }
-
-    /**
-     * Insert a new call entry in the test DB.
-     * @param number The phone number.
-     * @param presentation Number representing display rules for "allowed",
-     *               "payphone", "restricted", or "unknown".
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
-     */
-    private void insert(String number, int presentation, long date, int duration, int type) {
-        insertValues(getValuesToInsert(number, presentation, date, duration, type));
-    }
-
-    /** Inserts the given values in the cursor. */
-    private void insertValues(Object[] values) {
-        mCursor.addRow(values);
-        ++mIndex;
-    }
-
-    /**
-     * Returns the values for a new call entry.
-     *
-     * @param number The phone number.
-     * @param presentation Number representing display rules for "allowed",
-     *               "payphone", "restricted", or "unknown".
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
-     */
-    private Object[] getValuesToInsert(String number, int presentation,
-            long date, int duration, int type) {
-        Object[] values = CallLogQueryTestUtils.createTestValues();
-        values[CallLogQuery.ID] = mIndex;
-        values[CallLogQuery.NUMBER] = number;
-        values[CallLogQuery.NUMBER_PRESENTATION] = presentation;
-        values[CallLogQuery.DATE] = date == NOW ? new Date().getTime() : date;
-        values[CallLogQuery.DURATION] = duration < 0 ? mRnd.nextInt(10 * 60) : duration;
-        if (mVoicemail != null && mVoicemail.equals(number)) {
-            assertEquals(Calls.OUTGOING_TYPE, type);
-        }
-        values[CallLogQuery.CALL_TYPE] = type;
-        values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
-        return values;
-    }
-
-    /**
-     * Insert a new private call entry in the test DB.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertPrivate(long date, int duration) {
-        insert("", Calls.PRESENTATION_RESTRICTED, date, duration, Calls.INCOMING_TYPE);
-    }
-
-    /**
-     * Insert a new unknown call entry in the test DB.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertUnknown(long date, int duration) {
-        insert("", Calls.PRESENTATION_UNKNOWN, date, duration, Calls.INCOMING_TYPE);
-    }
-
-    /**
-     * Insert a new call to voicemail entry in the test DB.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertCalltoVoicemail(long date, int duration) {
-        // mVoicemail may be null
-        if (mVoicemail != null) {
-            insert(mVoicemail, Calls.PRESENTATION_ALLOWED, date, duration, Calls.OUTGOING_TYPE);
-        }
-    }
-
-    /**
-     * Insert a range [start, end) of random numbers in the DB. For
-     * each row, there is a 1/10 probability that the number will be
-     * marked as PRIVATE or UNKNOWN or VOICEMAIL. For regular numbers, a number is
-     * inserted, its last 4 digits will be the number of the iteration
-     * in the range.
-     * @param start Of the range.
-     * @param end Of the range (excluded).
-     * @return An array with 2 booleans [0 = private number, 1 =
-     * unknown number, 2 = voicemail] to indicate if at least one
-     * private or unknown or voicemail number has been inserted. Since
-     * the numbers are random some tests may want to enforce the
-     * insertion of such numbers.
-     */
-    // TODO: Should insert numbers with contact entries too.
-    private boolean[] insertRandomRange(int start, int end) {
-        boolean[] privateOrUnknownOrVm = new boolean[] {false, false, false};
-
-        for (int i = start; i < end; i++ ) {
-            int type = mRnd.nextInt(10);
-
-            if (0 == type) {
-                insertPrivate(NOW, RAND_DURATION);
-                privateOrUnknownOrVm[0] = true;
-            } else if (1 == type) {
-                insertUnknown(NOW, RAND_DURATION);
-                privateOrUnknownOrVm[1] = true;
-            } else if (2 == type) {
-                insertCalltoVoicemail(NOW, RAND_DURATION);
-                privateOrUnknownOrVm[2] = true;
-            } else {
-                int inout = mRnd.nextBoolean() ? Calls.OUTGOING_TYPE :  Calls.INCOMING_TYPE;
-                final Formatter formatter = new Formatter();
-                String number = formatter.format("1800123%04d", i).toString();
-                formatter.close();
-                insert(number, Calls.PRESENTATION_ALLOWED, NOW, RAND_DURATION, inout);
-            }
-        }
-        return privateOrUnknownOrVm;
-    }
-
-    /** Asserts that the name text view is shown and contains the given text. */
-    private void assertNameIs(CallLogListItemViewHolder viewHolder, String name) {
-        assertEquals(View.VISIBLE, viewHolder.phoneCallDetailsViews.nameView.getVisibility());
-        assertEquals(name, viewHolder.phoneCallDetailsViews.nameView.getText().toString());
-    }
-
-    /** Asserts that the label text view contains the given text. */
-    private void assertLabel(CallLogListItemViewHolder viewHolder, CharSequence number,
-            CharSequence label) {
-        if (label != null) {
-            assertTrue(viewHolder.phoneCallDetailsViews.callLocationAndDate.getText()
-                    .toString().contains(label));
-        }
-    }
-}
