diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d23e74a..459af59 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -378,18 +378,6 @@
             </intent-filter>
         </activity>
 
-        <!--
-            Internal photo selection activity.  This activity handles all configuration changes by
-            itself.
-        -->
-        <activity android:name=".activities.PhotoSelectionActivity"
-            android:theme="@style/Theme.PhotoSelector"
-            android:launchMode="singleTop"
-            android:windowSoftInputMode="stateUnchanged"
-            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
-            >
-        </activity>
-
         <!-- vCard related -->
         <activity android:name=".common.vcard.ImportVCardActivity"
             android:label="@string/launcherActivityLabel"
diff --git a/res/layout/photoselection_activity.xml b/res/layout/photoselection_activity.xml
deleted file mode 100644
index e7ef901..0000000
--- a/res/layout/photoselection_activity.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <View
-        android:id="@+id/backdrop"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="#000000" />
-    <view
-        android:id="@+id/photo"
-        class="com.android.contacts.detail.TransformableImageView"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:scaleType="centerCrop" />
-</FrameLayout>
\ No newline at end of file
diff --git a/src/com/android/contacts/activities/PhotoSelectionActivity.java b/src/com/android/contacts/activities/PhotoSelectionActivity.java
deleted file mode 100644
index c81c448..0000000
--- a/src/com/android/contacts/activities/PhotoSelectionActivity.java
+++ /dev/null
@@ -1,571 +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.activities;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.view.View;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.widget.FrameLayout.LayoutParams;
-import android.widget.ImageView;
-
-import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-import com.android.contacts.detail.PhotoSelectionHandler;
-import com.android.contacts.editor.PhotoActionPopup;
-import com.android.contacts.common.model.RawContactDeltaList;
-import com.android.contacts.util.SchedulingUtils;
-
-/**
- * Popup activity for choosing a contact photo within the Contacts app.
- */
-public class PhotoSelectionActivity extends Activity {
-
-    private static final String TAG = "PhotoSelectionActivity";
-
-    /** Number of ms for the animation to expand the photo. */
-    private static final int PHOTO_EXPAND_DURATION = 100;
-
-    /** Number of ms for the animation to contract the photo on activity exit. */
-    private static final int PHOTO_CONTRACT_DURATION = 50;
-
-    /** Number of ms for the animation to hide the backdrop on finish. */
-    private static final int BACKDROP_FADEOUT_DURATION = 100;
-
-    /** Key used to persist photo uri. */
-    private static final String KEY_CURRENT_PHOTO_URI = "currentphotouri";
-
-    /** Key used to persist whether a sub-activity is currently in progress. */
-    private static final String KEY_SUB_ACTIVITY_IN_PROGRESS = "subinprogress";
-
-    /** Intent extra to get the photo URI. */
-    public static final String PHOTO_URI = "photo_uri";
-
-    /** Intent extra to get the entity delta list. */
-    public static final String ENTITY_DELTA_LIST = "entity_delta_list";
-
-    /** Intent extra to indicate whether the contact is the user's profile. */
-    public static final String IS_PROFILE = "is_profile";
-
-    /** Intent extra to indicate whether the contact is from a directory (non-editable). */
-    public static final String IS_DIRECTORY_CONTACT = "is_directory_contact";
-
-    /**
-     * Intent extra to indicate whether the photo should be animated to show the full contents of
-     * the photo (on a larger portion of the screen) when clicked.  If unspecified or false, the
-     * photo will not move from its original location.
-     */
-    public static final String EXPAND_PHOTO = "expand_photo";
-
-    /** Source bounds of the image that was clicked on. */
-    private Rect mSourceBounds;
-
-    /**
-     * The photo URI. May be null, in which case the default avatar will be used.
-     */
-    private Uri mPhotoUri;
-
-    /** Entity delta list of the contact. */
-    private RawContactDeltaList mState;
-
-    /** Whether the contact is the user's profile. */
-    private boolean mIsProfile;
-
-    /** Whether the contact is from a directory. */
-    private boolean mIsDirectoryContact;
-
-    /** Whether to animate the photo to an expanded view covering more of the screen. */
-    private boolean mExpandPhoto;
-
-    /**
-     * Side length (in pixels) of the expanded photo if to be expanded. Photos are expected to
-     * be square.
-     */
-    private int mExpandedPhotoSize;
-
-    /** Height (in pixels) to leave underneath the expanded photo to show the list popup */
-    private int mHeightOffset;
-
-    /** The semi-transparent backdrop. */
-    private View mBackdrop;
-
-    /** The photo view. */
-    private ImageView mPhotoView;
-
-    /** The photo handler attached to this activity, if any. */
-    private PhotoHandler mPhotoHandler;
-
-    /** Animator to expand the photo out to full size. */
-    private ObjectAnimator mPhotoAnimator;
-
-    /** Listener for the animation. */
-    private AnimatorListenerAdapter mAnimationListener;
-
-    /** Whether a change in layout of the photo has occurred that has no animation yet. */
-    private boolean mAnimationPending;
-
-    /** Prior position of the image (for animating). */
-    Rect mOriginalPos = new Rect();
-
-    /** Layout params for the photo view before we started animating. */
-    private LayoutParams mPhotoStartParams;
-
-    /** Layout params for the photo view after we finished animating. */
-    private LayoutParams mPhotoEndParams;
-
-    /** Whether a sub-activity is currently in progress. */
-    private boolean mSubActivityInProgress;
-
-    private boolean mCloseActivityWhenCameBackFromSubActivity;
-
-    /**
-     * A photo result received by the activity, persisted across activity lifecycle.
-     */
-    private PendingPhotoResult mPendingPhotoResult;
-
-    /**
-     * The photo uri being interacted with, if any.  Saved/restored between activity instances.
-     */
-    private Uri mCurrentPhotoUri;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.photoselection_activity);
-        if (savedInstanceState != null) {
-            mCurrentPhotoUri = savedInstanceState.getParcelable(KEY_CURRENT_PHOTO_URI);
-            mSubActivityInProgress = savedInstanceState.getBoolean(KEY_SUB_ACTIVITY_IN_PROGRESS);
-        }
-
-        // Pull data out of the intent.
-        final Intent intent = getIntent();
-        mPhotoUri = intent.getParcelableExtra(PHOTO_URI);
-        mState = (RawContactDeltaList) intent.getParcelableExtra(ENTITY_DELTA_LIST);
-        mIsProfile = intent.getBooleanExtra(IS_PROFILE, false);
-        mIsDirectoryContact = intent.getBooleanExtra(IS_DIRECTORY_CONTACT, false);
-        mExpandPhoto = intent.getBooleanExtra(EXPAND_PHOTO, false);
-
-        // Pull out photo expansion properties from resources
-        mExpandedPhotoSize = getResources().getDimensionPixelSize(
-                R.dimen.detail_contact_photo_expanded_size);
-        mHeightOffset = getResources().getDimensionPixelOffset(
-                R.dimen.expanded_photo_height_offset);
-
-        mBackdrop = findViewById(R.id.backdrop);
-        mPhotoView = (ImageView) findViewById(R.id.photo);
-
-        mSourceBounds = intent.getSourceBounds();
-
-        // Fade in the background.
-        animateInBackground();
-
-        // Dismiss the dialog on clicking the backdrop.
-        mBackdrop.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                finish();
-            }
-        });
-
-        // Wait until the layout pass to show the photo, so that the source bounds will match up.
-        SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
-            @Override
-            public void run() {
-                displayPhoto();
-            }
-        });
-    }
-
-    /**
-     * Compute the adjusted expanded photo size to fit within the enclosing view with the same
-     * aspect ratio.
-     * @param enclosingView This is the view that the photo must fit within.
-     * @param heightOffset This is the amount of height to leave open for the photo action popup.
-     */
-    private int getAdjustedExpandedPhotoSize(View enclosingView, int heightOffset) {
-        // pull out the bounds of the backdrop
-        final Rect bounds = new Rect();
-        enclosingView.getDrawingRect(bounds);
-        final int boundsWidth = bounds.width();
-        final int boundsHeight = bounds.height() - heightOffset;
-
-        // ensure that the new expanded photo size can fit within the backdrop
-        final float alpha = Math.min((float) boundsHeight / (float) mExpandedPhotoSize,
-                (float) boundsWidth / (float) mExpandedPhotoSize);
-        if (alpha < 1.0f) {
-            // need to shrink width and height while maintaining aspect ratio
-            return (int) (alpha * mExpandedPhotoSize);
-        } else {
-            return mExpandedPhotoSize;
-        }
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        // The current look may not seem right on the new configuration, so let's just close self.
-
-        if (!mSubActivityInProgress) {
-            finishImmediatelyWithNoAnimation();
-        } else {
-            // A sub-activity is in progress, so don't close it yet, but close it when we come back
-            // to this activity.
-            mCloseActivityWhenCameBackFromSubActivity = true;
-        }
-    }
-
-    @Override
-    public void finish() {
-        if (!mSubActivityInProgress) {
-            closePhotoAndFinish();
-        } else {
-            finishImmediatelyWithNoAnimation();
-        }
-    }
-
-    /**
-     * Builds a well-formed intent for invoking this activity.
-     * @param context The context.
-     * @param photoUri The URI of the current photo (may be null, in which case the default
-     *     avatar image will be displayed).
-     * @param photoBitmap The bitmap of the current photo (may be null, in which case the default
-     *     avatar image will be displayed).
-     * @param photoBytes The bytes for the current photo (may be null, in which case the default
-     *     avatar image will be displayed).
-     * @param photoBounds The pixel bounds of the current photo.
-     * @param delta The entity delta list for the contact.
-     * @param isProfile Whether the contact is the user's profile.
-     * @param isDirectoryContact Whether the contact comes from a directory (non-editable).
-     * @param expandPhotoOnClick Whether the photo should be expanded on click or not (generally,
-     *     this should be true for phones, and false for tablets).
-     * @return An intent that can be used to invoke the photo selection activity.
-     */
-    public static Intent buildIntent(Context context, Uri photoUri, Bitmap photoBitmap,
-            byte[] photoBytes, Rect photoBounds, RawContactDeltaList delta, boolean isProfile,
-            boolean isDirectoryContact, boolean expandPhotoOnClick) {
-        Intent intent = new Intent(context, PhotoSelectionActivity.class);
-        if (photoUri != null && photoBitmap != null && photoBytes != null) {
-            intent.putExtra(PHOTO_URI, photoUri);
-        }
-        intent.setSourceBounds(photoBounds);
-        intent.putExtra(ENTITY_DELTA_LIST, (Parcelable) delta);
-        intent.putExtra(IS_PROFILE, isProfile);
-        intent.putExtra(IS_DIRECTORY_CONTACT, isDirectoryContact);
-        intent.putExtra(EXPAND_PHOTO, expandPhotoOnClick);
-        return intent;
-    }
-
-    private void finishImmediatelyWithNoAnimation() {
-        super.finish();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        if (mPhotoAnimator != null) {
-            mPhotoAnimator.cancel();
-            mPhotoAnimator = null;
-        }
-        if (mPhotoHandler != null) {
-            mPhotoHandler.destroy();
-            mPhotoHandler = null;
-        }
-    }
-
-    private void displayPhoto() {
-        // Animate the photo view into its end location.
-        final int[] pos = new int[2];
-        mBackdrop.getLocationOnScreen(pos);
-        LayoutParams layoutParams = new LayoutParams(mSourceBounds.width(),
-                mSourceBounds.height());
-        mOriginalPos.left = mSourceBounds.left - pos[0];
-        mOriginalPos.top = mSourceBounds.top - pos[1];
-        mOriginalPos.right = mOriginalPos.left + mSourceBounds.width();
-        mOriginalPos.bottom = mOriginalPos.top + mSourceBounds.height();
-        layoutParams.setMargins(mOriginalPos.left, mOriginalPos.top, mOriginalPos.right,
-                mOriginalPos.bottom);
-        mPhotoStartParams = layoutParams;
-        mPhotoView.setLayoutParams(layoutParams);
-        mPhotoView.requestLayout();
-
-        // Load the photo.
-        int photoWidth = getPhotoEndParams().width;
-        if (mPhotoUri != null) {
-            // If we have a URI, the bitmap should be cached directly.
-            ContactPhotoManager.getInstance(this).loadPhoto(mPhotoView, mPhotoUri, photoWidth,
-                    false /* darkTheme */, false /* isCircular */, null);
-        } else {
-            // If we don't have a URI, just display an empty ImageView. The default image from the
-            // ContactDetailFragment will show up in the background instead.
-            mPhotoView.setImageDrawable(null);
-        }
-
-        mPhotoView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
-            @Override
-            public void onLayoutChange(View v, int left, int top, int right, int bottom,
-                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                if (mAnimationPending) {
-                    mAnimationPending = false;
-                    PropertyValuesHolder pvhLeft =
-                            PropertyValuesHolder.ofInt("left", mOriginalPos.left, left);
-                    PropertyValuesHolder pvhTop =
-                            PropertyValuesHolder.ofInt("top", mOriginalPos.top, top);
-                    PropertyValuesHolder pvhRight =
-                            PropertyValuesHolder.ofInt("right", mOriginalPos.right, right);
-                    PropertyValuesHolder pvhBottom =
-                            PropertyValuesHolder.ofInt("bottom", mOriginalPos.bottom, bottom);
-                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(mPhotoView,
-                            pvhLeft, pvhTop, pvhRight, pvhBottom).setDuration(
-                            PHOTO_EXPAND_DURATION);
-                    if (mAnimationListener != null) {
-                        anim.addListener(mAnimationListener);
-                    }
-                    anim.start();
-                }
-            }
-        });
-        attachPhotoHandler();
-    }
-
-    /**
-     * This sets the photo's layout params at the end of the animation.
-     * <p>
-     * The scheme is to enlarge the photo to the desired size with the enlarged photo shifted
-     * to the top left of the screen as much as possible while keeping the underlying smaller
-     * photo occluded.
-     */
-    private LayoutParams getPhotoEndParams() {
-        if (mPhotoEndParams == null) {
-            mPhotoEndParams = new LayoutParams(mPhotoStartParams);
-            if (mExpandPhoto) {
-                final int adjustedPhotoSize = getAdjustedExpandedPhotoSize(mBackdrop,
-                        mHeightOffset);
-                int widthDelta = adjustedPhotoSize - mPhotoStartParams.width;
-                int heightDelta = adjustedPhotoSize - mPhotoStartParams.height;
-                if (widthDelta >= 1 || heightDelta >= 1) {
-                    // This is an actual expansion.
-                    mPhotoEndParams.width = adjustedPhotoSize;
-                    mPhotoEndParams.height = adjustedPhotoSize;
-                    mPhotoEndParams.topMargin =
-                            Math.max(mPhotoStartParams.topMargin - heightDelta, 0);
-                    mPhotoEndParams.leftMargin =
-                            Math.max(mPhotoStartParams.leftMargin - widthDelta, 0);
-                    mPhotoEndParams.bottomMargin = 0;
-                    mPhotoEndParams.rightMargin = 0;
-                }
-            }
-        }
-        return mPhotoEndParams;
-    }
-
-    private void animatePhotoOpen() {
-        mAnimationListener = new AnimatorListenerAdapter() {
-            private void capturePhotoPos() {
-                mPhotoView.requestLayout();
-                mOriginalPos.left = mPhotoView.getLeft();
-                mOriginalPos.top = mPhotoView.getTop();
-                mOriginalPos.right = mPhotoView.getRight();
-                mOriginalPos.bottom = mPhotoView.getBottom();
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                capturePhotoPos();
-                if (mPhotoHandler != null) {
-                    mPhotoHandler.onClick(mPhotoView);
-                }
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                capturePhotoPos();
-            }
-        };
-        animatePhoto(getPhotoEndParams());
-    }
-
-    private void closePhotoAndFinish() {
-        mAnimationListener = new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                // After the photo animates down, fade it away and finish.
-                ObjectAnimator anim = ObjectAnimator.ofFloat(
-                        mPhotoView, "alpha", 0f).setDuration(PHOTO_CONTRACT_DURATION);
-                anim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        finishImmediatelyWithNoAnimation();
-                    }
-                });
-                anim.start();
-            }
-        };
-
-        animatePhoto(mPhotoStartParams);
-        animateAwayBackground();
-    }
-
-    private void animatePhoto(MarginLayoutParams to) {
-        // Cancel any existing animation.
-        if (mPhotoAnimator != null) {
-            mPhotoAnimator.cancel();
-        }
-
-        mPhotoView.setLayoutParams(to);
-        mAnimationPending = true;
-        mPhotoView.requestLayout();
-    }
-
-    private void animateInBackground() {
-        ObjectAnimator.ofFloat(mBackdrop, "alpha", 0, 0.5f).setDuration(
-                PHOTO_EXPAND_DURATION).start();
-    }
-
-    private void animateAwayBackground() {
-        ObjectAnimator.ofFloat(mBackdrop, "alpha", 0f).setDuration(
-                BACKDROP_FADEOUT_DURATION).start();
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putParcelable(KEY_CURRENT_PHOTO_URI, mCurrentPhotoUri);
-        outState.putBoolean(KEY_SUB_ACTIVITY_IN_PROGRESS, mSubActivityInProgress);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (mPhotoHandler != null) {
-            mSubActivityInProgress = false;
-            if (mPhotoHandler.handlePhotoActivityResult(requestCode, resultCode, data)) {
-                // Clear out any pending photo result.
-                mPendingPhotoResult = null;
-            } else {
-                // User cancelled the sub-activity and returning to the photo selection activity.
-                if (mCloseActivityWhenCameBackFromSubActivity) {
-                    finishImmediatelyWithNoAnimation();
-                } else {
-                    // Re-display options.
-                    mPhotoHandler.onClick(mPhotoView);
-                }
-            }
-        } else {
-            // Create a pending photo result to be handled when the photo handler is created.
-            mPendingPhotoResult = new PendingPhotoResult(requestCode, resultCode, data);
-        }
-    }
-
-    private void attachPhotoHandler() {
-        // Always provide the same two choices (take a photo with the camera, select a photo
-        // from the gallery), but with slightly different wording.
-        // Note: don't worry about this being a read-only contact; this code will not be invoked.
-        int mode = (mPhotoUri == null) ? PhotoActionPopup.Modes.NO_PHOTO
-                : PhotoActionPopup.Modes.WRITE_ABLE_PHOTO;
-        // We don't want to provide a choice to remove the photo for two reasons:
-        //   1) the UX designs don't call for it
-        //   2) even if we wanted to, the implementation would be moderately hairy
-        mode &= ~PhotoActionPopup.Flags.REMOVE_PHOTO;
-
-        mPhotoHandler = new PhotoHandler(this, mPhotoView, mode, mState);
-
-        if (mPendingPhotoResult != null) {
-            mPhotoHandler.handlePhotoActivityResult(mPendingPhotoResult.mRequestCode,
-                    mPendingPhotoResult.mResultCode, mPendingPhotoResult.mData);
-            mPendingPhotoResult = null;
-        } else {
-            // Setting the photo in displayPhoto() resulted in a relayout
-            // request... to avoid jank, wait until this layout has happened.
-            SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
-                @Override
-                public void run() {
-                    animatePhotoOpen();
-                }
-            });
-        }
-    }
-
-    private final class PhotoHandler extends PhotoSelectionHandler {
-        private final PhotoActionListener mListener;
-
-        private PhotoHandler(
-                Context context, View photoView, int photoMode, RawContactDeltaList state) {
-            super(context, photoView, photoMode, PhotoSelectionActivity.this.mIsDirectoryContact,
-                    state);
-            mListener = new PhotoListener();
-        }
-
-        @Override
-        public PhotoActionListener getListener() {
-            return mListener;
-        }
-
-        @Override
-        public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) {
-            mSubActivityInProgress = true;
-            mCurrentPhotoUri = photoUri;
-            PhotoSelectionActivity.this.startActivityForResult(intent, requestCode);
-        }
-
-        private final class PhotoListener extends PhotoActionListener {
-            @Override
-            public void onPhotoSelected(Uri uri) {
-                RawContactDeltaList delta = getDeltaForAttachingPhotoToContact();
-                long rawContactId = getWritableEntityId();
-
-                Intent intent = ContactSaveService.createSaveContactIntent(
-                        mContext, delta, "", 0, mIsProfile, null, null, rawContactId, uri);
-                startService(intent);
-                finish();
-            }
-
-            @Override
-            public Uri getCurrentPhotoUri() {
-                return mCurrentPhotoUri;
-            }
-
-            @Override
-            public void onPhotoSelectionDismissed() {
-                if (!mSubActivityInProgress) {
-                    finish();
-                }
-            }
-        }
-    }
-
-    private static class PendingPhotoResult {
-        final private int mRequestCode;
-        final private int mResultCode;
-        final private Intent mData;
-        private PendingPhotoResult(int requestCode, int resultCode, Intent data) {
-            mRequestCode = requestCode;
-            mResultCode = resultCode;
-            mData = data;
-        }
-    }
-}
diff --git a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
deleted file mode 100644
index 437de45..0000000
--- a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2012 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.detail;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ImageView;
-
-import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.activities.PhotoSelectionActivity;
-import com.android.contacts.common.model.Contact;
-import com.android.contacts.common.model.RawContactDeltaList;
-import com.android.contacts.util.ImageViewDrawableSetter;
-
-/**
- * Extends superclass with methods specifically for setting the contact-detail
- * photo.
- */
-public class ContactDetailPhotoSetter extends ImageViewDrawableSetter {
-    public OnClickListener setupContactPhotoForClick(Context context, Contact contactData,
-            ImageView photoView, boolean expandPhotoOnClick) {
-        Bitmap bitmap = setupContactPhoto(contactData, photoView);
-        return setupClickListener(context, contactData, bitmap, expandPhotoOnClick);
-    }
-
-    private static final class PhotoClickListener implements OnClickListener {
-
-        private final Context mContext;
-        private final Contact mContactData;
-        private final Bitmap mPhotoBitmap;
-        private final byte[] mPhotoBytes;
-        private final boolean mExpandPhotoOnClick;
-
-        public PhotoClickListener(Context context, Contact contactData, Bitmap photoBitmap,
-                byte[] photoBytes, boolean expandPhotoOnClick) {
-            mContext = context;
-            mContactData = contactData;
-            mPhotoBitmap = photoBitmap;
-            mPhotoBytes = photoBytes;
-            mExpandPhotoOnClick = expandPhotoOnClick;
-        }
-
-        @Override
-        public void onClick(View v) {
-            // Assemble the intent.
-            RawContactDeltaList delta = mContactData.createRawContactDeltaList();
-
-            // Find location and bounds of target view, adjusting based on the
-            // assumed local density.
-            final float appScale =
-                    mContext.getResources().getCompatibilityInfo().applicationScale;
-            final int[] pos = new int[2];
-            v.getLocationOnScreen(pos);
-
-            // rect is the bounds (in pixels) of the photo view in screen coordinates
-            final Rect rect = new Rect();
-            rect.left = (int) (pos[0] * appScale + 0.5f);
-            rect.top = (int) (pos[1] * appScale + 0.5f);
-            rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
-            rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
-
-            Uri photoUri = null;
-            if (mContactData.getPhotoUri() != null) {
-                photoUri = Uri.parse(mContactData.getPhotoUri());
-            }
-            Intent photoSelectionIntent = PhotoSelectionActivity.buildIntent(mContext,
-                    photoUri, mPhotoBitmap, mPhotoBytes, rect, delta, mContactData.isUserProfile(),
-                    mContactData.isDirectoryEntry(), mExpandPhotoOnClick);
-            // Cache the bitmap directly, so the activity can pull it from the
-            // photo manager.
-            if (mPhotoBitmap != null) {
-                ContactPhotoManager.getInstance(mContext).cacheBitmap(
-                        photoUri, mPhotoBitmap, mPhotoBytes);
-            }
-            mContext.startActivity(photoSelectionIntent);
-        }
-    }
-
-    private OnClickListener setupClickListener(Context context, Contact contactData, Bitmap bitmap,
-            boolean expandPhotoOnClick) {
-        final ImageView target = getTarget();
-        if (target == null) return null;
-
-        return new PhotoClickListener(
-                context, contactData, bitmap, getCompressedImage(), expandPhotoOnClick);
-    }
-}
diff --git a/src/com/android/contacts/detail/TransformableImageView.java b/src/com/android/contacts/detail/TransformableImageView.java
deleted file mode 100644
index 1eb35aa..0000000
--- a/src/com/android/contacts/detail/TransformableImageView.java
+++ /dev/null
@@ -1,72 +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.detail;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-/**
- * Extension to ImageView that handles cropping during resize animations.
- */
-public class TransformableImageView extends ImageView {
-
-    public TransformableImageView(Context context) {
-        super(context);
-    }
-
-    public TransformableImageView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public TransformableImageView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        if (getDrawable() == null) {
-            return;
-        }
-        int saveCount = canvas.getSaveCount();
-        canvas.save();
-        canvas.translate(mPaddingLeft, mPaddingTop);
-        Matrix drawMatrix = new Matrix();
-        int dwidth = getDrawable().getIntrinsicWidth();
-        int dheight = getDrawable().getIntrinsicHeight();
-
-        int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
-        int vheight = getHeight() - mPaddingTop - mPaddingBottom;
-        float scale;
-        float dx = 0, dy = 0;
-
-        if (dwidth * vheight > vwidth * dheight) {
-            scale = (float) vheight / (float) dheight;
-            dx = (vwidth - dwidth * scale) * 0.5f;
-        } else {
-            scale = (float) vwidth / (float) dwidth;
-            dy = (vheight - dheight * scale) * 0.5f;
-        }
-
-        drawMatrix.setScale(scale, scale);
-        drawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
-        canvas.concat(drawMatrix);
-        getDrawable().draw(canvas);
-        canvas.restoreToCount(saveCount);
-    }
-}
