diff --git a/java/com/android/contacts/common/extensions/PhoneDirectoryExtender.java b/java/com/android/contacts/common/extensions/PhoneDirectoryExtender.java
index 6c932daf..5e9753f 100644
--- a/java/com/android/contacts/common/extensions/PhoneDirectoryExtender.java
+++ b/java/com/android/contacts/common/extensions/PhoneDirectoryExtender.java
@@ -17,18 +17,10 @@
 import android.content.Context;
 import android.net.Uri;
 import android.support.annotation.Nullable;
-import com.android.contacts.common.list.DirectoryPartition;
-import java.util.List;
 
 /** An interface for adding extended phone directories. */
 public interface PhoneDirectoryExtender {
 
-  /**
-   * Return a list of extended directories to add. May return null if no directories are to be
-   * added.
-   */
-  List<DirectoryPartition> getExtendedDirectories(Context context);
-
   /** returns true if the nearby places directory is enabled. */
   boolean isEnabled(Context context);
 
diff --git a/java/com/android/contacts/common/extensions/PhoneDirectoryExtenderStub.java b/java/com/android/contacts/common/extensions/PhoneDirectoryExtenderStub.java
index 4c3d3d1..5b3cb99 100644
--- a/java/com/android/contacts/common/extensions/PhoneDirectoryExtenderStub.java
+++ b/java/com/android/contacts/common/extensions/PhoneDirectoryExtenderStub.java
@@ -17,19 +17,11 @@
 import android.content.Context;
 import android.net.Uri;
 import android.support.annotation.Nullable;
-import com.android.contacts.common.list.DirectoryPartition;
-import java.util.Collections;
-import java.util.List;
 
 /** No-op implementation for phone directory extender. */
 class PhoneDirectoryExtenderStub implements PhoneDirectoryExtender {
 
   @Override
-  public List<DirectoryPartition> getExtendedDirectories(Context context) {
-    return Collections.emptyList();
-  }
-
-  @Override
   public boolean isEnabled(Context context) {
     return false;
   }
diff --git a/java/com/android/contacts/common/format/TextHighlighter.java b/java/com/android/contacts/common/format/TextHighlighter.java
deleted file mode 100644
index f397f04..0000000
--- a/java/com/android/contacts/common/format/TextHighlighter.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.common.format;
-
-import android.text.SpannableString;
-import android.text.style.CharacterStyle;
-import android.text.style.StyleSpan;
-import android.widget.TextView;
-
-/** Highlights the text in a text field. */
-public class TextHighlighter {
-
-  private int mTextStyle;
-
-  private CharacterStyle mTextStyleSpan;
-
-  public TextHighlighter(int textStyle) {
-    mTextStyle = textStyle;
-    mTextStyleSpan = getStyleSpan();
-  }
-
-  /**
-   * Sets the text on the given text view, highlighting the word that matches the given prefix.
-   *
-   * @param view the view on which to set the text
-   * @param text the string to use as the text
-   * @param prefix the prefix to look for
-   */
-  public void setPrefixText(TextView view, String text, String prefix) {
-    view.setText(applyPrefixHighlight(text, prefix));
-  }
-
-  private CharacterStyle getStyleSpan() {
-    return new StyleSpan(mTextStyle);
-  }
-
-  /**
-   * Applies highlight span to the text.
-   *
-   * @param text Text sequence to be highlighted.
-   * @param start Start position of the highlight sequence.
-   * @param end End position of the highlight sequence.
-   */
-  public void applyMaskingHighlight(SpannableString text, int start, int end) {
-    /** Sets text color of the masked locations to be highlighted. */
-    text.setSpan(getStyleSpan(), start, end, 0);
-  }
-
-  /**
-   * Returns a CharSequence which highlights the given prefix if found in the given text.
-   *
-   * @param text the text to which to apply the highlight
-   * @param prefix the prefix to look for
-   */
-  public CharSequence applyPrefixHighlight(CharSequence text, String prefix) {
-    if (prefix == null) {
-      return text;
-    }
-
-    // Skip non-word characters at the beginning of prefix.
-    int prefixStart = 0;
-    while (prefixStart < prefix.length()
-        && !Character.isLetterOrDigit(prefix.charAt(prefixStart))) {
-      prefixStart++;
-    }
-    final String trimmedPrefix = prefix.substring(prefixStart);
-
-    int index = indexOfWordPrefix(text, trimmedPrefix);
-    if (index != -1) {
-      final SpannableString result = new SpannableString(text);
-      result.setSpan(mTextStyleSpan, index, index + trimmedPrefix.length(), 0 /* flags */);
-      return result;
-    } else {
-      return text;
-    }
-  }
-
-  /**
-   * Finds the index of the first word that starts with the given prefix.
-   *
-   * <p>If not found, returns -1.
-   *
-   * @param text the text in which to search for the prefix
-   * @param prefix the text to find, in upper case letters
-   */
-  public static int indexOfWordPrefix(CharSequence text, String prefix) {
-    if (prefix == null || text == null) {
-      return -1;
-    }
-
-    int textLength = text.length();
-    int prefixLength = prefix.length();
-
-    if (prefixLength == 0 || textLength < prefixLength) {
-      return -1;
-    }
-
-    int i = 0;
-    while (i < textLength) {
-      // Skip non-word characters
-      while (i < textLength && !Character.isLetterOrDigit(text.charAt(i))) {
-        i++;
-      }
-
-      if (i + prefixLength > textLength) {
-        return -1;
-      }
-
-      // Compare the prefixes
-      int j;
-      for (j = 0; j < prefixLength; j++) {
-        if (Character.toUpperCase(text.charAt(i + j)) != prefix.charAt(j)) {
-          break;
-        }
-      }
-      if (j == prefixLength) {
-        return i;
-      }
-
-      // Skip this word
-      while (i < textLength && Character.isLetterOrDigit(text.charAt(i))) {
-        i++;
-      }
-    }
-
-    return -1;
-  }
-}
diff --git a/java/com/android/contacts/common/list/AutoScrollListView.java b/java/com/android/contacts/common/list/AutoScrollListView.java
deleted file mode 100644
index 8d6455f..0000000
--- a/java/com/android/contacts/common/list/AutoScrollListView.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.widget.ListView;
-
-/**
- * A ListView that can be asked to scroll (smoothly or otherwise) to a specific position. This class
- * takes advantage of similar functionality that exists in {@link ListView} and enhances it.
- */
-public class AutoScrollListView extends ListView {
-
-  /** Position the element at about 1/3 of the list height */
-  private static final float PREFERRED_SELECTION_OFFSET_FROM_TOP = 0.33f;
-
-  private int mRequestedScrollPosition = -1;
-  private boolean mSmoothScrollRequested;
-
-  public AutoScrollListView(Context context) {
-    super(context);
-  }
-
-  public AutoScrollListView(Context context, AttributeSet attrs) {
-    super(context, attrs);
-  }
-
-  public AutoScrollListView(Context context, AttributeSet attrs, int defStyle) {
-    super(context, attrs, defStyle);
-  }
-
-  /**
-   * Brings the specified position to view by optionally performing a jump-scroll maneuver: first it
-   * jumps to some position near the one requested and then does a smooth scroll to the requested
-   * position. This creates an impression of full smooth scrolling without actually traversing the
-   * entire list. If smooth scrolling is not requested, instantly positions the requested item at a
-   * preferred offset.
-   */
-  public void requestPositionToScreen(int position, boolean smoothScroll) {
-    mRequestedScrollPosition = position;
-    mSmoothScrollRequested = smoothScroll;
-    requestLayout();
-  }
-
-  @Override
-  protected void layoutChildren() {
-    super.layoutChildren();
-    if (mRequestedScrollPosition == -1) {
-      return;
-    }
-
-    final int position = mRequestedScrollPosition;
-    mRequestedScrollPosition = -1;
-
-    int firstPosition = getFirstVisiblePosition() + 1;
-    int lastPosition = getLastVisiblePosition();
-    if (position >= firstPosition && position <= lastPosition) {
-      return; // Already on screen
-    }
-
-    final int offset = (int) (getHeight() * PREFERRED_SELECTION_OFFSET_FROM_TOP);
-    if (!mSmoothScrollRequested) {
-      setSelectionFromTop(position, offset);
-
-      // Since we have changed the scrolling position, we need to redo child layout
-      // Calling "requestLayout" in the middle of a layout pass has no effect,
-      // so we call layoutChildren explicitly
-      super.layoutChildren();
-
-    } else {
-      // We will first position the list a couple of screens before or after
-      // the new selection and then scroll smoothly to it.
-      int twoScreens = (lastPosition - firstPosition) * 2;
-      int preliminaryPosition;
-      if (position < firstPosition) {
-        preliminaryPosition = position + twoScreens;
-        if (preliminaryPosition >= getCount()) {
-          preliminaryPosition = getCount() - 1;
-        }
-        if (preliminaryPosition < firstPosition) {
-          setSelection(preliminaryPosition);
-          super.layoutChildren();
-        }
-      } else {
-        preliminaryPosition = position - twoScreens;
-        if (preliminaryPosition < 0) {
-          preliminaryPosition = 0;
-        }
-        if (preliminaryPosition > lastPosition) {
-          setSelection(preliminaryPosition);
-          super.layoutChildren();
-        }
-      }
-
-      smoothScrollToPositionFromTop(position, offset);
-    }
-  }
-
-  @Override
-  protected void onLayout(boolean changed, int l, int t, int r, int b) {
-    super.onLayout(changed, l, t, r, b);
-
-    // Workaround for a bug and a bug.
-    if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.N
-        || android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
-      layoutChildren();
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/ContactEntryListAdapter.java b/java/com/android/contacts/common/list/ContactEntryListAdapter.java
deleted file mode 100644
index 413a1de..0000000
--- a/java/com/android/contacts/common/list/ContactEntryListAdapter.java
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.content.CursorLoader;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Directory;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.QuickContactBadge;
-import android.widget.SectionIndexer;
-import android.widget.TextView;
-import com.android.contacts.common.ContactsUtils;
-import com.android.contacts.common.R;
-import com.android.contacts.common.util.SearchUtil;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.cp2.DirectoryCompat;
-import com.android.dialer.compat.CompatUtils;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.contactphoto.ContactPhotoManager;
-import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest;
-import com.android.dialer.logging.InteractionEvent;
-import com.android.dialer.logging.Logger;
-import java.util.HashSet;
-
-/**
- * Common base class for various contact-related lists, e.g. contact list, phone number list etc.
- */
-public abstract class ContactEntryListAdapter extends IndexerListAdapter {
-
-  /**
-   * Indicates whether the {@link Directory#LOCAL_INVISIBLE} directory should be included in the
-   * search.
-   */
-  public static final boolean LOCAL_INVISIBLE_DIRECTORY_ENABLED = false;
-
-  private int mDisplayOrder;
-  private int mSortOrder;
-
-  private boolean mDisplayPhotos;
-  private boolean mCircularPhotos = true;
-  private boolean mQuickContactEnabled;
-  private boolean mAdjustSelectionBoundsEnabled;
-
-  /** The root view of the fragment that this adapter is associated with. */
-  private View mFragmentRootView;
-
-  private ContactPhotoManager mPhotoLoader;
-
-  private String mQueryString;
-  private String mUpperCaseQueryString;
-  private boolean mSearchMode;
-  private int mDirectorySearchMode;
-  private int mDirectoryResultLimit = Integer.MAX_VALUE;
-
-  private boolean mEmptyListEnabled = true;
-
-  private boolean mSelectionVisible;
-
-  private ContactListFilter mFilter;
-  private boolean mDarkTheme = false;
-
-  public static final int SUGGESTIONS_LOADER_ID = 0;
-
-  /** Resource used to provide header-text for default filter. */
-  private CharSequence mDefaultFilterHeaderText;
-
-  public ContactEntryListAdapter(Context context) {
-    super(context);
-    setDefaultFilterHeaderText(R.string.local_search_label);
-    addPartitions();
-  }
-
-  /**
-   * @param fragmentRootView Root view of the fragment. This is used to restrict the scope of image
-   *     loading requests that get cancelled on cursor changes.
-   */
-  protected void setFragmentRootView(View fragmentRootView) {
-    mFragmentRootView = fragmentRootView;
-  }
-
-  protected void setDefaultFilterHeaderText(int resourceId) {
-    mDefaultFilterHeaderText = getContext().getResources().getText(resourceId);
-  }
-
-  @Override
-  protected ContactListItemView newView(
-      Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
-    final ContactListItemView view = new ContactListItemView(context, null);
-    view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
-    view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled());
-    return view;
-  }
-
-  @Override
-  protected void bindView(View itemView, int partition, Cursor cursor, int position) {
-    final ContactListItemView view = (ContactListItemView) itemView;
-    view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
-    bindWorkProfileIcon(view, partition);
-  }
-
-  @Override
-  protected View createPinnedSectionHeaderView(Context context, ViewGroup parent) {
-    return new ContactListPinnedHeaderView(context, null, parent);
-  }
-
-  @Override
-  protected void setPinnedSectionTitle(View pinnedHeaderView, String title) {
-    ((ContactListPinnedHeaderView) pinnedHeaderView).setSectionHeaderTitle(title);
-  }
-
-  protected void addPartitions() {
-    if (ConfigProviderBindings.get(getContext()).getBoolean("p13n_ranker_should_enable", false)) {
-      addPartition(createSuggestionsDirectoryPartition());
-    }
-    addPartition(createDefaultDirectoryPartition());
-  }
-
-  protected DirectoryPartition createSuggestionsDirectoryPartition() {
-    DirectoryPartition partition = new DirectoryPartition(true, true);
-    partition.setDirectoryId(SUGGESTIONS_LOADER_ID);
-    partition.setDirectoryType(getContext().getString(R.string.contact_suggestions));
-    partition.setPriorityDirectory(true);
-    partition.setPhotoSupported(true);
-    partition.setLabel(getContext().getString(R.string.local_suggestions_search_label));
-    return partition;
-  }
-
-  protected DirectoryPartition createDefaultDirectoryPartition() {
-    DirectoryPartition partition = new DirectoryPartition(true, true);
-    partition.setDirectoryId(Directory.DEFAULT);
-    partition.setDirectoryType(getContext().getString(R.string.contactsList));
-    partition.setPriorityDirectory(true);
-    partition.setPhotoSupported(true);
-    partition.setLabel(mDefaultFilterHeaderText.toString());
-    return partition;
-  }
-
-  /**
-   * Remove all directories after the default directory. This is typically used when contacts list
-   * screens are asked to exit the search mode and thus need to remove all remote directory results
-   * for the search.
-   *
-   * <p>This code assumes that the default directory and directories before that should not be
-   * deleted (e.g. Join screen has "suggested contacts" directory before the default director, and
-   * we should not remove the directory).
-   */
-  public void removeDirectoriesAfterDefault() {
-    final int partitionCount = getPartitionCount();
-    for (int i = partitionCount - 1; i >= 0; i--) {
-      final Partition partition = getPartition(i);
-      if ((partition instanceof DirectoryPartition)
-          && ((DirectoryPartition) partition).getDirectoryId() == Directory.DEFAULT) {
-        break;
-      } else {
-        removePartition(i);
-      }
-    }
-  }
-
-  protected int getPartitionByDirectoryId(long id) {
-    int count = getPartitionCount();
-    for (int i = 0; i < count; i++) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition) {
-        if (((DirectoryPartition) partition).getDirectoryId() == id) {
-          return i;
-        }
-      }
-    }
-    return -1;
-  }
-
-  protected DirectoryPartition getDirectoryById(long id) {
-    int count = getPartitionCount();
-    for (int i = 0; i < count; i++) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition) {
-        final DirectoryPartition directoryPartition = (DirectoryPartition) partition;
-        if (directoryPartition.getDirectoryId() == id) {
-          return directoryPartition;
-        }
-      }
-    }
-    return null;
-  }
-
-  public abstract void configureLoader(CursorLoader loader, long directoryId);
-
-  /** Marks all partitions as "loading" */
-  public void onDataReload() {
-    boolean notify = false;
-    int count = getPartitionCount();
-    for (int i = 0; i < count; i++) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition) {
-        DirectoryPartition directoryPartition = (DirectoryPartition) partition;
-        if (!directoryPartition.isLoading()) {
-          notify = true;
-        }
-        directoryPartition.setStatus(DirectoryPartition.STATUS_NOT_LOADED);
-      }
-    }
-    if (notify) {
-      notifyDataSetChanged();
-    }
-  }
-
-  @Override
-  public void clearPartitions() {
-    int count = getPartitionCount();
-    for (int i = 0; i < count; i++) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition) {
-        DirectoryPartition directoryPartition = (DirectoryPartition) partition;
-        directoryPartition.setStatus(DirectoryPartition.STATUS_NOT_LOADED);
-      }
-    }
-    super.clearPartitions();
-  }
-
-  public boolean isSearchMode() {
-    return mSearchMode;
-  }
-
-  public void setSearchMode(boolean flag) {
-    mSearchMode = flag;
-  }
-
-  public String getQueryString() {
-    return mQueryString;
-  }
-
-  public void setQueryString(String queryString) {
-    mQueryString = queryString;
-    if (TextUtils.isEmpty(queryString)) {
-      mUpperCaseQueryString = null;
-    } else {
-      mUpperCaseQueryString = SearchUtil.cleanStartAndEndOfSearchQuery(queryString.toUpperCase());
-    }
-
-    // Enable default partition header if in search mode (including zero-suggest).
-    if (mQueryString != null) {
-      setDefaultPartitionHeader(true);
-    }
-  }
-
-  public String getUpperCaseQueryString() {
-    return mUpperCaseQueryString;
-  }
-
-  public int getDirectorySearchMode() {
-    return mDirectorySearchMode;
-  }
-
-  public void setDirectorySearchMode(int mode) {
-    mDirectorySearchMode = mode;
-  }
-
-  public int getDirectoryResultLimit() {
-    return mDirectoryResultLimit;
-  }
-
-  public void setDirectoryResultLimit(int limit) {
-    this.mDirectoryResultLimit = limit;
-  }
-
-  public int getDirectoryResultLimit(DirectoryPartition directoryPartition) {
-    final int limit = directoryPartition.getResultLimit();
-    return limit == DirectoryPartition.RESULT_LIMIT_DEFAULT ? mDirectoryResultLimit : limit;
-  }
-
-  public int getContactNameDisplayOrder() {
-    return mDisplayOrder;
-  }
-
-  public void setContactNameDisplayOrder(int displayOrder) {
-    mDisplayOrder = displayOrder;
-  }
-
-  public int getSortOrder() {
-    return mSortOrder;
-  }
-
-  public void setSortOrder(int sortOrder) {
-    mSortOrder = sortOrder;
-  }
-
-  protected ContactPhotoManager getPhotoLoader() {
-    return mPhotoLoader;
-  }
-
-  public void setPhotoLoader(ContactPhotoManager photoLoader) {
-    mPhotoLoader = photoLoader;
-  }
-
-  public boolean getDisplayPhotos() {
-    return mDisplayPhotos;
-  }
-
-  public void setDisplayPhotos(boolean displayPhotos) {
-    mDisplayPhotos = displayPhotos;
-  }
-
-  public boolean getCircularPhotos() {
-    return mCircularPhotos;
-  }
-
-  public boolean isSelectionVisible() {
-    return mSelectionVisible;
-  }
-
-  public void setSelectionVisible(boolean flag) {
-    this.mSelectionVisible = flag;
-  }
-
-  public boolean isQuickContactEnabled() {
-    return mQuickContactEnabled;
-  }
-
-  public void setQuickContactEnabled(boolean quickContactEnabled) {
-    mQuickContactEnabled = quickContactEnabled;
-  }
-
-  public boolean isAdjustSelectionBoundsEnabled() {
-    return mAdjustSelectionBoundsEnabled;
-  }
-
-  public void setAdjustSelectionBoundsEnabled(boolean enabled) {
-    mAdjustSelectionBoundsEnabled = enabled;
-  }
-
-  public void setProfileExists(boolean exists) {
-    // Stick the "ME" header for the profile
-    if (exists) {
-      setSectionHeader(R.string.user_profile_contacts_list_header, /* # of ME */ 1);
-    }
-  }
-
-  private void setSectionHeader(int resId, int numberOfItems) {
-    SectionIndexer indexer = getIndexer();
-    if (indexer != null) {
-      ((ContactsSectionIndexer) indexer)
-          .setProfileAndFavoritesHeader(getContext().getString(resId), numberOfItems);
-    }
-  }
-
-  public void setDarkTheme(boolean value) {
-    mDarkTheme = value;
-  }
-
-  /** Updates partitions according to the directory meta-data contained in the supplied cursor. */
-  public void changeDirectories(Cursor cursor) {
-    if (cursor.getCount() == 0) {
-      // Directory table must have at least local directory, without which this adapter will
-      // enter very weird state.
-      LogUtil.i(
-          "ContactEntryListAdapter.changeDirectories",
-          "directory search loader returned an empty cursor, which implies we have "
-              + "no directory entries.",
-          new RuntimeException());
-      return;
-    }
-    HashSet<Long> directoryIds = new HashSet<Long>();
-
-    int idColumnIndex = cursor.getColumnIndex(Directory._ID);
-    int directoryTypeColumnIndex = cursor.getColumnIndex(DirectoryListLoader.DIRECTORY_TYPE);
-    int displayNameColumnIndex = cursor.getColumnIndex(Directory.DISPLAY_NAME);
-    int photoSupportColumnIndex = cursor.getColumnIndex(Directory.PHOTO_SUPPORT);
-
-    // TODO preserve the order of partition to match those of the cursor
-    // Phase I: add new directories
-    cursor.moveToPosition(-1);
-    while (cursor.moveToNext()) {
-      long id = cursor.getLong(idColumnIndex);
-      directoryIds.add(id);
-      if (getPartitionByDirectoryId(id) == -1) {
-        DirectoryPartition partition = new DirectoryPartition(false, true);
-        partition.setDirectoryId(id);
-        if (DirectoryCompat.isRemoteDirectoryId(id)) {
-          if (DirectoryCompat.isEnterpriseDirectoryId(id)) {
-            partition.setLabel(mContext.getString(R.string.directory_search_label_work));
-          } else {
-            partition.setLabel(mContext.getString(R.string.directory_search_label));
-          }
-        } else {
-          if (DirectoryCompat.isEnterpriseDirectoryId(id)) {
-            partition.setLabel(mContext.getString(R.string.list_filter_phones_work));
-          } else {
-            partition.setLabel(mDefaultFilterHeaderText.toString());
-          }
-        }
-        partition.setDirectoryType(cursor.getString(directoryTypeColumnIndex));
-        partition.setDisplayName(cursor.getString(displayNameColumnIndex));
-        int photoSupport = cursor.getInt(photoSupportColumnIndex);
-        partition.setPhotoSupported(
-            photoSupport == Directory.PHOTO_SUPPORT_THUMBNAIL_ONLY
-                || photoSupport == Directory.PHOTO_SUPPORT_FULL);
-        addPartition(partition);
-      }
-    }
-
-    // Phase II: remove deleted directories
-    int count = getPartitionCount();
-    for (int i = count; --i >= 0; ) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition) {
-        long id = ((DirectoryPartition) partition).getDirectoryId();
-        if (!directoryIds.contains(id)) {
-          removePartition(i);
-        }
-      }
-    }
-
-    invalidate();
-    notifyDataSetChanged();
-  }
-
-  @Override
-  public void changeCursor(int partitionIndex, Cursor cursor) {
-    if (partitionIndex >= getPartitionCount()) {
-      // There is no partition for this data
-      return;
-    }
-
-    Partition partition = getPartition(partitionIndex);
-    if (partition instanceof DirectoryPartition) {
-      ((DirectoryPartition) partition).setStatus(DirectoryPartition.STATUS_LOADED);
-    }
-
-    if (mDisplayPhotos && mPhotoLoader != null && isPhotoSupported(partitionIndex)) {
-      mPhotoLoader.refreshCache();
-    }
-
-    super.changeCursor(partitionIndex, cursor);
-
-    if (isSectionHeaderDisplayEnabled() && partitionIndex == getIndexedPartition()) {
-      updateIndexer(cursor);
-    }
-
-    // When the cursor changes, cancel any pending asynchronous photo loads.
-    mPhotoLoader.cancelPendingRequests(mFragmentRootView);
-  }
-
-  public void changeCursor(Cursor cursor) {
-    changeCursor(0, cursor);
-  }
-
-  /** Updates the indexer, which is used to produce section headers. */
-  private void updateIndexer(Cursor cursor) {
-    if (cursor == null || cursor.isClosed()) {
-      setIndexer(null);
-      return;
-    }
-
-    Bundle bundle = cursor.getExtras();
-    if (bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES)
-        && bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS)) {
-      String[] sections = bundle.getStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
-      int[] counts = bundle.getIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
-
-      if (getExtraStartingSection()) {
-        // Insert an additional unnamed section at the top of the list.
-        String[] allSections = new String[sections.length + 1];
-        int[] allCounts = new int[counts.length + 1];
-        for (int i = 0; i < sections.length; i++) {
-          allSections[i + 1] = sections[i];
-          allCounts[i + 1] = counts[i];
-        }
-        allCounts[0] = 1;
-        allSections[0] = "";
-        setIndexer(new ContactsSectionIndexer(allSections, allCounts));
-      } else {
-        setIndexer(new ContactsSectionIndexer(sections, counts));
-      }
-    } else {
-      setIndexer(null);
-    }
-  }
-
-  protected boolean getExtraStartingSection() {
-    return false;
-  }
-
-  @Override
-  public int getViewTypeCount() {
-    // We need a separate view type for each item type, plus another one for
-    // each type with header, plus one for "other".
-    return getItemViewTypeCount() * 2 + 1;
-  }
-
-  @Override
-  public int getItemViewType(int partitionIndex, int position) {
-    int type = super.getItemViewType(partitionIndex, position);
-    if (!isUserProfile(position)
-        && isSectionHeaderDisplayEnabled()
-        && partitionIndex == getIndexedPartition()) {
-      Placement placement = getItemPlacementInSection(position);
-      return placement.firstInSection ? type : getItemViewTypeCount() + type;
-    } else {
-      return type;
-    }
-  }
-
-  @Override
-  public boolean isEmpty() {
-    // TODO
-    //        if (contactsListActivity.mProviderStatus != ProviderStatus.STATUS_NORMAL) {
-    //            return true;
-    //        }
-
-    if (!mEmptyListEnabled) {
-      return false;
-    } else if (isSearchMode()) {
-      return TextUtils.isEmpty(getQueryString());
-    } else {
-      return super.isEmpty();
-    }
-  }
-
-  public boolean isLoading() {
-    int count = getPartitionCount();
-    for (int i = 0; i < count; i++) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition && ((DirectoryPartition) partition).isLoading()) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /** Configures visibility parameters for the directory partitions. */
-  public void configurePartitionsVisibility(boolean isInSearchMode) {
-    for (int i = 0; i < getPartitionCount(); i++) {
-      setShowIfEmpty(i, false);
-      setHasHeader(i, isInSearchMode);
-    }
-  }
-
-  // Sets header for the default partition.
-  private void setDefaultPartitionHeader(boolean setHeader) {
-    // Iterate in reverse here to ensure the first DEFAULT directory has header.
-    // Both "Suggestions" and "All Contacts" directories have DEFAULT id.
-    int defaultPartitionIndex = -1;
-    for (int i = getPartitionCount() - 1; i >= 0; i--) {
-      Partition partition = getPartition(i);
-      if (partition instanceof DirectoryPartition
-          && ((DirectoryPartition) partition).getDirectoryId() == Directory.DEFAULT) {
-        defaultPartitionIndex = i;
-      }
-    }
-    setHasHeader(defaultPartitionIndex, setHeader);
-  }
-
-  @Override
-  protected View newHeaderView(Context context, int partition, Cursor cursor, ViewGroup parent) {
-    LayoutInflater inflater = LayoutInflater.from(context);
-    View view = inflater.inflate(R.layout.directory_header, parent, false);
-    if (!getPinnedPartitionHeadersEnabled()) {
-      // If the headers are unpinned, there is no need for their background
-      // color to be non-transparent. Setting this transparent reduces maintenance for
-      // non-pinned headers. We don't need to bother synchronizing the activity's
-      // background color with the header background color.
-      view.setBackground(null);
-    }
-    return view;
-  }
-
-  protected void bindWorkProfileIcon(final ContactListItemView view, int partitionId) {
-    final Partition partition = getPartition(partitionId);
-    if (partition instanceof DirectoryPartition) {
-      final DirectoryPartition directoryPartition = (DirectoryPartition) partition;
-      final long directoryId = directoryPartition.getDirectoryId();
-      final long userType = ContactsUtils.determineUserType(directoryId, null);
-      view.setWorkProfileIconEnabled(userType == ContactsUtils.USER_TYPE_WORK);
-    }
-  }
-
-  @Override
-  protected void bindHeaderView(View view, int partitionIndex, Cursor cursor) {
-    Partition partition = getPartition(partitionIndex);
-    if (!(partition instanceof DirectoryPartition)) {
-      return;
-    }
-
-    DirectoryPartition directoryPartition = (DirectoryPartition) partition;
-    long directoryId = directoryPartition.getDirectoryId();
-    TextView labelTextView = (TextView) view.findViewById(R.id.label);
-    TextView displayNameTextView = (TextView) view.findViewById(R.id.display_name);
-    labelTextView.setText(directoryPartition.getLabel());
-    if (!DirectoryCompat.isRemoteDirectoryId(directoryId)) {
-      displayNameTextView.setText(null);
-    } else {
-      String directoryName = directoryPartition.getDisplayName();
-      String displayName =
-          !TextUtils.isEmpty(directoryName) ? directoryName : directoryPartition.getDirectoryType();
-      displayNameTextView.setText(displayName);
-    }
-
-    final Resources res = getContext().getResources();
-    final int headerPaddingTop =
-        partitionIndex == 1 && getPartition(0).isEmpty()
-            ? 0
-            : res.getDimensionPixelOffset(R.dimen.directory_header_extra_top_padding);
-    // There should be no extra padding at the top of the first directory header
-    view.setPaddingRelative(
-        view.getPaddingStart(), headerPaddingTop, view.getPaddingEnd(), view.getPaddingBottom());
-  }
-
-  /** Checks whether the contact entry at the given position represents the user's profile. */
-  protected boolean isUserProfile(int position) {
-    // The profile only ever appears in the first position if it is present.  So if the position
-    // is anything beyond 0, it can't be the profile.
-    boolean isUserProfile = false;
-    if (position == 0) {
-      int partition = getPartitionForPosition(position);
-      if (partition >= 0) {
-        // Save the old cursor position - the call to getItem() may modify the cursor
-        // position.
-        int offset = getCursor(partition).getPosition();
-        Cursor cursor = (Cursor) getItem(position);
-        if (cursor != null) {
-          int profileColumnIndex = cursor.getColumnIndex(Contacts.IS_USER_PROFILE);
-          if (profileColumnIndex != -1) {
-            isUserProfile = cursor.getInt(profileColumnIndex) == 1;
-          }
-          // Restore the old cursor position.
-          cursor.moveToPosition(offset);
-        }
-      }
-    }
-    return isUserProfile;
-  }
-
-  public boolean isPhotoSupported(int partitionIndex) {
-    Partition partition = getPartition(partitionIndex);
-    if (partition instanceof DirectoryPartition) {
-      return ((DirectoryPartition) partition).isPhotoSupported();
-    }
-    return true;
-  }
-
-  /** Returns the currently selected filter. */
-  public ContactListFilter getFilter() {
-    return mFilter;
-  }
-
-  public void setFilter(ContactListFilter filter) {
-    mFilter = filter;
-  }
-
-  // TODO: move sharable logic (bindXX() methods) to here with extra arguments
-
-  /**
-   * Loads the photo for the quick contact view and assigns the contact uri.
-   *
-   * @param photoIdColumn Index of the photo id column
-   * @param photoUriColumn Index of the photo uri column. Optional: Can be -1
-   * @param contactIdColumn Index of the contact id column
-   * @param lookUpKeyColumn Index of the lookup key column
-   * @param displayNameColumn Index of the display name column
-   */
-  protected void bindQuickContact(
-      final ContactListItemView view,
-      int partitionIndex,
-      Cursor cursor,
-      int photoIdColumn,
-      int photoUriColumn,
-      int contactIdColumn,
-      int lookUpKeyColumn,
-      int displayNameColumn) {
-    long photoId = 0;
-    if (!cursor.isNull(photoIdColumn)) {
-      photoId = cursor.getLong(photoIdColumn);
-    }
-
-    QuickContactBadge quickContact = view.getQuickContact();
-    quickContact.assignContactUri(
-        getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn));
-    if (CompatUtils.hasPrioritizedMimeType()) {
-      // The Contacts app never uses the QuickContactBadge. Therefore, it is safe to assume
-      // that only Dialer will use this QuickContact badge. This means prioritizing the phone
-      // mimetype here is reasonable.
-      quickContact.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
-    }
-    Logger.get(mContext)
-        .logQuickContactOnTouch(
-            quickContact, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_SEARCH, true);
-
-    if (photoId != 0 || photoUriColumn == -1) {
-      getPhotoLoader().loadThumbnail(quickContact, photoId, mDarkTheme, mCircularPhotos, null);
-    } else {
-      final String photoUriString = cursor.getString(photoUriColumn);
-      final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
-      DefaultImageRequest request = null;
-      if (photoUri == null) {
-        request = getDefaultImageRequestFromCursor(cursor, displayNameColumn, lookUpKeyColumn);
-      }
-      getPhotoLoader().loadPhoto(quickContact, photoUri, -1, mDarkTheme, mCircularPhotos, request);
-    }
-  }
-
-  @Override
-  public boolean hasStableIds() {
-    // Whenever bindViewId() is called, the values passed into setId() are stable or
-    // stable-ish. For example, when one contact is modified we don't expect a second
-    // contact's Contact._ID values to change.
-    return true;
-  }
-
-  protected void bindViewId(final ContactListItemView view, Cursor cursor, int idColumn) {
-    // Set a semi-stable id, so that talkback won't get confused when the list gets
-    // refreshed. There is little harm in inserting the same ID twice.
-    long contactId = cursor.getLong(idColumn);
-    view.setId((int) (contactId % Integer.MAX_VALUE));
-  }
-
-  protected Uri getContactUri(
-      int partitionIndex, Cursor cursor, int contactIdColumn, int lookUpKeyColumn) {
-    long contactId = cursor.getLong(contactIdColumn);
-    String lookupKey = cursor.getString(lookUpKeyColumn);
-    long directoryId = ((DirectoryPartition) getPartition(partitionIndex)).getDirectoryId();
-    Uri uri = Contacts.getLookupUri(contactId, lookupKey);
-    if (uri != null && directoryId != Directory.DEFAULT) {
-      uri =
-          uri.buildUpon()
-              .appendQueryParameter(
-                  ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId))
-              .build();
-    }
-    return uri;
-  }
-
-  /**
-   * Retrieves the lookup key and display name from a cursor, and returns a {@link
-   * DefaultImageRequest} containing these contact details
-   *
-   * @param cursor Contacts cursor positioned at the current row to retrieve contact details for
-   * @param displayNameColumn Column index of the display name
-   * @param lookupKeyColumn Column index of the lookup key
-   * @return {@link DefaultImageRequest} with the displayName and identifier fields set to the
-   *     display name and lookup key of the contact.
-   */
-  public DefaultImageRequest getDefaultImageRequestFromCursor(
-      Cursor cursor, int displayNameColumn, int lookupKeyColumn) {
-    final String displayName = cursor.getString(displayNameColumn);
-    final String lookupKey = cursor.getString(lookupKeyColumn);
-    return new DefaultImageRequest(displayName, lookupKey, mCircularPhotos);
-  }
-}
diff --git a/java/com/android/contacts/common/list/ContactEntryListFragment.java b/java/com/android/contacts/common/list/ContactEntryListFragment.java
deleted file mode 100644
index c807ea8..0000000
--- a/java/com/android/contacts/common/list/ContactEntryListFragment.java
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.Context;
-import android.content.CursorLoader;
-import android.content.Loader;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Parcelable;
-import android.provider.ContactsContract.Directory;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnFocusChangeListener;
-import android.view.View.OnTouchListener;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AbsListView;
-import android.widget.AbsListView.OnScrollListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListView;
-import com.android.common.widget.CompositeCursorAdapter.Partition;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.ContactListViewUtils;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.contactphoto.ContactPhotoManager;
-import com.android.dialer.performancereport.PerformanceReport;
-import java.lang.ref.WeakReference;
-import java.util.Locale;
-
-/** Common base class for various contact-related list fragments. */
-public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter> extends Fragment
-    implements OnItemClickListener,
-        OnScrollListener,
-        OnFocusChangeListener,
-        OnTouchListener,
-        LoaderCallbacks<Cursor> {
-  private static final String KEY_LIST_STATE = "liststate";
-  private static final String KEY_SECTION_HEADER_DISPLAY_ENABLED = "sectionHeaderDisplayEnabled";
-  private static final String KEY_PHOTO_LOADER_ENABLED = "photoLoaderEnabled";
-  private static final String KEY_QUICK_CONTACT_ENABLED = "quickContactEnabled";
-  private static final String KEY_ADJUST_SELECTION_BOUNDS_ENABLED = "adjustSelectionBoundsEnabled";
-  private static final String KEY_INCLUDE_PROFILE = "includeProfile";
-  private static final String KEY_SEARCH_MODE = "searchMode";
-  private static final String KEY_VISIBLE_SCROLLBAR_ENABLED = "visibleScrollbarEnabled";
-  private static final String KEY_SCROLLBAR_POSITION = "scrollbarPosition";
-  private static final String KEY_QUERY_STRING = "queryString";
-  private static final String KEY_DIRECTORY_SEARCH_MODE = "directorySearchMode";
-  private static final String KEY_SELECTION_VISIBLE = "selectionVisible";
-  private static final String KEY_DARK_THEME = "darkTheme";
-  private static final String KEY_LEGACY_COMPATIBILITY = "legacyCompatibility";
-  private static final String KEY_DIRECTORY_RESULT_LIMIT = "directoryResultLimit";
-
-  private static final String DIRECTORY_ID_ARG_KEY = "directoryId";
-
-  private static final int DIRECTORY_LOADER_ID = -1;
-
-  private static final int DIRECTORY_SEARCH_DELAY_MILLIS = 300;
-  private static final int DIRECTORY_SEARCH_MESSAGE = 1;
-
-  private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20;
-  private static final int STATUS_NOT_LOADED = 0;
-  private static final int STATUS_LOADING = 1;
-  private static final int STATUS_LOADED = 2;
-  protected boolean mUserProfileExists;
-  private boolean mSectionHeaderDisplayEnabled;
-  private boolean mPhotoLoaderEnabled;
-  private boolean mQuickContactEnabled = true;
-  private boolean mAdjustSelectionBoundsEnabled = true;
-  private boolean mIncludeProfile;
-  private boolean mSearchMode;
-  private boolean mVisibleScrollbarEnabled;
-  private boolean mShowEmptyListForEmptyQuery;
-  private int mVerticalScrollbarPosition = getDefaultVerticalScrollbarPosition();
-  private String mQueryString;
-  private int mDirectorySearchMode = DirectoryListLoader.SEARCH_MODE_NONE;
-  private boolean mSelectionVisible;
-  private boolean mLegacyCompatibility;
-  private boolean mEnabled = true;
-  private T mAdapter;
-  private View mView;
-  private ListView mListView;
-  /** Used to save the scrolling state of the list when the fragment is not recreated. */
-  private int mListViewTopIndex;
-
-  private int mListViewTopOffset;
-  /** Used for keeping track of the scroll state of the list. */
-  private Parcelable mListState;
-
-  private int mDisplayOrder;
-  private int mSortOrder;
-  private int mDirectoryResultLimit = DEFAULT_DIRECTORY_RESULT_LIMIT;
-  private ContactPhotoManager mPhotoManager;
-  private ContactsPreferences mContactsPrefs;
-  private boolean mForceLoad;
-  private boolean mDarkTheme;
-  private int mDirectoryListStatus = STATUS_NOT_LOADED;
-
-  /**
-   * Indicates whether we are doing the initial complete load of data (false) or a refresh caused by
-   * a change notification (true)
-   */
-  private boolean mLoadPriorityDirectoriesOnly;
-
-  private Context mContext;
-
-  private LoaderManager mLoaderManager;
-
-  private Handler mDelayedDirectorySearchHandler;
-
-  private static class DelayedDirectorySearchHandler extends Handler {
-    private final WeakReference<ContactEntryListFragment<?>> contactEntryListFragmentRef;
-
-    private DelayedDirectorySearchHandler(ContactEntryListFragment<?> contactEntryListFragment) {
-      this.contactEntryListFragmentRef = new WeakReference<>(contactEntryListFragment);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-      ContactEntryListFragment<?> contactEntryListFragment = contactEntryListFragmentRef.get();
-      if (contactEntryListFragment == null) {
-        return;
-      }
-      if (msg.what == DIRECTORY_SEARCH_MESSAGE) {
-        contactEntryListFragment.loadDirectoryPartition(msg.arg1, (DirectoryPartition) msg.obj);
-      }
-    }
-  }
-
-  private ContactsPreferences.ChangeListener mPreferencesChangeListener =
-      new ContactsPreferences.ChangeListener() {
-        @Override
-        public void onChange() {
-          loadPreferences();
-          reloadData();
-        }
-      };
-
-  protected ContactEntryListFragment() {
-    mDelayedDirectorySearchHandler = new DelayedDirectorySearchHandler(this);
-  }
-
-  protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);
-
-  protected abstract T createListAdapter();
-
-  /**
-   * @param position Please note that the position is already adjusted for header views, so "0"
-   *     means the first list item below header views.
-   */
-  protected abstract void onItemClick(int position, long id);
-
-  @Override
-  public void onAttach(Context context) {
-    super.onAttach(context);
-    setContext(context);
-    setLoaderManager(super.getLoaderManager());
-  }
-
-  @Override
-  public Context getContext() {
-    return mContext;
-  }
-
-  /** Sets a context for the fragment in the unit test environment. */
-  public void setContext(Context context) {
-    mContext = context;
-    configurePhotoLoader();
-  }
-
-  public void setEnabled(boolean enabled) {
-    if (mEnabled != enabled) {
-      mEnabled = enabled;
-      if (mAdapter != null) {
-        if (mEnabled) {
-          reloadData();
-        } else {
-          mAdapter.clearPartitions();
-        }
-      }
-    }
-  }
-
-  @Override
-  public LoaderManager getLoaderManager() {
-    return mLoaderManager;
-  }
-
-  /** Overrides a loader manager for use in unit tests. */
-  public void setLoaderManager(LoaderManager loaderManager) {
-    mLoaderManager = loaderManager;
-  }
-
-  public T getAdapter() {
-    return mAdapter;
-  }
-
-  @Override
-  public View getView() {
-    return mView;
-  }
-
-  public ListView getListView() {
-    return mListView;
-  }
-
-  @Override
-  public void onSaveInstanceState(Bundle outState) {
-    super.onSaveInstanceState(outState);
-    outState.putBoolean(KEY_SECTION_HEADER_DISPLAY_ENABLED, mSectionHeaderDisplayEnabled);
-    outState.putBoolean(KEY_PHOTO_LOADER_ENABLED, mPhotoLoaderEnabled);
-    outState.putBoolean(KEY_QUICK_CONTACT_ENABLED, mQuickContactEnabled);
-    outState.putBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED, mAdjustSelectionBoundsEnabled);
-    outState.putBoolean(KEY_INCLUDE_PROFILE, mIncludeProfile);
-    outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
-    outState.putBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED, mVisibleScrollbarEnabled);
-    outState.putInt(KEY_SCROLLBAR_POSITION, mVerticalScrollbarPosition);
-    outState.putInt(KEY_DIRECTORY_SEARCH_MODE, mDirectorySearchMode);
-    outState.putBoolean(KEY_SELECTION_VISIBLE, mSelectionVisible);
-    outState.putBoolean(KEY_LEGACY_COMPATIBILITY, mLegacyCompatibility);
-    outState.putString(KEY_QUERY_STRING, mQueryString);
-    outState.putInt(KEY_DIRECTORY_RESULT_LIMIT, mDirectoryResultLimit);
-    outState.putBoolean(KEY_DARK_THEME, mDarkTheme);
-
-    if (mListView != null) {
-      outState.putParcelable(KEY_LIST_STATE, mListView.onSaveInstanceState());
-    }
-  }
-
-  @Override
-  public void onCreate(Bundle savedState) {
-    super.onCreate(savedState);
-    restoreSavedState(savedState);
-    mAdapter = createListAdapter();
-    mContactsPrefs = new ContactsPreferences(mContext);
-  }
-
-  public void restoreSavedState(Bundle savedState) {
-    if (savedState == null) {
-      return;
-    }
-
-    mSectionHeaderDisplayEnabled = savedState.getBoolean(KEY_SECTION_HEADER_DISPLAY_ENABLED);
-    mPhotoLoaderEnabled = savedState.getBoolean(KEY_PHOTO_LOADER_ENABLED);
-    mQuickContactEnabled = savedState.getBoolean(KEY_QUICK_CONTACT_ENABLED);
-    mAdjustSelectionBoundsEnabled = savedState.getBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED);
-    mIncludeProfile = savedState.getBoolean(KEY_INCLUDE_PROFILE);
-    mSearchMode = savedState.getBoolean(KEY_SEARCH_MODE);
-    mVisibleScrollbarEnabled = savedState.getBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED);
-    mVerticalScrollbarPosition = savedState.getInt(KEY_SCROLLBAR_POSITION);
-    mDirectorySearchMode = savedState.getInt(KEY_DIRECTORY_SEARCH_MODE);
-    mSelectionVisible = savedState.getBoolean(KEY_SELECTION_VISIBLE);
-    mLegacyCompatibility = savedState.getBoolean(KEY_LEGACY_COMPATIBILITY);
-    mQueryString = savedState.getString(KEY_QUERY_STRING);
-    mDirectoryResultLimit = savedState.getInt(KEY_DIRECTORY_RESULT_LIMIT);
-    mDarkTheme = savedState.getBoolean(KEY_DARK_THEME);
-
-    // Retrieve list state. This will be applied in onLoadFinished
-    mListState = savedState.getParcelable(KEY_LIST_STATE);
-  }
-
-  @Override
-  public void onStart() {
-    super.onStart();
-
-    mContactsPrefs.registerChangeListener(mPreferencesChangeListener);
-
-    mForceLoad = loadPreferences();
-
-    mDirectoryListStatus = STATUS_NOT_LOADED;
-    mLoadPriorityDirectoriesOnly = true;
-
-    startLoading();
-  }
-
-  protected void startLoading() {
-    if (mAdapter == null) {
-      // The method was called before the fragment was started
-      return;
-    }
-
-    configureAdapter();
-    int partitionCount = mAdapter.getPartitionCount();
-    for (int i = 0; i < partitionCount; i++) {
-      Partition partition = mAdapter.getPartition(i);
-      if (partition instanceof DirectoryPartition) {
-        DirectoryPartition directoryPartition = (DirectoryPartition) partition;
-        if (directoryPartition.getStatus() == DirectoryPartition.STATUS_NOT_LOADED) {
-          if (directoryPartition.isPriorityDirectory() || !mLoadPriorityDirectoriesOnly) {
-            startLoadingDirectoryPartition(i);
-          }
-        }
-      } else {
-        getLoaderManager().initLoader(i, null, this);
-      }
-    }
-
-    // Next time this method is called, we should start loading non-priority directories
-    mLoadPriorityDirectoriesOnly = false;
-  }
-
-  @Override
-  public Loader<Cursor> onCreateLoader(int id, Bundle args) {
-    if (id == DIRECTORY_LOADER_ID) {
-      DirectoryListLoader loader = new DirectoryListLoader(mContext);
-      loader.setDirectorySearchMode(mAdapter.getDirectorySearchMode());
-      loader.setLocalInvisibleDirectoryEnabled(
-          ContactEntryListAdapter.LOCAL_INVISIBLE_DIRECTORY_ENABLED);
-      return loader;
-    } else {
-      CursorLoader loader = createCursorLoader(mContext);
-      long directoryId =
-          args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
-              ? args.getLong(DIRECTORY_ID_ARG_KEY)
-              : Directory.DEFAULT;
-      mAdapter.configureLoader(loader, directoryId);
-      return loader;
-    }
-  }
-
-  public CursorLoader createCursorLoader(Context context) {
-    return new CursorLoader(context, null, null, null, null, null) {
-      @Override
-      protected Cursor onLoadInBackground() {
-        try {
-          return super.onLoadInBackground();
-        } catch (RuntimeException e) {
-          // We don't even know what the projection should be, so no point trying to
-          // return an empty MatrixCursor with the correct projection here.
-          LogUtil.w(
-              "ContactEntryListFragment.onLoadInBackground",
-              "RuntimeException while trying to query ContactsProvider.");
-          return null;
-        }
-      }
-    };
-  }
-
-  private void startLoadingDirectoryPartition(int partitionIndex) {
-    DirectoryPartition partition = (DirectoryPartition) mAdapter.getPartition(partitionIndex);
-    partition.setStatus(DirectoryPartition.STATUS_LOADING);
-    long directoryId = partition.getDirectoryId();
-    if (mForceLoad) {
-      if (directoryId == Directory.DEFAULT) {
-        loadDirectoryPartition(partitionIndex, partition);
-      } else {
-        loadDirectoryPartitionDelayed(partitionIndex, partition);
-      }
-    } else {
-      Bundle args = new Bundle();
-      args.putLong(DIRECTORY_ID_ARG_KEY, directoryId);
-      getLoaderManager().initLoader(partitionIndex, args, this);
-    }
-  }
-
-  /**
-   * Queues up a delayed request to search the specified directory. Since directory search will
-   * likely introduce a lot of network traffic, we want to wait for a pause in the user's typing
-   * before sending a directory request.
-   */
-  private void loadDirectoryPartitionDelayed(int partitionIndex, DirectoryPartition partition) {
-    mDelayedDirectorySearchHandler.removeMessages(DIRECTORY_SEARCH_MESSAGE, partition);
-    Message msg =
-        mDelayedDirectorySearchHandler.obtainMessage(
-            DIRECTORY_SEARCH_MESSAGE, partitionIndex, 0, partition);
-    mDelayedDirectorySearchHandler.sendMessageDelayed(msg, DIRECTORY_SEARCH_DELAY_MILLIS);
-  }
-
-  /** Loads the directory partition. */
-  protected void loadDirectoryPartition(int partitionIndex, DirectoryPartition partition) {
-    Bundle args = new Bundle();
-    args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId());
-    getLoaderManager().restartLoader(partitionIndex, args, this);
-  }
-
-  /** Cancels all queued directory loading requests. */
-  private void removePendingDirectorySearchRequests() {
-    mDelayedDirectorySearchHandler.removeMessages(DIRECTORY_SEARCH_MESSAGE);
-  }
-
-  @Override
-  public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-    if (!mEnabled) {
-      return;
-    }
-
-    int loaderId = loader.getId();
-    if (loaderId == DIRECTORY_LOADER_ID) {
-      mDirectoryListStatus = STATUS_LOADED;
-      mAdapter.changeDirectories(data);
-      startLoading();
-    } else {
-      onPartitionLoaded(loaderId, data);
-      if (isSearchMode()) {
-        int directorySearchMode = getDirectorySearchMode();
-        if (directorySearchMode != DirectoryListLoader.SEARCH_MODE_NONE) {
-          if (mDirectoryListStatus == STATUS_NOT_LOADED) {
-            mDirectoryListStatus = STATUS_LOADING;
-            getLoaderManager().initLoader(DIRECTORY_LOADER_ID, null, this);
-          } else {
-            startLoading();
-          }
-        }
-      } else {
-        mDirectoryListStatus = STATUS_NOT_LOADED;
-        getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
-      }
-    }
-  }
-
-  @Override
-  public void onLoaderReset(Loader<Cursor> loader) {}
-
-  protected void onPartitionLoaded(int partitionIndex, Cursor data) {
-    if (partitionIndex >= mAdapter.getPartitionCount()) {
-      // When we get unsolicited data, ignore it.  This could happen
-      // when we are switching from search mode to the default mode.
-      return;
-    }
-
-    // Return for non-"Suggestions" if on the zero-suggest screen.
-    if (TextUtils.isEmpty(mQueryString) && partitionIndex > 0) {
-      return;
-    }
-
-    mAdapter.changeCursor(partitionIndex, data);
-    setProfileHeader();
-
-    if (!isLoading()) {
-      completeRestoreInstanceState();
-    }
-  }
-
-  public boolean isLoading() {
-    //noinspection SimplifiableIfStatement
-    if (mAdapter != null && mAdapter.isLoading()) {
-      return true;
-    }
-
-    return isLoadingDirectoryList();
-
-  }
-
-  public boolean isLoadingDirectoryList() {
-    return isSearchMode()
-        && getDirectorySearchMode() != DirectoryListLoader.SEARCH_MODE_NONE
-        && (mDirectoryListStatus == STATUS_NOT_LOADED || mDirectoryListStatus == STATUS_LOADING);
-  }
-
-  @Override
-  public void onStop() {
-    super.onStop();
-    mContactsPrefs.unregisterChangeListener();
-    mAdapter.clearPartitions();
-  }
-
-  protected void reloadData() {
-    removePendingDirectorySearchRequests();
-    mAdapter.onDataReload();
-    mLoadPriorityDirectoriesOnly = true;
-    mForceLoad = true;
-    startLoading();
-  }
-
-  /**
-   * Shows a view at the top of the list with a pseudo local profile prompting the user to add a
-   * local profile. Default implementation does nothing.
-   */
-  protected void setProfileHeader() {
-    mUserProfileExists = false;
-  }
-
-  /** Provides logic that dismisses this fragment. The default implementation does nothing. */
-  protected void finish() {}
-
-  public boolean isSectionHeaderDisplayEnabled() {
-    return mSectionHeaderDisplayEnabled;
-  }
-
-  public void setSectionHeaderDisplayEnabled(boolean flag) {
-    if (mSectionHeaderDisplayEnabled != flag) {
-      mSectionHeaderDisplayEnabled = flag;
-      if (mAdapter != null) {
-        mAdapter.setSectionHeaderDisplayEnabled(flag);
-      }
-      configureVerticalScrollbar();
-    }
-  }
-
-  public boolean isVisibleScrollbarEnabled() {
-    return mVisibleScrollbarEnabled;
-  }
-
-  public void setVisibleScrollbarEnabled(boolean flag) {
-    if (mVisibleScrollbarEnabled != flag) {
-      mVisibleScrollbarEnabled = flag;
-      configureVerticalScrollbar();
-    }
-  }
-
-  private void configureVerticalScrollbar() {
-    boolean hasScrollbar = isVisibleScrollbarEnabled() && isSectionHeaderDisplayEnabled();
-
-    if (mListView != null) {
-      mListView.setFastScrollEnabled(hasScrollbar);
-      mListView.setVerticalScrollbarPosition(mVerticalScrollbarPosition);
-      mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
-    }
-  }
-
-  public boolean isPhotoLoaderEnabled() {
-    return mPhotoLoaderEnabled;
-  }
-
-  public void setPhotoLoaderEnabled(boolean flag) {
-    mPhotoLoaderEnabled = flag;
-    configurePhotoLoader();
-  }
-
-  public void setQuickContactEnabled(boolean flag) {
-    this.mQuickContactEnabled = flag;
-  }
-
-  public void setAdjustSelectionBoundsEnabled(boolean flag) {
-    mAdjustSelectionBoundsEnabled = flag;
-  }
-
-  public final boolean isSearchMode() {
-    return mSearchMode;
-  }
-
-  /**
-   * Enter/exit search mode. This is method is tightly related to the current query, and should only
-   * be called by {@link #setQueryString}.
-   *
-   * <p>Also note this method doesn't call {@link #reloadData()}; {@link #setQueryString} does it.
-   */
-  protected void setSearchMode(boolean flag) {
-    if (mSearchMode != flag) {
-      mSearchMode = flag;
-
-      if (!flag) {
-        mDirectoryListStatus = STATUS_NOT_LOADED;
-        getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
-      }
-
-      if (mAdapter != null) {
-        mAdapter.setSearchMode(flag);
-
-        mAdapter.clearPartitions();
-        if (!flag) {
-          // If we are switching from search to regular display, remove all directory
-          // partitions after default one, assuming they are remote directories which
-          // should be cleaned up on exiting the search mode.
-          mAdapter.removeDirectoriesAfterDefault();
-        }
-        mAdapter.configurePartitionsVisibility(flag);
-      }
-
-      if (mListView != null) {
-        mListView.setFastScrollEnabled(!flag);
-      }
-    }
-  }
-
-  @Nullable
-  public final String getQueryString() {
-    return mQueryString;
-  }
-
-  public void setQueryString(String queryString) {
-    if (!TextUtils.equals(mQueryString, queryString)) {
-      if (mShowEmptyListForEmptyQuery && mAdapter != null && mListView != null) {
-        if (TextUtils.isEmpty(mQueryString)) {
-          // Restore the adapter if the query used to be empty.
-          mListView.setAdapter(mAdapter);
-        } else if (TextUtils.isEmpty(queryString)) {
-          // Instantly clear the list view if the new query is empty.
-          mListView.setAdapter(null);
-        }
-      }
-
-      mQueryString = queryString;
-      setSearchMode(!TextUtils.isEmpty(mQueryString) || mShowEmptyListForEmptyQuery);
-
-      if (mAdapter != null) {
-        mAdapter.setQueryString(queryString);
-        reloadData();
-      }
-    }
-  }
-
-  public void setShowEmptyListForNullQuery(boolean show) {
-    mShowEmptyListForEmptyQuery = show;
-  }
-
-  public boolean getShowEmptyListForNullQuery() {
-    return mShowEmptyListForEmptyQuery;
-  }
-
-  public int getDirectoryLoaderId() {
-    return DIRECTORY_LOADER_ID;
-  }
-
-  public int getDirectorySearchMode() {
-    return mDirectorySearchMode;
-  }
-
-  public void setDirectorySearchMode(int mode) {
-    mDirectorySearchMode = mode;
-  }
-
-  protected int getContactNameDisplayOrder() {
-    return mDisplayOrder;
-  }
-
-  protected void setContactNameDisplayOrder(int displayOrder) {
-    mDisplayOrder = displayOrder;
-    if (mAdapter != null) {
-      mAdapter.setContactNameDisplayOrder(displayOrder);
-    }
-  }
-
-  public int getSortOrder() {
-    return mSortOrder;
-  }
-
-  public void setSortOrder(int sortOrder) {
-    mSortOrder = sortOrder;
-    if (mAdapter != null) {
-      mAdapter.setSortOrder(sortOrder);
-    }
-  }
-
-  public void setDirectoryResultLimit(int limit) {
-    mDirectoryResultLimit = limit;
-  }
-
-  protected boolean loadPreferences() {
-    boolean changed = false;
-    if (getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) {
-      setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
-      changed = true;
-    }
-
-    if (getSortOrder() != mContactsPrefs.getSortOrder()) {
-      setSortOrder(mContactsPrefs.getSortOrder());
-      changed = true;
-    }
-
-    return changed;
-  }
-
-  @Override
-  public View onCreateView(
-      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-    onCreateView(inflater, container);
-
-    boolean searchMode = isSearchMode();
-    mAdapter.setSearchMode(searchMode);
-    mAdapter.configurePartitionsVisibility(searchMode);
-    mAdapter.setPhotoLoader(mPhotoManager);
-    mListView.setAdapter(mAdapter);
-    return mView;
-  }
-
-  protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
-    mView = inflateView(inflater, container);
-
-    mListView = mView.findViewById(android.R.id.list);
-    if (mListView == null) {
-      throw new RuntimeException(
-          "Your content must have a ListView whose id attribute is " + "'android.R.id.list'");
-    }
-
-    View emptyView = mView.findViewById(android.R.id.empty);
-    if (emptyView != null) {
-      mListView.setEmptyView(emptyView);
-    }
-
-    mListView.setOnItemClickListener(this);
-    mListView.setOnFocusChangeListener(this);
-    mListView.setOnTouchListener(this);
-    mListView.setFastScrollEnabled(!isSearchMode());
-
-    // Tell list view to not show dividers. We'll do it ourself so that we can *not* show
-    // them when an A-Z headers is visible.
-    mListView.setDividerHeight(0);
-
-    // We manually save/restore the listview state
-    mListView.setSaveEnabled(false);
-
-    configureVerticalScrollbar();
-    configurePhotoLoader();
-
-    getAdapter().setFragmentRootView(getView());
-
-    ContactListViewUtils.applyCardPaddingToView(getResources(), mListView, mView);
-  }
-
-  @Override
-  public void onHiddenChanged(boolean hidden) {
-    super.onHiddenChanged(hidden);
-    if (getActivity() != null && getView() != null && !hidden) {
-      // If the padding was last applied when in a hidden state, it may have been applied
-      // incorrectly. Therefore we need to reapply it.
-      ContactListViewUtils.applyCardPaddingToView(getResources(), mListView, getView());
-    }
-  }
-
-  protected void configurePhotoLoader() {
-    if (isPhotoLoaderEnabled() && mContext != null) {
-      if (mPhotoManager == null) {
-        mPhotoManager = ContactPhotoManager.getInstance(mContext);
-      }
-      if (mListView != null) {
-        mListView.setOnScrollListener(this);
-      }
-      if (mAdapter != null) {
-        mAdapter.setPhotoLoader(mPhotoManager);
-      }
-    }
-  }
-
-  protected void configureAdapter() {
-    if (mAdapter == null) {
-      return;
-    }
-
-    mAdapter.setQuickContactEnabled(mQuickContactEnabled);
-    mAdapter.setAdjustSelectionBoundsEnabled(mAdjustSelectionBoundsEnabled);
-    mAdapter.setQueryString(mQueryString);
-    mAdapter.setDirectorySearchMode(mDirectorySearchMode);
-    mAdapter.setPinnedPartitionHeadersEnabled(false);
-    mAdapter.setContactNameDisplayOrder(mDisplayOrder);
-    mAdapter.setSortOrder(mSortOrder);
-    mAdapter.setSectionHeaderDisplayEnabled(mSectionHeaderDisplayEnabled);
-    mAdapter.setSelectionVisible(mSelectionVisible);
-    mAdapter.setDirectoryResultLimit(mDirectoryResultLimit);
-    mAdapter.setDarkTheme(mDarkTheme);
-  }
-
-  @Override
-  public void onScroll(
-      AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}
-
-  @Override
-  public void onScrollStateChanged(AbsListView view, int scrollState) {
-    PerformanceReport.recordScrollStateChange(scrollState);
-    if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
-      mPhotoManager.pause();
-    } else if (isPhotoLoaderEnabled()) {
-      mPhotoManager.resume();
-    }
-  }
-
-  @Override
-  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-    hideSoftKeyboard();
-
-    int adjPosition = position - mListView.getHeaderViewsCount();
-    if (adjPosition >= 0) {
-      onItemClick(adjPosition, id);
-    }
-  }
-
-  private void hideSoftKeyboard() {
-    // Hide soft keyboard, if visible
-    InputMethodManager inputMethodManager =
-        (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
-    inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
-  }
-
-  /** Dismisses the soft keyboard when the list takes focus. */
-  @Override
-  public void onFocusChange(View view, boolean hasFocus) {
-    if (view == mListView && hasFocus) {
-      hideSoftKeyboard();
-    }
-  }
-
-  /** Dismisses the soft keyboard when the list is touched. */
-  @Override
-  public boolean onTouch(View view, MotionEvent event) {
-    if (view == mListView) {
-      hideSoftKeyboard();
-    }
-    return false;
-  }
-
-  @Override
-  public void onPause() {
-    // Save the scrolling state of the list view
-    mListViewTopIndex = mListView.getFirstVisiblePosition();
-    View v = mListView.getChildAt(0);
-    mListViewTopOffset = (v == null) ? 0 : (v.getTop() - mListView.getPaddingTop());
-
-    super.onPause();
-    removePendingDirectorySearchRequests();
-  }
-
-  @Override
-  public void onResume() {
-    super.onResume();
-    // Restore the selection of the list view. See a bug.
-    // This has to be done manually because if the list view has its emptyView set,
-    // the scrolling state will be reset when clearPartitions() is called on the adapter.
-    mListView.setSelectionFromTop(mListViewTopIndex, mListViewTopOffset);
-  }
-
-  /** Restore the list state after the adapter is populated. */
-  protected void completeRestoreInstanceState() {
-    if (mListState != null) {
-      mListView.onRestoreInstanceState(mListState);
-      mListState = null;
-    }
-  }
-
-  public void setDarkTheme(boolean value) {
-    mDarkTheme = value;
-    if (mAdapter != null) {
-      mAdapter.setDarkTheme(value);
-    }
-  }
-
-  private int getDefaultVerticalScrollbarPosition() {
-    final Locale locale = Locale.getDefault();
-    final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
-    switch (layoutDirection) {
-      case View.LAYOUT_DIRECTION_RTL:
-        return View.SCROLLBAR_POSITION_LEFT;
-      case View.LAYOUT_DIRECTION_LTR:
-      default:
-        return View.SCROLLBAR_POSITION_RIGHT;
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/ContactListAdapter.java b/java/com/android/contacts/common/list/ContactListAdapter.java
deleted file mode 100644
index 721609d..0000000
--- a/java/com/android/contacts/common/list/ContactListAdapter.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.SearchSnippets;
-import android.view.ViewGroup;
-import com.android.contacts.common.R;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest;
-
-/**
- * A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type. Also
- * includes support for including the {@link ContactsContract.Profile} record in the list.
- */
-public abstract class ContactListAdapter extends ContactEntryListAdapter {
-
-  private CharSequence mUnknownNameText;
-
-  public ContactListAdapter(Context context) {
-    super(context);
-
-    mUnknownNameText = context.getText(R.string.missing_name);
-  }
-
-  protected static Uri buildSectionIndexerUri(Uri uri) {
-    return uri.buildUpon().appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true").build();
-  }
-
-  public Uri getContactUri(int partitionIndex, Cursor cursor) {
-    long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
-    String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
-    Uri uri = Contacts.getLookupUri(contactId, lookupKey);
-    long directoryId = ((DirectoryPartition) getPartition(partitionIndex)).getDirectoryId();
-    if (uri != null && directoryId != Directory.DEFAULT) {
-      uri =
-          uri.buildUpon()
-              .appendQueryParameter(
-                  ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId))
-              .build();
-    }
-    return uri;
-  }
-
-  @Override
-  protected ContactListItemView newView(
-      Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
-    ContactListItemView view = super.newView(context, partition, cursor, position, parent);
-    view.setUnknownNameText(mUnknownNameText);
-    view.setQuickContactEnabled(isQuickContactEnabled());
-    view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled());
-    view.setActivatedStateSupported(isSelectionVisible());
-    return view;
-  }
-
-  protected void bindSectionHeaderAndDivider(
-      ContactListItemView view, int position, Cursor cursor) {
-    view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
-    if (isSectionHeaderDisplayEnabled()) {
-      Placement placement = getItemPlacementInSection(position);
-      view.setSectionHeader(placement.sectionHeader);
-    } else {
-      view.setSectionHeader(null);
-    }
-  }
-
-  protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) {
-    if (!isPhotoSupported(partitionIndex)) {
-      view.removePhotoView();
-      return;
-    }
-
-    // Set the photo, if available
-    long photoId = 0;
-    if (!cursor.isNull(ContactQuery.CONTACT_PHOTO_ID)) {
-      photoId = cursor.getLong(ContactQuery.CONTACT_PHOTO_ID);
-    }
-
-    if (photoId != 0) {
-      getPhotoLoader()
-          .loadThumbnail(view.getPhotoView(), photoId, false, getCircularPhotos(), null);
-    } else {
-      final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI);
-      final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
-      DefaultImageRequest request = null;
-      if (photoUri == null) {
-        request =
-            getDefaultImageRequestFromCursor(
-                cursor, ContactQuery.CONTACT_DISPLAY_NAME, ContactQuery.CONTACT_LOOKUP_KEY);
-      }
-      getPhotoLoader()
-          .loadDirectoryPhoto(view.getPhotoView(), photoUri, false, getCircularPhotos(), request);
-    }
-  }
-
-  protected void bindNameAndViewId(final ContactListItemView view, Cursor cursor) {
-    view.showDisplayName(cursor, ContactQuery.CONTACT_DISPLAY_NAME);
-    // Note: we don't show phonetic any more (See issue 5265330)
-
-    bindViewId(view, cursor, ContactQuery.CONTACT_ID);
-  }
-
-  protected void bindPresenceAndStatusMessage(final ContactListItemView view, Cursor cursor) {
-    view.showPresenceAndStatusMessage(
-        cursor, ContactQuery.CONTACT_PRESENCE_STATUS, ContactQuery.CONTACT_CONTACT_STATUS);
-  }
-
-  protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
-    view.showSnippet(cursor, ContactQuery.CONTACT_SNIPPET);
-  }
-
-  @Override
-  public void changeCursor(int partitionIndex, Cursor cursor) {
-    super.changeCursor(partitionIndex, cursor);
-
-    if (cursor == null || !cursor.moveToFirst()) {
-      return;
-    }
-
-    // hasProfile tells whether the first row is a profile
-    final boolean hasProfile = cursor.getInt(ContactQuery.CONTACT_IS_USER_PROFILE) == 1;
-
-    // Add ME profile on top of favorites
-    cursor.moveToFirst();
-    setProfileExists(hasProfile);
-  }
-
-  /** @return Projection useful for children. */
-  protected final String[] getProjection(boolean forSearch) {
-    final int sortOrder = getContactNameDisplayOrder();
-    if (forSearch) {
-      if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
-        return ContactQuery.FILTER_PROJECTION_PRIMARY;
-      } else {
-        return ContactQuery.FILTER_PROJECTION_ALTERNATIVE;
-      }
-    } else {
-      if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
-        return ContactQuery.CONTACT_PROJECTION_PRIMARY;
-      } else {
-        return ContactQuery.CONTACT_PROJECTION_ALTERNATIVE;
-      }
-    }
-  }
-
-  protected static class ContactQuery {
-
-    public static final int CONTACT_ID = 0;
-    public static final int CONTACT_DISPLAY_NAME = 1;
-    public static final int CONTACT_PRESENCE_STATUS = 2;
-    public static final int CONTACT_CONTACT_STATUS = 3;
-    public static final int CONTACT_PHOTO_ID = 4;
-    public static final int CONTACT_PHOTO_URI = 5;
-    public static final int CONTACT_LOOKUP_KEY = 6;
-    public static final int CONTACT_IS_USER_PROFILE = 7;
-    public static final int CONTACT_PHONETIC_NAME = 8;
-    public static final int CONTACT_STARRED = 9;
-    public static final int CONTACT_SNIPPET = 10;
-    private static final String[] CONTACT_PROJECTION_PRIMARY =
-        new String[] {
-          Contacts._ID, // 0
-          Contacts.DISPLAY_NAME_PRIMARY, // 1
-          Contacts.CONTACT_PRESENCE, // 2
-          Contacts.CONTACT_STATUS, // 3
-          Contacts.PHOTO_ID, // 4
-          Contacts.PHOTO_THUMBNAIL_URI, // 5
-          Contacts.LOOKUP_KEY, // 6
-          Contacts.IS_USER_PROFILE, // 7
-          Contacts.PHONETIC_NAME, // 8
-          Contacts.STARRED, // 9
-        };
-    private static final String[] CONTACT_PROJECTION_ALTERNATIVE =
-        new String[] {
-          Contacts._ID, // 0
-          Contacts.DISPLAY_NAME_ALTERNATIVE, // 1
-          Contacts.CONTACT_PRESENCE, // 2
-          Contacts.CONTACT_STATUS, // 3
-          Contacts.PHOTO_ID, // 4
-          Contacts.PHOTO_THUMBNAIL_URI, // 5
-          Contacts.LOOKUP_KEY, // 6
-          Contacts.IS_USER_PROFILE, // 7
-          Contacts.PHONETIC_NAME, // 8
-          Contacts.STARRED, // 9
-        };
-    private static final String[] FILTER_PROJECTION_PRIMARY =
-        new String[] {
-          Contacts._ID, // 0
-          Contacts.DISPLAY_NAME_PRIMARY, // 1
-          Contacts.CONTACT_PRESENCE, // 2
-          Contacts.CONTACT_STATUS, // 3
-          Contacts.PHOTO_ID, // 4
-          Contacts.PHOTO_THUMBNAIL_URI, // 5
-          Contacts.LOOKUP_KEY, // 6
-          Contacts.IS_USER_PROFILE, // 7
-          Contacts.PHONETIC_NAME, // 8
-          Contacts.STARRED, // 9
-          SearchSnippets.SNIPPET, // 10
-        };
-    private static final String[] FILTER_PROJECTION_ALTERNATIVE =
-        new String[] {
-          Contacts._ID, // 0
-          Contacts.DISPLAY_NAME_ALTERNATIVE, // 1
-          Contacts.CONTACT_PRESENCE, // 2
-          Contacts.CONTACT_STATUS, // 3
-          Contacts.PHOTO_ID, // 4
-          Contacts.PHOTO_THUMBNAIL_URI, // 5
-          Contacts.LOOKUP_KEY, // 6
-          Contacts.IS_USER_PROFILE, // 7
-          Contacts.PHONETIC_NAME, // 8
-          Contacts.STARRED, // 9
-          SearchSnippets.SNIPPET, // 10
-        };
-  }
-}
diff --git a/java/com/android/contacts/common/list/ContactListItemView.java b/java/com/android/contacts/common/list/ContactListItemView.java
deleted file mode 100644
index 409aa1b..0000000
--- a/java/com/android/contacts/common/list/ContactListItemView.java
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
-import android.database.Cursor;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.SearchSnippets;
-import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.telephony.PhoneNumberUtils;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.TextUtils.TruncateAt;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView.SelectionBoundsAdjuster;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-import android.widget.QuickContactBadge;
-import android.widget.TextView;
-import com.android.contacts.common.ContactPresenceIconUtil;
-import com.android.contacts.common.ContactStatusUtil;
-import com.android.contacts.common.R;
-import com.android.contacts.common.format.TextHighlighter;
-import com.android.contacts.common.list.PhoneNumberListAdapter.Listener;
-import com.android.contacts.common.util.ContactDisplayUtils;
-import com.android.contacts.common.util.SearchUtil;
-import com.android.dialer.callintent.CallIntentBuilder;
-import com.android.dialer.util.ViewUtil;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A custom view for an item in the contact list. The view contains the contact's photo, a set of
- * text views (for name, status, etc...) and icons for presence and call. The view uses no XML file
- * for layout and all the measurements and layouts are done in the onMeasure and onLayout methods.
- *
- * <p>The layout puts the contact's photo on the right side of the view, the call icon (if present)
- * to the left of the photo, the text lines are aligned to the left and the presence icon (if
- * present) is set to the left of the status line.
- *
- * <p>The layout also supports a header (used as a header of a group of contacts) that is above the
- * contact's data and a divider between contact view.
- */
-public class ContactListItemView extends ViewGroup implements SelectionBoundsAdjuster {
-
-  /** IntDef for indices of ViewPager tabs. */
-  @Retention(RetentionPolicy.SOURCE)
-  @IntDef({NONE, VIDEO, DUO, CALL_AND_SHARE})
-  public @interface CallToAction {}
-
-  public static final int NONE = 0;
-  public static final int VIDEO = 1;
-  public static final int DUO = 2;
-  public static final int CALL_AND_SHARE = 3;
-
-  private final PhotoPosition mPhotoPosition = getDefaultPhotoPosition();
-  private static final Pattern SPLIT_PATTERN =
-      Pattern.compile("([\\w-\\.]+)@((?:[\\w]+\\.)+)([a-zA-Z]{2,4})|[\\w]+");
-  static final char SNIPPET_START_MATCH = '[';
-  static final char SNIPPET_END_MATCH = ']';
-  /** A helper used to highlight a prefix in a text field. */
-  private final TextHighlighter mTextHighlighter;
-  // Style values for layout and appearance
-  // The initialized values are defaults if none is provided through xml.
-  private int mPreferredHeight = 0;
-  private int mGapBetweenImageAndText = 0;
-  private int mGapBetweenLabelAndData = 0;
-  private int mPresenceIconMargin = 4;
-  private int mPresenceIconSize = 16;
-  private int mTextIndent = 0;
-  private int mTextOffsetTop;
-  private int mNameTextViewTextSize;
-  private int mHeaderWidth;
-  private Drawable mActivatedBackgroundDrawable;
-  private int mCallToActionSize = 48;
-  private int mCallToActionMargin = 16;
-  // Set in onLayout. Represent left and right position of the View on the screen.
-  private int mLeftOffset;
-  private int mRightOffset;
-  /** Used with {@link #mLabelView}, specifying the width ratio between label and data. */
-  private int mLabelViewWidthWeight = 3;
-  /** Used with {@link #mDataView}, specifying the width ratio between label and data. */
-  private int mDataViewWidthWeight = 5;
-
-  private ArrayList<HighlightSequence> mNameHighlightSequence;
-  private ArrayList<HighlightSequence> mNumberHighlightSequence;
-  // Highlighting prefix for names.
-  private String mHighlightedPrefix;
-  /** Indicates whether the view should leave room for the "video call" icon. */
-  private boolean mSupportVideoCall;
-
-  // Header layout data
-  private TextView mHeaderTextView;
-  private boolean mIsSectionHeaderEnabled;
-  // The views inside the contact view
-  private boolean mQuickContactEnabled = true;
-  private QuickContactBadge mQuickContact;
-  private ImageView mPhotoView;
-  private TextView mNameTextView;
-  private TextView mLabelView;
-  private TextView mDataView;
-  private TextView mSnippetView;
-  private TextView mStatusView;
-  private ImageView mPresenceIcon;
-  @NonNull private final ImageView mCallToActionView;
-  private ImageView mWorkProfileIcon;
-  private ColorStateList mSecondaryTextColor;
-  private int mDefaultPhotoViewSize = 0;
-  /**
-   * Can be effective even when {@link #mPhotoView} is null, as we want to have horizontal padding
-   * to align other data in this View.
-   */
-  private int mPhotoViewWidth;
-  /**
-   * Can be effective even when {@link #mPhotoView} is null, as we want to have vertical padding.
-   */
-  private int mPhotoViewHeight;
-  /**
-   * Only effective when {@link #mPhotoView} is null. When true all the Views on the right side of
-   * the photo should have horizontal padding on those left assuming there is a photo.
-   */
-  private boolean mKeepHorizontalPaddingForPhotoView;
-  /** Only effective when {@link #mPhotoView} is null. */
-  private boolean mKeepVerticalPaddingForPhotoView;
-  /**
-   * True when {@link #mPhotoViewWidth} and {@link #mPhotoViewHeight} are ready for being used.
-   * False indicates those values should be updated before being used in position calculation.
-   */
-  private boolean mPhotoViewWidthAndHeightAreReady = false;
-
-  private int mNameTextViewHeight;
-  private int mNameTextViewTextColor = Color.BLACK;
-  private int mPhoneticNameTextViewHeight;
-  private int mLabelViewHeight;
-  private int mDataViewHeight;
-  private int mSnippetTextViewHeight;
-  private int mStatusTextViewHeight;
-  private int mCheckBoxWidth;
-  // Holds Math.max(mLabelTextViewHeight, mDataViewHeight), assuming Label and Data share the
-  // same row.
-  private int mLabelAndDataViewMaxHeight;
-  private boolean mActivatedStateSupported;
-  private boolean mAdjustSelectionBoundsEnabled = true;
-  private Rect mBoundsWithoutHeader = new Rect();
-  private CharSequence mUnknownNameText;
-
-  private String mPhoneNumber;
-  private int mPosition = -1;
-  private @CallToAction int mCallToAction = NONE;
-
-  public ContactListItemView(Context context, AttributeSet attrs, boolean supportVideoCallIcon) {
-    this(context, attrs);
-
-    mSupportVideoCall = supportVideoCallIcon;
-  }
-
-  public ContactListItemView(Context context, AttributeSet attrs) {
-    super(context, attrs);
-
-    TypedArray a;
-
-    if (R.styleable.ContactListItemView != null) {
-      // Read all style values
-      a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView);
-      mPreferredHeight =
-          a.getDimensionPixelSize(
-              R.styleable.ContactListItemView_list_item_height, mPreferredHeight);
-      mActivatedBackgroundDrawable =
-          a.getDrawable(R.styleable.ContactListItemView_activated_background);
-      mGapBetweenImageAndText =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_gap_between_image_and_text,
-              mGapBetweenImageAndText);
-      mGapBetweenLabelAndData =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_gap_between_label_and_data,
-              mGapBetweenLabelAndData);
-      mPresenceIconMargin =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_presence_icon_margin, mPresenceIconMargin);
-      mPresenceIconSize =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_presence_icon_size, mPresenceIconSize);
-      mDefaultPhotoViewSize =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_photo_size, mDefaultPhotoViewSize);
-      mTextIndent =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_text_indent, mTextIndent);
-      mTextOffsetTop =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_text_offset_top, mTextOffsetTop);
-      mDataViewWidthWeight =
-          a.getInteger(
-              R.styleable.ContactListItemView_list_item_data_width_weight, mDataViewWidthWeight);
-      mLabelViewWidthWeight =
-          a.getInteger(
-              R.styleable.ContactListItemView_list_item_label_width_weight, mLabelViewWidthWeight);
-      mNameTextViewTextColor =
-          a.getColor(
-              R.styleable.ContactListItemView_list_item_name_text_color, mNameTextViewTextColor);
-      mNameTextViewTextSize =
-          (int)
-              a.getDimension(
-                  R.styleable.ContactListItemView_list_item_name_text_size,
-                  (int) getResources().getDimension(R.dimen.contact_browser_list_item_text_size));
-      mCallToActionSize =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_video_call_icon_size, mCallToActionSize);
-      mCallToActionMargin =
-          a.getDimensionPixelOffset(
-              R.styleable.ContactListItemView_list_item_video_call_icon_margin,
-              mCallToActionMargin);
-
-      setPaddingRelative(
-          a.getDimensionPixelOffset(R.styleable.ContactListItemView_list_item_padding_left, 0),
-          a.getDimensionPixelOffset(R.styleable.ContactListItemView_list_item_padding_top, 0),
-          a.getDimensionPixelOffset(R.styleable.ContactListItemView_list_item_padding_right, 0),
-          a.getDimensionPixelOffset(R.styleable.ContactListItemView_list_item_padding_bottom, 0));
-
-      a.recycle();
-    }
-
-    mTextHighlighter = new TextHighlighter(Typeface.BOLD);
-
-    if (R.styleable.Theme != null) {
-      a = getContext().obtainStyledAttributes(R.styleable.Theme);
-      mSecondaryTextColor = a.getColorStateList(R.styleable.Theme_android_textColorSecondary);
-      a.recycle();
-    }
-
-    mHeaderWidth = getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width);
-
-    if (mActivatedBackgroundDrawable != null) {
-      mActivatedBackgroundDrawable.setCallback(this);
-    }
-
-    mNameHighlightSequence = new ArrayList<>();
-    mNumberHighlightSequence = new ArrayList<>();
-
-    mCallToActionView = new ImageView(getContext());
-    mCallToActionView.setId(R.id.call_to_action);
-    mCallToActionView.setLayoutParams(new LayoutParams(mCallToActionSize, mCallToActionSize));
-    mCallToActionView.setScaleType(ScaleType.CENTER);
-    mCallToActionView.setImageTintList(
-        ContextCompat.getColorStateList(getContext(), R.color.search_video_call_icon_tint));
-    addView(mCallToActionView);
-
-    setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
-  }
-
-  public static PhotoPosition getDefaultPhotoPosition() {
-    int layoutDirection = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault());
-    return layoutDirection == View.LAYOUT_DIRECTION_RTL ? PhotoPosition.RIGHT : PhotoPosition.LEFT;
-  }
-
-  /**
-   * Helper method for splitting a string into tokens. The lists passed in are populated with the
-   * tokens and offsets into the content of each token. The tokenization function parses e-mail
-   * addresses as a single token; otherwise it splits on any non-alphanumeric character.
-   *
-   * @param content Content to split.
-   * @return List of token strings.
-   */
-  private static List<String> split(String content) {
-    final Matcher matcher = SPLIT_PATTERN.matcher(content);
-    final ArrayList<String> tokens = new ArrayList<>();
-    while (matcher.find()) {
-      tokens.add(matcher.group());
-    }
-    return tokens;
-  }
-
-  public void setUnknownNameText(CharSequence unknownNameText) {
-    mUnknownNameText = unknownNameText;
-  }
-
-  public void setQuickContactEnabled(boolean flag) {
-    mQuickContactEnabled = flag;
-  }
-
-  /**
-   * Sets whether the call to action is shown. For the {@link CallToAction} to be shown, it must be
-   * supported as well.
-   *
-   * @param action {@link CallToAction} you want to display (if it's supported).
-   * @param listener Listener to notify when the call to action is clicked.
-   * @param position The position in the adapter of the call to action.
-   */
-  public void setCallToAction(@CallToAction int action, Listener listener, int position) {
-    mCallToAction = action;
-    mPosition = position;
-
-    Drawable drawable;
-    int description;
-    OnClickListener onClickListener;
-    if (action == CALL_AND_SHARE) {
-      drawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_phone_attach);
-      drawable.setAutoMirrored(true);
-      description = R.string.description_search_call_and_share;
-      onClickListener = v -> listener.onCallAndShareIconClicked(position);
-    } else if (action == VIDEO && mSupportVideoCall) {
-      drawable =
-          ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_videocam_vd_theme_24);
-      drawable.setAutoMirrored(true);
-      description = R.string.description_search_video_call;
-      onClickListener = v -> listener.onVideoCallIconClicked(position);
-    } else if (action == DUO) {
-      CallIntentBuilder.increaseLightbringerCallButtonAppearInSearchCount();
-      drawable =
-          ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_videocam_vd_theme_24);
-      drawable.setAutoMirrored(true);
-      description = R.string.description_search_video_call;
-      onClickListener = v -> listener.onDuoVideoIconClicked(position);
-    } else {
-      mCallToActionView.setVisibility(View.GONE);
-      mCallToActionView.setOnClickListener(null);
-      return;
-    }
-
-    mCallToActionView.setContentDescription(getContext().getString(description));
-    mCallToActionView.setOnClickListener(onClickListener);
-    mCallToActionView.setImageDrawable(drawable);
-    mCallToActionView.setVisibility(View.VISIBLE);
-  }
-
-  public @CallToAction int getCallToAction() {
-    return mCallToAction;
-  }
-
-  public int getPosition() {
-    return mPosition;
-  }
-
-  /**
-   * Sets whether the view supports a video calling icon. This is independent of whether the view is
-   * actually showing an icon. Support for the video calling icon ensures that the layout leaves
-   * space for the video icon, should it be shown.
-   *
-   * @param supportVideoCall {@code true} if the video call icon is supported, {@code false}
-   *     otherwise.
-   */
-  public void setSupportVideoCallIcon(boolean supportVideoCall) {
-    mSupportVideoCall = supportVideoCall;
-  }
-
-  @Override
-  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-    // We will match parent's width and wrap content vertically, but make sure
-    // height is no less than listPreferredItemHeight.
-    final int specWidth = resolveSize(0, widthMeasureSpec);
-    final int preferredHeight = mPreferredHeight;
-
-    mNameTextViewHeight = 0;
-    mPhoneticNameTextViewHeight = 0;
-    mLabelViewHeight = 0;
-    mDataViewHeight = 0;
-    mLabelAndDataViewMaxHeight = 0;
-    mSnippetTextViewHeight = 0;
-    mStatusTextViewHeight = 0;
-    mCheckBoxWidth = 0;
-
-    ensurePhotoViewSize();
-
-    // Width each TextView is able to use.
-    int effectiveWidth;
-    // All the other Views will honor the photo, so available width for them may be shrunk.
-    if (mPhotoViewWidth > 0 || mKeepHorizontalPaddingForPhotoView) {
-      effectiveWidth =
-          specWidth
-              - getPaddingLeft()
-              - getPaddingRight()
-              - (mPhotoViewWidth + mGapBetweenImageAndText);
-    } else {
-      effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight();
-    }
-
-    if (mIsSectionHeaderEnabled) {
-      effectiveWidth -= mHeaderWidth + mGapBetweenImageAndText;
-    }
-
-    effectiveWidth -= (mCallToActionSize + mCallToActionMargin);
-
-    // Go over all visible text views and measure actual width of each of them.
-    // Also calculate their heights to get the total height for this entire view.
-
-    if (isVisible(mNameTextView)) {
-      // Calculate width for name text - this parallels similar measurement in onLayout.
-      int nameTextWidth = effectiveWidth;
-      if (mPhotoPosition != PhotoPosition.LEFT) {
-        nameTextWidth -= mTextIndent;
-      }
-      mNameTextView.measure(
-          MeasureSpec.makeMeasureSpec(nameTextWidth, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-      mNameTextViewHeight = mNameTextView.getMeasuredHeight();
-    }
-
-    // If both data (phone number/email address) and label (type like "MOBILE") are quite long,
-    // we should ellipsize both using appropriate ratio.
-    final int dataWidth;
-    final int labelWidth;
-    if (isVisible(mDataView)) {
-      if (isVisible(mLabelView)) {
-        final int totalWidth = effectiveWidth - mGapBetweenLabelAndData;
-        dataWidth =
-            ((totalWidth * mDataViewWidthWeight) / (mDataViewWidthWeight + mLabelViewWidthWeight));
-        labelWidth =
-            ((totalWidth * mLabelViewWidthWeight) / (mDataViewWidthWeight + mLabelViewWidthWeight));
-      } else {
-        dataWidth = effectiveWidth;
-        labelWidth = 0;
-      }
-    } else {
-      dataWidth = 0;
-      if (isVisible(mLabelView)) {
-        labelWidth = effectiveWidth;
-      } else {
-        labelWidth = 0;
-      }
-    }
-
-    if (isVisible(mDataView)) {
-      mDataView.measure(
-          MeasureSpec.makeMeasureSpec(dataWidth, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-      mDataViewHeight = mDataView.getMeasuredHeight();
-    }
-
-    if (isVisible(mLabelView)) {
-      mLabelView.measure(
-          MeasureSpec.makeMeasureSpec(labelWidth, MeasureSpec.AT_MOST),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-      mLabelViewHeight = mLabelView.getMeasuredHeight();
-    }
-    mLabelAndDataViewMaxHeight = Math.max(mLabelViewHeight, mDataViewHeight);
-
-    if (isVisible(mSnippetView)) {
-      mSnippetView.measure(
-          MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-      mSnippetTextViewHeight = mSnippetView.getMeasuredHeight();
-    }
-
-    // Status view height is the biggest of the text view and the presence icon
-    if (isVisible(mPresenceIcon)) {
-      mPresenceIcon.measure(
-          MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY));
-      mStatusTextViewHeight = mPresenceIcon.getMeasuredHeight();
-    }
-
-    mCallToActionView.measure(
-        MeasureSpec.makeMeasureSpec(mCallToActionSize, MeasureSpec.EXACTLY),
-        MeasureSpec.makeMeasureSpec(mCallToActionSize, MeasureSpec.EXACTLY));
-
-    if (isVisible(mWorkProfileIcon)) {
-      mWorkProfileIcon.measure(
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-      mNameTextViewHeight = Math.max(mNameTextViewHeight, mWorkProfileIcon.getMeasuredHeight());
-    }
-
-    if (isVisible(mStatusView)) {
-      // Presence and status are in a same row, so status will be affected by icon size.
-      final int statusWidth;
-      if (isVisible(mPresenceIcon)) {
-        statusWidth = (effectiveWidth - mPresenceIcon.getMeasuredWidth() - mPresenceIconMargin);
-      } else {
-        statusWidth = effectiveWidth;
-      }
-      mStatusView.measure(
-          MeasureSpec.makeMeasureSpec(statusWidth, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-      mStatusTextViewHeight = Math.max(mStatusTextViewHeight, mStatusView.getMeasuredHeight());
-    }
-
-    // Calculate height including padding.
-    int height =
-        (mNameTextViewHeight
-            + mPhoneticNameTextViewHeight
-            + mLabelAndDataViewMaxHeight
-            + mSnippetTextViewHeight
-            + mStatusTextViewHeight);
-
-    // Make sure the height is at least as high as the photo
-    height = Math.max(height, mPhotoViewHeight + getPaddingBottom() + getPaddingTop());
-
-    // Make sure height is at least the preferred height
-    height = Math.max(height, preferredHeight);
-
-    // Measure the header if it is visible.
-    if (mHeaderTextView != null && mHeaderTextView.getVisibility() == VISIBLE) {
-      mHeaderTextView.measure(
-          MeasureSpec.makeMeasureSpec(mHeaderWidth, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-    }
-
-    setMeasuredDimension(specWidth, height);
-  }
-
-  @Override
-  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-    final int height = bottom - top;
-    final int width = right - left;
-
-    // Determine the vertical bounds by laying out the header first.
-    int topBound = 0;
-    int leftBound = getPaddingLeft();
-    int rightBound = width - getPaddingRight();
-
-    final boolean isLayoutRtl = ViewUtil.isViewLayoutRtl(this);
-
-    // Put the section header on the left side of the contact view.
-    if (mIsSectionHeaderEnabled) {
-      // Align the text view all the way left, to be consistent with Contacts.
-      if (isLayoutRtl) {
-        rightBound = width;
-      } else {
-        leftBound = 0;
-      }
-      if (mHeaderTextView != null) {
-        int headerHeight = mHeaderTextView.getMeasuredHeight();
-        int headerTopBound = (height + topBound - headerHeight) / 2 + mTextOffsetTop;
-
-        mHeaderTextView.layout(
-            isLayoutRtl ? rightBound - mHeaderWidth : leftBound,
-            headerTopBound,
-            isLayoutRtl ? rightBound : leftBound + mHeaderWidth,
-            headerTopBound + headerHeight);
-      }
-      if (isLayoutRtl) {
-        rightBound -= mHeaderWidth;
-      } else {
-        leftBound += mHeaderWidth;
-      }
-    }
-
-    mBoundsWithoutHeader.set(left + leftBound, topBound, left + rightBound, height);
-    mLeftOffset = left + leftBound;
-    mRightOffset = left + rightBound;
-    if (mIsSectionHeaderEnabled) {
-      if (isLayoutRtl) {
-        rightBound -= mGapBetweenImageAndText;
-      } else {
-        leftBound += mGapBetweenImageAndText;
-      }
-    }
-
-    if (mActivatedStateSupported && isActivated()) {
-      mActivatedBackgroundDrawable.setBounds(mBoundsWithoutHeader);
-    }
-
-    final View photoView = mQuickContact != null ? mQuickContact : mPhotoView;
-    if (mPhotoPosition == PhotoPosition.LEFT) {
-      // Photo is the left most view. All the other Views should on the right of the photo.
-      if (photoView != null) {
-        // Center the photo vertically
-        final int photoTop = topBound + (height - topBound - mPhotoViewHeight) / 2;
-        photoView.layout(
-            leftBound, photoTop, leftBound + mPhotoViewWidth, photoTop + mPhotoViewHeight);
-        leftBound += mPhotoViewWidth + mGapBetweenImageAndText;
-      } else if (mKeepHorizontalPaddingForPhotoView) {
-        // Draw nothing but keep the padding.
-        leftBound += mPhotoViewWidth + mGapBetweenImageAndText;
-      }
-    } else {
-      // Photo is the right most view. Right bound should be adjusted that way.
-      if (photoView != null) {
-        // Center the photo vertically
-        final int photoTop = topBound + (height - topBound - mPhotoViewHeight) / 2;
-        photoView.layout(
-            rightBound - mPhotoViewWidth, photoTop, rightBound, photoTop + mPhotoViewHeight);
-        rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText);
-      } else if (mKeepHorizontalPaddingForPhotoView) {
-        // Draw nothing but keep the padding.
-        rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText);
-      }
-
-      // Add indent between left-most padding and texts.
-      leftBound += mTextIndent;
-    }
-
-    // Place the call to action at the end of the list (e.g. take into account RTL mode).
-    // Center the icon vertically
-    final int callToActionTop = topBound + (height - topBound - mCallToActionSize) / 2;
-
-    if (!isLayoutRtl) {
-      // When photo is on left, icon is placed on the right edge.
-      mCallToActionView.layout(
-          rightBound - mCallToActionSize,
-          callToActionTop,
-          rightBound,
-          callToActionTop + mCallToActionSize);
-    } else {
-      // When photo is on right, icon is placed on the left edge.
-      mCallToActionView.layout(
-          leftBound,
-          callToActionTop,
-          leftBound + mCallToActionSize,
-          callToActionTop + mCallToActionSize);
-    }
-
-    if (mPhotoPosition == PhotoPosition.LEFT) {
-      rightBound -= (mCallToActionSize + mCallToActionMargin);
-    } else {
-      leftBound += mCallToActionSize + mCallToActionMargin;
-    }
-
-    // Center text vertically, then apply the top offset.
-    final int totalTextHeight =
-        mNameTextViewHeight
-            + mPhoneticNameTextViewHeight
-            + mLabelAndDataViewMaxHeight
-            + mSnippetTextViewHeight
-            + mStatusTextViewHeight;
-    int textTopBound = (height + topBound - totalTextHeight) / 2 + mTextOffsetTop;
-
-    // Work Profile icon align top
-    int workProfileIconWidth = 0;
-    if (isVisible(mWorkProfileIcon)) {
-      workProfileIconWidth = mWorkProfileIcon.getMeasuredWidth();
-      final int distanceFromEnd = mCheckBoxWidth > 0 ? mCheckBoxWidth + mGapBetweenImageAndText : 0;
-      if (mPhotoPosition == PhotoPosition.LEFT) {
-        // When photo is on left, label is placed on the right edge of the list item.
-        mWorkProfileIcon.layout(
-            rightBound - workProfileIconWidth - distanceFromEnd,
-            textTopBound,
-            rightBound - distanceFromEnd,
-            textTopBound + mNameTextViewHeight);
-      } else {
-        // When photo is on right, label is placed on the left of data view.
-        mWorkProfileIcon.layout(
-            leftBound + distanceFromEnd,
-            textTopBound,
-            leftBound + workProfileIconWidth + distanceFromEnd,
-            textTopBound + mNameTextViewHeight);
-      }
-    }
-
-    // Layout all text view and presence icon
-    // Put name TextView first
-    if (isVisible(mNameTextView)) {
-      final int distanceFromEnd =
-          workProfileIconWidth
-              + (mCheckBoxWidth > 0 ? mCheckBoxWidth + mGapBetweenImageAndText : 0);
-      if (mPhotoPosition == PhotoPosition.LEFT) {
-        mNameTextView.layout(
-            leftBound,
-            textTopBound,
-            rightBound - distanceFromEnd,
-            textTopBound + mNameTextViewHeight);
-      } else {
-        mNameTextView.layout(
-            leftBound + distanceFromEnd,
-            textTopBound,
-            rightBound,
-            textTopBound + mNameTextViewHeight);
-      }
-    }
-
-    if (isVisible(mNameTextView) || isVisible(mWorkProfileIcon)) {
-      textTopBound += mNameTextViewHeight;
-    }
-
-    // Presence and status
-    if (isLayoutRtl) {
-      int statusRightBound = rightBound;
-      if (isVisible(mPresenceIcon)) {
-        int iconWidth = mPresenceIcon.getMeasuredWidth();
-        mPresenceIcon.layout(
-            rightBound - iconWidth, textTopBound, rightBound, textTopBound + mStatusTextViewHeight);
-        statusRightBound -= (iconWidth + mPresenceIconMargin);
-      }
-
-      if (isVisible(mStatusView)) {
-        mStatusView.layout(
-            leftBound, textTopBound, statusRightBound, textTopBound + mStatusTextViewHeight);
-      }
-    } else {
-      int statusLeftBound = leftBound;
-      if (isVisible(mPresenceIcon)) {
-        int iconWidth = mPresenceIcon.getMeasuredWidth();
-        mPresenceIcon.layout(
-            leftBound, textTopBound, leftBound + iconWidth, textTopBound + mStatusTextViewHeight);
-        statusLeftBound += (iconWidth + mPresenceIconMargin);
-      }
-
-      if (isVisible(mStatusView)) {
-        mStatusView.layout(
-            statusLeftBound, textTopBound, rightBound, textTopBound + mStatusTextViewHeight);
-      }
-    }
-
-    if (isVisible(mStatusView) || isVisible(mPresenceIcon)) {
-      textTopBound += mStatusTextViewHeight;
-    }
-
-    // Rest of text views
-    int dataLeftBound = leftBound;
-
-    // Label and Data align bottom.
-    if (isVisible(mLabelView)) {
-      if (!isLayoutRtl) {
-        mLabelView.layout(
-            dataLeftBound,
-            textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight,
-            rightBound,
-            textTopBound + mLabelAndDataViewMaxHeight);
-        dataLeftBound += mLabelView.getMeasuredWidth() + mGapBetweenLabelAndData;
-      } else {
-        dataLeftBound = leftBound + mLabelView.getMeasuredWidth();
-        mLabelView.layout(
-            rightBound - mLabelView.getMeasuredWidth(),
-            textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight,
-            rightBound,
-            textTopBound + mLabelAndDataViewMaxHeight);
-        rightBound -= (mLabelView.getMeasuredWidth() + mGapBetweenLabelAndData);
-      }
-    }
-
-    if (isVisible(mDataView)) {
-      if (!isLayoutRtl) {
-        mDataView.layout(
-            dataLeftBound,
-            textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight,
-            rightBound,
-            textTopBound + mLabelAndDataViewMaxHeight);
-      } else {
-        mDataView.layout(
-            rightBound - mDataView.getMeasuredWidth(),
-            textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight,
-            rightBound,
-            textTopBound + mLabelAndDataViewMaxHeight);
-      }
-    }
-    if (isVisible(mLabelView) || isVisible(mDataView)) {
-      textTopBound += mLabelAndDataViewMaxHeight;
-    }
-
-    if (isVisible(mSnippetView)) {
-      mSnippetView.layout(
-          leftBound, textTopBound, rightBound, textTopBound + mSnippetTextViewHeight);
-    }
-  }
-
-  @Override
-  public void adjustListItemSelectionBounds(Rect bounds) {
-    if (mAdjustSelectionBoundsEnabled) {
-      bounds.top += mBoundsWithoutHeader.top;
-      bounds.bottom = bounds.top + mBoundsWithoutHeader.height();
-      bounds.left = mBoundsWithoutHeader.left;
-      bounds.right = mBoundsWithoutHeader.right;
-    }
-  }
-
-  protected boolean isVisible(View view) {
-    return view != null && view.getVisibility() == View.VISIBLE;
-  }
-
-  /** Extracts width and height from the style */
-  private void ensurePhotoViewSize() {
-    if (!mPhotoViewWidthAndHeightAreReady) {
-      mPhotoViewWidth = mPhotoViewHeight = getDefaultPhotoViewSize();
-      if (!mQuickContactEnabled && mPhotoView == null) {
-        if (!mKeepHorizontalPaddingForPhotoView) {
-          mPhotoViewWidth = 0;
-        }
-        if (!mKeepVerticalPaddingForPhotoView) {
-          mPhotoViewHeight = 0;
-        }
-      }
-
-      mPhotoViewWidthAndHeightAreReady = true;
-    }
-  }
-
-  protected int getDefaultPhotoViewSize() {
-    return mDefaultPhotoViewSize;
-  }
-
-  /**
-   * Gets a LayoutParam that corresponds to the default photo size.
-   *
-   * @return A new LayoutParam.
-   */
-  private LayoutParams getDefaultPhotoLayoutParams() {
-    LayoutParams params = generateDefaultLayoutParams();
-    params.width = getDefaultPhotoViewSize();
-    params.height = params.width;
-    return params;
-  }
-
-  @Override
-  protected void drawableStateChanged() {
-    super.drawableStateChanged();
-    if (mActivatedStateSupported) {
-      mActivatedBackgroundDrawable.setState(getDrawableState());
-    }
-  }
-
-  @Override
-  protected boolean verifyDrawable(Drawable who) {
-    return who == mActivatedBackgroundDrawable || super.verifyDrawable(who);
-  }
-
-  @Override
-  public void jumpDrawablesToCurrentState() {
-    super.jumpDrawablesToCurrentState();
-    if (mActivatedStateSupported) {
-      mActivatedBackgroundDrawable.jumpToCurrentState();
-    }
-  }
-
-  @Override
-  public void dispatchDraw(Canvas canvas) {
-    if (mActivatedStateSupported && isActivated()) {
-      mActivatedBackgroundDrawable.draw(canvas);
-    }
-
-    super.dispatchDraw(canvas);
-  }
-
-  /** Sets section header or makes it invisible if the title is null. */
-  public void setSectionHeader(String title) {
-    if (!TextUtils.isEmpty(title)) {
-      if (mHeaderTextView == null) {
-        mHeaderTextView = new TextView(getContext());
-        mHeaderTextView.setTextAppearance(R.style.SectionHeaderStyle);
-        mHeaderTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
-        addView(mHeaderTextView);
-      }
-      setMarqueeText(mHeaderTextView, title);
-      mHeaderTextView.setVisibility(View.VISIBLE);
-      mHeaderTextView.setAllCaps(true);
-    } else if (mHeaderTextView != null) {
-      mHeaderTextView.setVisibility(View.GONE);
-    }
-  }
-
-  public void setIsSectionHeaderEnabled(boolean isSectionHeaderEnabled) {
-    mIsSectionHeaderEnabled = isSectionHeaderEnabled;
-  }
-
-  /** Returns the quick contact badge, creating it if necessary. */
-  public QuickContactBadge getQuickContact() {
-    if (!mQuickContactEnabled) {
-      throw new IllegalStateException("QuickContact is disabled for this view");
-    }
-    if (mQuickContact == null) {
-      mQuickContact = new QuickContactBadge(getContext());
-      mQuickContact.setOverlay(null);
-      mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams());
-      if (mNameTextView != null) {
-        mQuickContact.setContentDescription(
-            getContext()
-                .getString(R.string.description_quick_contact_for, mNameTextView.getText()));
-      }
-
-      addView(mQuickContact);
-      mPhotoViewWidthAndHeightAreReady = false;
-    }
-    return mQuickContact;
-  }
-
-  /** Returns the photo view, creating it if necessary. */
-  public ImageView getPhotoView() {
-    if (mPhotoView == null) {
-      mPhotoView = new ImageView(getContext());
-      mPhotoView.setLayoutParams(getDefaultPhotoLayoutParams());
-      // Quick contact style used above will set a background - remove it
-      mPhotoView.setBackground(null);
-      addView(mPhotoView);
-      mPhotoViewWidthAndHeightAreReady = false;
-    }
-    return mPhotoView;
-  }
-
-  /** Removes the photo view. */
-  public void removePhotoView() {
-    removePhotoView(false, true);
-  }
-
-  /**
-   * Removes the photo view.
-   *
-   * @param keepHorizontalPadding True means data on the right side will have padding on left,
-   *     pretending there is still a photo view.
-   * @param keepVerticalPadding True means the View will have some height enough for accommodating a
-   *     photo view.
-   */
-  public void removePhotoView(boolean keepHorizontalPadding, boolean keepVerticalPadding) {
-    mPhotoViewWidthAndHeightAreReady = false;
-    mKeepHorizontalPaddingForPhotoView = keepHorizontalPadding;
-    mKeepVerticalPaddingForPhotoView = keepVerticalPadding;
-    if (mPhotoView != null) {
-      removeView(mPhotoView);
-      mPhotoView = null;
-    }
-    if (mQuickContact != null) {
-      removeView(mQuickContact);
-      mQuickContact = null;
-    }
-  }
-
-  /**
-   * Sets a word prefix that will be highlighted if encountered in fields like name and search
-   * snippet. This will disable the mask highlighting for names.
-   *
-   * <p>NOTE: must be all upper-case
-   */
-  public void setHighlightedPrefix(String upperCasePrefix) {
-    mHighlightedPrefix = upperCasePrefix;
-  }
-
-  /** Clears previously set highlight sequences for the view. */
-  public void clearHighlightSequences() {
-    mNameHighlightSequence.clear();
-    mNumberHighlightSequence.clear();
-    mHighlightedPrefix = null;
-  }
-
-  /**
-   * Adds a highlight sequence to the name highlighter.
-   *
-   * @param start The start position of the highlight sequence.
-   * @param end The end position of the highlight sequence.
-   */
-  public void addNameHighlightSequence(int start, int end) {
-    mNameHighlightSequence.add(new HighlightSequence(start, end));
-  }
-
-  /**
-   * Adds a highlight sequence to the number highlighter.
-   *
-   * @param start The start position of the highlight sequence.
-   * @param end The end position of the highlight sequence.
-   */
-  public void addNumberHighlightSequence(int start, int end) {
-    mNumberHighlightSequence.add(new HighlightSequence(start, end));
-  }
-
-  /** Returns the text view for the contact name, creating it if necessary. */
-  public TextView getNameTextView() {
-    if (mNameTextView == null) {
-      mNameTextView = new TextView(getContext());
-      mNameTextView.setSingleLine(true);
-      mNameTextView.setEllipsize(getTextEllipsis());
-      mNameTextView.setTextColor(mNameTextViewTextColor);
-      mNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mNameTextViewTextSize);
-      // Manually call setActivated() since this view may be added after the first
-      // setActivated() call toward this whole item view.
-      mNameTextView.setActivated(isActivated());
-      mNameTextView.setGravity(Gravity.CENTER_VERTICAL);
-      mNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
-      mNameTextView.setId(R.id.cliv_name_textview);
-      mNameTextView.setElegantTextHeight(false);
-      addView(mNameTextView);
-    }
-    return mNameTextView;
-  }
-
-  /** Adds or updates a text view for the data label. */
-  public void setLabel(CharSequence text) {
-    if (TextUtils.isEmpty(text)) {
-      if (mLabelView != null) {
-        mLabelView.setVisibility(View.GONE);
-      }
-    } else {
-      getLabelView();
-      setMarqueeText(mLabelView, text);
-      mLabelView.setVisibility(VISIBLE);
-    }
-  }
-
-  /** Returns the text view for the data label, creating it if necessary. */
-  public TextView getLabelView() {
-    if (mLabelView == null) {
-      mLabelView = new TextView(getContext());
-      mLabelView.setLayoutParams(
-          new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-
-      mLabelView.setSingleLine(true);
-      mLabelView.setEllipsize(getTextEllipsis());
-      mLabelView.setTextAppearance(R.style.TextAppearanceSmall);
-      if (mPhotoPosition == PhotoPosition.LEFT) {
-        mLabelView.setAllCaps(true);
-      } else {
-        mLabelView.setTypeface(mLabelView.getTypeface(), Typeface.BOLD);
-      }
-      mLabelView.setActivated(isActivated());
-      mLabelView.setId(R.id.cliv_label_textview);
-      addView(mLabelView);
-    }
-    return mLabelView;
-  }
-
-  /**
-   * Sets phone number for a list item. This takes care of number highlighting if the highlight mask
-   * exists.
-   */
-  public void setPhoneNumber(String text) {
-    mPhoneNumber = text;
-    if (text == null) {
-      if (mDataView != null) {
-        mDataView.setVisibility(View.GONE);
-      }
-    } else {
-      getDataView();
-
-      // TODO: Format number using PhoneNumberUtils.formatNumber before assigning it to
-      // mDataView. Make sure that determination of the highlight sequences are done only
-      // after number formatting.
-
-      // Sets phone number texts for display after highlighting it, if applicable.
-      // CharSequence textToSet = text;
-      final SpannableString textToSet = new SpannableString(text);
-
-      if (mNumberHighlightSequence.size() != 0) {
-        final HighlightSequence highlightSequence = mNumberHighlightSequence.get(0);
-        mTextHighlighter.applyMaskingHighlight(
-            textToSet, highlightSequence.start, highlightSequence.end);
-      }
-
-      setMarqueeText(mDataView, textToSet);
-      mDataView.setVisibility(VISIBLE);
-
-      // We have a phone number as "mDataView" so make it always LTR and VIEW_START
-      mDataView.setTextDirection(View.TEXT_DIRECTION_LTR);
-      mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
-    }
-  }
-
-  public String getPhoneNumber() {
-    return mPhoneNumber;
-  }
-
-  private void setMarqueeText(TextView textView, CharSequence text) {
-    if (getTextEllipsis() == TruncateAt.MARQUEE) {
-      // To show MARQUEE correctly (with END effect during non-active state), we need
-      // to build Spanned with MARQUEE in addition to TextView's ellipsize setting.
-      final SpannableString spannable = new SpannableString(text);
-      spannable.setSpan(
-          TruncateAt.MARQUEE, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-      textView.setText(spannable);
-    } else {
-      textView.setText(text);
-    }
-  }
-
-  /** Returns the text view for the data text, creating it if necessary. */
-  public TextView getDataView() {
-    if (mDataView == null) {
-      mDataView = new TextView(getContext());
-      mDataView.setSingleLine(true);
-      mDataView.setEllipsize(getTextEllipsis());
-      mDataView.setTextAppearance(R.style.TextAppearanceSmall);
-      mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
-      mDataView.setActivated(isActivated());
-      mDataView.setId(R.id.cliv_data_view);
-      mDataView.setElegantTextHeight(false);
-      addView(mDataView);
-    }
-    return mDataView;
-  }
-
-  /** Adds or updates a text view for the search snippet. */
-  public void setSnippet(String text) {
-    if (TextUtils.isEmpty(text)) {
-      if (mSnippetView != null) {
-        mSnippetView.setVisibility(View.GONE);
-      }
-    } else {
-      mTextHighlighter.setPrefixText(getSnippetView(), text, mHighlightedPrefix);
-      mSnippetView.setVisibility(VISIBLE);
-      if (ContactDisplayUtils.isPossiblePhoneNumber(text)) {
-        // Give the text-to-speech engine a hint that it's a phone number
-        mSnippetView.setContentDescription(PhoneNumberUtils.createTtsSpannable(text));
-      } else {
-        mSnippetView.setContentDescription(null);
-      }
-    }
-  }
-
-  /** Returns the text view for the search snippet, creating it if necessary. */
-  public TextView getSnippetView() {
-    if (mSnippetView == null) {
-      mSnippetView = new TextView(getContext());
-      mSnippetView.setSingleLine(true);
-      mSnippetView.setEllipsize(getTextEllipsis());
-      mSnippetView.setTextAppearance(android.R.style.TextAppearance_Small);
-      mSnippetView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
-      mSnippetView.setActivated(isActivated());
-      addView(mSnippetView);
-    }
-    return mSnippetView;
-  }
-
-  /** Returns the text view for the status, creating it if necessary. */
-  public TextView getStatusView() {
-    if (mStatusView == null) {
-      mStatusView = new TextView(getContext());
-      mStatusView.setSingleLine(true);
-      mStatusView.setEllipsize(getTextEllipsis());
-      mStatusView.setTextAppearance(android.R.style.TextAppearance_Small);
-      mStatusView.setTextColor(mSecondaryTextColor);
-      mStatusView.setActivated(isActivated());
-      mStatusView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
-      addView(mStatusView);
-    }
-    return mStatusView;
-  }
-
-  /** Adds or updates a text view for the status. */
-  public void setStatus(CharSequence text) {
-    if (TextUtils.isEmpty(text)) {
-      if (mStatusView != null) {
-        mStatusView.setVisibility(View.GONE);
-      }
-    } else {
-      getStatusView();
-      setMarqueeText(mStatusView, text);
-      mStatusView.setVisibility(VISIBLE);
-    }
-  }
-
-  /** Adds or updates the presence icon view. */
-  public void setPresence(Drawable icon) {
-    if (icon != null) {
-      if (mPresenceIcon == null) {
-        mPresenceIcon = new ImageView(getContext());
-        addView(mPresenceIcon);
-      }
-      mPresenceIcon.setImageDrawable(icon);
-      mPresenceIcon.setScaleType(ScaleType.CENTER);
-      mPresenceIcon.setVisibility(View.VISIBLE);
-    } else {
-      if (mPresenceIcon != null) {
-        mPresenceIcon.setVisibility(View.GONE);
-      }
-    }
-  }
-
-  /**
-   * Set to display work profile icon or not
-   *
-   * @param enabled set to display work profile icon or not
-   */
-  public void setWorkProfileIconEnabled(boolean enabled) {
-    if (mWorkProfileIcon != null) {
-      mWorkProfileIcon.setVisibility(enabled ? View.VISIBLE : View.GONE);
-    } else if (enabled) {
-      mWorkProfileIcon = new ImageView(getContext());
-      addView(mWorkProfileIcon);
-      mWorkProfileIcon.setImageResource(R.drawable.ic_work_profile);
-      mWorkProfileIcon.setScaleType(ScaleType.CENTER_INSIDE);
-      mWorkProfileIcon.setVisibility(View.VISIBLE);
-    }
-  }
-
-  private TruncateAt getTextEllipsis() {
-    return TruncateAt.MARQUEE;
-  }
-
-  public void showDisplayName(Cursor cursor, int nameColumnIndex) {
-    CharSequence name = cursor.getString(nameColumnIndex);
-    setDisplayName(name);
-
-    // Since the quick contact content description is derived from the display name and there is
-    // no guarantee that when the quick contact is initialized the display name is already set,
-    // do it here too.
-    if (mQuickContact != null) {
-      mQuickContact.setContentDescription(
-          getContext().getString(R.string.description_quick_contact_for, mNameTextView.getText()));
-    }
-  }
-
-  public void setDisplayName(CharSequence name) {
-    if (!TextUtils.isEmpty(name)) {
-      // Chooses the available highlighting method for highlighting.
-      if (mHighlightedPrefix != null) {
-        name = mTextHighlighter.applyPrefixHighlight(name, mHighlightedPrefix);
-      } else if (mNameHighlightSequence.size() != 0) {
-        final SpannableString spannableName = new SpannableString(name);
-        for (HighlightSequence highlightSequence : mNameHighlightSequence) {
-          mTextHighlighter.applyMaskingHighlight(
-              spannableName, highlightSequence.start, highlightSequence.end);
-        }
-        name = spannableName;
-      }
-    } else {
-      name = mUnknownNameText;
-    }
-    setMarqueeText(getNameTextView(), name);
-
-    if (ContactDisplayUtils.isPossiblePhoneNumber(name)) {
-      // Give the text-to-speech engine a hint that it's a phone number
-      mNameTextView.setTextDirection(View.TEXT_DIRECTION_LTR);
-      mNameTextView.setContentDescription(PhoneNumberUtils.createTtsSpannable(name.toString()));
-    } else {
-      // Remove span tags of highlighting for talkback to avoid reading highlighting and rest
-      // of the name into two separate parts.
-      mNameTextView.setContentDescription(name.toString());
-    }
-  }
-
-  public void hideDisplayName() {
-    if (mNameTextView != null) {
-      removeView(mNameTextView);
-      mNameTextView = null;
-    }
-  }
-
-  /** Sets the proper icon (star or presence or nothing) and/or status message. */
-  public void showPresenceAndStatusMessage(
-      Cursor cursor, int presenceColumnIndex, int contactStatusColumnIndex) {
-    Drawable icon = null;
-    int presence = 0;
-    if (!cursor.isNull(presenceColumnIndex)) {
-      presence = cursor.getInt(presenceColumnIndex);
-      icon = ContactPresenceIconUtil.getPresenceIcon(getContext(), presence);
-    }
-    setPresence(icon);
-
-    String statusMessage = null;
-    if (contactStatusColumnIndex != 0 && !cursor.isNull(contactStatusColumnIndex)) {
-      statusMessage = cursor.getString(contactStatusColumnIndex);
-    }
-    // If there is no status message from the contact, but there was a presence value, then use
-    // the default status message string
-    if (statusMessage == null && presence != 0) {
-      statusMessage = ContactStatusUtil.getStatusString(getContext(), presence);
-    }
-    setStatus(statusMessage);
-  }
-
-  /** Shows search snippet. */
-  public void showSnippet(Cursor cursor, int summarySnippetColumnIndex) {
-    if (cursor.getColumnCount() <= summarySnippetColumnIndex
-        || !SearchSnippets.SNIPPET.equals(cursor.getColumnName(summarySnippetColumnIndex))) {
-      setSnippet(null);
-      return;
-    }
-
-    String snippet = cursor.getString(summarySnippetColumnIndex);
-
-    // Do client side snippeting if provider didn't do it
-    final Bundle extras = cursor.getExtras();
-    if (extras.getBoolean(ContactsContract.DEFERRED_SNIPPETING)) {
-
-      final String query = extras.getString(ContactsContract.DEFERRED_SNIPPETING_QUERY);
-
-      String displayName = null;
-      int displayNameIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
-      if (displayNameIndex >= 0) {
-        displayName = cursor.getString(displayNameIndex);
-      }
-
-      snippet = updateSnippet(snippet, query, displayName);
-
-    } else {
-      if (snippet != null) {
-        int from = 0;
-        int to = snippet.length();
-        int start = snippet.indexOf(SNIPPET_START_MATCH);
-        if (start == -1) {
-          snippet = null;
-        } else {
-          int firstNl = snippet.lastIndexOf('\n', start);
-          if (firstNl != -1) {
-            from = firstNl + 1;
-          }
-          int end = snippet.lastIndexOf(SNIPPET_END_MATCH);
-          if (end != -1) {
-            int lastNl = snippet.indexOf('\n', end);
-            if (lastNl != -1) {
-              to = lastNl;
-            }
-          }
-
-          StringBuilder sb = new StringBuilder();
-          for (int i = from; i < to; i++) {
-            char c = snippet.charAt(i);
-            if (c != SNIPPET_START_MATCH && c != SNIPPET_END_MATCH) {
-              sb.append(c);
-            }
-          }
-          snippet = sb.toString();
-        }
-      }
-    }
-
-    setSnippet(snippet);
-  }
-
-  /**
-   * Used for deferred snippets from the database. The contents come back as large strings which
-   * need to be extracted for display.
-   *
-   * @param snippet The snippet from the database.
-   * @param query The search query substring.
-   * @param displayName The contact display name.
-   * @return The proper snippet to display.
-   */
-  private String updateSnippet(String snippet, String query, String displayName) {
-
-    if (TextUtils.isEmpty(snippet) || TextUtils.isEmpty(query)) {
-      return null;
-    }
-    query = SearchUtil.cleanStartAndEndOfSearchQuery(query.toLowerCase());
-
-    // If the display name already contains the query term, return empty - snippets should
-    // not be needed in that case.
-    if (!TextUtils.isEmpty(displayName)) {
-      final String lowerDisplayName = displayName.toLowerCase();
-      final List<String> nameTokens = split(lowerDisplayName);
-      for (String nameToken : nameTokens) {
-        if (nameToken.startsWith(query)) {
-          return null;
-        }
-      }
-    }
-
-    // The snippet may contain multiple data lines.
-    // Show the first line that matches the query.
-    final SearchUtil.MatchedLine matched = SearchUtil.findMatchingLine(snippet, query);
-
-    if (matched != null && matched.line != null) {
-      // Tokenize for long strings since the match may be at the end of it.
-      // Skip this part for short strings since the whole string will be displayed.
-      // Most contact strings are short so the snippetize method will be called infrequently.
-      final int lengthThreshold =
-          getResources().getInteger(R.integer.snippet_length_before_tokenize);
-      if (matched.line.length() > lengthThreshold) {
-        return snippetize(matched.line, matched.startIndex, lengthThreshold);
-      } else {
-        return matched.line;
-      }
-    }
-
-    // No match found.
-    return null;
-  }
-
-  private String snippetize(String line, int matchIndex, int maxLength) {
-    // Show up to maxLength characters. But we only show full tokens so show the last full token
-    // up to maxLength characters. So as many starting tokens as possible before trying ending
-    // tokens.
-    int remainingLength = maxLength;
-    int tempRemainingLength = remainingLength;
-
-    // Start the end token after the matched query.
-    int index = matchIndex;
-    int endTokenIndex = index;
-
-    // Find the match token first.
-    while (index < line.length()) {
-      if (!Character.isLetterOrDigit(line.charAt(index))) {
-        endTokenIndex = index;
-        remainingLength = tempRemainingLength;
-        break;
-      }
-      tempRemainingLength--;
-      index++;
-    }
-
-    // Find as much content before the match.
-    index = matchIndex - 1;
-    tempRemainingLength = remainingLength;
-    int startTokenIndex = matchIndex;
-    while (index > -1 && tempRemainingLength > 0) {
-      if (!Character.isLetterOrDigit(line.charAt(index))) {
-        startTokenIndex = index;
-        remainingLength = tempRemainingLength;
-      }
-      tempRemainingLength--;
-      index--;
-    }
-
-    index = endTokenIndex;
-    tempRemainingLength = remainingLength;
-    // Find remaining content at after match.
-    while (index < line.length() && tempRemainingLength > 0) {
-      if (!Character.isLetterOrDigit(line.charAt(index))) {
-        endTokenIndex = index;
-      }
-      tempRemainingLength--;
-      index++;
-    }
-    // Append ellipse if there is content before or after.
-    final StringBuilder sb = new StringBuilder();
-    if (startTokenIndex > 0) {
-      sb.append("...");
-    }
-    sb.append(line.substring(startTokenIndex, endTokenIndex));
-    if (endTokenIndex < line.length()) {
-      sb.append("...");
-    }
-    return sb.toString();
-  }
-
-  public void setActivatedStateSupported(boolean flag) {
-    this.mActivatedStateSupported = flag;
-  }
-
-  public void setAdjustSelectionBoundsEnabled(boolean enabled) {
-    mAdjustSelectionBoundsEnabled = enabled;
-  }
-
-  @Override
-  public void requestLayout() {
-    // We will assume that once measured this will not need to resize
-    // itself, so there is no need to pass the layout request to the parent
-    // view (ListView).
-    forceLayout();
-  }
-
-  /**
-   * Set drawable resources directly for the drawable resource of the photo view.
-   *
-   * @param drawable A drawable resource.
-   */
-  public void setDrawable(Drawable drawable) {
-    ImageView photo = getPhotoView();
-    photo.setScaleType(ImageView.ScaleType.CENTER);
-    int iconColor = ContextCompat.getColor(getContext(), R.color.search_shortcut_icon_color);
-    photo.setImageDrawable(drawable);
-    photo.setImageTintList(ColorStateList.valueOf(iconColor));
-  }
-
-  @Override
-  public boolean onTouchEvent(MotionEvent event) {
-    final float x = event.getX();
-    final float y = event.getY();
-    // If the touch event's coordinates are not within the view's header, then delegate
-    // to super.onTouchEvent so that regular view behavior is preserved. Otherwise, consume
-    // and ignore the touch event.
-    if (mBoundsWithoutHeader.contains((int) x, (int) y) || !pointIsInView(x, y)) {
-      return super.onTouchEvent(event);
-    } else {
-      return true;
-    }
-  }
-
-  private boolean pointIsInView(float localX, float localY) {
-    return localX >= mLeftOffset
-        && localX < mRightOffset
-        && localY >= 0
-        && localY < (getBottom() - getTop());
-  }
-
-  /**
-   * Where to put contact photo. This affects the other Views' layout or look-and-feel.
-   *
-   * <p>TODO: replace enum with int constants
-   */
-  public enum PhotoPosition {
-    LEFT,
-    RIGHT
-  }
-
-  protected static class HighlightSequence {
-
-    private final int start;
-    private final int end;
-
-    HighlightSequence(int start, int end) {
-      this.start = start;
-      this.end = end;
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/ContactListPinnedHeaderView.java b/java/com/android/contacts/common/list/ContactListPinnedHeaderView.java
deleted file mode 100644
index 1f3e2bf..0000000
--- a/java/com/android/contacts/common/list/ContactListPinnedHeaderView.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.TextView;
-import com.android.contacts.common.R;
-
-/** A custom view for the pinned section header shown at the top of the contact list. */
-public class ContactListPinnedHeaderView extends TextView {
-
-  public ContactListPinnedHeaderView(Context context, AttributeSet attrs, View parent) {
-    super(context, attrs);
-
-    if (R.styleable.ContactListItemView == null) {
-      return;
-    }
-    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView);
-    int backgroundColor =
-        a.getColor(R.styleable.ContactListItemView_list_item_background_color, Color.WHITE);
-    int textOffsetTop =
-        a.getDimensionPixelSize(R.styleable.ContactListItemView_list_item_text_offset_top, 0);
-    int paddingStartOffset =
-        a.getDimensionPixelSize(R.styleable.ContactListItemView_list_item_padding_left, 0);
-    int textWidth = getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width);
-    int widthIncludingPadding = paddingStartOffset + textWidth;
-    a.recycle();
-
-    setBackgroundColor(backgroundColor);
-    setTextAppearance(getContext(), R.style.SectionHeaderStyle);
-    setLayoutParams(new LayoutParams(textWidth, LayoutParams.WRAP_CONTENT));
-    setLayoutDirection(parent.getLayoutDirection());
-    setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
-
-    // Apply text top offset. Multiply by two, because we are implementing this by padding for a
-    // vertically centered view, rather than adjusting the position directly via a layout.
-    setPaddingRelative(
-        0, getPaddingTop() + (textOffsetTop * 2), getPaddingEnd(), getPaddingBottom());
-  }
-
-  /** Sets section header or makes it invisible if the title is null. */
-  public void setSectionHeaderTitle(String title) {
-    if (!TextUtils.isEmpty(title)) {
-      setText(title);
-    } else {
-      setVisibility(View.GONE);
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/ContactsSectionIndexer.java b/java/com/android/contacts/common/list/ContactsSectionIndexer.java
deleted file mode 100644
index 3f0f2b7..0000000
--- a/java/com/android/contacts/common/list/ContactsSectionIndexer.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.text.TextUtils;
-import android.widget.SectionIndexer;
-import java.util.Arrays;
-
-/**
- * A section indexer that is configured with precomputed section titles and their respective counts.
- */
-public class ContactsSectionIndexer implements SectionIndexer {
-
-  private static final String BLANK_HEADER_STRING = " ";
-  private String[] mSections;
-  private int[] mPositions;
-  private int mCount;
-
-  /**
-   * Constructor.
-   *
-   * @param sections a non-null array
-   * @param counts a non-null array of the same size as <code>sections</code>
-   */
-  public ContactsSectionIndexer(String[] sections, int[] counts) {
-    if (sections == null || counts == null) {
-      throw new NullPointerException();
-    }
-
-    if (sections.length != counts.length) {
-      throw new IllegalArgumentException(
-          "The sections and counts arrays must have the same length");
-    }
-
-    // TODO process sections/counts based on current locale and/or specific section titles
-
-    this.mSections = sections;
-    mPositions = new int[counts.length];
-    int position = 0;
-    for (int i = 0; i < counts.length; i++) {
-      if (TextUtils.isEmpty(mSections[i])) {
-        mSections[i] = BLANK_HEADER_STRING;
-      } else if (!mSections[i].equals(BLANK_HEADER_STRING)) {
-        mSections[i] = mSections[i].trim();
-      }
-
-      mPositions[i] = position;
-      position += counts[i];
-    }
-    mCount = position;
-  }
-
-  public Object[] getSections() {
-    return mSections;
-  }
-
-  public int getPositionForSection(int section) {
-    if (section < 0 || section >= mSections.length) {
-      return -1;
-    }
-
-    return mPositions[section];
-  }
-
-  public int getSectionForPosition(int position) {
-    if (position < 0 || position >= mCount) {
-      return -1;
-    }
-
-    int index = Arrays.binarySearch(mPositions, position);
-
-    /*
-     * Consider this example: section positions are 0, 3, 5; the supplied
-     * position is 4. The section corresponding to position 4 starts at
-     * position 3, so the expected return value is 1. Binary search will not
-     * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
-     * To get from that number to the expected value of 1 we need to negate
-     * and subtract 2.
-     */
-    return index >= 0 ? index : -index - 2;
-  }
-
-  public void setProfileAndFavoritesHeader(String header, int numberOfItemsToAdd) {
-    if (mSections != null) {
-      // Don't do anything if the header is already set properly.
-      if (mSections.length > 0 && header.equals(mSections[0])) {
-        return;
-      }
-
-      // Since the section indexer isn't aware of the profile at the top, we need to add a
-      // special section at the top for it and shift everything else down.
-      String[] tempSections = new String[mSections.length + 1];
-      int[] tempPositions = new int[mPositions.length + 1];
-      tempSections[0] = header;
-      tempPositions[0] = 0;
-      for (int i = 1; i <= mPositions.length; i++) {
-        tempSections[i] = mSections[i - 1];
-        tempPositions[i] = mPositions[i - 1] + numberOfItemsToAdd;
-      }
-      mSections = tempSections;
-      mPositions = tempPositions;
-      mCount = mCount + numberOfItemsToAdd;
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/DefaultContactListAdapter.java b/java/com/android/contacts/common/list/DefaultContactListAdapter.java
deleted file mode 100644
index 7bcae0e..0000000
--- a/java/com/android/contacts/common/list/DefaultContactListAdapter.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.content.CursorLoader;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.net.Uri;
-import android.net.Uri.Builder;
-import android.preference.PreferenceManager;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.SearchSnippets;
-import android.text.TextUtils;
-import android.view.View;
-import com.android.contacts.common.compat.ContactsCompat;
-import com.android.contacts.common.preference.ContactsPreferences;
-import java.util.ArrayList;
-import java.util.List;
-
-/** A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type. */
-public class DefaultContactListAdapter extends ContactListAdapter {
-
-  public DefaultContactListAdapter(Context context) {
-    super(context);
-  }
-
-  @Override
-  public void configureLoader(CursorLoader loader, long directoryId) {
-    String sortOrder = null;
-    if (isSearchMode()) {
-      String query = getQueryString();
-      if (query == null) {
-        query = "";
-      }
-      query = query.trim();
-      if (TextUtils.isEmpty(query)) {
-        // Regardless of the directory, we don't want anything returned,
-        // so let's just send a "nothing" query to the local directory.
-        loader.setUri(Contacts.CONTENT_URI);
-        loader.setProjection(getProjection(false));
-        loader.setSelection("0");
-      } else {
-        final Builder builder = ContactsCompat.getContentUri().buildUpon();
-        appendSearchParameters(builder, query, directoryId);
-        loader.setUri(builder.build());
-        loader.setProjection(getProjection(true));
-      }
-    } else {
-      final ContactListFilter filter = getFilter();
-      configureUri(loader, directoryId, filter);
-      loader.setProjection(getProjection(false));
-      configureSelection(loader, directoryId, filter);
-    }
-
-    if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
-      if (sortOrder == null) {
-        sortOrder = Contacts.SORT_KEY_PRIMARY;
-      } else {
-        sortOrder += ", " + Contacts.SORT_KEY_PRIMARY;
-      }
-    } else {
-      if (sortOrder == null) {
-        sortOrder = Contacts.SORT_KEY_ALTERNATIVE;
-      } else {
-        sortOrder += ", " + Contacts.SORT_KEY_ALTERNATIVE;
-      }
-    }
-    loader.setSortOrder(sortOrder);
-  }
-
-  private void appendSearchParameters(Builder builder, String query, long directoryId) {
-    builder.appendPath(query); // Builder will encode the query
-    builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId));
-    if (directoryId != Directory.DEFAULT && directoryId != Directory.LOCAL_INVISIBLE) {
-      builder.appendQueryParameter(
-          ContactsContract.LIMIT_PARAM_KEY,
-          String.valueOf(getDirectoryResultLimit(getDirectoryById(directoryId))));
-    }
-    builder.appendQueryParameter(SearchSnippets.DEFERRED_SNIPPETING_KEY, "1");
-  }
-
-  protected void configureUri(CursorLoader loader, long directoryId, ContactListFilter filter) {
-    Uri uri = Contacts.CONTENT_URI;
-
-    if (directoryId == Directory.DEFAULT && isSectionHeaderDisplayEnabled()) {
-      uri = ContactListAdapter.buildSectionIndexerUri(uri);
-    }
-
-    // The "All accounts" filter is the same as the entire contents of Directory.DEFAULT
-    if (filter != null
-        && filter.filterType != ContactListFilter.FILTER_TYPE_CUSTOM
-        && filter.filterType != ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
-      final Uri.Builder builder = uri.buildUpon();
-      builder.appendQueryParameter(
-          ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT));
-      if (filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
-        filter.addAccountQueryParameterToUrl(builder);
-      }
-      uri = builder.build();
-    }
-
-    loader.setUri(uri);
-  }
-
-  private void configureSelection(CursorLoader loader, long directoryId, ContactListFilter filter) {
-    if (filter == null) {
-      return;
-    }
-
-    if (directoryId != Directory.DEFAULT) {
-      return;
-    }
-
-    StringBuilder selection = new StringBuilder();
-    List<String> selectionArgs = new ArrayList<String>();
-
-    switch (filter.filterType) {
-      case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS:
-        {
-          // We have already added directory=0 to the URI, which takes care of this
-          // filter
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT:
-        {
-          // We have already added the lookup key to the URI, which takes care of this
-          // filter
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_STARRED:
-        {
-          selection.append(Contacts.STARRED + "!=0");
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY:
-        {
-          selection.append(Contacts.HAS_PHONE_NUMBER + "=1");
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_CUSTOM:
-        {
-          selection.append(Contacts.IN_VISIBLE_GROUP + "=1");
-          if (isCustomFilterForPhoneNumbersOnly()) {
-            selection.append(" AND " + Contacts.HAS_PHONE_NUMBER + "=1");
-          }
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_ACCOUNT:
-        {
-          // We use query parameters for account filter, so no selection to add here.
-          break;
-        }
-    }
-    loader.setSelection(selection.toString());
-    loader.setSelectionArgs(selectionArgs.toArray(new String[0]));
-  }
-
-  @Override
-  protected void bindView(View itemView, int partition, Cursor cursor, int position) {
-    super.bindView(itemView, partition, cursor, position);
-    final ContactListItemView view = (ContactListItemView) itemView;
-
-    view.setHighlightedPrefix(isSearchMode() ? getUpperCaseQueryString() : null);
-
-    bindSectionHeaderAndDivider(view, position, cursor);
-
-    if (isQuickContactEnabled()) {
-      bindQuickContact(
-          view,
-          partition,
-          cursor,
-          ContactQuery.CONTACT_PHOTO_ID,
-          ContactQuery.CONTACT_PHOTO_URI,
-          ContactQuery.CONTACT_ID,
-          ContactQuery.CONTACT_LOOKUP_KEY,
-          ContactQuery.CONTACT_DISPLAY_NAME);
-    } else {
-      if (getDisplayPhotos()) {
-        bindPhoto(view, partition, cursor);
-      }
-    }
-
-    bindNameAndViewId(view, cursor);
-    bindPresenceAndStatusMessage(view, cursor);
-
-    if (isSearchMode()) {
-      bindSearchSnippet(view, cursor);
-    } else {
-      view.setSnippet(null);
-    }
-  }
-
-  private boolean isCustomFilterForPhoneNumbersOnly() {
-    // TODO: this flag should not be stored in shared prefs.  It needs to be in the db.
-    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
-    return prefs.getBoolean(
-        ContactsPreferences.PREF_DISPLAY_ONLY_PHONES,
-        ContactsPreferences.PREF_DISPLAY_ONLY_PHONES_DEFAULT);
-  }
-}
diff --git a/java/com/android/contacts/common/list/DirectoryListLoader.java b/java/com/android/contacts/common/list/DirectoryListLoader.java
deleted file mode 100644
index ce78d2c..0000000
--- a/java/com/android/contacts/common/list/DirectoryListLoader.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.AsyncTaskLoader;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.ContactsContract.Directory;
-import android.text.TextUtils;
-import com.android.contacts.common.R;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.cp2.DirectoryCompat;
-import com.android.dialer.util.PermissionsUtil;
-
-/** A specialized loader for the list of directories, see {@link Directory}. */
-public class DirectoryListLoader extends AsyncTaskLoader<Cursor> {
-
-  public static final int SEARCH_MODE_NONE = 0;
-  public static final int SEARCH_MODE_DEFAULT = 1;
-  public static final int SEARCH_MODE_CONTACT_SHORTCUT = 2;
-  public static final int SEARCH_MODE_DATA_SHORTCUT = 3;
-  // This is a virtual column created for a MatrixCursor.
-  public static final String DIRECTORY_TYPE = "directoryType";
-  private static final String[] RESULT_PROJECTION = {
-    Directory._ID, DIRECTORY_TYPE, Directory.DISPLAY_NAME, Directory.PHOTO_SUPPORT,
-  };
-  private final ContentObserver mObserver =
-      new ContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange) {
-          forceLoad();
-        }
-      };
-  private int mDirectorySearchMode;
-  private boolean mLocalInvisibleDirectoryEnabled;
-  private MatrixCursor mDefaultDirectoryList;
-
-  public DirectoryListLoader(Context context) {
-    super(context);
-  }
-
-  public void setDirectorySearchMode(int mode) {
-    mDirectorySearchMode = mode;
-  }
-
-  /**
-   * A flag that indicates whether the {@link Directory#LOCAL_INVISIBLE} directory should be
-   * included in the results.
-   */
-  public void setLocalInvisibleDirectoryEnabled(boolean flag) {
-    this.mLocalInvisibleDirectoryEnabled = flag;
-  }
-
-  @Override
-  protected void onStartLoading() {
-    if (PermissionsUtil.hasContactsReadPermissions(getContext())) {
-      getContext()
-          .getContentResolver()
-          .registerContentObserver(DirectoryQuery.URI, false, mObserver);
-    } else {
-      LogUtil.w("DirectoryListLoader.onStartLoading", "contacts permission not available.");
-    }
-    forceLoad();
-  }
-
-  @Override
-  protected void onStopLoading() {
-    getContext().getContentResolver().unregisterContentObserver(mObserver);
-  }
-
-  @Override
-  public Cursor loadInBackground() {
-    if (mDirectorySearchMode == SEARCH_MODE_NONE) {
-      return getDefaultDirectories();
-    }
-
-    MatrixCursor result = new MatrixCursor(RESULT_PROJECTION);
-    Context context = getContext();
-    PackageManager pm = context.getPackageManager();
-    String selection;
-    switch (mDirectorySearchMode) {
-      case SEARCH_MODE_DEFAULT:
-        selection = null;
-        break;
-
-      case SEARCH_MODE_CONTACT_SHORTCUT:
-        selection = Directory.SHORTCUT_SUPPORT + "=" + Directory.SHORTCUT_SUPPORT_FULL;
-        break;
-
-      case SEARCH_MODE_DATA_SHORTCUT:
-        selection =
-            Directory.SHORTCUT_SUPPORT
-                + " IN ("
-                + Directory.SHORTCUT_SUPPORT_FULL
-                + ", "
-                + Directory.SHORTCUT_SUPPORT_DATA_ITEMS_ONLY
-                + ")";
-        break;
-
-      default:
-        throw new RuntimeException("Unsupported directory search mode: " + mDirectorySearchMode);
-    }
-    Cursor cursor = null;
-    try {
-      cursor =
-          context
-              .getContentResolver()
-              .query(
-                  DirectoryQuery.URI,
-                  DirectoryQuery.PROJECTION,
-                  selection,
-                  null,
-                  DirectoryQuery.ORDER_BY);
-
-      if (cursor == null) {
-        return result;
-      }
-
-      while (cursor.moveToNext()) {
-        long directoryId = cursor.getLong(DirectoryQuery.ID);
-        if (!mLocalInvisibleDirectoryEnabled && DirectoryCompat.isInvisibleDirectory(directoryId)) {
-          continue;
-        }
-        String directoryType = null;
-
-        String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
-        int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
-        if (!TextUtils.isEmpty(packageName) && typeResourceId != 0) {
-          try {
-            directoryType = pm.getResourcesForApplication(packageName).getString(typeResourceId);
-          } catch (Exception e) {
-            LogUtil.e(
-                "ContactEntryListAdapter.loadInBackground",
-                "cannot obtain directory type from package: " + packageName);
-          }
-        }
-        String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME);
-        int photoSupport = cursor.getInt(DirectoryQuery.PHOTO_SUPPORT);
-        result.addRow(new Object[] {directoryId, directoryType, displayName, photoSupport});
-      }
-    } catch (RuntimeException e) {
-      LogUtil.w(
-          "ContactEntryListAdapter.loadInBackground", "runtime exception when querying directory");
-    } finally {
-      if (cursor != null) {
-        cursor.close();
-      }
-    }
-
-    return result;
-  }
-
-  private Cursor getDefaultDirectories() {
-    if (mDefaultDirectoryList == null) {
-      mDefaultDirectoryList = new MatrixCursor(RESULT_PROJECTION);
-      mDefaultDirectoryList.addRow(
-          new Object[] {Directory.DEFAULT, getContext().getString(R.string.contactsList), null});
-      mDefaultDirectoryList.addRow(
-          new Object[] {
-            Directory.LOCAL_INVISIBLE,
-            getContext().getString(R.string.local_invisible_directory),
-            null
-          });
-    }
-    return mDefaultDirectoryList;
-  }
-
-  @Override
-  protected void onReset() {
-    stopLoading();
-  }
-
-  private static final class DirectoryQuery {
-
-    public static final Uri URI = DirectoryCompat.getContentUri();
-    public static final String ORDER_BY = Directory._ID;
-
-    public static final String[] PROJECTION = {
-      Directory._ID,
-      Directory.PACKAGE_NAME,
-      Directory.TYPE_RESOURCE_ID,
-      Directory.DISPLAY_NAME,
-      Directory.PHOTO_SUPPORT,
-    };
-
-    public static final int ID = 0;
-    public static final int PACKAGE_NAME = 1;
-    public static final int TYPE_RESOURCE_ID = 2;
-    public static final int DISPLAY_NAME = 3;
-    public static final int PHOTO_SUPPORT = 4;
-  }
-}
diff --git a/java/com/android/contacts/common/list/DirectoryPartition.java b/java/com/android/contacts/common/list/DirectoryPartition.java
deleted file mode 100644
index 26b8510..0000000
--- a/java/com/android/contacts/common/list/DirectoryPartition.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.provider.ContactsContract.Directory;
-import com.android.common.widget.CompositeCursorAdapter;
-
-/** Model object for a {@link Directory} row. */
-public final class DirectoryPartition extends CompositeCursorAdapter.Partition {
-
-  public static final int STATUS_NOT_LOADED = 0;
-  public static final int STATUS_LOADING = 1;
-  public static final int STATUS_LOADED = 2;
-
-  public static final int RESULT_LIMIT_DEFAULT = -1;
-
-  private long mDirectoryId;
-  private String mContentUri;
-  private String mDirectoryType;
-  private String mDisplayName;
-  private int mStatus;
-  private boolean mPriorityDirectory;
-  private boolean mPhotoSupported;
-  private int mResultLimit = RESULT_LIMIT_DEFAULT;
-  private boolean mDisplayNumber = true;
-
-  private String mLabel;
-
-  public DirectoryPartition(boolean showIfEmpty, boolean hasHeader) {
-    super(showIfEmpty, hasHeader);
-  }
-
-  /** Directory ID, see {@link Directory}. */
-  public long getDirectoryId() {
-    return mDirectoryId;
-  }
-
-  public void setDirectoryId(long directoryId) {
-    this.mDirectoryId = directoryId;
-  }
-
-  /**
-   * Directory type resolved from {@link Directory#PACKAGE_NAME} and {@link
-   * Directory#TYPE_RESOURCE_ID};
-   */
-  public String getDirectoryType() {
-    return mDirectoryType;
-  }
-
-  public void setDirectoryType(String directoryType) {
-    this.mDirectoryType = directoryType;
-  }
-
-  /** See {@link Directory#DISPLAY_NAME}. */
-  public String getDisplayName() {
-    return mDisplayName;
-  }
-
-  public void setDisplayName(String displayName) {
-    this.mDisplayName = displayName;
-  }
-
-  public int getStatus() {
-    return mStatus;
-  }
-
-  public void setStatus(int status) {
-    mStatus = status;
-  }
-
-  public boolean isLoading() {
-    return mStatus == STATUS_NOT_LOADED || mStatus == STATUS_LOADING;
-  }
-
-  /** Returns true if this directory should be loaded before non-priority directories. */
-  public boolean isPriorityDirectory() {
-    return mPriorityDirectory;
-  }
-
-  public void setPriorityDirectory(boolean priorityDirectory) {
-    mPriorityDirectory = priorityDirectory;
-  }
-
-  /** Returns true if this directory supports photos. */
-  public boolean isPhotoSupported() {
-    return mPhotoSupported;
-  }
-
-  public void setPhotoSupported(boolean flag) {
-    this.mPhotoSupported = flag;
-  }
-
-  /**
-   * Max number of results for this directory. Defaults to {@link #RESULT_LIMIT_DEFAULT} which
-   * implies using the adapter's {@link
-   * com.android.contacts.common.list.ContactListAdapter#getDirectoryResultLimit()}
-   */
-  public int getResultLimit() {
-    return mResultLimit;
-  }
-
-  public void setResultLimit(int resultLimit) {
-    mResultLimit = resultLimit;
-  }
-
-  /**
-   * Used by extended directories to specify a custom content URI. Extended directories MUST have a
-   * content URI
-   */
-  public String getContentUri() {
-    return mContentUri;
-  }
-
-  public void setContentUri(String contentUri) {
-    mContentUri = contentUri;
-  }
-
-  /** A label to display in the header next to the display name. */
-  public String getLabel() {
-    return mLabel;
-  }
-
-  public void setLabel(String label) {
-    mLabel = label;
-  }
-
-  @Override
-  public String toString() {
-    return "DirectoryPartition{"
-        + "mDirectoryId="
-        + mDirectoryId
-        + ", mContentUri='"
-        + mContentUri
-        + '\''
-        + ", mDirectoryType='"
-        + mDirectoryType
-        + '\''
-        + ", mDisplayName='"
-        + mDisplayName
-        + '\''
-        + ", mStatus="
-        + mStatus
-        + ", mPriorityDirectory="
-        + mPriorityDirectory
-        + ", mPhotoSupported="
-        + mPhotoSupported
-        + ", mResultLimit="
-        + mResultLimit
-        + ", mLabel='"
-        + mLabel
-        + '\''
-        + '}';
-  }
-
-  /**
-   * Whether or not to display the phone number in app that have that option - Dialer. If false,
-   * Phone Label should be used instead of Phone Number.
-   */
-  public boolean isDisplayNumber() {
-    return mDisplayNumber;
-  }
-
-  public void setDisplayNumber(boolean displayNumber) {
-    mDisplayNumber = displayNumber;
-  }
-}
diff --git a/java/com/android/contacts/common/list/IndexerListAdapter.java b/java/com/android/contacts/common/list/IndexerListAdapter.java
deleted file mode 100644
index 2289f6e..0000000
--- a/java/com/android/contacts/common/list/IndexerListAdapter.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-import android.widget.SectionIndexer;
-
-/** A list adapter that supports section indexer and a pinned header. */
-public abstract class IndexerListAdapter extends PinnedHeaderListAdapter implements SectionIndexer {
-
-  protected Context mContext;
-  private SectionIndexer mIndexer;
-  private int mIndexedPartition = 0;
-  private boolean mSectionHeaderDisplayEnabled;
-  private View mHeader;
-  private Placement mPlacementCache = new Placement();
-
-  /** Constructor. */
-  public IndexerListAdapter(Context context) {
-    super(context);
-    mContext = context;
-  }
-
-  /**
-   * Creates a section header view that will be pinned at the top of the list as the user scrolls.
-   */
-  protected abstract View createPinnedSectionHeaderView(Context context, ViewGroup parent);
-
-  /** Sets the title in the pinned header as the user scrolls. */
-  protected abstract void setPinnedSectionTitle(View pinnedHeaderView, String title);
-
-  public boolean isSectionHeaderDisplayEnabled() {
-    return mSectionHeaderDisplayEnabled;
-  }
-
-  public void setSectionHeaderDisplayEnabled(boolean flag) {
-    this.mSectionHeaderDisplayEnabled = flag;
-  }
-
-  public int getIndexedPartition() {
-    return mIndexedPartition;
-  }
-
-  public void setIndexedPartition(int partition) {
-    this.mIndexedPartition = partition;
-  }
-
-  public SectionIndexer getIndexer() {
-    return mIndexer;
-  }
-
-  public void setIndexer(SectionIndexer indexer) {
-    mIndexer = indexer;
-    mPlacementCache.invalidate();
-  }
-
-  public Object[] getSections() {
-    if (mIndexer == null) {
-      return new String[] {" "};
-    } else {
-      return mIndexer.getSections();
-    }
-  }
-
-  /** @return relative position of the section in the indexed partition */
-  public int getPositionForSection(int sectionIndex) {
-    if (mIndexer == null) {
-      return -1;
-    }
-
-    return mIndexer.getPositionForSection(sectionIndex);
-  }
-
-  /** @param position relative position in the indexed partition */
-  public int getSectionForPosition(int position) {
-    if (mIndexer == null) {
-      return -1;
-    }
-
-    return mIndexer.getSectionForPosition(position);
-  }
-
-  @Override
-  public int getPinnedHeaderCount() {
-    if (isSectionHeaderDisplayEnabled()) {
-      return super.getPinnedHeaderCount() + 1;
-    } else {
-      return super.getPinnedHeaderCount();
-    }
-  }
-
-  @Override
-  public View getPinnedHeaderView(int viewIndex, View convertView, ViewGroup parent) {
-    if (isSectionHeaderDisplayEnabled() && viewIndex == getPinnedHeaderCount() - 1) {
-      if (mHeader == null) {
-        mHeader = createPinnedSectionHeaderView(mContext, parent);
-      }
-      return mHeader;
-    } else {
-      return super.getPinnedHeaderView(viewIndex, convertView, parent);
-    }
-  }
-
-  @Override
-  public void configurePinnedHeaders(PinnedHeaderListView listView) {
-    super.configurePinnedHeaders(listView);
-
-    if (!isSectionHeaderDisplayEnabled()) {
-      return;
-    }
-
-    int index = getPinnedHeaderCount() - 1;
-    if (mIndexer == null || getCount() == 0) {
-      listView.setHeaderInvisible(index, false);
-    } else {
-      int listPosition = listView.getPositionAt(listView.getTotalTopPinnedHeaderHeight());
-      int position = listPosition - listView.getHeaderViewsCount();
-
-      int section = -1;
-      int partition = getPartitionForPosition(position);
-      if (partition == mIndexedPartition) {
-        int offset = getOffsetInPartition(position);
-        if (offset != -1) {
-          section = getSectionForPosition(offset);
-        }
-      }
-
-      if (section == -1) {
-        listView.setHeaderInvisible(index, false);
-      } else {
-        View topChild = listView.getChildAt(listPosition);
-        if (topChild != null) {
-          // Match the pinned header's height to the height of the list item.
-          mHeader.setMinimumHeight(topChild.getMeasuredHeight());
-        }
-        setPinnedSectionTitle(mHeader, (String) mIndexer.getSections()[section]);
-
-        // Compute the item position where the current partition begins
-        int partitionStart = getPositionForPartition(mIndexedPartition);
-        if (hasHeader(mIndexedPartition)) {
-          partitionStart++;
-        }
-
-        // Compute the item position where the next section begins
-        int nextSectionPosition = partitionStart + getPositionForSection(section + 1);
-        boolean isLastInSection = position == nextSectionPosition - 1;
-        listView.setFadingHeader(index, listPosition, isLastInSection);
-      }
-    }
-  }
-
-  /**
-   * Computes the item's placement within its section and populates the {@code placement} object
-   * accordingly. Please note that the returned object is volatile and should be copied if the
-   * result needs to be used later.
-   */
-  public Placement getItemPlacementInSection(int position) {
-    if (mPlacementCache.position == position) {
-      return mPlacementCache;
-    }
-
-    mPlacementCache.position = position;
-    if (isSectionHeaderDisplayEnabled()) {
-      int section = getSectionForPosition(position);
-      if (section != -1 && getPositionForSection(section) == position) {
-        mPlacementCache.firstInSection = true;
-        mPlacementCache.sectionHeader = (String) getSections()[section];
-      } else {
-        mPlacementCache.firstInSection = false;
-        mPlacementCache.sectionHeader = null;
-      }
-
-      mPlacementCache.lastInSection = (getPositionForSection(section + 1) - 1 == position);
-    } else {
-      mPlacementCache.firstInSection = false;
-      mPlacementCache.lastInSection = false;
-      mPlacementCache.sectionHeader = null;
-    }
-    return mPlacementCache;
-  }
-
-  /**
-   * An item view is displayed differently depending on whether it is placed at the beginning,
-   * middle or end of a section. It also needs to know the section header when it is at the
-   * beginning of a section. This object captures all this configuration.
-   */
-  public static final class Placement {
-
-    public boolean firstInSection;
-    public boolean lastInSection;
-    public String sectionHeader;
-    private int position = ListView.INVALID_POSITION;
-
-    public void invalidate() {
-      position = ListView.INVALID_POSITION;
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/PhoneNumberListAdapter.java b/java/com/android/contacts/common/list/PhoneNumberListAdapter.java
deleted file mode 100644
index 3c45abf..0000000
--- a/java/com/android/contacts/common/list/PhoneNumberListAdapter.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.content.CursorLoader;
-import android.database.Cursor;
-import android.net.Uri;
-import android.net.Uri.Builder;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Callable;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Directory;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewGroup;
-import com.android.contacts.common.ContactsUtils;
-import com.android.contacts.common.R;
-import com.android.contacts.common.compat.CallableCompat;
-import com.android.contacts.common.compat.PhoneCompat;
-import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor;
-import com.android.contacts.common.list.ContactListItemView.CallToAction;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.Constants;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.cp2.DirectoryCompat;
-import com.android.dialer.compat.CompatUtils;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest;
-import com.android.dialer.dialercontact.DialerContact;
-import com.android.dialer.duo.DuoComponent;
-import com.android.dialer.enrichedcall.EnrichedCallCapabilities;
-import com.android.dialer.enrichedcall.EnrichedCallComponent;
-import com.android.dialer.enrichedcall.EnrichedCallManager;
-import com.android.dialer.lettertile.LetterTileDrawable;
-import com.android.dialer.phonenumberutil.PhoneNumberHelper;
-import com.android.dialer.util.CallUtil;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A cursor adapter for the {@link Phone#CONTENT_ITEM_TYPE} and {@link
- * SipAddress#CONTENT_ITEM_TYPE}.
- *
- * <p>By default this adapter just handles phone numbers. When {@link #setUseCallableUri(boolean)}
- * is called with "true", this adapter starts handling SIP addresses too, by using {@link Callable}
- * API instead of {@link Phone}.
- */
-public class PhoneNumberListAdapter extends ContactEntryListAdapter {
-
-  private static final String TAG = PhoneNumberListAdapter.class.getSimpleName();
-  private static final String IGNORE_NUMBER_TOO_LONG_CLAUSE = "length(" + Phone.NUMBER + ") < 1000";
-  // A list of extended directories to add to the directories from the database
-  private final List<DirectoryPartition> mExtendedDirectories;
-  private final CharSequence mUnknownNameText;
-  protected final boolean mIsImsVideoEnabled;
-
-  // Extended directories will have ID's that are higher than any of the id's from the database,
-  // so that we can identify them and set them up properly. If no extended directories
-  // exist, this will be Long.MAX_VALUE
-  private long mFirstExtendedDirectoryId = Long.MAX_VALUE;
-  private boolean mUseCallableUri;
-  private Listener mListener;
-
-  public PhoneNumberListAdapter(Context context) {
-    super(context);
-    setDefaultFilterHeaderText(R.string.list_filter_phones);
-    mUnknownNameText = context.getText(android.R.string.unknownName);
-
-    mExtendedDirectories =
-        PhoneDirectoryExtenderAccessor.get(mContext).getExtendedDirectories(mContext);
-
-    int videoCapabilities = CallUtil.getVideoCallingAvailability(context);
-    mIsImsVideoEnabled =
-        CallUtil.isVideoEnabled(context)
-            && (videoCapabilities & CallUtil.VIDEO_CALLING_PRESENCE) != 0;
-  }
-
-  @Override
-  public void configureLoader(CursorLoader loader, long directoryId) {
-    String query = getQueryString();
-    if (query == null) {
-      query = "";
-    }
-    if (isExtendedDirectory(directoryId)) {
-      final DirectoryPartition directory = getExtendedDirectoryFromId(directoryId);
-      final String contentUri = directory.getContentUri();
-      if (contentUri == null) {
-        throw new IllegalStateException("Extended directory must have a content URL: " + directory);
-      }
-      final Builder builder = Uri.parse(contentUri).buildUpon();
-      builder.appendPath(query);
-      builder.appendQueryParameter(
-          ContactsContract.LIMIT_PARAM_KEY, String.valueOf(getDirectoryResultLimit(directory)));
-      loader.setUri(builder.build());
-      loader.setProjection(PhoneQuery.PROJECTION_PRIMARY);
-    } else {
-      final boolean isRemoteDirectoryQuery = DirectoryCompat.isRemoteDirectoryId(directoryId);
-      final Builder builder;
-      if (isSearchMode()) {
-        final Uri baseUri;
-        if (isRemoteDirectoryQuery) {
-          baseUri = PhoneCompat.getContentFilterUri();
-        } else if (mUseCallableUri) {
-          baseUri = CallableCompat.getContentFilterUri();
-        } else {
-          baseUri = PhoneCompat.getContentFilterUri();
-        }
-        builder = baseUri.buildUpon();
-        builder.appendPath(query); // Builder will encode the query
-        builder.appendQueryParameter(
-            ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId));
-        if (isRemoteDirectoryQuery) {
-          builder.appendQueryParameter(
-              ContactsContract.LIMIT_PARAM_KEY,
-              String.valueOf(getDirectoryResultLimit(getDirectoryById(directoryId))));
-        }
-      } else {
-        Uri baseUri = mUseCallableUri ? Callable.CONTENT_URI : Phone.CONTENT_URI;
-        builder =
-            baseUri
-                .buildUpon()
-                .appendQueryParameter(
-                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT));
-        if (isSectionHeaderDisplayEnabled()) {
-          builder.appendQueryParameter(Phone.EXTRA_ADDRESS_BOOK_INDEX, "true");
-        }
-        applyFilter(loader, builder, directoryId, getFilter());
-      }
-
-      // Ignore invalid phone numbers that are too long. These can potentially cause freezes
-      // in the UI and there is no reason to display them.
-      final String prevSelection = loader.getSelection();
-      final String newSelection;
-      if (!TextUtils.isEmpty(prevSelection)) {
-        newSelection = prevSelection + " AND " + IGNORE_NUMBER_TOO_LONG_CLAUSE;
-      } else {
-        newSelection = IGNORE_NUMBER_TOO_LONG_CLAUSE;
-      }
-      loader.setSelection(newSelection);
-
-      // Remove duplicates when it is possible.
-      builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true");
-      loader.setUri(builder.build());
-
-      // TODO a projection that includes the search snippet
-      if (getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
-        loader.setProjection(PhoneQuery.PROJECTION_PRIMARY);
-      } else {
-        loader.setProjection(PhoneQuery.PROJECTION_ALTERNATIVE);
-      }
-
-      if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) {
-        loader.setSortOrder(Phone.SORT_KEY_PRIMARY);
-      } else {
-        loader.setSortOrder(Phone.SORT_KEY_ALTERNATIVE);
-      }
-    }
-  }
-
-  protected boolean isExtendedDirectory(long directoryId) {
-    return directoryId >= mFirstExtendedDirectoryId;
-  }
-
-  private DirectoryPartition getExtendedDirectoryFromId(long directoryId) {
-    final int directoryIndex = (int) (directoryId - mFirstExtendedDirectoryId);
-    return mExtendedDirectories.get(directoryIndex);
-  }
-
-  /**
-   * Configure {@code loader} and {@code uriBuilder} according to {@code directoryId} and {@code
-   * filter}.
-   */
-  private void applyFilter(
-      CursorLoader loader, Uri.Builder uriBuilder, long directoryId, ContactListFilter filter) {
-    if (filter == null || directoryId != Directory.DEFAULT) {
-      return;
-    }
-
-    final StringBuilder selection = new StringBuilder();
-    final List<String> selectionArgs = new ArrayList<String>();
-
-    switch (filter.filterType) {
-      case ContactListFilter.FILTER_TYPE_CUSTOM:
-        {
-          selection.append(Contacts.IN_VISIBLE_GROUP + "=1");
-          selection.append(" AND " + Contacts.HAS_PHONE_NUMBER + "=1");
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_ACCOUNT:
-        {
-          filter.addAccountQueryParameterToUrl(uriBuilder);
-          break;
-        }
-      case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS:
-      case ContactListFilter.FILTER_TYPE_DEFAULT:
-        break; // No selection needed.
-      case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY:
-        break; // This adapter is always "phone only", so no selection needed either.
-      default:
-        LogUtil.w(
-            TAG,
-            "Unsupported filter type came "
-                + "(type: "
-                + filter.filterType
-                + ", toString: "
-                + filter
-                + ")"
-                + " showing all contacts.");
-        // No selection.
-        break;
-    }
-    loader.setSelection(selection.toString());
-    loader.setSelectionArgs(selectionArgs.toArray(new String[0]));
-  }
-
-  public String getPhoneNumber(int position) {
-    final Cursor item = (Cursor) getItem(position);
-    return item != null ? item.getString(PhoneQuery.PHONE_NUMBER) : null;
-  }
-
-  /**
-   * Retrieves the lookup key for the given cursor position.
-   *
-   * @param position The cursor position.
-   * @return The lookup key.
-   */
-  public String getLookupKey(int position) {
-    final Cursor item = (Cursor) getItem(position);
-    return item != null ? item.getString(PhoneQuery.LOOKUP_KEY) : null;
-  }
-
-  public DialerContact getDialerContact(int position) {
-    Cursor cursor = (Cursor) getItem(position);
-    if (cursor == null) {
-      LogUtil.e("PhoneNumberListAdapter.getDialerContact", "cursor was null.");
-      return null;
-    }
-
-    String displayName = cursor.getString(PhoneQuery.DISPLAY_NAME);
-    String number = cursor.getString(PhoneQuery.PHONE_NUMBER);
-    String photoUri = cursor.getString(PhoneQuery.PHOTO_URI);
-    Uri contactUri =
-        Contacts.getLookupUri(
-            cursor.getLong(PhoneQuery.CONTACT_ID), cursor.getString(PhoneQuery.LOOKUP_KEY));
-
-    DialerContact.Builder contact = DialerContact.newBuilder();
-    contact
-        .setNumber(number)
-        .setPhotoId(cursor.getLong(PhoneQuery.PHOTO_ID))
-        .setContactType(LetterTileDrawable.TYPE_DEFAULT)
-        .setNameOrNumber(displayName)
-        .setNumberLabel(
-            Phone.getTypeLabel(
-                    mContext.getResources(),
-                    cursor.getInt(PhoneQuery.PHONE_TYPE),
-                    cursor.getString(PhoneQuery.PHONE_LABEL))
-                .toString());
-
-    if (photoUri != null) {
-      contact.setPhotoUri(photoUri);
-    }
-
-    if (contactUri != null) {
-      contact.setContactUri(contactUri.toString());
-    }
-
-    if (!TextUtils.isEmpty(displayName)) {
-      contact.setDisplayNumber(number);
-    }
-
-    return contact.build();
-  }
-
-  @Override
-  protected ContactListItemView newView(
-      Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
-    ContactListItemView view = super.newView(context, partition, cursor, position, parent);
-    view.setUnknownNameText(mUnknownNameText);
-    view.setQuickContactEnabled(isQuickContactEnabled());
-    return view;
-  }
-
-  protected void setHighlight(ContactListItemView view, Cursor cursor) {
-    view.setHighlightedPrefix(isSearchMode() ? getUpperCaseQueryString() : null);
-  }
-
-  @Override
-  protected void bindView(View itemView, int partition, Cursor cursor, int position) {
-    super.bindView(itemView, partition, cursor, position);
-    ContactListItemView view = (ContactListItemView) itemView;
-
-    setHighlight(view, cursor);
-
-    // Look at elements before and after this position, checking if contact IDs are same.
-    // If they have one same contact ID, it means they can be grouped.
-    //
-    // In one group, only the first entry will show its photo and its name, and the other
-    // entries in the group show just their data (e.g. phone number, email address).
-    cursor.moveToPosition(position);
-    boolean isFirstEntry = true;
-    final long currentContactId = cursor.getLong(PhoneQuery.CONTACT_ID);
-    if (cursor.moveToPrevious() && !cursor.isBeforeFirst()) {
-      final long previousContactId = cursor.getLong(PhoneQuery.CONTACT_ID);
-      if (currentContactId == previousContactId) {
-        isFirstEntry = false;
-      }
-    }
-    cursor.moveToPosition(position);
-
-    bindViewId(view, cursor, PhoneQuery.PHONE_ID);
-
-    bindSectionHeaderAndDivider(view, position);
-    if (isFirstEntry) {
-      bindName(view, cursor);
-      if (isQuickContactEnabled()) {
-        bindQuickContact(
-            view,
-            partition,
-            cursor,
-            PhoneQuery.PHOTO_ID,
-            PhoneQuery.PHOTO_URI,
-            PhoneQuery.CONTACT_ID,
-            PhoneQuery.LOOKUP_KEY,
-            PhoneQuery.DISPLAY_NAME);
-      } else {
-        if (getDisplayPhotos()) {
-          bindPhoto(view, partition, cursor);
-        }
-      }
-    } else {
-      unbindName(view);
-
-      view.removePhotoView(true, false);
-    }
-
-    final DirectoryPartition directory = (DirectoryPartition) getPartition(partition);
-    // All sections have headers, so scroll position is off by 1.
-    position += getPositionForPartition(partition) + 1;
-
-    bindPhoneNumber(view, cursor, directory.isDisplayNumber(), position);
-  }
-
-  @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
-  public void bindPhoneNumber(
-      ContactListItemView view, Cursor cursor, boolean displayNumber, int position) {
-    CharSequence label = null;
-    if (displayNumber && !cursor.isNull(PhoneQuery.PHONE_TYPE)) {
-      final int type = cursor.getInt(PhoneQuery.PHONE_TYPE);
-      final String customLabel = cursor.getString(PhoneQuery.PHONE_LABEL);
-
-      // TODO cache
-      label = Phone.getTypeLabel(mContext.getResources(), type, customLabel);
-    }
-    view.setLabel(label);
-    final String text;
-    String number = cursor.getString(PhoneQuery.PHONE_NUMBER);
-    if (displayNumber) {
-      text = number;
-    } else {
-      // Display phone label. If that's null, display geocoded location for the number
-      final String phoneLabel = cursor.getString(PhoneQuery.PHONE_LABEL);
-      if (phoneLabel != null) {
-        text = phoneLabel;
-      } else {
-        final String phoneNumber = cursor.getString(PhoneQuery.PHONE_NUMBER);
-        text =
-            PhoneNumberHelper.getGeoDescription(
-                mContext,
-                phoneNumber,
-                PhoneNumberHelper.getCurrentCountryIso(mContext, null /* PhoneAccountHandle */));
-      }
-    }
-    view.setPhoneNumber(text);
-
-    @CallToAction int action = ContactListItemView.NONE;
-
-    if (CompatUtils.isVideoCompatible()) {
-      // Determine if carrier presence indicates the number supports video calling.
-      int carrierPresence = cursor.getInt(PhoneQuery.CARRIER_PRESENCE);
-      boolean isPresent = (carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) != 0;
-
-      boolean showViewIcon = mIsImsVideoEnabled && isPresent;
-      if (showViewIcon) {
-        action = ContactListItemView.VIDEO;
-      }
-    }
-
-    if (action == ContactListItemView.NONE
-        && DuoComponent.get(mContext).getDuo().isReachable(mContext, number)) {
-      action = ContactListItemView.DUO;
-    }
-
-    if (action == ContactListItemView.NONE) {
-      EnrichedCallManager manager = EnrichedCallComponent.get(mContext).getEnrichedCallManager();
-      EnrichedCallCapabilities capabilities = manager.getCapabilities(number);
-      if (capabilities != null && capabilities.isCallComposerCapable()) {
-        action = ContactListItemView.CALL_AND_SHARE;
-      } else if (capabilities == null
-          && getQueryString() != null
-          && getQueryString().length() >= 3) {
-        manager.requestCapabilities(number);
-      }
-    }
-
-    view.setCallToAction(action, mListener, position);
-  }
-
-  protected void bindSectionHeaderAndDivider(final ContactListItemView view, int position) {
-    if (isSectionHeaderDisplayEnabled()) {
-      Placement placement = getItemPlacementInSection(position);
-      view.setSectionHeader(placement.firstInSection ? placement.sectionHeader : null);
-    } else {
-      view.setSectionHeader(null);
-    }
-  }
-
-  protected void bindName(final ContactListItemView view, Cursor cursor) {
-    view.showDisplayName(cursor, PhoneQuery.DISPLAY_NAME);
-    // Note: we don't show phonetic names any more (see issue 5265330)
-  }
-
-  protected void unbindName(final ContactListItemView view) {
-    view.hideDisplayName();
-  }
-
-  @Override
-  protected void bindWorkProfileIcon(final ContactListItemView view, int partition) {
-    final DirectoryPartition directory = (DirectoryPartition) getPartition(partition);
-    final long directoryId = directory.getDirectoryId();
-    final long userType = ContactsUtils.determineUserType(directoryId, null);
-    // Work directory must not be a extended directory. An extended directory is custom
-    // directory in the app, but not a directory provided by framework. So it can't be
-    // USER_TYPE_WORK.
-    view.setWorkProfileIconEnabled(
-        !isExtendedDirectory(directoryId) && userType == ContactsUtils.USER_TYPE_WORK);
-  }
-
-  protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) {
-    if (!isPhotoSupported(partitionIndex)) {
-      view.removePhotoView();
-      return;
-    }
-
-    long photoId = 0;
-    if (!cursor.isNull(PhoneQuery.PHOTO_ID)) {
-      photoId = cursor.getLong(PhoneQuery.PHOTO_ID);
-    }
-
-    if (photoId != 0) {
-      getPhotoLoader()
-          .loadThumbnail(view.getPhotoView(), photoId, false, getCircularPhotos(), null);
-    } else {
-      final String photoUriString = cursor.getString(PhoneQuery.PHOTO_URI);
-      final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
-
-      DefaultImageRequest request = null;
-      if (photoUri == null) {
-        final String displayName = cursor.getString(PhoneQuery.DISPLAY_NAME);
-        final String lookupKey = cursor.getString(PhoneQuery.LOOKUP_KEY);
-        request = new DefaultImageRequest(displayName, lookupKey, getCircularPhotos());
-      }
-      getPhotoLoader()
-          .loadDirectoryPhoto(view.getPhotoView(), photoUri, false, getCircularPhotos(), request);
-    }
-  }
-
-  public void setUseCallableUri(boolean useCallableUri) {
-    mUseCallableUri = useCallableUri;
-  }
-
-  /**
-   * Override base implementation to inject extended directories between local & remote directories.
-   * This is done in the following steps: 1. Call base implementation to add directories from the
-   * cursor. 2. Iterate all base directories and establish the following information: a. The highest
-   * directory id so that we can assign unused id's to the extended directories. b. The index of the
-   * last non-remote directory. This is where we will insert extended directories. 3. Iterate the
-   * extended directories and for each one, assign an ID and insert it in the proper location.
-   */
-  @Override
-  public void changeDirectories(Cursor cursor) {
-    super.changeDirectories(cursor);
-    if (getDirectorySearchMode() == DirectoryListLoader.SEARCH_MODE_NONE) {
-      return;
-    }
-    int numExtendedDirectories = mExtendedDirectories.size();
-
-    if (ConfigProviderBindings.get(getContext()).getBoolean("p13n_ranker_should_enable", false)) {
-      // Suggested results wasn't formulated as an extended directory, so manually
-      // increment the count here when the feature is enabled. Suggestions are
-      // only shown when the ranker is enabled.
-      numExtendedDirectories++;
-    }
-
-    if (getPartitionCount() == cursor.getCount() + numExtendedDirectories) {
-      // already added all directories;
-      return;
-    }
-
-    mFirstExtendedDirectoryId = Long.MAX_VALUE;
-    if (!mExtendedDirectories.isEmpty()) {
-      // The Directory.LOCAL_INVISIBLE is not in the cursor but we can't reuse it's
-      // "special" ID.
-      long maxId = Directory.LOCAL_INVISIBLE;
-      int insertIndex = 0;
-      for (int i = 0, n = getPartitionCount(); i < n; i++) {
-        final DirectoryPartition partition = (DirectoryPartition) getPartition(i);
-        final long id = partition.getDirectoryId();
-        if (id > maxId) {
-          maxId = id;
-        }
-        if (!DirectoryCompat.isRemoteDirectoryId(id)) {
-          // assuming remote directories come after local, we will end up with the index
-          // where we should insert extended directories. This also works if there are no
-          // remote directories at all.
-          insertIndex = i + 1;
-        }
-      }
-      // Extended directories ID's cannot collide with base directories
-      mFirstExtendedDirectoryId = maxId + 1;
-      for (int i = 0; i < mExtendedDirectories.size(); i++) {
-        final long id = mFirstExtendedDirectoryId + i;
-        final DirectoryPartition directory = mExtendedDirectories.get(i);
-        if (getPartitionByDirectoryId(id) == -1) {
-          addPartition(insertIndex, directory);
-          directory.setDirectoryId(id);
-        }
-      }
-    }
-  }
-
-  @Override
-  protected Uri getContactUri(
-      int partitionIndex, Cursor cursor, int contactIdColumn, int lookUpKeyColumn) {
-    final DirectoryPartition directory = (DirectoryPartition) getPartition(partitionIndex);
-    final long directoryId = directory.getDirectoryId();
-    if (!isExtendedDirectory(directoryId)) {
-      return super.getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn);
-    }
-    return Contacts.CONTENT_LOOKUP_URI
-        .buildUpon()
-        .appendPath(Constants.LOOKUP_URI_ENCODED)
-        .appendQueryParameter(Directory.DISPLAY_NAME, directory.getLabel())
-        .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId))
-        .encodedFragment(cursor.getString(lookUpKeyColumn))
-        .build();
-  }
-
-  public Listener getListener() {
-    return mListener;
-  }
-
-  public void setListener(Listener listener) {
-    mListener = listener;
-  }
-
-  public interface Listener {
-
-    void onVideoCallIconClicked(int position);
-
-    void onDuoVideoIconClicked(int position);
-
-    void onCallAndShareIconClicked(int position);
-  }
-
-  public static class PhoneQuery {
-
-    /**
-     * Optional key used as part of a JSON lookup key to specify an analytics category associated
-     * with the row.
-     */
-    public static final String ANALYTICS_CATEGORY = "analytics_category";
-
-    /**
-     * Optional key used as part of a JSON lookup key to specify an analytics action associated with
-     * the row.
-     */
-    public static final String ANALYTICS_ACTION = "analytics_action";
-
-    /**
-     * Optional key used as part of a JSON lookup key to specify an analytics value associated with
-     * the row.
-     */
-    public static final String ANALYTICS_VALUE = "analytics_value";
-
-    public static final String[] PROJECTION_PRIMARY_INTERNAL =
-        new String[] {
-          Phone._ID, // 0
-          Phone.TYPE, // 1
-          Phone.LABEL, // 2
-          Phone.NUMBER, // 3
-          Phone.CONTACT_ID, // 4
-          Phone.LOOKUP_KEY, // 5
-          Phone.PHOTO_ID, // 6
-          Phone.DISPLAY_NAME_PRIMARY, // 7
-          Phone.PHOTO_THUMBNAIL_URI, // 8
-        };
-
-    public static final String[] PROJECTION_PRIMARY;
-    public static final String[] PROJECTION_ALTERNATIVE_INTERNAL =
-        new String[] {
-          Phone._ID, // 0
-          Phone.TYPE, // 1
-          Phone.LABEL, // 2
-          Phone.NUMBER, // 3
-          Phone.CONTACT_ID, // 4
-          Phone.LOOKUP_KEY, // 5
-          Phone.PHOTO_ID, // 6
-          Phone.DISPLAY_NAME_ALTERNATIVE, // 7
-          Phone.PHOTO_THUMBNAIL_URI, // 8
-        };
-    public static final String[] PROJECTION_ALTERNATIVE;
-    public static final int PHONE_ID = 0;
-    public static final int PHONE_TYPE = 1;
-    public static final int PHONE_LABEL = 2;
-    public static final int PHONE_NUMBER = 3;
-    public static final int CONTACT_ID = 4;
-    public static final int LOOKUP_KEY = 5;
-    public static final int PHOTO_ID = 6;
-    public static final int DISPLAY_NAME = 7;
-    public static final int PHOTO_URI = 8;
-    public static final int CARRIER_PRESENCE = 9;
-
-    static {
-      final List<String> projectionList =
-          new ArrayList<>(Arrays.asList(PROJECTION_PRIMARY_INTERNAL));
-      projectionList.add(Phone.CARRIER_PRESENCE); // 9
-      PROJECTION_PRIMARY = projectionList.toArray(new String[projectionList.size()]);
-    }
-
-    static {
-      final List<String> projectionList =
-          new ArrayList<>(Arrays.asList(PROJECTION_ALTERNATIVE_INTERNAL));
-      projectionList.add(Phone.CARRIER_PRESENCE); // 9
-      PROJECTION_ALTERNATIVE = projectionList.toArray(new String[projectionList.size()]);
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java b/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java
deleted file mode 100644
index 1a3b80f..0000000
--- a/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.Loader;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.support.annotation.MainThread;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import com.android.contacts.common.R;
-import com.android.contacts.common.list.PhoneNumberListAdapter.Listener;
-import com.android.contacts.common.util.AccountFilterUtil;
-import com.android.dialer.callintent.CallInitiationType;
-import com.android.dialer.callintent.CallInitiationType.Type;
-import com.android.dialer.callintent.CallSpecificAppData;
-import com.android.dialer.common.Assert;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.dialercontact.DialerContact;
-import com.android.dialer.duo.DuoComponent;
-import com.android.dialer.enrichedcall.EnrichedCallComponent;
-import com.android.dialer.enrichedcall.EnrichedCallManager;
-import com.android.dialer.logging.DialerImpression;
-import com.android.dialer.logging.Logger;
-import com.android.dialer.performancereport.PerformanceReport;
-import com.android.dialer.protos.ProtoParsers;
-import java.util.Set;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/** Fragment containing a phone number list for picking. */
-public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactEntryListAdapter>
-    implements PhoneNumberListAdapter.Listener, EnrichedCallManager.CapabilitiesListener {
-
-  private static final String KEY_FILTER = "filter";
-  private OnPhoneNumberPickerActionListener mListener;
-  private ContactListFilter mFilter;
-  private View mAccountFilterHeader;
-  /**
-   * Lives as ListView's header and is shown when {@link #mAccountFilterHeader} is set to View.GONE.
-   */
-  private View mPaddingView;
-  /** true if the loader has started at least once. */
-  private boolean mLoaderStarted;
-
-  private boolean mUseCallableUri;
-
-  private final Set<OnLoadFinishedListener> mLoadFinishedListeners = new ArraySet<>();
-
-  private CursorReranker mCursorReranker;
-
-  public PhoneNumberPickerFragment() {
-    setQuickContactEnabled(false);
-    setPhotoLoaderEnabled(true);
-    setSectionHeaderDisplayEnabled(false);
-    setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
-
-    // Show nothing instead of letting caller Activity show something.
-    setHasOptionsMenu(true);
-  }
-
-  /**
-   * Handles a click on the video call icon for a row in the list.
-   *
-   * @param position The position in the list where the click ocurred.
-   */
-  @Override
-  public void onVideoCallIconClicked(int position) {
-    Logger.get(getContext()).logImpression(DialerImpression.Type.IMS_VIDEO_REQUESTED_FROM_SEARCH);
-    callNumber(position, true /* isVideoCall */);
-  }
-
-  @Override
-  public void onDuoVideoIconClicked(int position) {
-    PerformanceReport.stopRecording();
-    String phoneNumber = getPhoneNumber(position);
-    Intent intent = DuoComponent.get(getContext()).getDuo().getIntent(getContext(), phoneNumber);
-    // DialtactsActivity.ACTIVITY_REQUEST_CODE_LIGHTBRINGER
-    // Cannot reference because of cyclic dependencies
-    Logger.get(getContext())
-        .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_SEARCH);
-    int dialactsActivityRequestCode = 3;
-    getActivity().startActivityForResult(intent, dialactsActivityRequestCode);
-  }
-
-  @Override
-  public void onCallAndShareIconClicked(int position) {
-    // Required because of cyclic dependencies of everything depending on contacts/common.
-    String componentName = "com.android.dialer.callcomposer.CallComposerActivity";
-    Intent intent = new Intent();
-    intent.setComponent(new ComponentName(getContext(), componentName));
-    DialerContact contact = ((PhoneNumberListAdapter) getAdapter()).getDialerContact(position);
-    ProtoParsers.put(intent, "CALL_COMPOSER_CONTACT", contact);
-    startActivity(intent);
-  }
-
-  public void setDirectorySearchEnabled(boolean flag) {
-    setDirectorySearchMode(
-        flag ? DirectoryListLoader.SEARCH_MODE_DEFAULT : DirectoryListLoader.SEARCH_MODE_NONE);
-  }
-
-  public void setOnPhoneNumberPickerActionListener(OnPhoneNumberPickerActionListener listener) {
-    this.mListener = listener;
-  }
-
-  public OnPhoneNumberPickerActionListener getOnPhoneNumberPickerListener() {
-    return mListener;
-  }
-
-  @Override
-  protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
-    super.onCreateView(inflater, container);
-
-    View paddingView = inflater.inflate(R.layout.contact_detail_list_padding, null, false);
-    mPaddingView = paddingView.findViewById(R.id.contact_detail_list_padding);
-    getListView().addHeaderView(paddingView);
-
-    mAccountFilterHeader = getView().findViewById(R.id.account_filter_header_container);
-    updateFilterHeaderView();
-
-    setVisibleScrollbarEnabled(getVisibleScrollbarEnabled());
-  }
-
-  @Override
-  public void onPause() {
-    super.onPause();
-    EnrichedCallComponent.get(getContext())
-        .getEnrichedCallManager()
-        .unregisterCapabilitiesListener(this);
-  }
-
-  @Override
-  public void onResume() {
-    super.onResume();
-    EnrichedCallComponent.get(getContext())
-        .getEnrichedCallManager()
-        .registerCapabilitiesListener(this);
-  }
-
-  protected boolean getVisibleScrollbarEnabled() {
-    return true;
-  }
-
-  @Override
-  protected void setSearchMode(boolean flag) {
-    super.setSearchMode(flag);
-    updateFilterHeaderView();
-  }
-
-  private void updateFilterHeaderView() {
-    final ContactListFilter filter = getFilter();
-    if (mAccountFilterHeader == null || filter == null) {
-      return;
-    }
-    final boolean shouldShowHeader =
-        !isSearchMode()
-            && AccountFilterUtil.updateAccountFilterTitleForPhone(
-                mAccountFilterHeader, filter, false);
-    if (shouldShowHeader) {
-      mPaddingView.setVisibility(View.GONE);
-      mAccountFilterHeader.setVisibility(View.VISIBLE);
-    } else {
-      mPaddingView.setVisibility(View.VISIBLE);
-      mAccountFilterHeader.setVisibility(View.GONE);
-    }
-  }
-
-  @Override
-  public void restoreSavedState(Bundle savedState) {
-    super.restoreSavedState(savedState);
-
-    if (savedState == null) {
-      return;
-    }
-
-    mFilter = savedState.getParcelable(KEY_FILTER);
-  }
-
-  @Override
-  public void onSaveInstanceState(Bundle outState) {
-    super.onSaveInstanceState(outState);
-    outState.putParcelable(KEY_FILTER, mFilter);
-  }
-
-  @Override
-  public boolean onOptionsItemSelected(MenuItem item) {
-    final int itemId = item.getItemId();
-    if (itemId == android.R.id.home) { // See ActionBar#setDisplayHomeAsUpEnabled()
-      if (mListener != null) {
-        mListener.onHomeInActionBarSelected();
-      }
-      return true;
-    }
-    return super.onOptionsItemSelected(item);
-  }
-
-  @Override
-  protected void onItemClick(int position, long id) {
-    callNumber(position, false /* isVideoCall */);
-  }
-
-  /**
-   * Initiates a call to the number at the specified position.
-   *
-   * @param position The position.
-   * @param isVideoCall {@code true} if the call should be initiated as a video call, {@code false}
-   *     otherwise.
-   */
-  private void callNumber(int position, boolean isVideoCall) {
-    final String number = getPhoneNumber(position);
-    if (!TextUtils.isEmpty(number)) {
-      cacheContactInfo(position);
-      CallSpecificAppData callSpecificAppData =
-          CallSpecificAppData.newBuilder()
-              .setAllowAssistedDialing(true)
-              .setCallInitiationType(getCallInitiationType(true /* isRemoteDirectory */))
-              .setPositionOfSelectedSearchResult(position)
-              .setCharactersInSearchString(getQueryString() == null ? 0 : getQueryString().length())
-              .build();
-      mListener.onPickPhoneNumber(number, isVideoCall, callSpecificAppData);
-    } else {
-      LogUtil.i(
-          "PhoneNumberPickerFragment.callNumber",
-          "item at %d was clicked before adapter is ready, ignoring",
-          position);
-    }
-
-    // Get the lookup key and track any analytics
-    final String lookupKey = getLookupKey(position);
-    if (!TextUtils.isEmpty(lookupKey)) {
-      maybeTrackAnalytics(lookupKey);
-    }
-  }
-
-  protected void cacheContactInfo(int position) {
-    // Not implemented. Hook for child classes
-  }
-
-  protected String getPhoneNumber(int position) {
-    final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
-    return adapter.getPhoneNumber(position);
-  }
-
-  protected String getLookupKey(int position) {
-    final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
-    return adapter.getLookupKey(position);
-  }
-
-  @Override
-  protected void startLoading() {
-    mLoaderStarted = true;
-    super.startLoading();
-  }
-
-  @Override
-  @MainThread
-  public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-    Assert.isMainThread();
-    // TODO(strongarm): define and verify behavior for "Nearby places", corp directories,
-    // and dividers listed in UI between these categories
-    if (mCursorReranker != null
-        && data != null
-        && !data.isClosed()
-        && data.getCount() > 0
-        && loader.getId() == 0) { // only re-rank if a suggestions loader with id of 0.
-      data = mCursorReranker.rerankCursor(data);
-    }
-    super.onLoadFinished(loader, data);
-
-    // disable scroll bar if there is no data
-    setVisibleScrollbarEnabled(data != null && !data.isClosed() && data.getCount() > 0);
-
-    if (data != null) {
-      notifyListeners();
-    }
-  }
-
-  /** Ranks cursor data rows and returns reference to new cursor object with reordered data. */
-  public interface CursorReranker {
-    @MainThread
-    Cursor rerankCursor(Cursor data);
-  }
-
-  @MainThread
-  public void setReranker(@Nullable CursorReranker reranker) {
-    Assert.isMainThread();
-    mCursorReranker = reranker;
-  }
-
-  /** Listener that is notified when cursor has finished loading data. */
-  public interface OnLoadFinishedListener {
-    void onLoadFinished();
-  }
-
-  @MainThread
-  public void addOnLoadFinishedListener(OnLoadFinishedListener listener) {
-    Assert.isMainThread();
-    mLoadFinishedListeners.add(listener);
-  }
-
-  @MainThread
-  public void removeOnLoadFinishedListener(OnLoadFinishedListener listener) {
-    Assert.isMainThread();
-    mLoadFinishedListeners.remove(listener);
-  }
-
-  @MainThread
-  protected void notifyListeners() {
-    Assert.isMainThread();
-    for (OnLoadFinishedListener listener : mLoadFinishedListeners) {
-      listener.onLoadFinished();
-    }
-  }
-
-  @Override
-  public void onCapabilitiesUpdated() {
-    if (getAdapter() != null) {
-      EnrichedCallManager manager =
-          EnrichedCallComponent.get(getContext()).getEnrichedCallManager();
-      Listener listener = ((PhoneNumberListAdapter) getAdapter()).getListener();
-
-      for (int i = 0; i < getListView().getChildCount(); i++) {
-        if (!(getListView().getChildAt(i) instanceof ContactListItemView)) {
-          continue;
-        }
-
-        // Since call and share is the lowest priority call to action, if any others are set,
-        // do not reset the call to action. Also do not set the call and share call to action if
-        // the number doesn't support call composer.
-        ContactListItemView view = (ContactListItemView) getListView().getChildAt(i);
-        if (view.getCallToAction() != ContactListItemView.NONE
-            || view.getPhoneNumber() == null
-            || manager.getCapabilities(view.getPhoneNumber()) == null
-            || !manager.getCapabilities(view.getPhoneNumber()).isCallComposerCapable()) {
-          continue;
-        }
-        view.setCallToAction(ContactListItemView.CALL_AND_SHARE, listener, view.getPosition());
-      }
-    }
-  }
-
-  @MainThread
-  @Override
-  public void onDetach() {
-    Assert.isMainThread();
-    mLoadFinishedListeners.clear();
-    super.onDetach();
-  }
-
-  public void setUseCallableUri(boolean useCallableUri) {
-    mUseCallableUri = useCallableUri;
-  }
-
-  public boolean usesCallableUri() {
-    return mUseCallableUri;
-  }
-
-  @Override
-  protected ContactEntryListAdapter createListAdapter() {
-    PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
-    adapter.setDisplayPhotos(true);
-    adapter.setUseCallableUri(mUseCallableUri);
-    return adapter;
-  }
-
-  @Override
-  protected void configureAdapter() {
-    super.configureAdapter();
-
-    final ContactEntryListAdapter adapter = getAdapter();
-    if (adapter == null) {
-      return;
-    }
-
-    if (!isSearchMode() && mFilter != null) {
-      adapter.setFilter(mFilter);
-    }
-  }
-
-  @Override
-  protected View inflateView(LayoutInflater inflater, ViewGroup container) {
-    return inflater.inflate(R.layout.contact_list_content, null);
-  }
-
-  public ContactListFilter getFilter() {
-    return mFilter;
-  }
-
-  public void setFilter(ContactListFilter filter) {
-    if ((mFilter == null && filter == null) || (mFilter != null && mFilter.equals(filter))) {
-      return;
-    }
-
-    mFilter = filter;
-    if (mLoaderStarted) {
-      reloadData();
-    }
-    updateFilterHeaderView();
-  }
-
-  /**
-   * @param isRemoteDirectory {@code true} if the call was initiated using a contact/phone number
-   *     not in the local contacts database
-   */
-  protected CallInitiationType.Type getCallInitiationType(boolean isRemoteDirectory) {
-    return Type.UNKNOWN_INITIATION;
-  }
-
-  /**
-   * Where a lookup key contains analytic event information, logs the associated analytics event.
-   *
-   * @param lookupKey The lookup key JSON object.
-   */
-  private void maybeTrackAnalytics(String lookupKey) {
-    try {
-      JSONObject json = new JSONObject(lookupKey);
-
-      String analyticsCategory =
-          json.getString(PhoneNumberListAdapter.PhoneQuery.ANALYTICS_CATEGORY);
-      String analyticsAction = json.getString(PhoneNumberListAdapter.PhoneQuery.ANALYTICS_ACTION);
-      String analyticsValue = json.getString(PhoneNumberListAdapter.PhoneQuery.ANALYTICS_VALUE);
-
-      if (TextUtils.isEmpty(analyticsCategory)
-          || TextUtils.isEmpty(analyticsAction)
-          || TextUtils.isEmpty(analyticsValue)) {
-        return;
-      }
-
-      // Assume that the analytic value being tracked could be a float value, but just cast
-      // to a long so that the analytic server can handle it.
-      long value;
-      try {
-        float floatValue = Float.parseFloat(analyticsValue);
-        value = (long) floatValue;
-      } catch (NumberFormatException nfe) {
-        return;
-      }
-
-      Logger.get(getActivity())
-          .sendHitEventAnalytics(analyticsCategory, analyticsAction, "" /* label */, value);
-    } catch (JSONException e) {
-      // Not an error; just a lookup key that doesn't have the right information.
-    }
-  }
-}
diff --git a/java/com/android/contacts/common/list/PinnedHeaderListAdapter.java b/java/com/android/contacts/common/list/PinnedHeaderListAdapter.java
deleted file mode 100644
index 0bdcef0..0000000
--- a/java/com/android/contacts/common/list/PinnedHeaderListAdapter.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import com.android.common.widget.CompositeCursorAdapter;
-
-/** A subclass of {@link CompositeCursorAdapter} that manages pinned partition headers. */
-public abstract class PinnedHeaderListAdapter extends CompositeCursorAdapter
-    implements PinnedHeaderListView.PinnedHeaderAdapter {
-
-  public static final int PARTITION_HEADER_TYPE = 0;
-
-  private boolean mPinnedPartitionHeadersEnabled;
-  private boolean[] mHeaderVisibility;
-
-  public PinnedHeaderListAdapter(Context context) {
-    super(context);
-  }
-
-  public boolean getPinnedPartitionHeadersEnabled() {
-    return mPinnedPartitionHeadersEnabled;
-  }
-
-  public void setPinnedPartitionHeadersEnabled(boolean flag) {
-    this.mPinnedPartitionHeadersEnabled = flag;
-  }
-
-  @Override
-  public int getPinnedHeaderCount() {
-    if (mPinnedPartitionHeadersEnabled) {
-      return getPartitionCount();
-    } else {
-      return 0;
-    }
-  }
-
-  protected boolean isPinnedPartitionHeaderVisible(int partition) {
-    return getPinnedPartitionHeadersEnabled()
-        && hasHeader(partition)
-        && !isPartitionEmpty(partition);
-  }
-
-  /** The default implementation creates the same type of view as a normal partition header. */
-  @Override
-  public View getPinnedHeaderView(int partition, View convertView, ViewGroup parent) {
-    if (hasHeader(partition)) {
-      View view = null;
-      if (convertView != null) {
-        Integer headerType = (Integer) convertView.getTag();
-        if (headerType != null && headerType == PARTITION_HEADER_TYPE) {
-          view = convertView;
-        }
-      }
-      if (view == null) {
-        view = newHeaderView(getContext(), partition, null, parent);
-        view.setTag(PARTITION_HEADER_TYPE);
-        view.setFocusable(false);
-        view.setEnabled(false);
-      }
-      bindHeaderView(view, partition, getCursor(partition));
-      view.setLayoutDirection(parent.getLayoutDirection());
-      return view;
-    } else {
-      return null;
-    }
-  }
-
-  @Override
-  public void configurePinnedHeaders(PinnedHeaderListView listView) {
-    if (!getPinnedPartitionHeadersEnabled()) {
-      return;
-    }
-
-    int size = getPartitionCount();
-
-    // Cache visibility bits, because we will need them several times later on
-    if (mHeaderVisibility == null || mHeaderVisibility.length != size) {
-      mHeaderVisibility = new boolean[size];
-    }
-    for (int i = 0; i < size; i++) {
-      boolean visible = isPinnedPartitionHeaderVisible(i);
-      mHeaderVisibility[i] = visible;
-      if (!visible) {
-        listView.setHeaderInvisible(i, true);
-      }
-    }
-
-    int headerViewsCount = listView.getHeaderViewsCount();
-
-    // Starting at the top, find and pin headers for partitions preceding the visible one(s)
-    int maxTopHeader = -1;
-    int topHeaderHeight = 0;
-    for (int i = 0; i < size; i++) {
-      if (mHeaderVisibility[i]) {
-        int position = listView.getPositionAt(topHeaderHeight) - headerViewsCount;
-        int partition = getPartitionForPosition(position);
-        if (i > partition) {
-          break;
-        }
-
-        listView.setHeaderPinnedAtTop(i, topHeaderHeight, false);
-        topHeaderHeight += listView.getPinnedHeaderHeight(i);
-        maxTopHeader = i;
-      }
-    }
-
-    // Starting at the bottom, find and pin headers for partitions following the visible one(s)
-    int maxBottomHeader = size;
-    int bottomHeaderHeight = 0;
-    int listHeight = listView.getHeight();
-    for (int i = size; --i > maxTopHeader; ) {
-      if (mHeaderVisibility[i]) {
-        int position = listView.getPositionAt(listHeight - bottomHeaderHeight) - headerViewsCount;
-        if (position < 0) {
-          break;
-        }
-
-        int partition = getPartitionForPosition(position - 1);
-        if (partition == -1 || i <= partition) {
-          break;
-        }
-
-        int height = listView.getPinnedHeaderHeight(i);
-        bottomHeaderHeight += height;
-
-        listView.setHeaderPinnedAtBottom(i, listHeight - bottomHeaderHeight, false);
-        maxBottomHeader = i;
-      }
-    }
-
-    // Headers in between the top-pinned and bottom-pinned should be hidden
-    for (int i = maxTopHeader + 1; i < maxBottomHeader; i++) {
-      if (mHeaderVisibility[i]) {
-        listView.setHeaderInvisible(i, isPartitionEmpty(i));
-      }
-    }
-  }
-
-  @Override
-  public int getScrollPositionForHeader(int viewIndex) {
-    return getPositionForPartition(viewIndex);
-  }
-}
diff --git a/java/com/android/contacts/common/list/PinnedHeaderListView.java b/java/com/android/contacts/common/list/PinnedHeaderListView.java
deleted file mode 100644
index a801624..0000000
--- a/java/com/android/contacts/common/list/PinnedHeaderListView.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.common.list;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.RectF;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AbsListView.OnScrollListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ListAdapter;
-import com.android.dialer.util.ViewUtil;
-
-/**
- * A ListView that maintains a header pinned at the top of the list. The pinned header can be pushed
- * up and dissolved as needed.
- */
-public class PinnedHeaderListView extends AutoScrollListView
-    implements OnScrollListener, OnItemSelectedListener {
-
-  private static final int MAX_ALPHA = 255;
-  private static final int TOP = 0;
-  private static final int BOTTOM = 1;
-  private static final int FADING = 2;
-  private static final int DEFAULT_ANIMATION_DURATION = 20;
-  private static final int DEFAULT_SMOOTH_SCROLL_DURATION = 100;
-  private PinnedHeaderAdapter mAdapter;
-  private int mSize;
-  private PinnedHeader[] mHeaders;
-  private RectF mBounds = new RectF();
-  private OnScrollListener mOnScrollListener;
-  private OnItemSelectedListener mOnItemSelectedListener;
-  private int mScrollState;
-  private boolean mScrollToSectionOnHeaderTouch = false;
-  private boolean mHeaderTouched = false;
-  private int mAnimationDuration = DEFAULT_ANIMATION_DURATION;
-  private boolean mAnimating;
-  private long mAnimationTargetTime;
-  private int mHeaderPaddingStart;
-  private int mHeaderWidth;
-
-  public PinnedHeaderListView(Context context) {
-    this(context, null, android.R.attr.listViewStyle);
-  }
-
-  public PinnedHeaderListView(Context context, AttributeSet attrs) {
-    this(context, attrs, android.R.attr.listViewStyle);
-  }
-
-  public PinnedHeaderListView(Context context, AttributeSet attrs, int defStyle) {
-    super(context, attrs, defStyle);
-    super.setOnScrollListener(this);
-    super.setOnItemSelectedListener(this);
-  }
-
-  @Override
-  protected void onLayout(boolean changed, int l, int t, int r, int b) {
-    super.onLayout(changed, l, t, r, b);
-    mHeaderPaddingStart = getPaddingStart();
-    mHeaderWidth = r - l - mHeaderPaddingStart - getPaddingEnd();
-  }
-
-  @Override
-  public void setAdapter(ListAdapter adapter) {
-    mAdapter = (PinnedHeaderAdapter) adapter;
-    super.setAdapter(adapter);
-  }
-
-  @Override
-  public void setOnScrollListener(OnScrollListener onScrollListener) {
-    mOnScrollListener = onScrollListener;
-    super.setOnScrollListener(this);
-  }
-
-  @Override
-  public void setOnItemSelectedListener(OnItemSelectedListener listener) {
-    mOnItemSelectedListener = listener;
-    super.setOnItemSelectedListener(this);
-  }
-
-  public void setScrollToSectionOnHeaderTouch(boolean value) {
-    mScrollToSectionOnHeaderTouch = value;
-  }
-
-  @Override
-  public void onScroll(
-      AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-    if (mAdapter != null) {
-      int count = mAdapter.getPinnedHeaderCount();
-      if (count != mSize) {
-        mSize = count;
-        if (mHeaders == null) {
-          mHeaders = new PinnedHeader[mSize];
-        } else if (mHeaders.length < mSize) {
-          PinnedHeader[] headers = mHeaders;
-          mHeaders = new PinnedHeader[mSize];
-          System.arraycopy(headers, 0, mHeaders, 0, headers.length);
-        }
-      }
-
-      for (int i = 0; i < mSize; i++) {
-        if (mHeaders[i] == null) {
-          mHeaders[i] = new PinnedHeader();
-        }
-        mHeaders[i].view = mAdapter.getPinnedHeaderView(i, mHeaders[i].view, this);
-      }
-
-      mAnimationTargetTime = System.currentTimeMillis() + mAnimationDuration;
-      mAdapter.configurePinnedHeaders(this);
-      invalidateIfAnimating();
-    }
-    if (mOnScrollListener != null) {
-      mOnScrollListener.onScroll(this, firstVisibleItem, visibleItemCount, totalItemCount);
-    }
-  }
-
-  @Override
-  protected float getTopFadingEdgeStrength() {
-    // Disable vertical fading at the top when the pinned header is present
-    return mSize > 0 ? 0 : super.getTopFadingEdgeStrength();
-  }
-
-  @Override
-  public void onScrollStateChanged(AbsListView view, int scrollState) {
-    mScrollState = scrollState;
-    if (mOnScrollListener != null) {
-      mOnScrollListener.onScrollStateChanged(this, scrollState);
-    }
-  }
-
-  /**
-   * Ensures that the selected item is positioned below the top-pinned headers and above the
-   * bottom-pinned ones.
-   */
-  @Override
-  public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-    int height = getHeight();
-
-    int windowTop = 0;
-    int windowBottom = height;
-
-    for (int i = 0; i < mSize; i++) {
-      PinnedHeader header = mHeaders[i];
-      if (header.visible) {
-        if (header.state == TOP) {
-          windowTop = header.y + header.height;
-        } else if (header.state == BOTTOM) {
-          windowBottom = header.y;
-          break;
-        }
-      }
-    }
-
-    View selectedView = getSelectedView();
-    if (selectedView != null) {
-      if (selectedView.getTop() < windowTop) {
-        setSelectionFromTop(position, windowTop);
-      } else if (selectedView.getBottom() > windowBottom) {
-        setSelectionFromTop(position, windowBottom - selectedView.getHeight());
-      }
-    }
-
-    if (mOnItemSelectedListener != null) {
-      mOnItemSelectedListener.onItemSelected(parent, view, position, id);
-    }
-  }
-
-  @Override
-  public void onNothingSelected(AdapterView<?> parent) {
-    if (mOnItemSelectedListener != null) {
-      mOnItemSelectedListener.onNothingSelected(parent);
-    }
-  }
-
-  public int getPinnedHeaderHeight(int viewIndex) {
-    ensurePinnedHeaderLayout(viewIndex);
-    return mHeaders[viewIndex].view.getHeight();
-  }
-
-  /**
-   * Set header to be pinned at the top.
-   *
-   * @param viewIndex index of the header view
-   * @param y is position of the header in pixels.
-   * @param animate true if the transition to the new coordinate should be animated
-   */
-  public void setHeaderPinnedAtTop(int viewIndex, int y, boolean animate) {
-    ensurePinnedHeaderLayout(viewIndex);
-    PinnedHeader header = mHeaders[viewIndex];
-    header.visible = true;
-    header.y = y;
-    header.state = TOP;
-
-    // TODO perhaps we should animate at the top as well
-    header.animating = false;
-  }
-
-  /**
-   * Set header to be pinned at the bottom.
-   *
-   * @param viewIndex index of the header view
-   * @param y is position of the header in pixels.
-   * @param animate true if the transition to the new coordinate should be animated
-   */
-  public void setHeaderPinnedAtBottom(int viewIndex, int y, boolean animate) {
-    ensurePinnedHeaderLayout(viewIndex);
-    PinnedHeader header = mHeaders[viewIndex];
-    header.state = BOTTOM;
-    if (header.animating) {
-      header.targetTime = mAnimationTargetTime;
-      header.sourceY = header.y;
-      header.targetY = y;
-    } else if (animate && (header.y != y || !header.visible)) {
-      if (header.visible) {
-        header.sourceY = header.y;
-      } else {
-        header.visible = true;
-        header.sourceY = y + header.height;
-      }
-      header.animating = true;
-      header.targetVisible = true;
-      header.targetTime = mAnimationTargetTime;
-      header.targetY = y;
-    } else {
-      header.visible = true;
-      header.y = y;
-    }
-  }
-
-  /**
-   * Set header to be pinned at the top of the first visible item.
-   *
-   * @param viewIndex index of the header view
-   * @param position is position of the header in pixels.
-   */
-  public void setFadingHeader(int viewIndex, int position, boolean fade) {
-    ensurePinnedHeaderLayout(viewIndex);
-
-    View child = getChildAt(position - getFirstVisiblePosition());
-    if (child == null) {
-      return;
-    }
-
-    PinnedHeader header = mHeaders[viewIndex];
-    header.visible = true;
-    header.state = FADING;
-    header.alpha = MAX_ALPHA;
-    header.animating = false;
-
-    int top = getTotalTopPinnedHeaderHeight();
-    header.y = top;
-    if (fade) {
-      int bottom = child.getBottom() - top;
-      int headerHeight = header.height;
-      if (bottom < headerHeight) {
-        int portion = bottom - headerHeight;
-        header.alpha = MAX_ALPHA * (headerHeight + portion) / headerHeight;
-        header.y = top + portion;
-      }
-    }
-  }
-
-  /**
-   * Makes header invisible.
-   *
-   * @param viewIndex index of the header view
-   * @param animate true if the transition to the new coordinate should be animated
-   */
-  public void setHeaderInvisible(int viewIndex, boolean animate) {
-    PinnedHeader header = mHeaders[viewIndex];
-    if (header.visible && (animate || header.animating) && header.state == BOTTOM) {
-      header.sourceY = header.y;
-      if (!header.animating) {
-        header.visible = true;
-        header.targetY = getBottom() + header.height;
-      }
-      header.animating = true;
-      header.targetTime = mAnimationTargetTime;
-      header.targetVisible = false;
-    } else {
-      header.visible = false;
-    }
-  }
-
-  private void ensurePinnedHeaderLayout(int viewIndex) {
-    View view = mHeaders[viewIndex].view;
-    if (view.isLayoutRequested()) {
-      ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
-      int widthSpec;
-      int heightSpec;
-
-      if (layoutParams != null && layoutParams.width > 0) {
-        widthSpec = View.MeasureSpec.makeMeasureSpec(layoutParams.width, View.MeasureSpec.EXACTLY);
-      } else {
-        widthSpec = View.MeasureSpec.makeMeasureSpec(mHeaderWidth, View.MeasureSpec.EXACTLY);
-      }
-
-      if (layoutParams != null && layoutParams.height > 0) {
-        heightSpec =
-            View.MeasureSpec.makeMeasureSpec(layoutParams.height, View.MeasureSpec.EXACTLY);
-      } else {
-        heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
-      }
-      view.measure(widthSpec, heightSpec);
-      int height = view.getMeasuredHeight();
-      mHeaders[viewIndex].height = height;
-      view.layout(0, 0, view.getMeasuredWidth(), height);
-    }
-  }
-
-  /** Returns the sum of heights of headers pinned to the top. */
-  public int getTotalTopPinnedHeaderHeight() {
-    for (int i = mSize; --i >= 0; ) {
-      PinnedHeader header = mHeaders[i];
-      if (header.visible && header.state == TOP) {
-        return header.y + header.height;
-      }
-    }
-    return 0;
-  }
-
-  /** Returns the list item position at the specified y coordinate. */
-  public int getPositionAt(int y) {
-    do {
-      int position = pointToPosition(getPaddingLeft() + 1, y);
-      if (position != -1) {
-        return position;
-      }
-      // If position == -1, we must have hit a separator. Let's examine
-      // a nearby pixel
-      y--;
-    } while (y > 0);
-    return 0;
-  }
-
-  @Override
-  public boolean onInterceptTouchEvent(MotionEvent ev) {
-    mHeaderTouched = false;
-    if (super.onInterceptTouchEvent(ev)) {
-      return true;
-    }
-
-    if (mScrollState == SCROLL_STATE_IDLE) {
-      final int y = (int) ev.getY();
-      final int x = (int) ev.getX();
-      for (int i = mSize; --i >= 0; ) {
-        PinnedHeader header = mHeaders[i];
-        // For RTL layouts, this also takes into account that the scrollbar is on the left
-        // side.
-        final int padding = getPaddingLeft();
-        if (header.visible
-            && header.y <= y
-            && header.y + header.height > y
-            && x >= padding
-            && padding + header.view.getWidth() >= x) {
-          mHeaderTouched = true;
-          if (mScrollToSectionOnHeaderTouch && ev.getAction() == MotionEvent.ACTION_DOWN) {
-            return smoothScrollToPartition(i);
-          } else {
-            return true;
-          }
-        }
-      }
-    }
-
-    return false;
-  }
-
-  @Override
-  public boolean onTouchEvent(MotionEvent ev) {
-    if (mHeaderTouched) {
-      if (ev.getAction() == MotionEvent.ACTION_UP) {
-        mHeaderTouched = false;
-      }
-      return true;
-    }
-    return super.onTouchEvent(ev);
-  }
-
-  private boolean smoothScrollToPartition(int partition) {
-    if (mAdapter == null) {
-      return false;
-    }
-    final int position = mAdapter.getScrollPositionForHeader(partition);
-    if (position == -1) {
-      return false;
-    }
-
-    int offset = 0;
-    for (int i = 0; i < partition; i++) {
-      PinnedHeader header = mHeaders[i];
-      if (header.visible) {
-        offset += header.height;
-      }
-    }
-    smoothScrollToPositionFromTop(
-        position + getHeaderViewsCount(), offset, DEFAULT_SMOOTH_SCROLL_DURATION);
-    return true;
-  }
-
-  private void invalidateIfAnimating() {
-    mAnimating = false;
-    for (int i = 0; i < mSize; i++) {
-      if (mHeaders[i].animating) {
-        mAnimating = true;
-        invalidate();
-        return;
-      }
-    }
-  }
-
-  @Override
-  protected void dispatchDraw(Canvas canvas) {
-    long currentTime = mAnimating ? System.currentTimeMillis() : 0;
-
-    int top = 0;
-    int bottom = getBottom();
-    boolean hasVisibleHeaders = false;
-    for (int i = 0; i < mSize; i++) {
-      PinnedHeader header = mHeaders[i];
-      if (header.visible) {
-        hasVisibleHeaders = true;
-        if (header.state == BOTTOM && header.y < bottom) {
-          bottom = header.y;
-        } else if (header.state == TOP || header.state == FADING) {
-          int newTop = header.y + header.height;
-          if (newTop > top) {
-            top = newTop;
-          }
-        }
-      }
-    }
-
-    if (hasVisibleHeaders) {
-      canvas.save();
-    }
-
-    super.dispatchDraw(canvas);
-
-    if (hasVisibleHeaders) {
-      canvas.restore();
-
-      // If the first item is visible and if it has a positive top that is greater than the
-      // first header's assigned y-value, use that for the first header's y value. This way,
-      // the header inherits any padding applied to the list view.
-      if (mSize > 0 && getFirstVisiblePosition() == 0) {
-        View firstChild = getChildAt(0);
-        PinnedHeader firstHeader = mHeaders[0];
-
-        if (firstHeader != null) {
-          int firstHeaderTop = firstChild != null ? firstChild.getTop() : 0;
-          firstHeader.y = Math.max(firstHeader.y, firstHeaderTop);
-        }
-      }
-
-      // First draw top headers, then the bottom ones to handle the Z axis correctly
-      for (int i = mSize; --i >= 0; ) {
-        PinnedHeader header = mHeaders[i];
-        if (header.visible && (header.state == TOP || header.state == FADING)) {
-          drawHeader(canvas, header, currentTime);
-        }
-      }
-
-      for (int i = 0; i < mSize; i++) {
-        PinnedHeader header = mHeaders[i];
-        if (header.visible && header.state == BOTTOM) {
-          drawHeader(canvas, header, currentTime);
-        }
-      }
-    }
-
-    invalidateIfAnimating();
-  }
-
-  private void drawHeader(Canvas canvas, PinnedHeader header, long currentTime) {
-    if (header.animating) {
-      int timeLeft = (int) (header.targetTime - currentTime);
-      if (timeLeft <= 0) {
-        header.y = header.targetY;
-        header.visible = header.targetVisible;
-        header.animating = false;
-      } else {
-        header.y =
-            header.targetY + (header.sourceY - header.targetY) * timeLeft / mAnimationDuration;
-      }
-    }
-    if (header.visible) {
-      View view = header.view;
-      int saveCount = canvas.save();
-      int translateX =
-          ViewUtil.isViewLayoutRtl(this)
-              ? getWidth() - mHeaderPaddingStart - view.getWidth()
-              : mHeaderPaddingStart;
-      canvas.translate(translateX, header.y);
-      if (header.state == FADING) {
-        mBounds.set(0, 0, view.getWidth(), view.getHeight());
-        canvas.saveLayerAlpha(mBounds, header.alpha);
-      }
-      view.draw(canvas);
-      canvas.restoreToCount(saveCount);
-    }
-  }
-
-  /** Adapter interface. The list adapter must implement this interface. */
-  public interface PinnedHeaderAdapter {
-
-    /** Returns the overall number of pinned headers, visible or not. */
-    int getPinnedHeaderCount();
-
-    /** Creates or updates the pinned header view. */
-    View getPinnedHeaderView(int viewIndex, View convertView, ViewGroup parent);
-
-    /**
-     * Configures the pinned headers to match the visible list items. The adapter should call {@link
-     * PinnedHeaderListView#setHeaderPinnedAtTop}, {@link
-     * PinnedHeaderListView#setHeaderPinnedAtBottom}, {@link PinnedHeaderListView#setFadingHeader}
-     * or {@link PinnedHeaderListView#setHeaderInvisible}, for each header that needs to change its
-     * position or visibility.
-     */
-    void configurePinnedHeaders(PinnedHeaderListView listView);
-
-    /**
-     * Returns the list position to scroll to if the pinned header is touched. Return -1 if the list
-     * does not need to be scrolled.
-     */
-    int getScrollPositionForHeader(int viewIndex);
-  }
-
-  private static final class PinnedHeader {
-
-    View view;
-    boolean visible;
-    int y;
-    int height;
-    int alpha;
-    int state;
-
-    boolean animating;
-    boolean targetVisible;
-    int sourceY;
-    int targetY;
-    long targetTime;
-  }
-}
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index 1a8e5cc..a9a11e0 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -26,7 +26,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -34,7 +33,6 @@
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.QuickContact;
 import android.speech.RecognizerIntent;
-import android.support.annotation.MainThread;
 import android.support.annotation.NonNull;
 import android.support.annotation.VisibleForTesting;
 import android.support.design.widget.CoordinatorLayout;
@@ -66,9 +64,6 @@
 import android.widget.Toast;
 import com.android.contacts.common.dialog.ClearFrequentsDialog;
 import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
-import com.android.contacts.common.list.PhoneNumberListAdapter;
-import com.android.contacts.common.list.PhoneNumberPickerFragment.CursorReranker;
-import com.android.contacts.common.list.PhoneNumberPickerFragment.OnLoadFinishedListener;
 import com.android.dialer.animation.AnimUtils;
 import com.android.dialer.animation.AnimationListenerAdapter;
 import com.android.dialer.app.calllog.CallLogActivity;
@@ -84,9 +79,6 @@
 import com.android.dialer.app.list.OnDragDropListener;
 import com.android.dialer.app.list.OnListFragmentScrolledListener;
 import com.android.dialer.app.list.PhoneFavoriteSquareTileView;
-import com.android.dialer.app.list.RegularSearchFragment;
-import com.android.dialer.app.list.SearchFragment;
-import com.android.dialer.app.list.SmartDialSearchFragment;
 import com.android.dialer.app.settings.DialerSettingsActivity;
 import com.android.dialer.app.widget.ActionBarController;
 import com.android.dialer.app.widget.SearchEditTextLayout;
@@ -120,11 +112,6 @@
 import com.android.dialer.logging.UiAction;
 import com.android.dialer.metrics.Metrics;
 import com.android.dialer.metrics.MetricsComponent;
-import com.android.dialer.p13n.inference.P13nRanking;
-import com.android.dialer.p13n.inference.protocol.P13nRanker;
-import com.android.dialer.p13n.inference.protocol.P13nRanker.P13nRefreshCompleteListener;
-import com.android.dialer.p13n.logging.P13nLogger;
-import com.android.dialer.p13n.logging.P13nLogging;
 import com.android.dialer.performancereport.PerformanceReport;
 import com.android.dialer.postcall.PostCall;
 import com.android.dialer.precall.PreCall;
@@ -161,7 +148,6 @@
         ContactsFragment.OnContactsListScrolledListener,
         DialpadFragment.HostInterface,
         OldSpeedDialFragment.HostInterface,
-        SearchFragment.HostInterface,
         OnDragDropListener,
         OnPhoneNumberPickerActionListener,
         PopupMenu.OnMenuItemClickListener,
@@ -192,8 +178,6 @@
   private static final String KEY_IS_DIALPAD_SHOWN = "is_dialpad_shown";
   private static final String KEY_FAB_VISIBLE = "fab_visible";
   private static final String TAG_NEW_SEARCH_FRAGMENT = "new_search";
-  private static final String TAG_REGULAR_SEARCH_FRAGMENT = "search";
-  private static final String TAG_SMARTDIAL_SEARCH_FRAGMENT = "smartdial";
   private static final String TAG_FAVORITES_FRAGMENT = "favorites";
   /** Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}. */
   private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";
@@ -212,11 +196,6 @@
 
   /** Root layout of DialtactsActivity */
   private CoordinatorLayout parentLayout;
-  /** Fragment for searching phone numbers using the alphanumeric keyboard. */
-  private RegularSearchFragment regularSearchFragment;
-
-  /** Fragment for searching phone numbers using the dialpad. */
-  private SmartDialSearchFragment smartDialSearchFragment;
 
   /** new Fragment for search phone numbers using the keyboard and the dialpad. */
   private NewSearchFragment newSearchFragment;
@@ -267,8 +246,6 @@
   private boolean wasConfigurationChange;
   private long timeTabSelected;
 
-  private P13nLogger p13nLogger;
-  private P13nRanker p13nRanker;
   public boolean isMultiSelectModeEnabled;
 
   private boolean isLastTabEnabled;
@@ -312,7 +289,6 @@
           LogUtil.v("DialtactsActivity.onTextChanged", "previous query: " + searchQuery);
           searchQuery = newText;
 
-          // TODO(calderwoodra): show p13n when newText is empty.
           // Show search fragment only when the query string is changed to non-empty text.
           if (!TextUtils.isEmpty(newText)) {
             // Call enterSearchUi only if we are switching search modes, or showing a search
@@ -324,11 +300,7 @@
             }
           }
 
-          if (smartDialSearchFragment != null && smartDialSearchFragment.isVisible()) {
-            smartDialSearchFragment.setQueryString(searchQuery);
-          } else if (regularSearchFragment != null && regularSearchFragment.isVisible()) {
-            regularSearchFragment.setQueryString(searchQuery);
-          } else if (newSearchFragment != null && newSearchFragment.isVisible()) {
+          if (newSearchFragment != null && newSearchFragment.isVisible()) {
             newSearchFragment.setQuery(searchQuery, getCallInitiationType());
           }
         }
@@ -496,14 +468,9 @@
     SmartDialPrefix.initializeNanpSettings(this);
     Trace.endSection();
 
-    p13nLogger = P13nLogging.get(getApplicationContext());
-    p13nRanker = P13nRanking.get(getApplicationContext());
     Trace.endSection();
 
-    // Update the new search fragment to the correct position and the ActionBar's visibility.
-    if (ConfigProviderBindings.get(this).getBoolean("enable_new_search_fragment", false)) {
-      updateSearchFragmentPosition();
-    }
+    updateSearchFragmentPosition();
   }
 
   @NonNull
@@ -624,14 +591,6 @@
     setSearchBoxHint();
     timeTabSelected = SystemClock.elapsedRealtime();
 
-    p13nLogger.reset();
-    p13nRanker.refresh(
-        new P13nRefreshCompleteListener() {
-          @Override
-          public void onP13nRefreshComplete() {
-            // TODO(strongarm): make zero-query search results visible
-          }
-        });
     Trace.endSection();
   }
 
@@ -696,15 +655,6 @@
     LogUtil.i("DialtactsActivity.onAttachFragment", "fragment: %s", fragment);
     if (fragment instanceof DialpadFragment) {
       dialpadFragment = (DialpadFragment) fragment;
-    } else if (fragment instanceof SmartDialSearchFragment) {
-      smartDialSearchFragment = (SmartDialSearchFragment) fragment;
-      smartDialSearchFragment.setOnPhoneNumberPickerActionListener(this);
-      if (!TextUtils.isEmpty(dialpadQuery)) {
-        smartDialSearchFragment.setAddToContactNumber(dialpadQuery);
-      }
-    } else if (fragment instanceof SearchFragment) {
-      regularSearchFragment = (RegularSearchFragment) fragment;
-      regularSearchFragment.setOnPhoneNumberPickerActionListener(this);
     } else if (fragment instanceof ListsFragment) {
       listsFragment = (ListsFragment) fragment;
       listsFragment.addOnPageChangeListener(this);
@@ -712,28 +662,6 @@
       newSearchFragment = (NewSearchFragment) fragment;
       updateSearchFragmentPosition();
     }
-    if (fragment instanceof SearchFragment) {
-      final SearchFragment searchFragment = (SearchFragment) fragment;
-      searchFragment.setReranker(
-          new CursorReranker() {
-            @Override
-            @MainThread
-            public Cursor rerankCursor(Cursor data) {
-              Assert.isMainThread();
-              String queryString = searchFragment.getQueryString();
-              return p13nRanker.rankCursor(data, queryString == null ? 0 : queryString.length());
-            }
-          });
-      searchFragment.addOnLoadFinishedListener(
-          new OnLoadFinishedListener() {
-            @Override
-            public void onLoadFinished() {
-              p13nLogger.onSearchQuery(
-                  searchFragment.getQueryString(),
-                  (PhoneNumberListAdapter) searchFragment.getAdapter());
-            }
-          });
-    }
   }
 
   protected void handleMenuSettings() {
@@ -1001,24 +929,7 @@
   }
 
   private void updateSearchFragmentPosition() {
-    SearchFragment fragment = null;
-    if (smartDialSearchFragment != null) {
-      fragment = smartDialSearchFragment;
-    } else if (regularSearchFragment != null) {
-      fragment = regularSearchFragment;
-    }
-    LogUtil.d(
-        "DialtactsActivity.updateSearchFragmentPosition",
-        "fragment: %s, isVisible: %b",
-        fragment,
-        fragment != null && fragment.isVisible());
-    if (fragment != null) {
-      // We need to force animation here even when fragment is not visible since it might not be
-      // visible immediately after screen orientation change and dialpad height would not be
-      // available immediately which is required to update position. By forcing an animation,
-      // position will be updated after a delay by when the dialpad height would be available.
-      fragment.updatePosition(true /* animate */);
-    } else if (newSearchFragment != null) {
+    if (newSearchFragment != null) {
       int animationDuration = getResources().getInteger(R.integer.dialpad_slide_in_duration);
       int actionbarHeight = getResources().getDimensionPixelSize(R.dimen.action_bar_height_large);
       int shadowHeight = getResources().getDrawable(R.drawable.search_shadow).getIntrinsicHeight();
@@ -1208,29 +1119,9 @@
       return;
     }
 
-    final FragmentTransaction transaction = getFragmentManager().beginTransaction();
-    if (inDialpadSearch && smartDialSearchFragment != null) {
-      transaction.remove(smartDialSearchFragment);
-    } else if (inRegularSearch && regularSearchFragment != null) {
-      transaction.remove(regularSearchFragment);
-    }
-
-    final String tag;
-    inDialpadSearch = false;
-    inRegularSearch = false;
-    inNewSearch = false;
-    boolean useNewSearch =
-        ConfigProviderBindings.get(this).getBoolean("enable_new_search_fragment", false);
-    if (useNewSearch) {
-      tag = TAG_NEW_SEARCH_FRAGMENT;
-      inNewSearch = true;
-    } else if (smartDialSearch) {
-      tag = TAG_SMARTDIAL_SEARCH_FRAGMENT;
-      inDialpadSearch = true;
-    } else {
-      tag = TAG_REGULAR_SEARCH_FRAGMENT;
-      inRegularSearch = true;
-    }
+    FragmentTransaction transaction = getFragmentManager().beginTransaction();
+    String tag = TAG_NEW_SEARCH_FRAGMENT;
+    inNewSearch = true;
 
     floatingActionButtonController.scaleOut();
 
@@ -1240,59 +1131,23 @@
       transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
     }
 
-    Fragment fragment = getFragmentManager().findFragmentByTag(tag);
+    NewSearchFragment fragment = (NewSearchFragment) getFragmentManager().findFragmentByTag(tag);
     if (fragment == null) {
-      if (useNewSearch) {
-        fragment = NewSearchFragment.newInstance(!isDialpadShown());
-      } else if (smartDialSearch) {
-        fragment = new SmartDialSearchFragment();
-      } else {
-        fragment = Bindings.getLegacy(this).newRegularSearchFragment();
-        ((SearchFragment) fragment)
-            .setOnTouchListener(
-                (v, event) -> {
-                  // Show the FAB when the user touches the lists fragment and the soft
-                  // keyboard is hidden.
-                  hideDialpadFragment(true, false);
-                  v.performClick();
-                  return false;
-                });
-      }
+      fragment = NewSearchFragment.newInstance(!isDialpadShown());
       transaction.add(R.id.dialtacts_frame, fragment, tag);
     } else {
-      // TODO(calderwoodra): if this is a transition from dialpad to searchbar, animate fragment
-      // down, and vice versa. Perhaps just add a coordinator behavior with the search bar.
       transaction.show(fragment);
     }
 
     // DialtactsActivity will provide the options menu
     fragment.setHasOptionsMenu(false);
-
-    // Will show empty list if P13nRanker is not enabled. Else, re-ranked list by the ranker.
-    if (!useNewSearch) {
-      ((SearchFragment) fragment)
-          .setShowEmptyListForNullQuery(p13nRanker.shouldShowEmptyListForNullQuery());
-    } else {
-      // TODO(calderwoodra): add p13n ranker to new search.
-    }
-
-    if (!smartDialSearch && !useNewSearch) {
-      ((SearchFragment) fragment).setQueryString(query);
-    } else if (useNewSearch) {
-      ((NewSearchFragment) fragment).setQuery(query, getCallInitiationType());
-    }
+    fragment.setQuery(query, getCallInitiationType());
     transaction.commit();
 
     if (animate) {
       Assert.isNotNull(listsFragment.getView()).animate().alpha(0).withLayer();
     }
     listsFragment.setUserVisibleHint(false);
-
-    if (smartDialSearch) {
-      Logger.get(this).logScreenView(ScreenEvent.Type.SMART_DIAL_SEARCH, this);
-    } else {
-      Logger.get(this).logScreenView(ScreenEvent.Type.REGULAR_SEARCH, this);
-    }
   }
 
   /** Hides the search fragment */
@@ -1336,12 +1191,6 @@
     }
 
     final FragmentTransaction transaction = getFragmentManager().beginTransaction();
-    if (smartDialSearchFragment != null) {
-      transaction.remove(smartDialSearchFragment);
-    }
-    if (regularSearchFragment != null) {
-      transaction.remove(regularSearchFragment);
-    }
     if (newSearchFragment != null) {
       transaction.remove(newSearchFragment);
     }
@@ -1405,9 +1254,6 @@
   @Override
   public void onDialpadQueryChanged(String query) {
     dialpadQuery = query;
-    if (smartDialSearchFragment != null) {
-      smartDialSearchFragment.setAddToContactNumber(query);
-    }
     if (newSearchFragment != null) {
       newSearchFragment.setRawNumber(query);
     }
@@ -1443,13 +1289,6 @@
 
   @Override
   public boolean onDialpadSpacerTouchWithEmptyQuery() {
-    if (inDialpadSearch
-        && smartDialSearchFragment != null
-        && !smartDialSearchFragment.isShowingPermissionRequest()) {
-      PerformanceReport.recordClick(UiAction.Type.CLOSE_DIALPAD);
-      hideDialpadFragment(true /* animate */, true /* clearDialpad */);
-      return true;
-    }
     return false;
   }
 
@@ -1625,25 +1464,15 @@
   @Override
   public void onPageScrollStateChanged(int state) {}
 
-  @Override
   public boolean isActionBarShowing() {
     return actionBarController.isActionBarShowing();
   }
 
-  @Override
   public boolean isDialpadShown() {
     return isDialpadShown;
   }
 
   @Override
-  public int getDialpadHeight() {
-    if (dialpadFragment != null) {
-      return dialpadFragment.getDialpadHeight();
-    }
-    return 0;
-  }
-
-  @Override
   public void setActionBarHideOffset(int offset) {
     getActionBarSafely().setHideOffset(offset);
   }
diff --git a/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java b/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java
index cae35d5..270ec6d 100644
--- a/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java
+++ b/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java
@@ -29,7 +29,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ImageView;
 import android.widget.TextView;
 import com.android.dialer.app.R;
 import com.android.dialer.blocking.BlockedNumbersMigrator;
@@ -73,13 +72,11 @@
     getListView().addHeaderView(inflater.inflate(R.layout.blocked_number_header, null));
     getListView().addFooterView(inflater.inflate(R.layout.blocked_number_footer, null));
     //replace the icon for add number with LetterTileDrawable(), so it will have identical style
-    ImageView addNumberIcon = (ImageView) getActivity().findViewById(R.id.add_number_icon);
     LetterTileDrawable drawable = new LetterTileDrawable(getResources());
     drawable.setLetter(ADD_BLOCKED_NUMBER_ICON_LETTER);
     drawable.setColor(
         ActivityCompat.getColor(getActivity(), R.color.add_blocked_number_icon_color));
     drawable.setIsCircular(true);
-    addNumberIcon.setImageDrawable(drawable);
 
     if (adapter == null) {
       adapter =
@@ -97,7 +94,6 @@
     blockedNumberListDivider = getActivity().findViewById(R.id.blocked_number_list_divider);
     getListView().findViewById(R.id.import_button).setOnClickListener(this);
     getListView().findViewById(R.id.view_numbers_button).setOnClickListener(this);
-    getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(this);
 
     footerText = (TextView) getActivity().findViewById(R.id.blocked_number_footer_textview);
     voicemailEnabledChecker = new VisualVoicemailEnabledChecker(getContext(), this);
@@ -137,8 +133,6 @@
     if (FilteredNumberCompat.canUseNewFiltering()) {
       migratePromoView.setVisibility(View.VISIBLE);
       blockedNumbersText.setVisibility(View.GONE);
-      getListView().findViewById(R.id.add_number_linear_layout).setVisibility(View.GONE);
-      getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(null);
       blockedNumberListDivider.setVisibility(View.GONE);
       importSettings.setVisibility(View.GONE);
       getListView().findViewById(R.id.import_button).setOnClickListener(null);
@@ -218,9 +212,7 @@
     }
 
     int resId = view.getId();
-    if (resId == R.id.add_number_linear_layout) {
-      activity.showSearchUi();
-    } else if (resId == R.id.view_numbers_button) {
+    if (resId == R.id.view_numbers_button) {
       activity.showNumbersToImportPreviewUi();
     } else if (resId == R.id.import_button) {
       FilteredNumbersUtil.importSendToVoicemailContacts(
diff --git a/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java b/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java
index 858d283..5475b4e 100644
--- a/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java
+++ b/java/com/android/dialer/app/filterednumber/BlockedNumbersSettingsActivity.java
@@ -19,17 +19,13 @@
 import android.support.v7.app.AppCompatActivity;
 import android.view.MenuItem;
 import com.android.dialer.app.R;
-import com.android.dialer.app.list.BlockedListSearchFragment;
-import com.android.dialer.app.list.SearchFragment;
 import com.android.dialer.logging.Logger;
 import com.android.dialer.logging.ScreenEvent;
 
 /** TODO(calderwoodra): documentation */
-public class BlockedNumbersSettingsActivity extends AppCompatActivity
-    implements SearchFragment.HostInterface {
+public class BlockedNumbersSettingsActivity extends AppCompatActivity {
 
   private static final String TAG_BLOCKED_MANAGEMENT_FRAGMENT = "blocked_management";
-  private static final String TAG_BLOCKED_SEARCH_FRAGMENT = "blocked_search";
   private static final String TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT = "view_numbers_to_import";
 
   @Override
@@ -60,27 +56,6 @@
     Logger.get(this).logScreenView(ScreenEvent.Type.BLOCKED_NUMBER_MANAGEMENT, this);
   }
 
-  /** Shows fragment with search UI for browsing/finding numbers to block. */
-  public void showSearchUi() {
-    BlockedListSearchFragment fragment =
-        (BlockedListSearchFragment)
-            getFragmentManager().findFragmentByTag(TAG_BLOCKED_SEARCH_FRAGMENT);
-    if (fragment == null) {
-      fragment = new BlockedListSearchFragment();
-      fragment.setHasOptionsMenu(false);
-      fragment.setShowEmptyListForNullQuery(true);
-      fragment.setDirectorySearchEnabled(false);
-    }
-
-    getFragmentManager()
-        .beginTransaction()
-        .replace(R.id.blocked_numbers_activity_container, fragment, TAG_BLOCKED_SEARCH_FRAGMENT)
-        .addToBackStack(null)
-        .commit();
-
-    Logger.get(this).logScreenView(ScreenEvent.Type.BLOCKED_NUMBER_ADD_NUMBER, this);
-  }
-
   /**
    * Shows fragment with UI to preview the numbers of contacts currently marked as send-to-voicemail
    * in Contacts. These numbers can be imported into Dialer's blocked number list.
@@ -119,24 +94,4 @@
       super.onBackPressed();
     }
   }
-
-  @Override
-  public boolean isActionBarShowing() {
-    return false;
-  }
-
-  @Override
-  public boolean isDialpadShown() {
-    return false;
-  }
-
-  @Override
-  public int getDialpadHeight() {
-    return 0;
-  }
-
-  @Override
-  public int getActionBarHeight() {
-    return 0;
-  }
 }
diff --git a/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java b/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java
index a483af9..6eaa2b6 100644
--- a/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java
+++ b/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java
@@ -22,7 +22,6 @@
 import com.android.dialer.app.calllog.CallLogAdapter;
 import com.android.dialer.app.calllog.calllogcache.CallLogCache;
 import com.android.dialer.app.contactinfo.ContactInfoCache;
-import com.android.dialer.app.list.RegularSearchFragment;
 import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter;
 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
 
@@ -47,6 +46,4 @@
       VoicemailPlaybackPresenter voicemailPlaybackPresenter,
       @NonNull FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler,
       int activityType);
-
-  RegularSearchFragment newRegularSearchFragment();
 }
diff --git a/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java b/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java
index 488fbad..e95c470 100644
--- a/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java
+++ b/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java
@@ -22,7 +22,6 @@
 import com.android.dialer.app.calllog.CallLogAdapter;
 import com.android.dialer.app.calllog.calllogcache.CallLogCache;
 import com.android.dialer.app.contactinfo.ContactInfoCache;
-import com.android.dialer.app.list.RegularSearchFragment;
 import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter;
 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
 
@@ -53,9 +52,4 @@
         filteredNumberAsyncQueryHandler,
         activityType);
   }
-
-  @Override
-  public RegularSearchFragment newRegularSearchFragment() {
-    return new RegularSearchFragment();
-  }
 }
diff --git a/java/com/android/dialer/app/list/AllContactsFragment.java b/java/com/android/dialer/app/list/AllContactsFragment.java
deleted file mode 100644
index 5076fd9..0000000
--- a/java/com/android/dialer/app/list/AllContactsFragment.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.list;
-
-import static android.Manifest.permission.READ_CONTACTS;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.QuickContact;
-import android.support.v13.app.FragmentCompat;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import com.android.contacts.common.list.ContactEntryListAdapter;
-import com.android.contacts.common.list.ContactEntryListFragment;
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.common.list.DefaultContactListAdapter;
-import com.android.dialer.app.R;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.compat.CompatUtils;
-import com.android.dialer.logging.InteractionEvent;
-import com.android.dialer.logging.Logger;
-import com.android.dialer.util.DialerUtils;
-import com.android.dialer.util.IntentUtil;
-import com.android.dialer.util.PermissionsUtil;
-import com.android.dialer.widget.EmptyContentView;
-import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
-import java.util.Arrays;
-
-/** Fragments to show all contacts with phone numbers. */
-public class AllContactsFragment extends ContactEntryListFragment<ContactEntryListAdapter>
-    implements OnEmptyViewActionButtonClickedListener,
-        FragmentCompat.OnRequestPermissionsResultCallback {
-
-  private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1;
-
-  private EmptyContentView emptyListView;
-
-  /**
-   * Listen to broadcast events about permissions in order to be notified if the READ_CONTACTS
-   * permission is granted via the UI in another fragment.
-   */
-  private BroadcastReceiver readContactsPermissionGrantedReceiver =
-      new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-          reloadData();
-        }
-      };
-
-  public AllContactsFragment() {
-    setQuickContactEnabled(false);
-    setAdjustSelectionBoundsEnabled(true);
-    setPhotoLoaderEnabled(true);
-    setSectionHeaderDisplayEnabled(true);
-    setDarkTheme(false);
-    setVisibleScrollbarEnabled(true);
-  }
-
-  @Override
-  public void onViewCreated(View view, android.os.Bundle savedInstanceState) {
-    super.onViewCreated(view, savedInstanceState);
-
-    emptyListView = (EmptyContentView) view.findViewById(R.id.empty_list_view);
-    emptyListView.setImage(R.drawable.empty_contacts);
-    emptyListView.setDescription(R.string.all_contacts_empty);
-    emptyListView.setActionClickedListener(this);
-    getListView().setEmptyView(emptyListView);
-    emptyListView.setVisibility(View.GONE);
-  }
-
-  @Override
-  public void onStart() {
-    super.onStart();
-    PermissionsUtil.registerPermissionReceiver(
-        getActivity(), readContactsPermissionGrantedReceiver, READ_CONTACTS);
-  }
-
-  @Override
-  public void onStop() {
-    PermissionsUtil.unregisterPermissionReceiver(
-        getActivity(), readContactsPermissionGrantedReceiver);
-    super.onStop();
-  }
-
-  @Override
-  protected void startLoading() {
-    if (PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
-      super.startLoading();
-      emptyListView.setDescription(R.string.all_contacts_empty);
-      emptyListView.setActionLabel(R.string.all_contacts_empty_add_contact_action);
-    } else {
-      emptyListView.setDescription(R.string.permission_no_contacts);
-      emptyListView.setActionLabel(R.string.permission_single_turn_on);
-      emptyListView.setVisibility(View.VISIBLE);
-    }
-  }
-
-  @Override
-  public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-    super.onLoadFinished(loader, data);
-
-    if (data == null || data.getCount() == 0) {
-      emptyListView.setVisibility(View.VISIBLE);
-    }
-  }
-
-  @Override
-  protected ContactEntryListAdapter createListAdapter() {
-    final DefaultContactListAdapter adapter =
-        new DefaultContactListAdapter(getActivity()) {
-          @Override
-          protected void bindView(View itemView, int partition, Cursor cursor, int position) {
-            super.bindView(itemView, partition, cursor, position);
-            itemView.setTag(this.getContactUri(partition, cursor));
-          }
-        };
-    adapter.setDisplayPhotos(true);
-    adapter.setFilter(
-        ContactListFilter.createFilterWithType(ContactListFilter.FILTER_TYPE_DEFAULT));
-    adapter.setSectionHeaderDisplayEnabled(isSectionHeaderDisplayEnabled());
-    return adapter;
-  }
-
-  @Override
-  protected View inflateView(LayoutInflater inflater, ViewGroup container) {
-    return inflater.inflate(R.layout.all_contacts_fragment, null);
-  }
-
-  @Override
-  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-    final Uri uri = (Uri) view.getTag();
-    if (uri != null) {
-      Logger.get(getContext())
-          .logInteraction(InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_ALL_CONTACTS_GENERAL);
-      if (CompatUtils.hasPrioritizedMimeType()) {
-        QuickContact.showQuickContact(getContext(), view, uri, null, Phone.CONTENT_ITEM_TYPE);
-      } else {
-        QuickContact.showQuickContact(getActivity(), view, uri, QuickContact.MODE_LARGE, null);
-      }
-    }
-  }
-
-  @Override
-  protected void onItemClick(int position, long id) {
-    // Do nothing. Implemented to satisfy ContactEntryListFragment.
-  }
-
-  @Override
-  public void onEmptyViewActionButtonClicked() {
-    final Activity activity = getActivity();
-    if (activity == null) {
-      return;
-    }
-
-    String[] deniedPermissions =
-        PermissionsUtil.getPermissionsCurrentlyDenied(
-            getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer);
-    if (deniedPermissions.length > 0) {
-      LogUtil.i(
-          "AllContactsFragment.onEmptyViewActionButtonClicked",
-          "Requesting permissions: " + Arrays.toString(deniedPermissions));
-      FragmentCompat.requestPermissions(
-          this, deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE);
-    } else {
-      // Add new contact
-      DialerUtils.startActivityWithErrorToast(
-          activity, IntentUtil.getNewContactIntent(), R.string.add_contact_not_available);
-    }
-  }
-
-  @Override
-  public void onRequestPermissionsResult(
-      int requestCode, String[] permissions, int[] grantResults) {
-    if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE) {
-      if (grantResults.length >= 1 && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
-        // Force a refresh of the data since we were missing the permission before this.
-        reloadData();
-      }
-    }
-  }
-}
diff --git a/java/com/android/dialer/app/list/BlockedListSearchAdapter.java b/java/com/android/dialer/app/list/BlockedListSearchAdapter.java
deleted file mode 100644
index 575d6e6..0000000
--- a/java/com/android/dialer/app/list/BlockedListSearchAdapter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2015 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.app.list;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.view.View;
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.dialer.app.R;
-import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
-import com.android.dialer.location.GeoUtil;
-
-/** List adapter to display search results for adding a blocked number. */
-public class BlockedListSearchAdapter extends RegularSearchListAdapter {
-
-  private Resources resources;
-  private FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler;
-
-  public BlockedListSearchAdapter(Context context) {
-    super(context);
-    resources = context.getResources();
-    disableAllShortcuts();
-    setShortcutEnabled(SHORTCUT_BLOCK_NUMBER, true);
-
-    filteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(context);
-  }
-
-  @Override
-  protected boolean isChanged(boolean showNumberShortcuts) {
-    return setShortcutEnabled(SHORTCUT_BLOCK_NUMBER, showNumberShortcuts || isQuerySipAddress);
-  }
-
-  public void setViewBlocked(ContactListItemView view, Integer id) {
-    view.setTag(R.id.block_id, id);
-    final int textColor = resources.getColor(R.color.blocked_number_block_color);
-    view.getDataView().setTextColor(textColor);
-    view.getLabelView().setTextColor(textColor);
-    //TODO: Add icon
-  }
-
-  public void setViewUnblocked(ContactListItemView view) {
-    view.setTag(R.id.block_id, null);
-    final int textColor = resources.getColor(R.color.dialer_secondary_text_color);
-    view.getDataView().setTextColor(textColor);
-    view.getLabelView().setTextColor(textColor);
-    //TODO: Remove icon
-  }
-
-  @Override
-  protected void bindView(View itemView, int partition, Cursor cursor, int position) {
-    super.bindView(itemView, partition, cursor, position);
-
-    final ContactListItemView view = (ContactListItemView) itemView;
-    // Reset view state to unblocked.
-    setViewUnblocked(view);
-
-    final String number = getPhoneNumber(position);
-    final String countryIso = GeoUtil.getCurrentCountryIso(mContext);
-    final FilteredNumberAsyncQueryHandler.OnCheckBlockedListener onCheckListener =
-        new FilteredNumberAsyncQueryHandler.OnCheckBlockedListener() {
-          @Override
-          public void onCheckComplete(Integer id) {
-            if (id != null && id != FilteredNumberAsyncQueryHandler.INVALID_ID) {
-              setViewBlocked(view, id);
-            }
-          }
-        };
-    filteredNumberAsyncQueryHandler.isBlockedNumber(onCheckListener, number, countryIso);
-  }
-}
diff --git a/java/com/android/dialer/app/list/BlockedListSearchFragment.java b/java/com/android/dialer/app/list/BlockedListSearchFragment.java
deleted file mode 100644
index ce812af..0000000
--- a/java/com/android/dialer/app/list/BlockedListSearchFragment.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2015 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.app.list;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.EditText;
-import android.widget.Toast;
-import com.android.contacts.common.list.ContactEntryListAdapter;
-import com.android.contacts.common.util.ContactDisplayUtils;
-import com.android.dialer.app.R;
-import com.android.dialer.app.widget.SearchEditTextLayout;
-import com.android.dialer.blocking.BlockNumberDialogFragment;
-import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
-import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.location.GeoUtil;
-import com.android.dialer.logging.InteractionEvent;
-import com.android.dialer.logging.Logger;
-import com.android.dialer.phonenumberutil.PhoneNumberHelper;
-
-/** TODO(calderwoodra): documentation */
-public class BlockedListSearchFragment extends RegularSearchFragment
-    implements BlockNumberDialogFragment.Callback {
-
-  private final TextWatcher phoneSearchQueryTextListener =
-      new TextWatcher() {
-        @Override
-        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
-        @Override
-        public void onTextChanged(CharSequence s, int start, int before, int count) {
-          setQueryString(s.toString());
-        }
-
-        @Override
-        public void afterTextChanged(Editable s) {}
-      };
-  private final SearchEditTextLayout.Callback searchLayoutCallback =
-      new SearchEditTextLayout.Callback() {
-        @Override
-        public void onBackButtonClicked() {
-          getActivity().onBackPressed();
-        }
-
-        @Override
-        public void onSearchViewClicked() {}
-      };
-  private FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler;
-  private EditText searchView;
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-
-    setShowEmptyListForNullQuery(true);
-    /*
-     * Pass in the empty string here so ContactEntryListFragment#setQueryString interprets it as
-     * an empty search query, rather than as an uninitalized value. In the latter case, the
-     * adapter returned by #createListAdapter is used, which populates the view with contacts.
-     * Passing in the empty string forces ContactEntryListFragment to interpret it as an empty
-     * query, which results in showing an empty view
-     */
-    setQueryString(getQueryString() == null ? "" : getQueryString());
-    filteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(getContext());
-  }
-
-  @Override
-  public void onResume() {
-    super.onResume();
-
-    ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
-    actionBar.setCustomView(R.layout.search_edittext);
-    actionBar.setDisplayShowCustomEnabled(true);
-    actionBar.setDisplayHomeAsUpEnabled(false);
-    actionBar.setDisplayShowHomeEnabled(false);
-
-    final SearchEditTextLayout searchEditTextLayout =
-        (SearchEditTextLayout) actionBar.getCustomView().findViewById(R.id.search_view_container);
-    searchEditTextLayout.expand(false, true);
-    searchEditTextLayout.setCallback(searchLayoutCallback);
-    searchEditTextLayout.setBackgroundDrawable(null);
-
-    searchView = (EditText) searchEditTextLayout.findViewById(R.id.search_view);
-    searchView.addTextChangedListener(phoneSearchQueryTextListener);
-    searchView.setHint(R.string.block_number_search_hint);
-
-    searchEditTextLayout
-        .findViewById(R.id.search_box_expanded)
-        .setBackgroundColor(getContext().getResources().getColor(android.R.color.white));
-
-    if (!TextUtils.isEmpty(getQueryString())) {
-      searchView.setText(getQueryString());
-    }
-
-    // TODO: Don't set custom text size; use default search text size.
-    searchView.setTextSize(
-        TypedValue.COMPLEX_UNIT_PX,
-        getResources().getDimension(R.dimen.blocked_number_search_text_size));
-  }
-
-  @Override
-  protected ContactEntryListAdapter createListAdapter() {
-    BlockedListSearchAdapter adapter = new BlockedListSearchAdapter(getActivity());
-    adapter.setDisplayPhotos(true);
-    // Don't show SIP addresses.
-    adapter.setUseCallableUri(false);
-    // Keep in sync with the queryString set in #onCreate
-    adapter.setQueryString(getQueryString() == null ? "" : getQueryString());
-    return adapter;
-  }
-
-  @Override
-  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-    super.onItemClick(parent, view, position, id);
-    final int adapterPosition = position - getListView().getHeaderViewsCount();
-    final BlockedListSearchAdapter adapter = (BlockedListSearchAdapter) getAdapter();
-    final int shortcutType = adapter.getShortcutTypeFromPosition(adapterPosition);
-    final Integer blockId = (Integer) view.getTag(R.id.block_id);
-    final String number;
-    switch (shortcutType) {
-      case DialerPhoneNumberListAdapter.SHORTCUT_INVALID:
-        // Handles click on a search result, either contact or nearby places result.
-        number = adapter.getPhoneNumber(adapterPosition);
-        blockContactNumber(number, blockId);
-        break;
-      case DialerPhoneNumberListAdapter.SHORTCUT_BLOCK_NUMBER:
-        // Handles click on 'Block number' shortcut to add the user query as a number.
-        number = adapter.getQueryString();
-        blockNumber(number);
-        break;
-      default:
-        LogUtil.w(
-            "BlockedListSearchFragment.onItemClick",
-            "ignoring unsupported shortcut type: " + shortcutType);
-        break;
-    }
-  }
-
-  @Override
-  protected void onItemClick(int position, long id) {
-    // Prevent SearchFragment.onItemClicked from being called.
-  }
-
-  private void blockNumber(final String number) {
-    final String countryIso = GeoUtil.getCurrentCountryIso(getContext());
-    final OnCheckBlockedListener onCheckListener =
-        new OnCheckBlockedListener() {
-          @Override
-          public void onCheckComplete(Integer id) {
-            if (id == null) {
-              BlockNumberDialogFragment.show(
-                  id,
-                  number,
-                  countryIso,
-                  PhoneNumberHelper.formatNumber(getContext(), number, countryIso),
-                  R.id.blocked_numbers_activity_container,
-                  getFragmentManager(),
-                  BlockedListSearchFragment.this);
-            } else if (id == FilteredNumberAsyncQueryHandler.INVALID_ID) {
-              Toast.makeText(
-                      getContext(),
-                      ContactDisplayUtils.getTtsSpannedPhoneNumber(
-                          getResources(), R.string.invalidNumber, number),
-                      Toast.LENGTH_SHORT)
-                  .show();
-            } else {
-              Toast.makeText(
-                      getContext(),
-                      ContactDisplayUtils.getTtsSpannedPhoneNumber(
-                          getResources(), R.string.alreadyBlocked, number),
-                      Toast.LENGTH_SHORT)
-                  .show();
-            }
-          }
-        };
-    filteredNumberAsyncQueryHandler.isBlockedNumber(onCheckListener, number, countryIso);
-  }
-
-  @Override
-  public void onFilterNumberSuccess() {
-    Logger.get(getContext()).logInteraction(InteractionEvent.Type.BLOCK_NUMBER_MANAGEMENT_SCREEN);
-    goBack();
-  }
-
-  @Override
-  public void onUnfilterNumberSuccess() {
-    LogUtil.e(
-        "BlockedListSearchFragment.onUnfilterNumberSuccess",
-        "unblocked a number from the BlockedListSearchFragment");
-    goBack();
-  }
-
-  private void goBack() {
-    Activity activity = getActivity();
-    if (activity == null) {
-      return;
-    }
-    activity.onBackPressed();
-  }
-
-  @Override
-  public void onChangeFilteredNumberUndo() {
-    getAdapter().notifyDataSetChanged();
-  }
-
-  private void blockContactNumber(final String number, final Integer blockId) {
-    if (blockId != null) {
-      Toast.makeText(
-              getContext(),
-              ContactDisplayUtils.getTtsSpannedPhoneNumber(
-                  getResources(), R.string.alreadyBlocked, number),
-              Toast.LENGTH_SHORT)
-          .show();
-      return;
-    }
-
-    BlockNumberDialogFragment.show(
-        blockId,
-        number,
-        GeoUtil.getCurrentCountryIso(getContext()),
-        number,
-        R.id.blocked_numbers_activity_container,
-        getFragmentManager(),
-        this);
-  }
-}
diff --git a/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java b/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java
deleted file mode 100644
index d5609b8..0000000
--- a/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.app.list;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.support.v4.content.ContextCompat;
-import android.telephony.PhoneNumberUtils;
-import android.text.BidiFormatter;
-import android.text.TextDirectionHeuristics;
-import android.view.View;
-import android.view.ViewGroup;
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.contacts.common.list.PhoneNumberListAdapter;
-import com.android.contacts.common.util.ContactDisplayUtils;
-import com.android.dialer.app.R;
-import com.android.dialer.location.GeoUtil;
-import com.android.dialer.phonenumberutil.PhoneNumberHelper;
-
-/**
- * {@link PhoneNumberListAdapter} with the following added shortcuts, that are displayed as list
- * items: 1) Directly calling the phone number query 2) Adding the phone number query to a contact
- *
- * <p>These shortcuts can be enabled or disabled to toggle whether or not they show up in the list.
- */
-public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter {
-
-  public static final int SHORTCUT_INVALID = -1;
-  public static final int SHORTCUT_DIRECT_CALL = 0;
-  public static final int SHORTCUT_CREATE_NEW_CONTACT = 1;
-  public static final int SHORTCUT_ADD_TO_EXISTING_CONTACT = 2;
-  public static final int SHORTCUT_SEND_SMS_MESSAGE = 3;
-  public static final int SHORTCUT_MAKE_VIDEO_CALL = 4;
-  public static final int SHORTCUT_BLOCK_NUMBER = 5;
-  public static final int SHORTCUT_COUNT = 6;
-
-  private final boolean[] shortcutEnabled = new boolean[SHORTCUT_COUNT];
-  private final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
-  private final String countryIso;
-
-  private String formattedQueryString;
-
-  public DialerPhoneNumberListAdapter(Context context) {
-    super(context);
-
-    countryIso = GeoUtil.getCurrentCountryIso(context);
-  }
-
-  @Override
-  public int getCount() {
-    return super.getCount() + getShortcutCount();
-  }
-
-  /** @return The number of enabled shortcuts. Ranges from 0 to a maximum of SHORTCUT_COUNT */
-  public int getShortcutCount() {
-    int count = 0;
-    for (int i = 0; i < shortcutEnabled.length; i++) {
-      if (shortcutEnabled[i]) {
-        count++;
-      }
-    }
-    return count;
-  }
-
-  public void disableAllShortcuts() {
-    for (int i = 0; i < shortcutEnabled.length; i++) {
-      shortcutEnabled[i] = false;
-    }
-  }
-
-  @Override
-  public int getItemViewType(int position) {
-    final int shortcut = getShortcutTypeFromPosition(position);
-    if (shortcut >= 0) {
-      // shortcutPos should always range from 1 to SHORTCUT_COUNT
-      return super.getViewTypeCount() + shortcut;
-    } else {
-      return super.getItemViewType(position);
-    }
-  }
-
-  @Override
-  public int getViewTypeCount() {
-    // Number of item view types in the super implementation + 2 for the 2 new shortcuts
-    return super.getViewTypeCount() + SHORTCUT_COUNT;
-  }
-
-  @Override
-  public View getView(int position, View convertView, ViewGroup parent) {
-    final int shortcutType = getShortcutTypeFromPosition(position);
-    if (shortcutType >= 0) {
-      if (convertView != null) {
-        assignShortcutToView((ContactListItemView) convertView, shortcutType);
-        return convertView;
-      } else {
-        final ContactListItemView v =
-            new ContactListItemView(getContext(), null, mIsImsVideoEnabled);
-        assignShortcutToView(v, shortcutType);
-        return v;
-      }
-    } else {
-      return super.getView(position, convertView, parent);
-    }
-  }
-
-  @Override
-  protected ContactListItemView newView(
-      Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
-    final ContactListItemView view = super.newView(context, partition, cursor, position, parent);
-
-    view.setSupportVideoCallIcon(mIsImsVideoEnabled);
-    return view;
-  }
-
-  /**
-   * @param position The position of the item
-   * @return The enabled shortcut type matching the given position if the item is a shortcut, -1
-   *     otherwise
-   */
-  public int getShortcutTypeFromPosition(int position) {
-    int shortcutCount = position - super.getCount();
-    if (shortcutCount >= 0) {
-      // Iterate through the array of shortcuts, looking only for shortcuts where
-      // mShortcutEnabled[i] is true
-      for (int i = 0; shortcutCount >= 0 && i < shortcutEnabled.length; i++) {
-        if (shortcutEnabled[i]) {
-          shortcutCount--;
-          if (shortcutCount < 0) {
-            return i;
-          }
-        }
-      }
-      throw new IllegalArgumentException(
-          "Invalid position - greater than cursor count " + " but not a shortcut.");
-    }
-    return SHORTCUT_INVALID;
-  }
-
-  @Override
-  public boolean isEmpty() {
-    return getShortcutCount() == 0 && super.isEmpty();
-  }
-
-  @Override
-  public boolean isEnabled(int position) {
-    final int shortcutType = getShortcutTypeFromPosition(position);
-    if (shortcutType >= 0) {
-      return true;
-    } else {
-      return super.isEnabled(position);
-    }
-  }
-
-  private void assignShortcutToView(ContactListItemView v, int shortcutType) {
-    final CharSequence text;
-    final Drawable drawable;
-    final Resources resources = getContext().getResources();
-    final String number = getFormattedQueryString();
-    switch (shortcutType) {
-      case SHORTCUT_DIRECT_CALL:
-        text =
-            ContactDisplayUtils.getTtsSpannedPhoneNumber(
-                resources,
-                R.string.search_shortcut_call_number,
-                bidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR));
-        drawable = ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_call_vd_theme_24);
-        break;
-      case SHORTCUT_CREATE_NEW_CONTACT:
-        text = resources.getString(R.string.search_shortcut_create_new_contact);
-        drawable =
-            ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_person_add_vd_theme_24);
-        drawable.setAutoMirrored(true);
-        break;
-      case SHORTCUT_ADD_TO_EXISTING_CONTACT:
-        text = resources.getString(R.string.search_shortcut_add_to_contact);
-        drawable =
-            ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_person_add_vd_theme_24);
-        break;
-      case SHORTCUT_SEND_SMS_MESSAGE:
-        text = resources.getString(R.string.search_shortcut_send_sms_message);
-        drawable =
-            ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_message_vd_theme_24);
-        break;
-      case SHORTCUT_MAKE_VIDEO_CALL:
-        text = resources.getString(R.string.search_shortcut_make_video_call);
-        drawable =
-            ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_videocam_vd_theme_24);
-        break;
-      case SHORTCUT_BLOCK_NUMBER:
-        text = resources.getString(R.string.search_shortcut_block_number);
-        drawable =
-            ContextCompat.getDrawable(getContext(), R.drawable.ic_not_interested_googblue_24dp);
-        break;
-      default:
-        throw new IllegalArgumentException("Invalid shortcut type");
-    }
-    v.setDrawable(drawable);
-    v.setDisplayName(text);
-    v.setAdjustSelectionBoundsEnabled(false);
-  }
-
-  /** @return True if the shortcut state (disabled vs enabled) was changed by this operation */
-  public boolean setShortcutEnabled(int shortcutType, boolean visible) {
-    final boolean changed = shortcutEnabled[shortcutType] != visible;
-    shortcutEnabled[shortcutType] = visible;
-    return changed;
-  }
-
-  public String getFormattedQueryString() {
-    return formattedQueryString;
-  }
-
-  @Override
-  public void setQueryString(String queryString) {
-    formattedQueryString =
-        PhoneNumberHelper.formatNumber(
-            getContext(), PhoneNumberUtils.normalizeNumber(queryString), countryIso);
-    super.setQueryString(queryString);
-  }
-}
diff --git a/java/com/android/dialer/app/list/DialtactsPagerAdapter.java b/java/com/android/dialer/app/list/DialtactsPagerAdapter.java
index d272932..364ae6f 100644
--- a/java/com/android/dialer/app/list/DialtactsPagerAdapter.java
+++ b/java/com/android/dialer/app/list/DialtactsPagerAdapter.java
@@ -56,11 +56,9 @@
   private final List<Fragment> fragments = new ArrayList<>();
   private final String[] tabTitles;
   private final boolean useNewSpeedDialTab;
-  private final boolean useNewContactsTab;
   private OldSpeedDialFragment oldSpeedDialFragment;
   private SpeedDialFragment speedDialFragment;
   private CallLogFragment callLogFragment;
-  private AllContactsFragment oldContactsFragment;
   private ContactsFragment contactsFragment;
   private CallLogFragment voicemailFragment;
 
@@ -71,8 +69,6 @@
     super(fm);
     useNewSpeedDialTab =
         ConfigProviderBindings.get(context).getBoolean("enable_new_favorites_tab", false);
-    useNewContactsTab =
-        ConfigProviderBindings.get(context).getBoolean("enable_new_contacts_tab", true);
     this.tabTitles = tabTitles;
     hasActiveVoicemailProvider = hasVoicemailProvider;
     fragments.addAll(Collections.nCopies(TAB_COUNT_WITH_VOICEMAIL, null));
@@ -105,17 +101,10 @@
         }
         return callLogFragment;
       case TAB_INDEX_ALL_CONTACTS:
-        if (useNewContactsTab) {
-          if (contactsFragment == null) {
-            contactsFragment = ContactsFragment.newInstance(Header.ADD_CONTACT);
-          }
-          return contactsFragment;
-        } else {
-          if (oldContactsFragment == null) {
-            oldContactsFragment = new AllContactsFragment();
-          }
-          return oldContactsFragment;
+        if (contactsFragment == null) {
+          contactsFragment = ContactsFragment.newInstance(Header.ADD_CONTACT);
         }
+        return contactsFragment;
       case TAB_INDEX_VOICEMAIL:
         if (voicemailFragment == null) {
           voicemailFragment = new VisualVoicemailCallLogFragment();
@@ -145,8 +134,6 @@
       callLogFragment = (CallLogFragment) fragment;
     } else if (fragment instanceof ContactsFragment) {
       contactsFragment = (ContactsFragment) fragment;
-    } else if (fragment instanceof AllContactsFragment) {
-      oldContactsFragment = (AllContactsFragment) fragment;
     } else if (fragment instanceof CallLogFragment && position == TAB_INDEX_VOICEMAIL) {
       voicemailFragment = (CallLogFragment) fragment;
       LogUtil.v("ViewPagerAdapter.instantiateItem", voicemailFragment.toString());
diff --git a/java/com/android/dialer/app/list/RegularSearchFragment.java b/java/com/android/dialer/app/list/RegularSearchFragment.java
deleted file mode 100644
index d1927f0..0000000
--- a/java/com/android/dialer/app/list/RegularSearchFragment.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.list;
-
-import static android.Manifest.permission.READ_CONTACTS;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v13.app.FragmentCompat;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-import com.android.contacts.common.list.ContactEntryListAdapter;
-import com.android.contacts.common.list.PinnedHeaderListView;
-import com.android.dialer.app.R;
-import com.android.dialer.callintent.CallInitiationType;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.concurrent.DialerExecutor;
-import com.android.dialer.common.concurrent.DialerExecutor.Worker;
-import com.android.dialer.common.concurrent.DialerExecutorComponent;
-import com.android.dialer.phonenumbercache.CachedNumberLookupService;
-import com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
-import com.android.dialer.phonenumbercache.PhoneNumberCache;
-import com.android.dialer.util.PermissionsUtil;
-import com.android.dialer.widget.EmptyContentView;
-import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
-import java.util.Arrays;
-
-public class RegularSearchFragment extends SearchFragment
-    implements OnEmptyViewActionButtonClickedListener,
-        FragmentCompat.OnRequestPermissionsResultCallback {
-
-  public static final int PERMISSION_REQUEST_CODE = 1;
-
-  private static final int SEARCH_DIRECTORY_RESULT_LIMIT = 5;
-  protected String permissionToRequest;
-
-  private DialerExecutor<CachedContactInfo> addContactTask;
-
-  public RegularSearchFragment() {
-    configureDirectorySearch();
-  }
-
-  public void configureDirectorySearch() {
-    setDirectorySearchEnabled(true);
-    setDirectoryResultLimit(SEARCH_DIRECTORY_RESULT_LIMIT);
-  }
-
-  @Override
-  public void onCreate(Bundle savedState) {
-    super.onCreate(savedState);
-
-    addContactTask =
-        DialerExecutorComponent.get(getContext())
-            .dialerExecutorFactory()
-            .createUiTaskBuilder(
-                getFragmentManager(),
-                "RegularSearchFragment.addContact",
-                new AddContactWorker(getContext().getApplicationContext()))
-            .build();
-  }
-
-  @Override
-  protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
-    super.onCreateView(inflater, container);
-    ((PinnedHeaderListView) getListView()).setScrollToSectionOnHeaderTouch(true);
-  }
-
-  @Override
-  protected ContactEntryListAdapter createListAdapter() {
-    RegularSearchListAdapter adapter = new RegularSearchListAdapter(getActivity());
-    adapter.setDisplayPhotos(true);
-    adapter.setUseCallableUri(usesCallableUri());
-    adapter.setListener(this);
-    return adapter;
-  }
-
-  @Override
-  protected void cacheContactInfo(int position) {
-    CachedNumberLookupService cachedNumberLookupService =
-        PhoneNumberCache.get(getContext()).getCachedNumberLookupService();
-    if (cachedNumberLookupService != null) {
-      final RegularSearchListAdapter adapter = (RegularSearchListAdapter) getAdapter();
-      CachedContactInfo cachedContactInfo =
-          adapter.getContactInfo(cachedNumberLookupService, position);
-      addContactTask.executeSerial(cachedContactInfo);
-    }
-  }
-
-  @Override
-  protected void setupEmptyView() {
-    if (emptyView != null && getActivity() != null) {
-      final int imageResource;
-      final int actionLabelResource;
-      final int descriptionResource;
-      final OnEmptyViewActionButtonClickedListener listener;
-      if (!PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
-        imageResource = R.drawable.empty_contacts;
-        actionLabelResource = R.string.permission_single_turn_on;
-        descriptionResource = R.string.permission_no_search;
-        listener = this;
-        permissionToRequest = READ_CONTACTS;
-      } else {
-        imageResource = EmptyContentView.NO_IMAGE;
-        actionLabelResource = EmptyContentView.NO_LABEL;
-        descriptionResource = EmptyContentView.NO_LABEL;
-        listener = null;
-        permissionToRequest = null;
-      }
-
-      emptyView.setImage(imageResource);
-      emptyView.setActionLabel(actionLabelResource);
-      emptyView.setDescription(descriptionResource);
-      if (listener != null) {
-        emptyView.setActionClickedListener(listener);
-      }
-    }
-  }
-
-  @Override
-  public void onEmptyViewActionButtonClicked() {
-    final Activity activity = getActivity();
-    if (activity == null) {
-      return;
-    }
-
-    if (READ_CONTACTS.equals(permissionToRequest)) {
-      String[] deniedPermissions =
-          PermissionsUtil.getPermissionsCurrentlyDenied(
-              getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer);
-      if (deniedPermissions.length > 0) {
-        LogUtil.i(
-            "RegularSearchFragment.onEmptyViewActionButtonClicked",
-            "Requesting permissions: " + Arrays.toString(deniedPermissions));
-        FragmentCompat.requestPermissions(this, deniedPermissions, PERMISSION_REQUEST_CODE);
-      }
-    }
-  }
-
-  @Override
-  public void onRequestPermissionsResult(
-      int requestCode, String[] permissions, int[] grantResults) {
-    if (requestCode == PERMISSION_REQUEST_CODE) {
-      setupEmptyView();
-      if (grantResults != null
-          && grantResults.length == 1
-          && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
-        PermissionsUtil.notifyPermissionGranted(getActivity(), permissions[0]);
-      }
-    }
-  }
-
-  @Override
-  protected CallInitiationType.Type getCallInitiationType(boolean isRemoteDirectory) {
-    return isRemoteDirectory
-        ? CallInitiationType.Type.REMOTE_DIRECTORY
-        : CallInitiationType.Type.REGULAR_SEARCH;
-  }
-
-  public interface CapabilityChecker {
-
-    boolean isNearbyPlacesSearchEnabled();
-  }
-
-  private static class AddContactWorker implements Worker<CachedContactInfo, Void> {
-
-    private final Context appContext;
-
-    private AddContactWorker(Context appContext) {
-      this.appContext = appContext;
-    }
-
-    @Nullable
-    @Override
-    public Void doInBackground(@Nullable CachedContactInfo contactInfo) throws Throwable {
-      CachedNumberLookupService cachedNumberLookupService =
-          PhoneNumberCache.get(appContext).getCachedNumberLookupService();
-      if (cachedNumberLookupService != null) {
-        cachedNumberLookupService.addContact(appContext, contactInfo);
-      }
-      return null;
-    }
-  }
-}
diff --git a/java/com/android/dialer/app/list/RegularSearchListAdapter.java b/java/com/android/dialer/app/list/RegularSearchListAdapter.java
deleted file mode 100644
index c92f48c..0000000
--- a/java/com/android/dialer/app/list/RegularSearchListAdapter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.list;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.text.TextUtils;
-import com.android.contacts.common.ContactsUtils;
-import com.android.contacts.common.list.DirectoryPartition;
-import com.android.dialer.common.cp2.DirectoryCompat;
-import com.android.dialer.phonenumbercache.CachedNumberLookupService;
-import com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
-import com.android.dialer.phonenumbercache.ContactInfo;
-import com.android.dialer.phonenumberutil.PhoneNumberHelper;
-import com.android.dialer.util.CallUtil;
-
-/** List adapter to display regular search results. */
-public class RegularSearchListAdapter extends DialerPhoneNumberListAdapter {
-
-  protected boolean isQuerySipAddress;
-
-  public RegularSearchListAdapter(Context context) {
-    super(context);
-    setShortcutEnabled(SHORTCUT_CREATE_NEW_CONTACT, false);
-    setShortcutEnabled(SHORTCUT_ADD_TO_EXISTING_CONTACT, false);
-  }
-
-  public CachedContactInfo getContactInfo(CachedNumberLookupService lookupService, int position) {
-    ContactInfo info = new ContactInfo();
-    CachedContactInfo cacheInfo = lookupService.buildCachedContactInfo(info);
-    final Cursor item = (Cursor) getItem(position);
-    if (item != null) {
-      final DirectoryPartition partition =
-          (DirectoryPartition) getPartition(getPartitionForPosition(position));
-      final long directoryId = partition.getDirectoryId();
-      final boolean isExtendedDirectory = isExtendedDirectory(directoryId);
-
-      info.name = item.getString(PhoneQuery.DISPLAY_NAME);
-      info.type = item.getInt(PhoneQuery.PHONE_TYPE);
-      info.label = item.getString(PhoneQuery.PHONE_LABEL);
-      info.number = item.getString(PhoneQuery.PHONE_NUMBER);
-      final String photoUriStr = item.getString(PhoneQuery.PHOTO_URI);
-      info.photoUri = photoUriStr == null ? null : Uri.parse(photoUriStr);
-      /*
-       * An extended directory is custom directory in the app, but not a directory provided by
-       * framework. So it can't be USER_TYPE_WORK.
-       *
-       * When a search result is selected, RegularSearchFragment calls getContactInfo and
-       * cache the resulting @{link ContactInfo} into local db. Set usertype to USER_TYPE_WORK
-       * only if it's NOT extended directory id and is enterprise directory.
-       */
-      info.userType =
-          !isExtendedDirectory && DirectoryCompat.isEnterpriseDirectoryId(directoryId)
-              ? ContactsUtils.USER_TYPE_WORK
-              : ContactsUtils.USER_TYPE_CURRENT;
-
-      cacheInfo.setLookupKey(item.getString(PhoneQuery.LOOKUP_KEY));
-
-      final String sourceName = partition.getLabel();
-      if (isExtendedDirectory) {
-        cacheInfo.setExtendedSource(sourceName, directoryId);
-      } else {
-        cacheInfo.setDirectorySource(sourceName, directoryId);
-      }
-    }
-    return cacheInfo;
-  }
-
-  @Override
-  public String getFormattedQueryString() {
-    if (isQuerySipAddress) {
-      // Return unnormalized SIP address
-      return getQueryString();
-    }
-    return super.getFormattedQueryString();
-  }
-
-  @Override
-  public void setQueryString(String queryString) {
-    // Don't show actions if the query string contains a letter.
-    final boolean showNumberShortcuts =
-        !TextUtils.isEmpty(getFormattedQueryString()) && hasDigitsInQueryString();
-    isQuerySipAddress = PhoneNumberHelper.isUriNumber(queryString);
-
-    if (isChanged(showNumberShortcuts)) {
-      notifyDataSetChanged();
-    }
-    super.setQueryString(queryString);
-  }
-
-  protected boolean isChanged(boolean showNumberShortcuts) {
-    boolean changed = false;
-    changed |= setShortcutEnabled(SHORTCUT_DIRECT_CALL, showNumberShortcuts || isQuerySipAddress);
-    changed |= setShortcutEnabled(SHORTCUT_SEND_SMS_MESSAGE, showNumberShortcuts);
-    changed |=
-        setShortcutEnabled(
-            SHORTCUT_MAKE_VIDEO_CALL, showNumberShortcuts && CallUtil.isVideoEnabled(getContext()));
-    return changed;
-  }
-
-  /** Whether there is at least one digit in the query string. */
-  private boolean hasDigitsInQueryString() {
-    String queryString = getQueryString();
-    int length = queryString.length();
-    for (int i = 0; i < length; i++) {
-      if (Character.isDigit(queryString.charAt(i))) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/java/com/android/dialer/app/list/SearchFragment.java b/java/com/android/dialer/app/list/SearchFragment.java
deleted file mode 100644
index afb6789..0000000
--- a/java/com/android/dialer/app/list/SearchFragment.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.list;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
-import android.app.Activity;
-import android.app.DialogFragment;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.Interpolator;
-import android.widget.AbsListView;
-import android.widget.AbsListView.OnScrollListener;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.Space;
-import com.android.contacts.common.list.ContactEntryListAdapter;
-import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
-import com.android.contacts.common.list.PhoneNumberPickerFragment;
-import com.android.dialer.animation.AnimUtils;
-import com.android.dialer.app.R;
-import com.android.dialer.app.widget.DialpadSearchEmptyContentView;
-import com.android.dialer.callintent.CallSpecificAppData;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.dialpadview.DialpadFragment.ErrorDialogFragment;
-import com.android.dialer.logging.DialerImpression;
-import com.android.dialer.logging.Logger;
-import com.android.dialer.util.DialerUtils;
-import com.android.dialer.util.IntentUtil;
-import com.android.dialer.util.PermissionsUtil;
-import com.android.dialer.widget.EmptyContentView;
-
-public class SearchFragment extends PhoneNumberPickerFragment {
-
-  protected EmptyContentView emptyView;
-  private OnListFragmentScrolledListener activityScrollListener;
-  private View.OnTouchListener activityOnTouchListener;
-  /*
-   * Stores the untouched user-entered string that is used to populate the add to contacts
-   * intent.
-   */
-  private String addToContactNumber;
-  private int actionBarHeight;
-  private int shadowHeight;
-  private int paddingTop;
-  private int showDialpadDuration;
-  private int hideDialpadDuration;
-  /**
-   * Used to resize the list view containing search results so that it fits the available space
-   * above the dialpad. Does not have a user-visible effect in regular touch usage (since the
-   * dialpad hides that portion of the ListView anyway), but improves usability in accessibility
-   * mode.
-   */
-  private Space spacer;
-
-  private HostInterface activity;
-
-  @Override
-  public void onAttach(Activity activity) {
-    super.onAttach(activity);
-
-    setQuickContactEnabled(true);
-    setAdjustSelectionBoundsEnabled(false);
-    setDarkTheme(false);
-    setUseCallableUri(true);
-
-    try {
-      activityScrollListener = (OnListFragmentScrolledListener) activity;
-    } catch (ClassCastException e) {
-      LogUtil.v(
-          "SearchFragment.onAttach",
-          activity.toString()
-              + " doesn't implement OnListFragmentScrolledListener. "
-              + "Ignoring.");
-    }
-  }
-
-  @Override
-  public void onStart() {
-    LogUtil.d("SearchFragment.onStart", "");
-    super.onStart();
-
-    activity = (HostInterface) getActivity();
-
-    final Resources res = getResources();
-    actionBarHeight = activity.getActionBarHeight();
-    shadowHeight = res.getDrawable(R.drawable.search_shadow).getIntrinsicHeight();
-    paddingTop = res.getDimensionPixelSize(R.dimen.search_list_padding_top);
-    showDialpadDuration = res.getInteger(R.integer.dialpad_slide_in_duration);
-    hideDialpadDuration = res.getInteger(R.integer.dialpad_slide_out_duration);
-
-    final ListView listView = getListView();
-
-    if (emptyView == null) {
-      if (this instanceof SmartDialSearchFragment) {
-        emptyView = new DialpadSearchEmptyContentView(getActivity());
-      } else {
-        emptyView = new EmptyContentView(getActivity());
-      }
-      ((ViewGroup) getListView().getParent()).addView(emptyView);
-      getListView().setEmptyView(emptyView);
-      setupEmptyView();
-    }
-
-    listView.setBackgroundColor(res.getColor(R.color.background_dialer_results));
-    listView.setClipToPadding(false);
-    setVisibleScrollbarEnabled(false);
-
-    //Turn of accessibility live region as the list constantly update itself and spam messages.
-    listView.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_NONE);
-    ContentChangedFilter.addToParent(listView);
-
-    listView.setOnScrollListener(
-        new OnScrollListener() {
-          @Override
-          public void onScrollStateChanged(AbsListView view, int scrollState) {
-            if (activityScrollListener != null) {
-              activityScrollListener.onListFragmentScrollStateChange(scrollState);
-            }
-          }
-
-          @Override
-          public void onScroll(
-              AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}
-        });
-    if (activityOnTouchListener != null) {
-      listView.setOnTouchListener(activityOnTouchListener);
-    }
-
-    updatePosition(false /* animate */);
-  }
-
-  @Override
-  public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
-    Animator animator = null;
-    if (nextAnim != 0) {
-      animator = AnimatorInflater.loadAnimator(getActivity(), nextAnim);
-    }
-    if (animator != null) {
-      final View view = getView();
-      final int oldLayerType = view.getLayerType();
-      animator.addListener(
-          new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-              view.setLayerType(oldLayerType, null);
-            }
-          });
-    }
-    return animator;
-  }
-
-  public void setAddToContactNumber(String addToContactNumber) {
-    this.addToContactNumber = addToContactNumber;
-  }
-
-  /**
-   * Return true if phone number is prohibited by a value -
-   * (R.string.config_prohibited_phone_number_regexp) in the config files. False otherwise.
-   */
-  public boolean checkForProhibitedPhoneNumber(String number) {
-    // Regular expression prohibiting manual phone call. Can be empty i.e. "no rule".
-    String prohibitedPhoneNumberRegexp =
-        getResources().getString(R.string.config_prohibited_phone_number_regexp);
-
-    // "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated
-    // test equipment.
-    if (number != null
-        && !TextUtils.isEmpty(prohibitedPhoneNumberRegexp)
-        && number.matches(prohibitedPhoneNumberRegexp)) {
-      LogUtil.i(
-          "SearchFragment.checkForProhibitedPhoneNumber",
-          "the phone number is prohibited explicitly by a rule");
-      if (getActivity() != null) {
-        DialogFragment dialogFragment =
-            ErrorDialogFragment.newInstance(R.string.dialog_phone_call_prohibited_message);
-        dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
-      }
-
-      return true;
-    }
-    return false;
-  }
-
-  @Override
-  protected ContactEntryListAdapter createListAdapter() {
-    DialerPhoneNumberListAdapter adapter = new DialerPhoneNumberListAdapter(getActivity());
-    adapter.setDisplayPhotos(true);
-    adapter.setUseCallableUri(super.usesCallableUri());
-    adapter.setListener(this);
-    return adapter;
-  }
-
-  @Override
-  protected void onItemClick(int position, long id) {
-    final DialerPhoneNumberListAdapter adapter = (DialerPhoneNumberListAdapter) getAdapter();
-    final int shortcutType = adapter.getShortcutTypeFromPosition(position);
-    final OnPhoneNumberPickerActionListener listener;
-    final Intent intent;
-    final String number;
-
-    LogUtil.i("SearchFragment.onItemClick", "shortcutType: " + shortcutType);
-
-    switch (shortcutType) {
-      case DialerPhoneNumberListAdapter.SHORTCUT_DIRECT_CALL:
-        number = adapter.getQueryString();
-        listener = getOnPhoneNumberPickerListener();
-        if (listener != null && !checkForProhibitedPhoneNumber(number)) {
-          CallSpecificAppData callSpecificAppData =
-              CallSpecificAppData.newBuilder()
-                  .setCallInitiationType(getCallInitiationType(false /* isRemoteDirectory */))
-                  .setPositionOfSelectedSearchResult(position)
-                  .setCharactersInSearchString(
-                      getQueryString() == null ? 0 : getQueryString().length())
-                  .build();
-          listener.onPickPhoneNumber(number, false /* isVideoCall */, callSpecificAppData);
-        }
-        break;
-      case DialerPhoneNumberListAdapter.SHORTCUT_CREATE_NEW_CONTACT:
-        if (this instanceof SmartDialSearchFragment) {
-          Logger.get(getContext())
-              .logImpression(DialerImpression.Type.CREATE_NEW_CONTACT_FROM_DIALPAD);
-        }
-        number =
-            TextUtils.isEmpty(addToContactNumber)
-                ? adapter.getFormattedQueryString()
-                : addToContactNumber;
-        intent = IntentUtil.getNewContactIntent(number);
-        DialerUtils.startActivityWithErrorToast(getActivity(), intent);
-        break;
-      case DialerPhoneNumberListAdapter.SHORTCUT_ADD_TO_EXISTING_CONTACT:
-        if (this instanceof SmartDialSearchFragment) {
-          Logger.get(getContext())
-              .logImpression(DialerImpression.Type.ADD_TO_A_CONTACT_FROM_DIALPAD);
-        }
-        number =
-            TextUtils.isEmpty(addToContactNumber)
-                ? adapter.getFormattedQueryString()
-                : addToContactNumber;
-        intent = IntentUtil.getAddToExistingContactIntent(number);
-        DialerUtils.startActivityWithErrorToast(
-            getActivity(), intent, R.string.add_contact_not_available);
-        break;
-      case DialerPhoneNumberListAdapter.SHORTCUT_SEND_SMS_MESSAGE:
-        number =
-            TextUtils.isEmpty(addToContactNumber)
-                ? adapter.getFormattedQueryString()
-                : addToContactNumber;
-        intent = IntentUtil.getSendSmsIntent(number);
-        DialerUtils.startActivityWithErrorToast(getActivity(), intent);
-        break;
-      case DialerPhoneNumberListAdapter.SHORTCUT_MAKE_VIDEO_CALL:
-        number =
-            TextUtils.isEmpty(addToContactNumber) ? adapter.getQueryString() : addToContactNumber;
-        listener = getOnPhoneNumberPickerListener();
-        if (listener != null && !checkForProhibitedPhoneNumber(number)) {
-          CallSpecificAppData callSpecificAppData =
-              CallSpecificAppData.newBuilder()
-                  .setCallInitiationType(getCallInitiationType(false /* isRemoteDirectory */))
-                  .setPositionOfSelectedSearchResult(position)
-                  .setCharactersInSearchString(
-                      getQueryString() == null ? 0 : getQueryString().length())
-                  .build();
-          listener.onPickPhoneNumber(number, true /* isVideoCall */, callSpecificAppData);
-        }
-        break;
-      case DialerPhoneNumberListAdapter.SHORTCUT_INVALID:
-      default:
-        super.onItemClick(position, id);
-        break;
-    }
-  }
-
-  /**
-   * Updates the position and padding of the search fragment, depending on whether the dialpad is
-   * shown. This can be optionally animated.
-   */
-  public void updatePosition(boolean animate) {
-    LogUtil.d("SearchFragment.updatePosition", "animate: %b", animate);
-    if (activity == null) {
-      // Activity will be set in onStart, and this method will be called again
-      return;
-    }
-
-    // Use negative shadow height instead of 0 to account for the 9-patch's shadow.
-    int startTranslationValue =
-        activity.isDialpadShown() ? actionBarHeight - shadowHeight : -shadowHeight;
-    int endTranslationValue = 0;
-    // Prevents ListView from being translated down after a rotation when the ActionBar is up.
-    if (animate || activity.isActionBarShowing()) {
-      endTranslationValue = activity.isDialpadShown() ? 0 : actionBarHeight - shadowHeight;
-    }
-    if (animate) {
-      // If the dialpad will be shown, then this animation involves sliding the list up.
-      final boolean slideUp = activity.isDialpadShown();
-
-      Interpolator interpolator = slideUp ? AnimUtils.EASE_IN : AnimUtils.EASE_OUT;
-      int duration = slideUp ? showDialpadDuration : hideDialpadDuration;
-      getView().setTranslationY(startTranslationValue);
-      getView()
-          .animate()
-          .translationY(endTranslationValue)
-          .setInterpolator(interpolator)
-          .setDuration(duration)
-          .setListener(
-              new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                  if (!slideUp) {
-                    resizeListView();
-                  }
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                  if (slideUp) {
-                    resizeListView();
-                  }
-                }
-              });
-
-    } else {
-      getView().setTranslationY(endTranslationValue);
-      resizeListView();
-    }
-
-    // There is padding which should only be applied when the dialpad is not shown.
-    int paddingTop = activity.isDialpadShown() ? 0 : this.paddingTop;
-    final ListView listView = getListView();
-    listView.setPaddingRelative(
-        listView.getPaddingStart(),
-        paddingTop,
-        listView.getPaddingEnd(),
-        listView.getPaddingBottom());
-  }
-
-  public void resizeListView() {
-    if (spacer == null) {
-      return;
-    }
-    int spacerHeight = activity.isDialpadShown() ? activity.getDialpadHeight() : 0;
-    LogUtil.d(
-        "SearchFragment.resizeListView",
-        "spacerHeight: %d -> %d, isDialpadShown: %b, dialpad height: %d",
-        spacer.getHeight(),
-        spacerHeight,
-        activity.isDialpadShown(),
-        activity.getDialpadHeight());
-    if (spacerHeight != spacer.getHeight()) {
-      final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) spacer.getLayoutParams();
-      lp.height = spacerHeight;
-      spacer.setLayoutParams(lp);
-    }
-  }
-
-  @Override
-  protected void startLoading() {
-    if (getActivity() == null) {
-      return;
-    }
-
-    if (PermissionsUtil.hasContactsReadPermissions(getActivity())) {
-      super.startLoading();
-    } else if (TextUtils.isEmpty(getQueryString())) {
-      // Clear out any existing call shortcuts.
-      final DialerPhoneNumberListAdapter adapter = (DialerPhoneNumberListAdapter) getAdapter();
-      adapter.disableAllShortcuts();
-    } else {
-      // The contact list is not going to change (we have no results since permissions are
-      // denied), but the shortcuts might because of the different query, so update the
-      // list.
-      getAdapter().notifyDataSetChanged();
-    }
-
-    setupEmptyView();
-  }
-
-  public void setOnTouchListener(View.OnTouchListener onTouchListener) {
-    activityOnTouchListener = onTouchListener;
-  }
-
-  @Override
-  protected View inflateView(LayoutInflater inflater, ViewGroup container) {
-    final LinearLayout parent = (LinearLayout) super.inflateView(inflater, container);
-    final int orientation = getResources().getConfiguration().orientation;
-    if (orientation == Configuration.ORIENTATION_PORTRAIT) {
-      spacer = new Space(getActivity());
-      parent.addView(
-          spacer, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0));
-    }
-    return parent;
-  }
-
-  protected void setupEmptyView() {}
-
-  public interface HostInterface {
-
-    boolean isActionBarShowing();
-
-    boolean isDialpadShown();
-
-    int getDialpadHeight();
-
-    int getActionBarHeight();
-  }
-}
diff --git a/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java b/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java
deleted file mode 100644
index c84bff7..0000000
--- a/java/com/android/dialer/app/list/SmartDialNumberListAdapter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.list;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.support.annotation.NonNull;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.smartdial.SmartDialCursorLoader;
-import com.android.dialer.smartdial.util.SmartDialMatchPosition;
-import com.android.dialer.smartdial.util.SmartDialNameMatcher;
-import com.android.dialer.util.CallUtil;
-import java.util.ArrayList;
-
-/** List adapter to display the SmartDial search results. */
-public class SmartDialNumberListAdapter extends DialerPhoneNumberListAdapter {
-
-  private static final String TAG = SmartDialNumberListAdapter.class.getSimpleName();
-  private static final boolean DEBUG = false;
-
-  private final Context context;
-  @NonNull private final SmartDialNameMatcher nameMatcher;
-
-  public SmartDialNumberListAdapter(Context context) {
-    super(context);
-    this.context = context;
-    nameMatcher = new SmartDialNameMatcher("");
-    setShortcutEnabled(SmartDialNumberListAdapter.SHORTCUT_DIRECT_CALL, false);
-
-    if (DEBUG) {
-      LogUtil.v(TAG, "Constructing List Adapter");
-    }
-  }
-
-  /** Sets query for the SmartDialCursorLoader. */
-  public void configureLoader(SmartDialCursorLoader loader) {
-    if (DEBUG) {
-      LogUtil.v(TAG, "Configure Loader with query" + getQueryString());
-    }
-
-    if (getQueryString() == null) {
-      loader.configureQuery("");
-      nameMatcher.setQuery("");
-    } else {
-      loader.configureQuery(getQueryString());
-      nameMatcher.setQuery(PhoneNumberUtils.normalizeNumber(getQueryString()));
-    }
-  }
-
-  /**
-   * Sets highlight options for a List item in the SmartDial search results.
-   *
-   * @param view ContactListItemView where the result will be displayed.
-   * @param cursor Object containing information of the associated List item.
-   */
-  @Override
-  protected void setHighlight(ContactListItemView view, Cursor cursor) {
-    view.clearHighlightSequences();
-
-    if (nameMatcher.matches(context, cursor.getString(PhoneQuery.DISPLAY_NAME))) {
-      final ArrayList<SmartDialMatchPosition> nameMatches = nameMatcher.getMatchPositions();
-      for (SmartDialMatchPosition match : nameMatches) {
-        view.addNameHighlightSequence(match.start, match.end);
-        if (DEBUG) {
-          LogUtil.v(
-              TAG,
-              cursor.getString(PhoneQuery.DISPLAY_NAME)
-                  + " "
-                  + nameMatcher.getQuery()
-                  + " "
-                  + String.valueOf(match.start));
-        }
-      }
-    }
-
-    final SmartDialMatchPosition numberMatch =
-        nameMatcher.matchesNumber(context, cursor.getString(PhoneQuery.PHONE_NUMBER));
-    if (numberMatch != null) {
-      view.addNumberHighlightSequence(numberMatch.start, numberMatch.end);
-    }
-  }
-
-  @Override
-  public void setQueryString(String queryString) {
-    final boolean showNumberShortcuts = !TextUtils.isEmpty(getFormattedQueryString());
-    boolean changed = false;
-    changed |= setShortcutEnabled(SHORTCUT_CREATE_NEW_CONTACT, showNumberShortcuts);
-    changed |= setShortcutEnabled(SHORTCUT_ADD_TO_EXISTING_CONTACT, showNumberShortcuts);
-    changed |= setShortcutEnabled(SHORTCUT_SEND_SMS_MESSAGE, showNumberShortcuts);
-    changed |=
-        setShortcutEnabled(
-            SHORTCUT_MAKE_VIDEO_CALL, showNumberShortcuts && CallUtil.isVideoEnabled(getContext()));
-    if (changed) {
-      notifyDataSetChanged();
-    }
-    super.setQueryString(queryString);
-  }
-
-  public void setShowEmptyListForNullQuery(boolean show) {
-    nameMatcher.setShouldMatchEmptyQuery(!show);
-  }
-}
diff --git a/java/com/android/dialer/app/list/SmartDialSearchFragment.java b/java/com/android/dialer/app/list/SmartDialSearchFragment.java
deleted file mode 100644
index fdf0b5a..0000000
--- a/java/com/android/dialer/app/list/SmartDialSearchFragment.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.list;
-
-import static android.Manifest.permission.CALL_PHONE;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.Loader;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.support.v13.app.FragmentCompat;
-import com.android.contacts.common.list.ContactEntryListAdapter;
-import com.android.dialer.app.R;
-import com.android.dialer.callintent.CallInitiationType;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.database.DialerDatabaseHelper;
-import com.android.dialer.smartdial.SmartDialCursorLoader;
-import com.android.dialer.util.PermissionsUtil;
-import com.android.dialer.widget.EmptyContentView;
-import java.util.Arrays;
-
-/** Implements a fragment to load and display SmartDial search results. */
-public class SmartDialSearchFragment extends SearchFragment
-    implements EmptyContentView.OnEmptyViewActionButtonClickedListener,
-        FragmentCompat.OnRequestPermissionsResultCallback {
-
-  private static final int CALL_PHONE_PERMISSION_REQUEST_CODE = 1;
-
-  private final BroadcastReceiver smartDialUpdatedReceiver =
-      new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-          LogUtil.i("SmartDialSearchFragment.onReceive", "smart dial update broadcast received");
-          reloadData();
-        }
-      };
-
-  /** Creates a SmartDialListAdapter to display and operate on search results. */
-  @Override
-  protected ContactEntryListAdapter createListAdapter() {
-    SmartDialNumberListAdapter adapter = new SmartDialNumberListAdapter(getActivity());
-    adapter.setUseCallableUri(super.usesCallableUri());
-    adapter.setQuickContactEnabled(true);
-    adapter.setShowEmptyListForNullQuery(getShowEmptyListForNullQuery());
-    // Set adapter's query string to restore previous instance state.
-    adapter.setQueryString(getQueryString());
-    adapter.setListener(this);
-    return adapter;
-  }
-
-  /** Creates a SmartDialCursorLoader object to load query results. */
-  @Override
-  public Loader<Cursor> onCreateLoader(int id, Bundle args) {
-    // Smart dialing does not support Directory Load, falls back to normal search instead.
-    if (id == getDirectoryLoaderId()) {
-      return super.onCreateLoader(id, args);
-    } else {
-      final SmartDialNumberListAdapter adapter = (SmartDialNumberListAdapter) getAdapter();
-      SmartDialCursorLoader loader = new SmartDialCursorLoader(super.getContext());
-      loader.setShowEmptyListForNullQuery(getShowEmptyListForNullQuery());
-      adapter.configureLoader(loader);
-      return loader;
-    }
-  }
-
-  @Override
-  public boolean getShowEmptyListForNullQuery() {
-    return true;
-  }
-
-  @Override
-  protected void setupEmptyView() {
-    if (emptyView != null && getActivity() != null) {
-      if (!PermissionsUtil.hasPermission(getActivity(), CALL_PHONE)) {
-        emptyView.setImage(R.drawable.empty_contacts);
-        emptyView.setActionLabel(R.string.permission_single_turn_on);
-        emptyView.setDescription(R.string.permission_place_call);
-        emptyView.setActionClickedListener(this);
-      } else {
-        emptyView.setImage(EmptyContentView.NO_IMAGE);
-        emptyView.setActionLabel(EmptyContentView.NO_LABEL);
-        emptyView.setDescription(EmptyContentView.NO_LABEL);
-      }
-    }
-  }
-
-  @Override
-  public void onStart() {
-    super.onStart();
-
-    LogUtil.i("SmartDialSearchFragment.onStart", "registering smart dial update receiver");
-
-    getActivity()
-        .registerReceiver(
-            smartDialUpdatedReceiver,
-            new IntentFilter(DialerDatabaseHelper.ACTION_SMART_DIAL_UPDATED));
-  }
-
-  @Override
-  public void onStop() {
-    super.onStop();
-
-    LogUtil.i("SmartDialSearchFragment.onStop", "unregistering smart dial update receiver");
-
-    getActivity().unregisterReceiver(smartDialUpdatedReceiver);
-  }
-
-  @Override
-  public void onEmptyViewActionButtonClicked() {
-    final Activity activity = getActivity();
-    if (activity == null) {
-      return;
-    }
-
-    String[] deniedPermissions =
-        PermissionsUtil.getPermissionsCurrentlyDenied(
-            getContext(), PermissionsUtil.allPhoneGroupPermissionsUsedInDialer);
-    if (deniedPermissions.length > 0) {
-      LogUtil.i(
-          "SmartDialSearchFragment.onEmptyViewActionButtonClicked",
-          "Requesting permissions: " + Arrays.toString(deniedPermissions));
-      FragmentCompat.requestPermissions(
-          this, deniedPermissions, CALL_PHONE_PERMISSION_REQUEST_CODE);
-    }
-  }
-
-  @Override
-  public void onRequestPermissionsResult(
-      int requestCode, String[] permissions, int[] grantResults) {
-    if (requestCode == CALL_PHONE_PERMISSION_REQUEST_CODE) {
-      setupEmptyView();
-    }
-  }
-
-  @Override
-  protected CallInitiationType.Type getCallInitiationType(boolean isRemoteDirectory) {
-    return CallInitiationType.Type.SMART_DIAL;
-  }
-
-  public boolean isShowingPermissionRequest() {
-    return emptyView != null && emptyView.isShowingContent();
-  }
-
-  @Override
-  public void setShowEmptyListForNullQuery(boolean show) {
-    if (getAdapter() != null) {
-      ((SmartDialNumberListAdapter) getAdapter()).setShowEmptyListForNullQuery(show);
-    }
-    super.setShowEmptyListForNullQuery(show);
-  }
-}
diff --git a/java/com/android/dialer/app/res/layout/all_contacts_fragment.xml b/java/com/android/dialer/app/res/layout/all_contacts_fragment.xml
deleted file mode 100644
index 422c529..0000000
--- a/java/com/android/dialer/app/res/layout/all_contacts_fragment.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<LinearLayout
-  xmlns:android="http://schemas.android.com/apk/res/android"
-  android:id="@+id/pinned_header_list_layout"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent"
-  android:orientation="vertical">
-
-  <!-- Shown only when an Account filter is set.
-       - paddingTop should be here to show "shade" effect correctly. -->
-  <!-- TODO: Remove the filter header. -->
-  <include layout="@layout/account_filter_header"/>
-
-  <FrameLayout
-    android:layout_width="match_parent"
-    android:layout_height="0dip"
-    android:layout_weight="1">
-    <view
-      android:id="@android:id/list"
-      style="@style/DialtactsTheme"
-      class="com.android.contacts.common.list.PinnedHeaderListView"
-      android:layout_width="match_parent"
-      android:layout_height="match_parent"
-      android:layout_marginStart="?attr/contact_browser_list_padding_left"
-      android:layout_marginEnd="?attr/contact_browser_list_padding_right"
-      android:paddingTop="18dp"
-      android:fadingEdge="none"
-      android:fastScrollEnabled="true"
-      android:nestedScrollingEnabled="true"
-      android:cropToPadding="false"
-      android:clipToPadding="false"/>
-
-    <com.android.dialer.widget.EmptyContentView
-      android:id="@+id/empty_list_view"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_gravity="center"
-      android:visibility="gone"/>
-
-  </FrameLayout>
-</LinearLayout>
diff --git a/java/com/android/dialer/app/res/layout/blocked_number_header.xml b/java/com/android/dialer/app/res/layout/blocked_number_header.xml
index e34510b..e1019d1 100644
--- a/java/com/android/dialer/app/res/layout/blocked_number_header.xml
+++ b/java/com/android/dialer/app/res/layout/blocked_number_header.xml
@@ -166,46 +166,6 @@
 
       </LinearLayout>
 
-      <LinearLayout
-        android:id="@+id/add_number_linear_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingTop="@dimen/blocked_number_add_top_margin"
-        android:paddingBottom="@dimen/blocked_number_add_bottom_margin"
-        android:paddingStart="@dimen/blocked_number_horizontal_margin"
-        android:background="?android:attr/selectableItemBackground"
-        android:baselineAligned="false"
-        android:clickable="true"
-        android:contentDescription="@string/addBlockedNumber"
-        android:focusable="true"
-        android:gravity="center_vertical"
-        android:orientation="horizontal">
-
-        <ImageView
-          android:id="@+id/add_number_icon"
-          android:layout_width="@dimen/contact_photo_size"
-          android:layout_height="@dimen/contact_photo_size"
-          android:importantForAccessibility="no"/>
-        <LinearLayout
-          android:layout_width="0dp"
-          android:layout_height="wrap_content"
-          android:layout_weight="1"
-          android:layout_marginStart="@dimen/blocked_number_horizontal_margin"
-          android:gravity="center_vertical"
-          android:orientation="vertical">
-
-          <TextView
-            android:id="@+id/add_number_textview"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:includeFontPadding="false"
-            android:text="@string/addBlockedNumber"
-            android:textColor="@color/blocked_number_primary_text_color"
-            android:textSize="@dimen/blocked_number_primary_text_size"/>
-        </LinearLayout>
-
-      </LinearLayout>
-
       <View
         android:id="@+id/blocked_number_list_divider"
         android:layout_width="match_parent"
diff --git a/java/com/android/dialer/p13n/inference/P13nRanking.java b/java/com/android/dialer/p13n/inference/P13nRanking.java
deleted file mode 100644
index 79b4d71..0000000
--- a/java/com/android/dialer/p13n/inference/P13nRanking.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.p13n.inference;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.support.annotation.MainThread;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import com.android.dialer.common.Assert;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.p13n.inference.protocol.P13nRanker;
-import com.android.dialer.p13n.inference.protocol.P13nRankerFactory;
-import java.util.List;
-
-/** Single entry point for all personalized ranking. */
-public final class P13nRanking {
-
-  private static P13nRanker ranker;
-
-  private P13nRanking() {}
-
-  @MainThread
-  @NonNull
-  public static P13nRanker get(@NonNull Context context) {
-    Assert.isNotNull(context);
-    Assert.isMainThread();
-
-    if (ranker != null) {
-      return ranker;
-    }
-
-    if (!ConfigProviderBindings.get(context).getBoolean("p13n_ranker_should_enable", false)) {
-      setToIdentityRanker();
-      return ranker;
-    }
-
-    Context application = context.getApplicationContext();
-    if (application instanceof P13nRankerFactory) {
-      ranker = ((P13nRankerFactory) application).newP13nRanker();
-    }
-
-    if (ranker == null) {
-      setToIdentityRanker();
-    }
-    return ranker;
-  }
-
-  private static void setToIdentityRanker() {
-    ranker =
-        new P13nRanker() {
-          @Override
-          public void refresh(@Nullable P13nRefreshCompleteListener listener) {}
-
-          @Override
-          public List<String> rankList(List<String> phoneNumbers) {
-            return phoneNumbers;
-          }
-
-          @NonNull
-          @Override
-          public Cursor rankCursor(@NonNull Cursor phoneQueryResults, int queryLength) {
-            return phoneQueryResults;
-          }
-
-          @Override
-          public boolean shouldShowEmptyListForNullQuery() {
-            return true;
-          }
-        };
-  }
-
-  public static void setForTesting(@NonNull P13nRanker ranker) {
-    P13nRanking.ranker = ranker;
-  }
-}
diff --git a/java/com/android/dialer/p13n/inference/protocol/P13nRanker.java b/java/com/android/dialer/p13n/inference/protocol/P13nRanker.java
deleted file mode 100644
index 41f1de4..0000000
--- a/java/com/android/dialer/p13n/inference/protocol/P13nRanker.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.p13n.inference.protocol;
-
-import android.database.Cursor;
-import android.support.annotation.MainThread;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import java.util.List;
-
-/** Provides personalized ranking of outgoing call targets. */
-public interface P13nRanker {
-
-  /**
-   * Re-orders a list of phone numbers according to likelihood they will be the next outgoing call.
-   *
-   * @param phoneNumbers the list of candidate numbers to call (may be in contacts list or not)
-   */
-  @NonNull
-  @MainThread
-  List<String> rankList(@NonNull List<String> phoneNumbers);
-
-  /**
-   * Re-orders a retrieved contact list according to likelihood they will be the next outgoing call.
-   *
-   * <p>A new cursor with reordered data is returned; the input cursor is unmodified except for its
-   * position. If the order is unchanged, this method may return a reference to the unmodified input
-   * cursor directly. The order would be unchanged if the ranking cache is not yet ready, or if the
-   * input cursor is closed or invalid, or if any other error occurs in the ranking process.
-   *
-   * @param phoneQueryResults cursor of results of a Dialer search query
-   * @param queryLength length of the search query that resulted in the cursor data, if below 0,
-   *     assumes no length is specified, thus applies the default behavior which is same as when
-   *     queryLength is greater than zero.
-   * @return new cursor of data reordered by ranking (or reference to input cursor if order
-   *     unchanged)
-   */
-  @NonNull
-  @MainThread
-  Cursor rankCursor(@NonNull Cursor phoneQueryResults, int queryLength);
-
-  /**
-   * Refreshes ranking cache (pulls fresh contextual features, pre-caches inference results, etc.).
-   *
-   * <p>Asynchronously runs in background as the process might take a few seconds, notifying a
-   * listener upon completion; meanwhile, any calls to {@link #rankList} will simply return the
-   * input in same order.
-   *
-   * @param listener callback for when ranking refresh has completed; null value skips notification.
-   */
-  @MainThread
-  void refresh(@Nullable P13nRefreshCompleteListener listener);
-
-  /** Decides if results should be displayed for no-query search. */
-  @MainThread
-  boolean shouldShowEmptyListForNullQuery();
-
-  /**
-   * Callback class for when ranking refresh has completed.
-   *
-   * <p>Primary use is to notify {@link com.android.dialer.app.DialtactsActivity} that the ranking
-   * functions {@link #rankList} and {@link #rankCursor(Cursor, int)} will now give useful results.
-   */
-  interface P13nRefreshCompleteListener {
-
-    /** Callback for when ranking refresh has completed. */
-    void onP13nRefreshComplete();
-  }
-}
diff --git a/java/com/android/dialer/p13n/inference/protocol/P13nRankerFactory.java b/java/com/android/dialer/p13n/inference/protocol/P13nRankerFactory.java
deleted file mode 100644
index 7038cf4..0000000
--- a/java/com/android/dialer/p13n/inference/protocol/P13nRankerFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.p13n.inference.protocol;
-
-import android.support.annotation.Nullable;
-
-/**
- * This interface should be implemented by the Application subclass. It allows this module to get
- * references to the {@link P13nRanker}.
- */
-public interface P13nRankerFactory {
-  @Nullable
-  P13nRanker newP13nRanker();
-}
diff --git a/java/com/android/dialer/p13n/logging/P13nLogger.java b/java/com/android/dialer/p13n/logging/P13nLogger.java
deleted file mode 100644
index 069a293..0000000
--- a/java/com/android/dialer/p13n/logging/P13nLogger.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.p13n.logging;
-
-import com.android.contacts.common.list.PhoneNumberListAdapter;
-
-/** Allows logging of data for personalization. */
-public interface P13nLogger {
-
-  /**
-   * Logs a search query (text or digits) entered by user.
-   *
-   * @param query search text (or digits) entered by user
-   * @param adapter list adapter providing access to contacts matching search query
-   */
-  void onSearchQuery(String query, PhoneNumberListAdapter adapter);
-
-  /**
-   * Resets logging session (clears searches, re-initializes app entry timestamp, etc.) Should be
-   * called when Dialer app is resumed.
-   */
-  void reset();
-}
diff --git a/java/com/android/dialer/p13n/logging/P13nLoggerFactory.java b/java/com/android/dialer/p13n/logging/P13nLoggerFactory.java
deleted file mode 100644
index 7350e99..0000000
--- a/java/com/android/dialer/p13n/logging/P13nLoggerFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.p13n.logging;
-
-import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-/**
- * This interface should be implemented by the Application subclass. It allows this module to get
- * references to the P13nLogger.
- */
-public interface P13nLoggerFactory {
-
-  @Nullable
-  P13nLogger newP13nLogger(@NonNull Context context);
-}
diff --git a/java/com/android/dialer/p13n/logging/P13nLogging.java b/java/com/android/dialer/p13n/logging/P13nLogging.java
deleted file mode 100644
index 21b9725..0000000
--- a/java/com/android/dialer/p13n/logging/P13nLogging.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.p13n.logging;
-
-import android.content.Context;
-import android.support.annotation.NonNull;
-import com.android.contacts.common.list.PhoneNumberListAdapter;
-import com.android.dialer.common.Assert;
-
-/** Single entry point for all logging for personalization. */
-public final class P13nLogging {
-
-  private static P13nLogger logger;
-
-  private P13nLogging() {}
-
-  @NonNull
-  public static P13nLogger get(@NonNull Context context) {
-    Assert.isNotNull(context);
-    Assert.isMainThread();
-    if (logger != null) {
-      return logger;
-    }
-
-    Context application = context.getApplicationContext();
-    if (application instanceof P13nLoggerFactory) {
-      logger = ((P13nLoggerFactory) application).newP13nLogger(context);
-    }
-
-    if (logger == null) {
-      logger =
-          new P13nLogger() {
-            @Override
-            public void onSearchQuery(String query, PhoneNumberListAdapter adapter) {}
-
-            @Override
-            public void reset() {}
-          };
-    }
-    return logger;
-  }
-
-  public static void setForTesting(@NonNull P13nLogger logger) {
-    P13nLogging.logger = logger;
-  }
-}
diff --git a/java/com/android/dialer/smartdial/SmartDialCursorLoader.java b/java/com/android/dialer/smartdial/SmartDialCursorLoader.java
index f2e41b2..205362c 100644
--- a/java/com/android/dialer/smartdial/SmartDialCursorLoader.java
+++ b/java/com/android/dialer/smartdial/SmartDialCursorLoader.java
@@ -20,7 +20,7 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.database.MatrixCursor;
-import com.android.contacts.common.list.PhoneNumberListAdapter.PhoneQuery;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.database.Database;
 import com.android.dialer.database.DialerDatabaseHelper;
@@ -28,6 +28,8 @@
 import com.android.dialer.smartdial.util.SmartDialNameMatcher;
 import com.android.dialer.util.PermissionsUtil;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /** Implements a Loader<Cursor> class to asynchronously load SmartDial search results. */
 public class SmartDialCursorLoader extends AsyncTaskLoader<Cursor> {
@@ -179,4 +181,60 @@
       nameMatcher.setShouldMatchEmptyQuery(!show);
     }
   }
+
+  /** Moved from contacts/common, contains all of the projections needed for Smart Dial queries. */
+  public static class PhoneQuery {
+
+    public static final String[] PROJECTION_PRIMARY_INTERNAL =
+        new String[] {
+          Phone._ID, // 0
+          Phone.TYPE, // 1
+          Phone.LABEL, // 2
+          Phone.NUMBER, // 3
+          Phone.CONTACT_ID, // 4
+          Phone.LOOKUP_KEY, // 5
+          Phone.PHOTO_ID, // 6
+          Phone.DISPLAY_NAME_PRIMARY, // 7
+          Phone.PHOTO_THUMBNAIL_URI, // 8
+        };
+
+    public static final String[] PROJECTION_PRIMARY;
+    public static final String[] PROJECTION_ALTERNATIVE_INTERNAL =
+        new String[] {
+          Phone._ID, // 0
+          Phone.TYPE, // 1
+          Phone.LABEL, // 2
+          Phone.NUMBER, // 3
+          Phone.CONTACT_ID, // 4
+          Phone.LOOKUP_KEY, // 5
+          Phone.PHOTO_ID, // 6
+          Phone.DISPLAY_NAME_ALTERNATIVE, // 7
+          Phone.PHOTO_THUMBNAIL_URI, // 8
+        };
+    public static final String[] PROJECTION_ALTERNATIVE;
+    public static final int PHONE_ID = 0;
+    public static final int PHONE_TYPE = 1;
+    public static final int PHONE_LABEL = 2;
+    public static final int PHONE_NUMBER = 3;
+    public static final int CONTACT_ID = 4;
+    public static final int LOOKUP_KEY = 5;
+    public static final int PHOTO_ID = 6;
+    public static final int DISPLAY_NAME = 7;
+    public static final int PHOTO_URI = 8;
+    public static final int CARRIER_PRESENCE = 9;
+
+    static {
+      final List<String> projectionList =
+          new ArrayList<>(Arrays.asList(PROJECTION_PRIMARY_INTERNAL));
+      projectionList.add(Phone.CARRIER_PRESENCE); // 9
+      PROJECTION_PRIMARY = projectionList.toArray(new String[projectionList.size()]);
+    }
+
+    static {
+      final List<String> projectionList =
+          new ArrayList<>(Arrays.asList(PROJECTION_ALTERNATIVE_INTERNAL));
+      projectionList.add(Phone.CARRIER_PRESENCE); // 9
+      PROJECTION_ALTERNATIVE = projectionList.toArray(new String[projectionList.size()]);
+    }
+  }
 }
