diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 22af3d5..f226683 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -37,7 +37,6 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
@@ -197,7 +196,7 @@
     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
     static final boolean DEBUG_MU = localLOGV || false;
     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
-    static final boolean VALIDATE_TOKENS = true;
+    static final boolean VALIDATE_TOKENS = false;
     static final boolean SHOW_ACTIVITY_START_TIME = true;
     
     // Control over CPU and battery monitoring.
@@ -329,7 +328,7 @@
     /**
      * List of intents that were used to start the most recent tasks.
      */
-    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
+    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
 
     public class PendingActivityExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
@@ -597,8 +596,13 @@
      * List of PendingThumbnailsRecord objects of clients who are still
      * waiting to receive all of the thumbnails for a task.
      */
-    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
-            new ArrayList<PendingThumbnailsRecord>();
+    final ArrayList mPendingThumbnails = new ArrayList();
+
+    /**
+     * List of HistoryRecord objects that have been finished and must
+     * still report back to a pending thumbnail receiver.
+     */
+    final ArrayList mCancelledThumbnails = new ArrayList();
 
     final ProviderMap mProviderMap;
 
@@ -2838,8 +2842,11 @@
             for (int i=0; i<activities.size(); i++) {
                 ActivityRecord r = activities.get(i);
                 if (!r.finishing) {
-                    mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED,
-                            null, "finish-heavy", true);
+                    int index = mMainStack.indexOfTokenLocked(r.appToken);
+                    if (index >= 0) {
+                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
+                                null, "finish-heavy", true);
+                    }
                 }
             }
             
@@ -2925,13 +2932,22 @@
         }
     }
 
-    @Override
     public boolean willActivityBeVisible(IBinder token) {
         synchronized(this) {
-            return mMainStack.willActivityBeVisibleLocked(token);
+            int i;
+            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
+                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+                if (r.appToken == token) {
+                    return true;
+                }
+                if (r.fullscreen && !r.finishing) {
+                    return false;
+                }
+            }
+            return true;
         }
     }
-
+    
     public void overridePendingTransition(IBinder token, String packageName,
             int enterAnim, int exitAnim) {
         synchronized(this) {
@@ -3701,7 +3717,13 @@
         }
         mWindowManager.closeSystemDialogs(reason);
 
-        mMainStack.closeSystemDialogsLocked();
+        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
+            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
+                r.stack.finishActivityLocked(r, i,
+                        Activity.RESULT_CANCELED, null, "close-sys", true);
+            }
+        }
 
         broadcastIntentLocked(null, null, intent, null,
                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
@@ -3908,12 +3930,37 @@
         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
                 -100, callerWillRestart, true, doit, evenPersistent,
                 name == null ? ("force stop user " + userId) : ("force stop " + name));
-
-        if (mMainStack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
-            if (!doit) {
-                return true;
+        
+        TaskRecord lastTask = null;
+        for (i=0; i<mMainStack.mHistory.size(); i++) {
+            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+            final boolean samePackage = r.packageName.equals(name)
+                    || (name == null && r.userId == userId);
+            if ((userId == UserHandle.USER_ALL || r.userId == userId)
+                    && (samePackage || r.task == lastTask)
+                    && (r.app == null || evenPersistent || !r.app.persistent)) {
+                if (!doit) {
+                    if (r.finishing) {
+                        // If this activity is just finishing, then it is not
+                        // interesting as far as something to stop.
+                        continue;
+                    }
+                    return true;
+                }
+                didSomething = true;
+                Slog.i(TAG, "  Force finishing activity " + r);
+                if (samePackage) {
+                    if (r.app != null) {
+                        r.app.removed = true;
+                    }
+                    r.app = null;
+                }
+                lastTask = r.task;
+                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
+                        null, "force-stop", true)) {
+                    i--;
+                }
             }
-            didSomething = true;
         }
 
         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
@@ -5623,12 +5670,12 @@
     // TASK MANAGEMENT
     // =========================================================
 
-    @Override
-    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
+    public List getTasks(int maxNum, int flags,
                          IThumbnailReceiver receiver) {
-        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
+        ArrayList list = new ArrayList();
 
-        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
+        PendingThumbnailsRecord pending = null;
+        IApplicationThread topThumbnail = null;
         ActivityRecord topRecord = null;
 
         synchronized(this) {
@@ -5654,19 +5701,88 @@
                 throw new SecurityException(msg);
             }
 
-            topRecord = mMainStack.getTasksLocked(maxNum, receiver, pending, list);
+            int pos = mMainStack.mHistory.size()-1;
+            ActivityRecord next =
+                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
+            ActivityRecord top = null;
+            TaskRecord curTask = null;
+            int numActivities = 0;
+            int numRunning = 0;
+            while (pos >= 0 && maxNum > 0) {
+                final ActivityRecord r = next;
+                pos--;
+                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
 
-            if (!pending.pendingRecords.isEmpty()) {
+                // Initialize state for next task if needed.
+                if (top == null ||
+                        (top.state == ActivityState.INITIALIZING
+                            && top.task == r.task)) {
+                    top = r;
+                    curTask = r.task;
+                    numActivities = numRunning = 0;
+                }
+
+                // Add 'r' into the current task.
+                numActivities++;
+                if (r.app != null && r.app.thread != null) {
+                    numRunning++;
+                }
+
+                if (localLOGV) Slog.v(
+                    TAG, r.intent.getComponent().flattenToShortString()
+                    + ": task=" + r.task);
+
+                // If the next one is a different task, generate a new
+                // TaskInfo entry for what we have.
+                if (next == null || next.task != curTask) {
+                    ActivityManager.RunningTaskInfo ci
+                            = new ActivityManager.RunningTaskInfo();
+                    ci.id = curTask.taskId;
+                    ci.baseActivity = r.intent.getComponent();
+                    ci.topActivity = top.intent.getComponent();
+                    if (top.thumbHolder != null) {
+                        ci.description = top.thumbHolder.lastDescription;
+                    }
+                    ci.numActivities = numActivities;
+                    ci.numRunning = numRunning;
+                    //System.out.println(
+                    //    "#" + maxNum + ": " + " descr=" + ci.description);
+                    if (ci.thumbnail == null && receiver != null) {
+                        if (localLOGV) Slog.v(
+                            TAG, "State=" + top.state + "Idle=" + top.idle
+                            + " app=" + top.app
+                            + " thr=" + (top.app != null ? top.app.thread : null));
+                        if (top.state == ActivityState.RESUMED
+                                || top.state == ActivityState.PAUSING) {
+                            if (top.idle && top.app != null
+                                && top.app.thread != null) {
+                                topRecord = top;
+                                topThumbnail = top.app.thread;
+                            } else {
+                                top.thumbnailNeeded = true;
+                            }
+                        }
+                        if (pending == null) {
+                            pending = new PendingThumbnailsRecord(receiver);
+                        }
+                        pending.pendingRecords.add(top);
+                    }
+                    list.add(ci);
+                    maxNum--;
+                    top = null;
+                }
+            }
+
+            if (pending != null) {
                 mPendingThumbnails.add(pending);
             }
         }
 
         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
 
-        if (topRecord != null) {
+        if (topThumbnail != null) {
             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
             try {
-                IApplicationThread topThumbnail = topRecord.app.thread;
                 topThumbnail.requestThumbnail(topRecord.appToken);
             } catch (Exception e) {
                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
@@ -5901,6 +6017,43 @@
         return false;
     }
     
+    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
+        int j;
+        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 
+        TaskRecord jt = startTask;
+        
+        // First look backwards
+        for (j=startIndex-1; j>=0; j--) {
+            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
+            if (r.task != jt) {
+                jt = r.task;
+                if (affinity.equals(jt.affinity)) {
+                    return j;
+                }
+            }
+        }
+        
+        // Now look forwards
+        final int N = mMainStack.mHistory.size();
+        jt = startTask;
+        for (j=startIndex+1; j<N; j++) {
+            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
+            if (r.task != jt) {
+                if (affinity.equals(jt.affinity)) {
+                    return j;
+                }
+                jt = r.task;
+            }
+        }
+        
+        // Might it be at the top?
+        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
+            return N-1;
+        }
+        
+        return -1;
+    }
+    
     /**
      * TODO: Add mController hook
      */
@@ -5929,8 +6082,20 @@
                     mMainStack.moveTaskToFrontLocked(tr, null, options);
                     return;
                 }
-                if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) {
-                    return;
+                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
+                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
+                    if (hr.task.taskId == task) {
+                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+                            mMainStack.mUserLeaving = true;
+                        }
+                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
+                            // Caller wants the home activity moved with it.  To accomplish this,
+                            // we'll just move the home task to the top first.
+                            mMainStack.moveHomeToFrontLocked();
+                        }
+                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
+                        return;
+                    }
                 }
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -5970,7 +6135,7 @@
         enforceNotIsolatedCaller("moveActivityTaskToBack");
         synchronized(this) {
             final long origId = Binder.clearCallingIdentity();
-            int taskId = mMainStack.getTaskForActivityLocked(token, !nonRoot);
+            int taskId = getTaskForActivityLocked(token, !nonRoot);
             if (taskId >= 0) {
                 return mMainStack.moveTaskToBackLocked(taskId, null);
             }
@@ -6000,10 +6165,27 @@
 
     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
         synchronized(this) {
-            return mMainStack.getTaskForActivityLocked(token, onlyRoot);
+            return getTaskForActivityLocked(token, onlyRoot);
         }
     }
 
+    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
+        final int N = mMainStack.mHistory.size();
+        TaskRecord lastTask = null;
+        for (int i=0; i<N; i++) {
+            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+            if (r.appToken == token) {
+                if (!onlyRoot || lastTask != r.task) {
+                    return r.task.taskId;
+                }
+                return -1;
+            }
+            lastTask = r.task;
+        }
+
+        return -1;
+    }
+
     // =========================================================
     // THUMBNAILS
     // =========================================================
@@ -6909,10 +7091,13 @@
                 "unhandledBack()");
 
         synchronized(this) {
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                mMainStack.unhandledBackLocked();
-            } finally {
+            int count = mMainStack.mHistory.size();
+            if (DEBUG_SWITCH) Slog.d(
+                TAG, "Performing unhandledBack(): stack size = " + count);
+            if (count > 1) {
+                final long origId = Binder.clearCallingIdentity();
+                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
+                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
                 Binder.restoreCallingIdentity(origId);
             }
         }
@@ -7974,7 +8159,15 @@
                     + " has crashed too many times: killing!");
             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
                     app.userId, app.info.processName, app.uid);
-            mMainStack.handleAppCrashLocked(app);
+            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
+                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
+                if (r.app == app) {
+                    Slog.w(TAG, "  Force finishing activity "
+                        + r.intent.getComponent().flattenToShortString());
+                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
+                            null, "crashed", false);
+                }
+            }
             if (!app.persistent) {
                 // We don't want to start this process again until the user
                 // explicitly does so...  but for persistent process, we really
@@ -7999,7 +8192,33 @@
             }
             mMainStack.resumeTopActivityLocked(null);
         } else {
-            mMainStack.finishTopRunningActivityLocked(app);
+            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
+            if (r != null && r.app == app) {
+                // If the top running activity is from this crashing
+                // process, then terminate it to avoid getting in a loop.
+                Slog.w(TAG, "  Force finishing activity "
+                        + r.intent.getComponent().flattenToShortString());
+                int index = mMainStack.indexOfActivityLocked(r);
+                r.stack.finishActivityLocked(r, index,
+                        Activity.RESULT_CANCELED, null, "crashed", false);
+                // Also terminate any activities below it that aren't yet
+                // stopped, to avoid a situation where one will get
+                // re-start our crashing activity once it gets resumed again.
+                index--;
+                if (index >= 0) {
+                    r = (ActivityRecord)mMainStack.mHistory.get(index);
+                    if (r.state == ActivityState.RESUMED
+                            || r.state == ActivityState.PAUSING
+                            || r.state == ActivityState.PAUSED) {
+                        if (!r.isHomeActivity || mHomeProcess != r.app) {
+                            Slog.w(TAG, "  Force finishing activity "
+                                    + r.intent.getComponent().flattenToShortString());
+                            r.stack.finishActivityLocked(r, index,
+                                    Activity.RESULT_CANCELED, null, "crashed", false);
+                        }
+                    }
+                }
+            }
         }
 
         // Bump up the crash count of any services currently running in the proc.
@@ -9018,7 +9237,8 @@
             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
         pw.println("  Main stack:");
-        mMainStack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
+        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
+                dumpPackage);
         pw.println(" ");
         pw.println("  Running activities (most recent first):");
         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
@@ -9548,10 +9768,32 @@
      */
     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
             int opti, boolean dumpAll) {
-        ArrayList<ActivityRecord> activities;
-        
-        synchronized (this) {
-            activities = mMainStack.getDumpActivitiesLocked(name);
+        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
+
+        if ("all".equals(name)) {
+            synchronized (this) {
+                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
+                    activities.add(r1);
+                }
+            }
+        } else if ("top".equals(name)) {
+            synchronized (this) {
+                final int N = mMainStack.mHistory.size();
+                if (N > 0) {
+                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
+                }
+            }
+        } else {
+            ItemMatcher matcher = new ItemMatcher();
+            matcher.build(name);
+
+            synchronized (this) {
+                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
+                    if (matcher.match(r1, r1.intent.getComponent())) {
+                        activities.add(r1);
+                    }
+                }
+            }
         }
 
         if (activities.size() <= 0) {
@@ -9803,7 +10045,7 @@
         return needSep;
     }
 
-    static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
+    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
             String prefix, String label, boolean complete, boolean brief, boolean client,
             String dumpPackage) {
         TaskRecord lastTask = null;
@@ -12341,14 +12583,95 @@
 
     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
             Intent resultData) {
+        ComponentName dest = destIntent.getComponent();
 
         synchronized (this) {
             ActivityRecord srec = ActivityRecord.forToken(token);
             if (srec == null) {
                 return false;
             }
-            ActivityStack stack = srec.stack;
-            return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData);
+            ArrayList<ActivityRecord> history = srec.stack.mHistory;
+            final int start = history.indexOf(srec);
+            if (start < 0) {
+                // Current activity is not in history stack; do nothing.
+                return false;
+            }
+            int finishTo = start - 1;
+            ActivityRecord parent = null;
+            boolean foundParentInTask = false;
+            if (dest != null) {
+                TaskRecord tr = srec.task;
+                for (int i = start - 1; i >= 0; i--) {
+                    ActivityRecord r = history.get(i);
+                    if (tr != r.task) {
+                        // Couldn't find parent in the same task; stop at the one above this.
+                        // (Root of current task; in-app "home" behavior)
+                        // Always at least finish the current activity.
+                        finishTo = Math.min(start - 1, i + 1);
+                        parent = history.get(finishTo);
+                        break;
+                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
+                            r.info.name.equals(dest.getClassName())) {
+                        finishTo = i;
+                        parent = r;
+                        foundParentInTask = true;
+                        break;
+                    }
+                }
+            }
+
+            if (mController != null) {
+                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
+                if (next != null) {
+                    // ask watcher if this is allowed
+                    boolean resumeOK = true;
+                    try {
+                        resumeOK = mController.activityResuming(next.packageName);
+                    } catch (RemoteException e) {
+                        mController = null;
+                    }
+
+                    if (!resumeOK) {
+                        return false;
+                    }
+                }
+            }
+            final long origId = Binder.clearCallingIdentity();
+            for (int i = start; i > finishTo; i--) {
+                ActivityRecord r = history.get(i);
+                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
+                        "navigate-up", true);
+                // Only return the supplied result for the first activity finished
+                resultCode = Activity.RESULT_CANCELED;
+                resultData = null;
+            }
+
+            if (parent != null && foundParentInTask) {
+                final int parentLaunchMode = parent.info.launchMode;
+                final int destIntentFlags = destIntent.getFlags();
+                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
+                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
+                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
+                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
+                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
+                } else {
+                    try {
+                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
+                                destIntent.getComponent(), 0, srec.userId);
+                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
+                                null, aInfo, parent.appToken, null,
+                                0, -1, parent.launchedFromUid, parent.launchedFromPackage,
+                                0, null, true, null);
+                        foundParentInTask = res == ActivityManager.START_SUCCESS;
+                    } catch (RemoteException e) {
+                        foundParentInTask = false;
+                    }
+                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
+                            resultData, "navigate-up", true);
+                }
+            }
+            Binder.restoreCallingIdentity(origId);
+            return foundParentInTask;
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index a2f3372..cde17c9 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -22,7 +22,6 @@
 
 import android.app.Activity;
 import android.app.ActivityOptions;
-import android.app.ResultInfo;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -96,9 +95,9 @@
     ActivityRecord resultTo; // who started this entry, so will get our reply
     final String resultWho; // additional identifier for use by resultTo.
     final int requestCode;  // code given by requester (resultTo)
-    ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
+    ArrayList results;      // pending ActivityResult objs we have received
     HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
-    ArrayList<Intent> newIntents; // any pending new intents for single-top mode
+    ArrayList newIntents;   // any pending new intents for single-top mode
     ActivityOptions pendingOptions; // most recently given options
     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
     UriPermissionOwner uriPermissions; // current special URI access perms.
@@ -471,8 +470,6 @@
     void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {
         if (inHistory && !finishing) {
             if (task != null) {
-                // TODO: If this is the last ActivityRecord in task, remove from ActivityStack.
-                task.removeActivity(this);
                 task.numActivities--;
             }
             if (newTask != null) {
@@ -507,7 +504,6 @@
             inHistory = false;
             if (task != null && !finishing) {
                 task.numActivities--;
-                task = null;
             }
             clearOptionsLocked();
         }
@@ -542,7 +538,7 @@
         ActivityResult r = new ActivityResult(from, resultWho,
         		requestCode, resultCode, resultData);
         if (results == null) {
-            results = new ArrayList<ResultInfo>();
+            results = new ArrayList();
         }
         results.add(r);
     }
@@ -953,8 +949,6 @@
         StringBuilder sb = new StringBuilder(128);
         sb.append("ActivityRecord{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
-        sb.append(" t");
-        sb.append(task.taskId);
         sb.append(" u");
         sb.append(userId);
         sb.append(' ');
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index e0b8015..526b24f 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -21,23 +21,18 @@
 
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.os.BatteryStatsImpl;
-import com.android.server.am.ActivityManagerService.ItemMatcher;
 import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
 import com.android.server.wm.AppTransition;
-import com.android.server.wm.TaskGroup;
 
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
-import android.app.IActivityController;
 import android.app.IActivityManager;
-import android.app.IThumbnailReceiver;
 import android.app.IThumbnailRetriever;
 import android.app.IApplicationThread;
 import android.app.PendingIntent;
 import android.app.ResultInfo;
-import android.app.ActivityManager.RunningTaskInfo;
 import android.app.IActivityManager.WaitResult;
 import android.content.ComponentName;
 import android.content.Context;
@@ -54,7 +49,6 @@
 import android.graphics.Bitmap.Config;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -67,12 +61,9 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.view.Display;
 
-import java.io.FileDescriptor;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -100,8 +91,7 @@
     static final boolean DEBUG_APP = false;
 
     static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS;
-    static final boolean VALIDATE_TASK_REPLACE = true;
-
+    
     // How long we wait until giving up on the last activity telling us it
     // is idle.
     static final int IDLE_TIMEOUT = 10*1000;
@@ -140,7 +130,7 @@
     // Set to false to disable the preview that is shown while a new activity
     // is being started.
     static final boolean SHOW_APP_STARTING_PREVIEW = true;
-
+    
     enum ActivityState {
         INITIALIZING,
         RESUMED,
@@ -157,28 +147,17 @@
     final boolean mMainStack;
     
     final Context mContext;
-
+    
     /**
      * The back history of all previous (and possibly still
-     * running) activities.  It contains #ActivityRecord objects.
+     * running) activities.  It contains HistoryRecord objects.
      */
-    private final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>();
-
-    /**
-     * The back history of all previous (and possibly still
-     * running) activities.  It contains #TaskRecord objects.
-     */
-    private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();
-
-    /**
-     * Mapping from taskId to TaskRecord
-     */
-    private SparseArray<TaskRecord> mTaskIdToTaskRecord = new SparseArray<TaskRecord>();
+    final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>();
 
     /**
      * Used for validating app tokens with window manager.
      */
-    final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>();
+    final ArrayList<IBinder> mValidateAppTokens = new ArrayList<IBinder>();
 
     /**
      * List of running activities, sorted by recent usage.
@@ -310,12 +289,6 @@
     private ActivityRecord mLastScreenshotActivity = null;
     private Bitmap mLastScreenshotBitmap = null;
 
-    /**
-     * List of ActivityRecord objects that have been finished and must
-     * still report back to a pending thumbnail receiver.
-     */
-    private final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
-
     int mThumbnailWidth = -1;
     int mThumbnailHeight = -1;
 
@@ -345,8 +318,6 @@
 
     final Handler mHandler;
 
-    String mLastHistoryModifier;
-
     final class ActivityStackHandler extends Handler {
         //public Handler() {
         //    if (localLOGV) Slog.v(TAG, "Handler started!");
@@ -473,66 +444,26 @@
     }
 
     final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
-        ActivityRecord newAr = newTopRunningActivityLocked(notTop);
-
         int i = mHistory.size()-1;
         while (i >= 0) {
             ActivityRecord r = mHistory.get(i);
             if (!r.finishing && r != notTop && okToShow(r)) {
-                if (VALIDATE_TASK_REPLACE && newAr != r) logHistories(
-                        "topRunningActivityLocked", true);
                 return r;
             }
             i--;
         }
-        if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG,
-                "topRunningActivityLocked: mismatch: newAr!=null");
-        return null;
-    }
-
-    final ActivityRecord newTopRunningActivityLocked(ActivityRecord notTop) {
-        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
-            final TaskRecord task = mTaskHistory.get(i);
-            final ArrayList<ActivityRecord> activities = task.mActivities;
-            for (int j = activities.size() - 1; j >= 0; --j) {
-                ActivityRecord r = activities.get(j);
-                if (!r.finishing && r != notTop && okToShow(r)) {
-                    return r;
-                }
-            }
-        }
         return null;
     }
 
     final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
-        ActivityRecord newAr = newTopRunningNonDelayedActivityLocked(notTop);
-
         int i = mHistory.size()-1;
         while (i >= 0) {
             ActivityRecord r = mHistory.get(i);
             if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
-                if (VALIDATE_TASK_REPLACE && newAr != r) Slog.w(TAG,
-                    "topRunningNonDelayedActivityLocked: mismatch: newAr=" + newAr + " r=" + r);
                 return r;
             }
             i--;
         }
-        if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG,
-                "topRunningNonDelayedActivityLocked: mismatch: newAr!=null");
-        return null;
-    }
-
-    final ActivityRecord newTopRunningNonDelayedActivityLocked(ActivityRecord notTop) {
-        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
-            final TaskRecord task = mTaskHistory.get(i);
-            final ArrayList<ActivityRecord> activities = task.mActivities;
-            for (int j = activities.size() - 1; j >= 0; --j) {
-                ActivityRecord r = activities.get(j);
-                if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
-                    return r;
-                }
-            }
-        }
         return null;
     }
 
@@ -546,111 +477,35 @@
      * @return Returns the HistoryRecord of the next activity on the stack.
      */
     final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
-        ActivityRecord newAr = newTopRunningActivityLocked(token, taskId);
-
         int i = mHistory.size()-1;
         while (i >= 0) {
             ActivityRecord r = mHistory.get(i);
             // Note: the taskId check depends on real taskId fields being non-zero
             if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)
                     && okToShow(r)) {
-                if (VALIDATE_TASK_REPLACE && newAr != r) Slog.w(TAG,
-                        "topRunningActivityLocked(token): mismatch: newAr=" + newAr + " r=" + r);
                 return r;
             }
             i--;
         }
-        if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG,
-                "topRunningActivityLocked(token): mismatch: newAr!=null");
         return null;
     }
 
-    final ActivityRecord newTopRunningActivityLocked(IBinder token, int taskId) {
-        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
-            TaskRecord task = mTaskHistory.get(taskNdx);
-            if (task.taskId == taskId) {
-                continue;
-            }
-            ArrayList<ActivityRecord> activities = task.mActivities;
-            for (int i = activities.size() - 1; i >= 0; --i) {
-                final ActivityRecord r = activities.get(i);
-                // Note: the taskId check depends on real taskId fields being non-zero
-                if (!r.finishing && (token != r.appToken) && okToShow(r)) {
-                    return r;
-                }
-            }
-        }
-        return null;
-    }
-
-    private final int indexOfTokenLocked(IBinder token) {
+    final int indexOfTokenLocked(IBinder token) {
         return mHistory.indexOf(ActivityRecord.forToken(token));
     }
 
-    final ActivityRecord isInStackLocked(IBinder token) {
-        ActivityRecord newAr = newIsInStackLocked(token);
+    final int indexOfActivityLocked(ActivityRecord r) {
+        return mHistory.indexOf(r);
+    }
 
+    final ActivityRecord isInStackLocked(IBinder token) {
         ActivityRecord r = ActivityRecord.forToken(token);
         if (mHistory.contains(r)) {
-            if (VALIDATE_TASK_REPLACE && newAr != r) Slog.w(TAG,
-                    "isInStackLocked: mismatch: newAr=" + newAr + " r=" + r);
             return r;
         }
-        if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG,
-                "isInStackLocked: mismatch: newAr!=null");
         return null;
     }
 
-    final ActivityRecord newIsInStackLocked(IBinder token) {
-        final ActivityRecord r = ActivityRecord.forToken(token);
-        if (r != null) {
-            final TaskRecord task = r.task;
-            if (mTaskHistory.contains(task) && task.mActivities.contains(r)) {
-                return r;
-            }
-        }
-        return null;
-    }
-
-    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
-        int newTaskId = newGetTaskForActivityLocked(token, onlyRoot);
-
-        TaskRecord lastTask = null;
-        final int N = mHistory.size();
-        for (int i = 0; i < N; i++) {
-            ActivityRecord r = mHistory.get(i);
-            if (r.appToken == token) {
-                if (!onlyRoot || lastTask != r.task) {
-                    if (VALIDATE_TASK_REPLACE && newTaskId != r.task.taskId) Slog.w(TAG,
-                            "getTaskForActivityLocked: mismatch: new=" + newTaskId
-                            + " taskId=" + r.task.taskId);
-                    return r.task.taskId;
-                }
-                if (VALIDATE_TASK_REPLACE && newTaskId != -1) Slog.w(TAG,
-                    "getTaskForActivityLocked: mismatch: newTaskId=" + newTaskId + " not -1.");
-                return -1;
-            }
-            lastTask = r.task;
-        }
-
-        if (VALIDATE_TASK_REPLACE && newTaskId != -1) Slog.w(TAG,
-            "getTaskForActivityLocked: mismatch at end: newTaskId=" + newTaskId + " not -1.");
-        return -1;
-    }
-
-    int newGetTaskForActivityLocked(IBinder token, boolean onlyRoot) {
-        final ActivityRecord r = ActivityRecord.forToken(token);
-        if (r == null) {
-            return -1;
-        }
-        final TaskRecord task = r.task;
-        switch (task.mActivities.indexOf(r)) {
-            case -1: return -1;
-            case 0: return task.taskId;
-            default: return onlyRoot ? -1 : task.taskId;
-        }
-    }
-
     private final boolean updateLRUListLocked(ActivityRecord r) {
         final boolean hadit = mLRUActivities.remove(r);
         mLRUActivities.add(r);
@@ -743,29 +598,17 @@
      * @return whether there are any activities for the specified user.
      */
     final boolean switchUserLocked(int userId, UserStartedState uss) {
-        if (VALIDATE_TOKENS) {
-            validateAppTokensLocked();
-        }
-        final boolean newResult = newSwitchUserLocked(userId, uss);
-
         mCurrentUser = userId;
         mStartingUsers.add(uss);
 
         // Only one activity? Nothing to do...
-        if (mHistory.size() < 2) {
-            if (VALIDATE_TASK_REPLACE && newResult) Slog.w(TAG,
-                    "switchUserLocked: mismatch: " + newResult + " " + false);
+        if (mHistory.size() < 2)
             return false;
-        }
 
         boolean haveActivities = false;
         // Check if the top activity is from the new user.
         ActivityRecord top = mHistory.get(mHistory.size() - 1);
-        if (top.userId == userId) {
-            if (VALIDATE_TASK_REPLACE && !newResult) Slog.w(TAG,
-                    "switchUserLocked: mismatch: " + newResult + " " + true);
-            return true;
-        }
+        if (top.userId == userId) return true;
         // Otherwise, move the user's activities to the top.
         int N = mHistory.size();
         int i = 0;
@@ -782,44 +625,7 @@
             }
         }
         // Transition from the old top to the new top
-        if (VALIDATE_TASK_REPLACE) Slog.w(TAG,
-                "switchUserLocked: calling resumeTopActivity " + top);
         resumeTopActivityLocked(top);
-        if (VALIDATE_TASK_REPLACE && (newResult != haveActivities)) Slog.w(TAG,
-                    "switchUserLocked: mismatch: " + newResult + " " + haveActivities);
-        return haveActivities;
-    }
-
-    /*
-     * Move the activities around in the stack to bring a user to the foreground.
-     * @return whether there are any activities for the specified user.
-     */
-    final boolean newSwitchUserLocked(int userId, UserStartedState uss) {
-//        mStartingUsers.add(uss);
-        if (mCurrentUser == userId) {
-            return true;
-        }
-        mCurrentUser = userId;
-
-        // Move userId's tasks to the top.
-        boolean haveActivities = false;
-        TaskRecord task = null;
-        int index = mTaskHistory.size();
-        for (int i = 0; i < index; ++i) {
-            task = mTaskHistory.get(i);
-            if (task.userId == userId) {
-                haveActivities = true;
-                mTaskHistory.remove(i);
-                mTaskHistory.add(task);
-                --index;
-            }
-        }
-
-        // task is now the original topmost TaskRecord. Transition from the old top to the new top.
-        ActivityRecord top = task != null ? task.getTopActivity() : null;
-        if (VALIDATE_TASK_REPLACE) Slog.w(TAG,
-                "newSwitchUserLocked: would call resumeTopActivity " + top);
-//        resumeTopActivityLocked(top);
         return haveActivities;
     }
 
@@ -903,13 +709,7 @@
                 try {
                     profileFd = profileFd.dup();
                 } catch (IOException e) {
-                    if (profileFd != null) {
-                        try {
-                            profileFd.close();
-                        } catch (IOException o) {
-                        }
-                        profileFd = null;
-                    }
+                    profileFd = null;
                 }
             }
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
@@ -1057,9 +857,6 @@
             mGoingToSleep.release();
         }
         // Ensure activities are no longer sleeping.
-        if (VALIDATE_TASK_REPLACE) {
-            verifyActivityRecords(true);
-        }
         for (int i=mHistory.size()-1; i>=0; i--) {
             ActivityRecord r = mHistory.get(i);
             r.setSleeping(false);
@@ -1104,9 +901,6 @@
 
             // Make sure any stopped but visible activities are now sleeping.
             // This ensures that the activity's onStop() is called.
-            if (VALIDATE_TASK_REPLACE) {
-                verifyActivityRecords(true);
-            }
             for (int i=mHistory.size()-1; i>=0; i--) {
                 ActivityRecord r = mHistory.get(i);
                 if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) {
@@ -1251,9 +1045,6 @@
         ActivityRecord r = null;
 
         synchronized (mService) {
-            if (VALIDATE_TASK_REPLACE) {
-                verifyActivityRecords(true);
-            }
             int index = indexOfTokenLocked(token);
             if (index >= 0) {
                 r = mHistory.get(index);
@@ -1271,9 +1062,6 @@
         ActivityRecord r = null;
 
         synchronized (mService) {
-            if (VALIDATE_TASK_REPLACE) {
-                verifyActivityRecords(true);
-            }
             int index = indexOfTokenLocked(token);
             if (index >= 0) {
                 r = mHistory.get(index);
@@ -1486,9 +1274,6 @@
 
         // If the top activity is not fullscreen, then we need to
         // make sure any activities under it are now visible.
-        if (VALIDATE_TASK_REPLACE) {
-            verifyActivityRecords(true);
-        }
         final int count = mHistory.size();
         int i = count-1;
         while (mHistory.get(i) != top) {
@@ -1937,7 +1722,7 @@
             
             try {
                 // Deliver all pending results.
-                ArrayList<ResultInfo> a = next.results;
+                ArrayList a = next.results;
                 if (a != null) {
                     final int N = a.size();
                     if (!next.finishing && N > 0) {
@@ -2025,21 +1810,8 @@
         return true;
     }
 
-    /** Temporary until startActivityLocked is rewritten for tasks. */
-    private int convertAddPos(int addPos) {
-        final int taskId = mHistory.get(addPos).task.taskId;
-        addPos--;
-        int taskOffset = 0;
-        while (addPos >= 0 && taskId == mHistory.get(addPos).task.taskId) {
-            ++taskOffset;
-            --addPos;
-        }
-        return taskOffset;
-    }
-
     private final void startActivityLocked(ActivityRecord r, boolean newTask,
             boolean doResume, boolean keepCurTransition, Bundle options) {
-        mLastHistoryModifier = "startActivityLocked";
         final int NH = mHistory.size();
 
         int addPos = -1;
@@ -2064,15 +1836,13 @@
                             Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos,
                                     here);
                         }
-                        r.task.addActivityToTop(r);
                         mHistory.add(addPos, r);
                         r.putInHistory();
-                        mService.mWindowManager.addAppToken(convertAddPos(addPos), r.appToken,
-                                r.task.taskId, r.info.screenOrientation, r.fullscreen,
+                        mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
+                                r.info.screenOrientation, r.fullscreen,
                                 (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
                         if (VALIDATE_TOKENS) {
                             validateAppTokensLocked();
-                            verifyActivityRecords(true);
                         }
                         ActivityOptions.abort(options);
                         return;
@@ -2105,15 +1875,9 @@
             here.fillInStackTrace();
             Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here);
         }
-        r.task.addActivityToTop(r);
         mHistory.add(addPos, r);
         r.putInHistory();
         r.frontOfTask = newTask;
-        if (VALIDATE_TASK_REPLACE) {
-            if (verifyActivityRecords(false)) {
-                Slog.w(TAG, "startActivityLocked: addPos=" + addPos);
-            }
-        }
         if (NH > 0) {
             // We want to show the starting preview window if we are
             // switching to a new task, or the next activity's process is
@@ -2139,8 +1903,8 @@
                 mNoAnimActivities.remove(r);
             }
             r.updateOptionsLocked(options);
-            mService.mWindowManager.addAppToken(convertAddPos(addPos),
-                    r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen,
+            mService.mWindowManager.addAppToken(
+                    addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen,
                     (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
             boolean doShow = true;
             if (newTask) {
@@ -2178,7 +1942,7 @@
         } else {
             // If this is the first activity, don't do any fancy animations,
             // because there is nothing for it to animate on top of.
-            mService.mWindowManager.addAppToken(convertAddPos(addPos), r.appToken, r.task.taskId,
+            mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
                     r.info.screenOrientation, r.fullscreen,
                     (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
             ActivityOptions.abort(options);
@@ -2190,27 +1954,13 @@
         if (doResume) {
             resumeTopActivityLocked(null);
         }
-        if (VALIDATE_TASK_REPLACE) {
-            if (verifyActivityRecords(true)) {
-                Slog.w(TAG, "startActivityLocked: addPos=" + addPos);
-            }
-        }
     }
 
     final void validateAppTokensLocked() {
         mValidateAppTokens.clear();
         mValidateAppTokens.ensureCapacity(mHistory.size());
-        int taskId = Integer.MIN_VALUE;
-        TaskGroup task = null;
         for (int i=0; i<mHistory.size(); i++) {
-            final ActivityRecord r = mHistory.get(i);
-            if (taskId != r.task.taskId) {
-                taskId = r.task.taskId;
-                task = new TaskGroup();
-                task.taskId = taskId;
-                mValidateAppTokens.add(task);
-            }
-            task.tokens.add(r.appToken);
+            mValidateAppTokens.add(mHistory.get(i).appToken);
         }
         mService.mWindowManager.validateAppTokens(mValidateAppTokens);
     }
@@ -2221,8 +1971,6 @@
      */
     private final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
             ActivityRecord newActivity) {
-        mLastHistoryModifier = "resetTaskIfNeededLocked";
-
         boolean forceReset = (newActivity.info.flags
                 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
         if (ACTIVITY_INACTIVE_RESET_TIME > 0
@@ -2318,20 +2066,19 @@
                             if (mService.mCurTask <= 0) {
                                 mService.mCurTask = 1;
                             }
-                            target.setTask(createTaskRecord(mService.mCurTask, target.info, null,
-                                    false), null, false);
+                            target.setTask(new TaskRecord(mService.mCurTask, target.info, null),
+                                    null, false);
                             target.task.affinityIntent = target.intent;
                             if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
                                     + " out to new task " + target.task);
                         }
-                        mService.mWindowManager.setAppGroupId(target.appToken, target.task.taskId);
+                        mService.mWindowManager.setAppGroupId(target.appToken, task.taskId);
                         if (replyChainEnd < 0) {
                             replyChainEnd = targetI;
                         }
                         int dstPos = 0;
                         ThumbnailHolder curThumbHolder = target.thumbHolder;
                         boolean gotOptions = !canMoveOptions;
-                        final int taskId = target.task.taskId;
                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
                             p = mHistory.get(srcPos);
                             if (p.finishing) {
@@ -2356,15 +2103,14 @@
                             }
                             mHistory.remove(srcPos);
                             mHistory.add(dstPos, p);
-                            mService.mWindowManager.setAppGroupId(p.appToken, taskId);
+                            mService.mWindowManager.moveAppToken(dstPos, p.appToken);
+                            mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
                             dstPos++;
+                            if (VALIDATE_TOKENS) {
+                                validateAppTokensLocked();
+                            }
                             i++;
                         }
-                        rebuildTaskHistory();
-                        mService.mWindowManager.moveTaskToBottom(taskId);
-                        if (VALIDATE_TOKENS) {
-                            validateAppTokensLocked();
-                        }
                         if (taskTop == p) {
                             taskTop = below;
                         }
@@ -2384,7 +2130,8 @@
                             // like these are all in the reply chain.
                             replyChainEnd = targetI+1;
                             while (replyChainEnd < mHistory.size() &&
-                                    (mHistory.get(replyChainEnd)).task == task) {
+                                    (mHistory.get(
+                                                replyChainEnd)).task == task) {
                                 replyChainEnd++;
                             }
                             replyChainEnd--;
@@ -2481,7 +2228,6 @@
                     if (replyChainEnd < 0) {
                         replyChainEnd = targetI;
                     }
-                    final int taskId = task.taskId;
                     if (DEBUG_TASKS) Slog.v(TAG, "Reparenting task at index "
                             + targetI + " to " + replyChainEnd);
                     for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
@@ -2507,13 +2253,11 @@
                         if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p
                                 + " from " + srcPos + " to " + lastReparentPos
                                 + " in to resetting task " + task);
-                        mService.mWindowManager.setAppGroupId(p.appToken, taskId);
-                    }
-                    rebuildTaskHistory();
-                    // TODO: This is wrong because it doesn't take lastReparentPos into account.
-                    mService.mWindowManager.moveTaskToTop(taskId);
-                    if (VALIDATE_TOKENS) {
-                        validateAppTokensLocked();
+                        mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken);
+                        mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
+                        if (VALIDATE_TOKENS) {
+                            validateAppTokensLocked();
+                        }
                     }
                     replyChainEnd = -1;
                     
@@ -2558,9 +2302,6 @@
             }
         }
 
-        if (VALIDATE_TASK_REPLACE) {
-            verifyActivityRecords(true);
-        }
         return taskTop;
     }
     
@@ -2627,7 +2368,7 @@
                 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
                         && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
                     if (!ret.finishing) {
-                        int index = mHistory.indexOf(ret);
+                        int index = indexOfTokenLocked(ret.appToken);
                         if (index >= 0) {
                             finishActivityLocked(ret, index, Activity.RESULT_CANCELED,
                                     null, "clear", false);
@@ -2725,7 +2466,6 @@
      */
     private final ActivityRecord moveActivityToFrontLocked(int where) {
         ActivityRecord newTop = mHistory.remove(where);
-        newMoveActivityToFrontLocked(newTop);
         int top = mHistory.size();
         ActivityRecord oldTop = mHistory.get(top-1);
         if (DEBUG_ADD_REMOVE) {
@@ -2735,17 +2475,6 @@
                     + top, here);
         }
         mHistory.add(top, newTop);
-        if (VALIDATE_TASK_REPLACE) {
-            verifyActivityRecords(true);
-        }
-        return newTop;
-    }
-
-    private final ActivityRecord newMoveActivityToFrontLocked(ActivityRecord newTop) {
-        final TaskRecord task = newTop.task;
-        ActivityRecord oldTop = task.getTopActivity();
-        task.mActivities.remove(newTop);
-        task.mActivities.add(newTop);
         oldTop.frontOfTask = false;
         newTop.frontOfTask = true;
         return newTop;
@@ -2756,7 +2485,6 @@
             String resultWho, int requestCode,
             int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
             boolean componentSpecified, ActivityRecord[] outActivity) {
-        mLastHistoryModifier = "startActivityLocked(IApplicationThread)";
 
         int err = ActivityManager.START_SUCCESS;
 
@@ -3239,7 +2967,7 @@
                 if (mService.mCurTask <= 0) {
                     mService.mCurTask = 1;
                 }
-                r.setTask(createTaskRecord(mService.mCurTask, r.info, intent, true), null, true);
+                r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true);
                 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                         + " in new task " + r.task);
             } else {
@@ -3303,7 +3031,7 @@
                 N > 0 ? mHistory.get(N-1) : null;
             r.setTask(prev != null
                     ? prev.task
-                    : createTaskRecord(mService.mCurTask, r.info, intent, true), null, true);
+                    : new TaskRecord(mService.mCurTask, r.info, intent), null, true);
             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                     + " in new guessed " + r.task);
         }
@@ -3795,7 +3523,7 @@
             }
 
             // Get the activity record.
-            int index = mHistory.indexOf(r);
+            int index = indexOfActivityLocked(r);
             if (index >= 0) {
                 res = r;
 
@@ -3851,9 +3579,9 @@
                 finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
                 mFinishingActivities.clear();
             }
-            if ((NT=mCancelledThumbnails.size()) > 0) {
-                thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
-                mCancelledThumbnails.clear();
+            if ((NT=mService.mCancelledThumbnails.size()) > 0) {
+                thumbnails = new ArrayList<ActivityRecord>(mService.mCancelledThumbnails);
+                mService.mCancelledThumbnails.clear();
             }
 
             if (mMainStack) {
@@ -3881,7 +3609,7 @@
         // Stop any activities that are scheduled to do so but have been
         // waiting for the next one to start.
         for (i=0; i<NS; i++) {
-            ActivityRecord r = stops.get(i);
+            ActivityRecord r = (ActivityRecord)stops.get(i);
             synchronized (mService) {
                 if (r.finishing) {
                     finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
@@ -3894,7 +3622,7 @@
         // Finish any activities that are scheduled to do so but have been
         // waiting for the next one to start.
         for (i=0; i<NF; i++) {
-            ActivityRecord r = finishes.get(i);
+            ActivityRecord r = (ActivityRecord)finishes.get(i);
             synchronized (mService) {
                 activityRemoved = destroyActivityLocked(r, true, false, "finish-idle");
             }
@@ -3902,7 +3630,7 @@
 
         // Report back to any thumbnail receivers.
         for (i=0; i<NT; i++) {
-            ActivityRecord r = thumbnails.get(i);
+            ActivityRecord r = (ActivityRecord)thumbnails.get(i);
             mService.sendPendingThumbnail(r, null, null, null, true);
         }
 
@@ -3957,7 +3685,7 @@
 
         int i;
         for (i=mHistory.size()-1; i>=0; i--) {
-            ActivityRecord r = mHistory.get(i);
+            ActivityRecord r = (ActivityRecord)mHistory.get(i);
             if (r.resultTo == self && r.requestCode == requestCode) {
                 if ((r.resultWho == null && resultWho == null) ||
                     (r.resultWho != null && r.resultWho.equals(resultWho))) {
@@ -3969,36 +3697,6 @@
         mService.updateOomAdjLocked();
     }
 
-    final void finishTopRunningActivityLocked(ProcessRecord app) {
-        ActivityRecord r = topRunningActivityLocked(null);
-        if (r != null && r.app == app) {
-            // If the top running activity is from this crashing
-            // process, then terminate it to avoid getting in a loop.
-            Slog.w(TAG, "  Force finishing activity "
-                    + r.intent.getComponent().flattenToShortString());
-            int index = mHistory.indexOf(r);
-            r.stack.finishActivityLocked(r, index,
-                    Activity.RESULT_CANCELED, null, "crashed", false);
-            // Also terminate any activities below it that aren't yet
-            // stopped, to avoid a situation where one will get
-            // re-start our crashing activity once it gets resumed again.
-            index--;
-            if (index >= 0) {
-                r = mHistory.get(index);
-                if (r.state == ActivityState.RESUMED
-                        || r.state == ActivityState.PAUSING
-                        || r.state == ActivityState.PAUSED) {
-                    if (!r.isHomeActivity || mService.mHomeProcess != r.app) {
-                        Slog.w(TAG, "  Force finishing activity "
-                                + r.intent.getComponent().flattenToShortString());
-                        r.stack.finishActivityLocked(r, index,
-                                Activity.RESULT_CANCELED, null, "crashed", false);
-                    }
-                }
-            }
-        }
-    }
-
     final boolean finishActivityAffinityLocked(IBinder token) {
         int index = indexOfTokenLocked(token);
         if (DEBUG_RESULTS) Slog.v(
@@ -4057,19 +3755,6 @@
      * @return Returns true if this activity has been removed from the history
      * list, or false if it is still in the list and will be removed later.
      */
-    final boolean finishActivityLocked(ActivityRecord r,
-            int resultCode, Intent resultData, String reason, boolean oomAdj) {
-        int index = mHistory.indexOf(r);
-        if (index >= 0) {
-            return finishActivityLocked(r, index, resultCode, resultData, reason, false, oomAdj);
-        }
-        return false;
-    }
-
-    /**
-     * @return Returns true if this activity has been removed from the history
-     * list, or false if it is still in the list and will be removed later.
-     */
     final boolean finishActivityLocked(ActivityRecord r, int index,
             int resultCode, Intent resultData, String reason, boolean oomAdj) {
         return finishActivityLocked(r, index, resultCode, resultData, reason, false, oomAdj);
@@ -4119,7 +3804,7 @@
             // There are clients waiting to receive thumbnails so, in case
             // this is an activity that someone is waiting for, add it
             // to the pending list so we can correctly update the clients.
-            mCancelledThumbnails.add(r);
+            mService.mCancelledThumbnails.add(r);
         }
 
         if (immediate) {
@@ -4162,7 +3847,7 @@
 
     private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
             int mode, boolean oomAdj) {
-        final int index = mHistory.indexOf(r);
+        final int index = indexOfActivityLocked(r);
         if (index < 0) {
             return null;
         }
@@ -4218,102 +3903,16 @@
                 resumeTopActivityLocked(null);
             }
             return activityRemoved ? null : r;
+        } else {
+            // Need to go through the full pause cycle to get this
+            // activity into the stopped state and then finish it.
+            if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
+            mFinishingActivities.add(r);
+            resumeTopActivityLocked(null);
         }
-
-        // Need to go through the full pause cycle to get this
-        // activity into the stopped state and then finish it.
-        if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
-        mFinishingActivities.add(r);
-        resumeTopActivityLocked(null);
         return r;
     }
 
-    final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
-            Intent resultData) {
-        final int start = mHistory.indexOf(srec);
-        if (start < 0) {
-            // Current activity is not in history stack; do nothing.
-            return false;
-        }
-        int finishTo = start - 1;
-        ActivityRecord parent = null;
-        boolean foundParentInTask = false;
-        ComponentName dest = destIntent.getComponent();
-        if (dest != null) {
-            TaskRecord tr = srec.task;
-            for (int i = start - 1; i >= 0; i--) {
-                ActivityRecord r = mHistory.get(i);
-                if (tr != r.task) {
-                    // Couldn't find parent in the same task; stop at the one above this.
-                    // (Root of current task; in-app "home" behavior)
-                    // Always at least finish the current activity.
-                    finishTo = Math.min(start - 1, i + 1);
-                    parent = mHistory.get(finishTo);
-                    break;
-                } else if (r.info.packageName.equals(dest.getPackageName()) &&
-                        r.info.name.equals(dest.getClassName())) {
-                    finishTo = i;
-                    parent = r;
-                    foundParentInTask = true;
-                    break;
-                }
-            }
-        }
-
-        IActivityController controller = mService.mController;
-        if (controller != null) {
-            ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
-            if (next != null) {
-                // ask watcher if this is allowed
-                boolean resumeOK = true;
-                try {
-                    resumeOK = controller.activityResuming(next.packageName);
-                } catch (RemoteException e) {
-                    mService.mController = null;
-                }
-
-                if (!resumeOK) {
-                    return false;
-                }
-            }
-        }
-        final long origId = Binder.clearCallingIdentity();
-        for (int i = start; i > finishTo; i--) {
-            ActivityRecord r = mHistory.get(i);
-            requestFinishActivityLocked(r.appToken, resultCode, resultData,
-                    "navigate-up", true);
-            // Only return the supplied result for the first activity finished
-            resultCode = Activity.RESULT_CANCELED;
-            resultData = null;
-        }
-
-        if (parent != null && foundParentInTask) {
-            final int parentLaunchMode = parent.info.launchMode;
-            final int destIntentFlags = destIntent.getFlags();
-            if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
-                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
-                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
-                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
-                parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
-            } else {
-                try {
-                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
-                            destIntent.getComponent(), 0, srec.userId);
-                    int res = startActivityLocked(srec.app.thread, destIntent,
-                            null, aInfo, parent.appToken, null,
-                            0, -1, parent.launchedFromUid, parent.launchedFromPackage,
-                            0, null, true, null);
-                    foundParentInTask = res == ActivityManager.START_SUCCESS;
-                } catch (RemoteException e) {
-                    foundParentInTask = false;
-                }
-                requestFinishActivityLocked(parent.appToken, resultCode,
-                        resultData, "navigate-up", true);
-            }
-        }
-        Binder.restoreCallingIdentity(origId);
-        return foundParentInTask;
-    }
     /**
      * Perform the common clean-up of an activity record.  This is called both
      * as part of destroyActivityLocked() (when destroying the client-side
@@ -4365,7 +3964,7 @@
             // There are clients waiting to receive thumbnails so, in case
             // this is an activity that someone is waiting for, add it
             // to the pending list so we can correctly update the clients.
-            mCancelledThumbnails.add(r);
+            mService.mCancelledThumbnails.add(r);
         }
 
         // Get rid of any pending idle timeouts.
@@ -4388,10 +3987,6 @@
             here.fillInStackTrace();
             Slog.i(TAG, "Removing activity " + r + " from stack");
         }
-        final TaskRecord task = r.task;
-        if (task != null) {
-            task.removeActivity(r);
-        }
         mHistory.remove(r);
         r.takeFromHistory();
         removeTimeoutsForActivityLocked(r);
@@ -4576,7 +4171,7 @@
                     mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
                 }
 
-                int index = mHistory.indexOf(r);
+                int index = indexOfActivityLocked(r);
                 if (index >= 0) {
                     if (r.state == ActivityState.DESTROYING) {
                         cleanUpActivityLocked(r, true, false);
@@ -4590,15 +4185,15 @@
         }
     }
     
-    private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
-            ProcessRecord app, String listName) {
+    private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app,
+            String listName) {
         int i = list.size();
         if (DEBUG_CLEANUP) Slog.v(
             TAG, "Removing app " + app + " from list " + listName
             + " with " + i + " entries");
         while (i > 0) {
             i--;
-            ActivityRecord r = list.get(i);
+            ActivityRecord r = (ActivityRecord)list.get(i);
             if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
             if (r.app == app) {
                 if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
@@ -4624,7 +4219,7 @@
             TAG, "Removing app " + app + " from history with " + i + " entries");
         while (i > 0) {
             i--;
-            ActivityRecord r = mHistory.get(i);
+            ActivityRecord r = (ActivityRecord)mHistory.get(i);
             if (DEBUG_CLEANUP) Slog.v(
                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
             if (r.app == app) {
@@ -4692,7 +4287,6 @@
      * of the stack.
      */
     final void moveHomeToFrontLocked() {
-        newMoveHomeToFrontLocked();
         TaskRecord homeTask = null;
         for (int i=mHistory.size()-1; i>=0; i--) {
             ActivityRecord hr = mHistory.get(i);
@@ -4702,23 +4296,6 @@
             }
         }
         if (homeTask != null) {
-//            moveTaskToFrontLocked(homeTask, null, null);
-        }
-    }
-
-    final void newMoveHomeToFrontLocked() {
-        TaskRecord homeTask = null;
-        for (int taskNdx = mTaskHistory.size() - 1; homeTask == null && taskNdx >= 0; --taskNdx) {
-            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
-            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                final ActivityRecord r = activities.get(activityNdx);
-                if (r.isHomeActivity) {
-                    homeTask = r.task;
-                    break;
-                }
-            }
-        }
-        if (homeTask != null) {
             moveTaskToFrontLocked(homeTask, null, null);
         }
     }
@@ -4735,39 +4312,32 @@
         mService.mWindowManager.prepareAppTransition(transit, false);
     }
 
-    final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
-        for (int i = mHistory.size() - 1; i >= 0; i--) {
-            ActivityRecord hr = mHistory.get(i);
-            if (hr.task.taskId == taskId) {
-                if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
-                    mUserLeaving = true;
-                }
-                if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
-                    // Caller wants the home activity moved with it.  To accomplish this,
-                    // we'll just move the home task to the top first.
-                    moveHomeToFrontLocked();
-                }
-                moveTaskToFrontLocked(hr.task, null, options);
-                return true;
-            }
-        }
-        return false;
-    }
-
     final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
+        if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
 
         final int task = tr.taskId;
         int top = mHistory.size()-1;
 
         if (top < 0 || (mHistory.get(top)).task.taskId == task) {
             // nothing to do!
+            if (reason != null &&
+                    (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+                ActivityOptions.abort(options);
+            } else {
+                updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
+            }
             return;
         }
 
+        ArrayList<IBinder> moved = new ArrayList<IBinder>();
+
+        // Applying the affinities may have removed entries from the history,
+        // so get the size again.
+        top = mHistory.size()-1;
+        int pos = top;
 
         // Shift all activities with this task up to the top
         // of the stack, keeping them in the same internal order.
-        int pos = top;
         while (pos >= 0) {
             ActivityRecord r = mHistory.get(pos);
             if (localLOGV) Slog.v(
@@ -4781,37 +4351,18 @@
                 }
                 mHistory.remove(pos);
                 mHistory.add(top, r);
+                moved.add(0, r.appToken);
                 top--;
             }
             pos--;
         }
-        //
-        // Start new code here! Delete everything above.
-        //
-        if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
 
-        final int numTasks = mTaskHistory.size();
-        final int index = mTaskHistory.indexOf(tr);
-        if (numTasks == 0 || index < 0 || index == numTasks - 1)  {
-            // nothing to do!
-            if (reason != null &&
-                    (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-                ActivityOptions.abort(options);
-            } else {
-                updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
-            }
-            return;
-        }
-
-        // Shift all activities with this task up to the top
-        // of the stack, keeping them in the same internal order.
-        mTaskHistory.remove(tr);
-        mTaskHistory.add(tr);
-
-        if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
+        if (DEBUG_TRANSITION) Slog.v(TAG,
+                "Prepare to front transition: task=" + tr);
         if (reason != null &&
                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-            mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+            mService.mWindowManager.prepareAppTransition(
+                    AppTransition.TRANSIT_NONE, false);
             ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
@@ -4820,18 +4371,14 @@
         } else {
             updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
         }
-
-        mService.mWindowManager.moveTaskToTop(task);
-
-        finishTaskMoveLocked(task);
-        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task);
-
+        
+        mService.mWindowManager.moveAppTokensToTop(moved);
         if (VALIDATE_TOKENS) {
             validateAppTokensLocked();
         }
-        if (VALIDATE_TASK_REPLACE) {
-            verifyActivityRecords(true);
-        }
+
+        finishTaskMoveLocked(task);
+        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task);
     }
 
     private final void finishTaskMoveLocked(int task) {
@@ -4851,7 +4398,7 @@
      */
     final boolean moveTaskToBackLocked(int task, ActivityRecord reason) {
         Slog.i(TAG, "moveTaskToBack: " + task);
-
+        
         // If we have a watcher, preflight the move before committing to it.  First check
         // for *other* available tasks, but if none are available, then try again allowing the
         // current task to be selected.
@@ -4874,14 +4421,11 @@
             }
         }
 
+        ArrayList<IBinder> moved = new ArrayList<IBinder>();
+
         if (DEBUG_TRANSITION) Slog.v(TAG,
                 "Prepare to back transition: task=" + task);
-
-        final TaskRecord tr = mTaskIdToTaskRecord.get(task);
-        mTaskHistory.remove(tr);
-        mTaskHistory.add(0, tr);
-
-        // BEGIN REGION TO REMOVE.
+        
         final int N = mHistory.size();
         int bottom = 0;
         int pos = 0;
@@ -4902,18 +4446,16 @@
                 }
                 mHistory.remove(pos);
                 mHistory.add(bottom, r);
+                moved.add(r.appToken);
                 bottom++;
             }
             pos++;
         }
-        if (VALIDATE_TASK_REPLACE) {
-            verifyActivityRecords(true);
-        }
-        // END REGION TO REMOVE
 
         if (reason != null &&
                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-            mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
+            mService.mWindowManager.prepareAppTransition(
+                    AppTransition.TRANSIT_NONE, false);
             ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
@@ -4922,8 +4464,7 @@
             mService.mWindowManager.prepareAppTransition(
                     AppTransition.TRANSIT_TASK_TO_BACK, false);
         }
-        mService.mWindowManager.moveTaskToBottom(task);
-
+        mService.mWindowManager.moveAppTokensToBottom(moved);
         if (VALIDATE_TOKENS) {
             validateAppTokensLocked();
         }
@@ -4956,8 +4497,9 @@
         TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true);
         if (info.numSubThumbbails <= 0) {
             return info.mainThumbnail != null ? info.mainThumbnail : tr.lastThumbnail;
+        } else {
+            return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
         }
-        return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
     }
 
     public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
@@ -5037,7 +4579,6 @@
         }
         if (thumbs.numSubThumbbails > 0) {
             thumbs.retriever = new IThumbnailRetriever.Stub() {
-                @Override
                 public Bitmap getThumbnail(int index) {
                     if (index < 0 || index >= thumbs.subtasks.size()) {
                         return null;
@@ -5236,283 +4777,4 @@
     public void dismissKeyguardOnNextActivityLocked() {
         mDismissKeyguardOnNextActivity = true;
     }
-
-    boolean willActivityBeVisibleLocked(IBinder token) {
-        int i;
-        for (i = mHistory.size() - 1; i >= 0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            if (r.appToken == token) {
-                    return true;
-            }
-            if (r.fullscreen && !r.finishing) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    void closeSystemDialogsLocked() {
-        for (int i = mHistory.size() - 1; i >= 0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
-                r.stack.finishActivityLocked(r, i,
-                        Activity.RESULT_CANCELED, null, "close-sys", true);
-            }
-        }
-    }
-
-    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
-        boolean didSomething = false;
-        TaskRecord lastTask = null;
-        final int N = mHistory.size();
-        for (int i = 0; i < N; i++) {
-            ActivityRecord r = mHistory.get(i);
-            final boolean samePackage = r.packageName.equals(name)
-                    || (name == null && r.userId == userId);
-            if ((userId == UserHandle.USER_ALL || r.userId == userId)
-                    && (samePackage || r.task == lastTask)
-                    && (r.app == null || evenPersistent || !r.app.persistent)) {
-                if (!doit) {
-                    if (r.finishing) {
-                        // If this activity is just finishing, then it is not
-                        // interesting as far as something to stop.
-                        continue;
-                    }
-                    return true;
-                }
-                didSomething = true;
-                Slog.i(TAG, "  Force finishing activity " + r);
-                if (samePackage) {
-                    if (r.app != null) {
-                        r.app.removed = true;
-                    }
-                    r.app = null;
-                }
-                lastTask = r.task;
-                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
-                        null, "force-stop", true)) {
-                    i--;
-                }
-            }
-        }
-        return didSomething;
-    }
-
-    ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
-        PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
-        ActivityRecord topRecord = null;
-        int pos = mHistory.size() - 1;
-        ActivityRecord next = pos >= 0 ? mHistory.get(pos) : null;
-        ActivityRecord top = null;
-        TaskRecord curTask = null;
-        int numActivities = 0;
-        int numRunning = 0;
-        while (pos >= 0 && maxNum > 0) {
-            final ActivityRecord r = next;
-            pos--;
-            next = pos >= 0 ? mHistory.get(pos) : null;
-
-            // Initialize state for next task if needed.
-            if (top == null || (top.state == ActivityState.INITIALIZING && top.task == r.task)) {
-                top = r;
-                curTask = r.task;
-                numActivities = numRunning = 0;
-            }
-
-            // Add 'r' into the current task.
-            numActivities++;
-            if (r.app != null && r.app.thread != null) {
-                numRunning++;
-            }
-
-            if (localLOGV) Slog.v(
-                TAG, r.intent.getComponent().flattenToShortString()
-                + ": task=" + r.task);
-
-            // If the next one is a different task, generate a new
-            // TaskInfo entry for what we have.
-            if (next == null || next.task != curTask) {
-                RunningTaskInfo ci = new RunningTaskInfo();
-                ci.id = curTask.taskId;
-                ci.baseActivity = r.intent.getComponent();
-                ci.topActivity = top.intent.getComponent();
-                if (top.thumbHolder != null) {
-                    ci.description = top.thumbHolder.lastDescription;
-                }
-                ci.numActivities = numActivities;
-                ci.numRunning = numRunning;
-                //System.out.println(
-                //    "#" + maxNum + ": " + " descr=" + ci.description);
-                if (receiver != null) {
-                    if (localLOGV) Slog.v(
-                        TAG, "State=" + top.state + "Idle=" + top.idle
-                        + " app=" + top.app
-                        + " thr=" + (top.app != null ? top.app.thread : null));
-                    if (top.state == ActivityState.RESUMED || top.state == ActivityState.PAUSING) {
-                        if (top.idle && top.app != null && top.app.thread != null) {
-                            topRecord = top;
-                        } else {
-                            top.thumbnailNeeded = true;
-                        }
-                    }
-                    pending.pendingRecords.add(top);
-                }
-                list.add(ci);
-                maxNum--;
-                top = null;
-            }
-        }
-        return topRecord;
-    }
-
-    public void unhandledBackLocked() {
-        int top = mHistory.size() - 1;
-        if (DEBUG_SWITCH) Slog.d(
-            TAG, "Performing unhandledBack(): top activity at " + top);
-        if (top > 0) {
-            finishActivityLocked(mHistory.get(top),
-                        top, Activity.RESULT_CANCELED, null, "unhandled-back", true);
-        }
-    }
-
-    void handleAppCrashLocked(ProcessRecord app) {
-        for (int i = mHistory.size() - 1; i >= 0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            if (r.app == app) {
-                Slog.w(TAG, "  Force finishing activity "
-                    + r.intent.getComponent().flattenToShortString());
-                r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
-                        null, "crashed", false);
-            }
-        }
-    }
-
-    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
-            boolean dumpClient, String dumpPackage) {
-        ActivityManagerService.dumpHistoryList(fd, pw, mHistory, "  ", "Hist", true, !dumpAll,
-            dumpClient, dumpPackage);
-    }
-
-    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
-        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
-
-        if ("all".equals(name)) {
-            for (ActivityRecord r1 : mHistory) {
-                activities.add(r1);
-            }
-        } else if ("top".equals(name)) {
-            final int N = mHistory.size();
-            if (N > 0) {
-                activities.add(mHistory.get(N-1));
-            }
-        } else {
-            ItemMatcher matcher = new ItemMatcher();
-            matcher.build(name);
-
-            for (ActivityRecord r1 : mHistory) {
-                if (matcher.match(r1, r1.intent.getComponent())) {
-                    activities.add(r1);
-                }
-            }
-        }
-
-        return activities;
-    }
-
-    ActivityRecord restartPackage(String packageName) {
-        ActivityRecord starting = topRunningActivityLocked(null);
-
-        // All activities that came from the package must be
-        // restarted as if there was a config change.
-        for (int i = mHistory.size() - 1; i >= 0; i--) {
-            ActivityRecord a = mHistory.get(i);
-            if (a.info.packageName.equals(packageName)) {
-                a.forceNewConfig = true;
-                if (starting != null && a == starting && a.visible) {
-                    a.startFreezingScreenLocked(starting.app, ActivityInfo.CONFIG_SCREEN_LAYOUT);
-                }
-            }
-        }
-
-        return starting;
-    }
-
-    void rebuildTaskHistory() {
-        mTaskHistory.clear();
-        final int numActivities = mHistory.size();
-        TaskRecord task = null;
-        for (int i = 0; i < numActivities; ++i) {
-            final ActivityRecord r = mHistory.get(i);
-            if (r.task != task) {
-                task = r.task;
-                task.mActivities.clear();
-                mTaskHistory.add(task);
-            }
-            task.mActivities.add(r);
-        }
-    }
-
-    boolean verifyActivityRecords(boolean rebuild) {
-        final int numHistory = mHistory.size();
-        int historyNdx = 0;
-
-        final int numTasks = mTaskHistory.size();
-        int taskNdx;
-        for (taskNdx = historyNdx = 0; taskNdx < numTasks; ++taskNdx) {
-            final TaskRecord task = mTaskHistory.get(taskNdx);
-            final ArrayList<ActivityRecord> activities = task.mActivities;
-            final int numActivities = activities.size();
-            int activityNdx;
-            for (activityNdx = 0;
-                    activityNdx < numActivities && historyNdx < numHistory;
-                    ++activityNdx, ++historyNdx) {
-                ActivityRecord r1 = mHistory.get(historyNdx);
-                ActivityRecord r2 = activities.get(activityNdx);
-                if (r1 != r2) {
-                    break;
-                }
-            }
-            if (activityNdx != numActivities) {
-                // either a mismatch or mHistory ran out before mTaskHistory.
-                break;
-            }
-        }
-        if (taskNdx != numTasks || historyNdx != numHistory) {
-            logHistories("verifyActivityRecords", rebuild);
-            return true;
-        }
-        return false;
-    }
-
-    private void logHistories(String caller, boolean rebuild) {
-        Slog.w(TAG, "Mismatch! " + caller + "  mHistory=" + mHistory);
-        ArrayList<ArrayList<ActivityRecord>> nestedRecords =
-                new ArrayList<ArrayList<ActivityRecord>>();
-        for (TaskRecord task : mTaskHistory) {
-            nestedRecords.add(task.mActivities);
-        }
-        Slog.w(TAG, "Mismatch! " + caller + " mTaskHistory" + nestedRecords);
-        Slog.w(TAG, "Mismatch! " + caller + " lastHistoryModifier=" + mLastHistoryModifier
-                + " Caller=" + Debug.getCallers(4));
-        if (rebuild) {
-            rebuildTaskHistory();
-        }
-    }
-
-    private TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
-            boolean toTop) {
-        TaskRecord oldTask = mTaskIdToTaskRecord.get(taskId);
-        if (oldTask != null) {
-            Slog.w(TAG, "createTaskRecord: Reusing taskId=" + taskId + " without removing");
-            mTaskHistory.remove(oldTask);
-        }
-        TaskRecord task = new TaskRecord(taskId, info, intent);
-        mTaskIdToTaskRecord.put(taskId, task);
-        if (toTop) {
-            mTaskHistory.add(task);
-        } else {
-            mTaskHistory.add(0, task);
-        }
-        return task;
-    }
 }
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index 863bdad..3a6492e 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -295,8 +295,20 @@
             Message msg = mHandler.obtainMessage(MSG_WRITE);
             mHandler.sendMessageDelayed(msg, 10000);
 
-            
-            ActivityRecord starting = mService.mMainStack.restartPackage(packageName);
+            ActivityRecord starting = mService.mMainStack.topRunningActivityLocked(null);
+
+            // All activities that came from the package must be
+            // restarted as if there was a config change.
+            for (int i=mService.mMainStack.mHistory.size()-1; i>=0; i--) {
+                ActivityRecord a = (ActivityRecord)mService.mMainStack.mHistory.get(i);
+                if (a.info.packageName.equals(packageName)) {
+                    a.forceNewConfig = true;
+                    if (starting != null && a == starting && a.visible) {
+                        a.startFreezingScreenLocked(starting.app,
+                                ActivityInfo.CONFIG_SCREEN_LAYOUT);
+                    }
+                }
+            }
 
             // Tell all processes that loaded this package about the change.
             for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
diff --git a/services/java/com/android/server/am/PendingThumbnailsRecord.java b/services/java/com/android/server/am/PendingThumbnailsRecord.java
index c460791..ed478c9 100644
--- a/services/java/com/android/server/am/PendingThumbnailsRecord.java
+++ b/services/java/com/android/server/am/PendingThumbnailsRecord.java
@@ -27,13 +27,13 @@
 class PendingThumbnailsRecord
 {
     final IThumbnailReceiver receiver;   // who is waiting.
-    final HashSet<ActivityRecord> pendingRecords; // HistoryRecord objects we still wait for.
+    HashSet pendingRecords; // HistoryRecord objects we still wait for.
     boolean finished;       // Is pendingRecords empty?
 
     PendingThumbnailsRecord(IThumbnailReceiver _receiver)
     {
         receiver = _receiver;
-        pendingRecords = new HashSet<ActivityRecord>();
+        pendingRecords = new HashSet();
         finished = false;
     }
 }
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index f9b0d4c..1bae9ca 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -23,7 +23,6 @@
 import android.util.Slog;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 class TaskRecord extends ThumbnailHolder {
     final int taskId;       // Unique identifier for this task.
@@ -40,11 +39,7 @@
 
     String stringName;      // caching of toString() result.
     int userId;             // user for which this task was created
-
-    int numFullscreen;      // Number of fullscreen activities.
-
-    final ArrayList<ActivityRecord> mActivities = new ArrayList<ActivityRecord>();
-
+    
     TaskRecord(int _taskId, ActivityInfo info, Intent _intent) {
         taskId = _taskId;
         affinity = info.taskAffinity;
@@ -109,63 +104,12 @@
             userId = UserHandle.getUserId(info.applicationInfo.uid);
         }
     }
-
-    ActivityRecord getTopActivity() {
-        for (int i = mActivities.size() - 1; i >= 0; --i) {
-            final ActivityRecord r = mActivities.get(i);
-            if (r.finishing) {
-                continue;
-            }
-            return r;
-        }
-        return null;
-    }
-
-    void addActivityAtBottom(ActivityRecord r) {
-        if (!mActivities.remove(r) && r.fullscreen) {
-            // Was not previously in list.
-            numFullscreen++;
-        }
-        mActivities.add(0, r);
-    }
-
-    void addActivityToTop(ActivityRecord r) {
-        if (!mActivities.remove(r) && r.fullscreen) {
-            // Was not previously in list.
-            numFullscreen++;
-        }
-        // TODO: This only matters to achieve identical results as mHistory. Later we won't need
-        // to skip over finishing activities.
-        int i;
-        for (i = mActivities.size() - 1; i >= 0; --i) {
-            if (!mActivities.get(i).finishing) {
-                break;
-            }
-        }
-        if (i >= 0) {
-            // Add below finishing activities.
-            mActivities.add(i + 1, r);
-        } else {
-            // All activities are finishing, add to top.
-            mActivities.add(r);
-        }
-    }
-
-    /** @return true if this was the last activity in the task */
-    boolean removeActivity(ActivityRecord r) {
-        if (mActivities.remove(r) && r.fullscreen) {
-            // Was previously in list.
-            numFullscreen--;
-        }
-        return mActivities.size() == 0;
-    }
-
+    
     void dump(PrintWriter pw, String prefix) {
         if (numActivities != 0 || rootWasReset || userId != 0) {
             pw.print(prefix); pw.print("numActivities="); pw.print(numActivities);
                     pw.print(" rootWasReset="); pw.print(rootWasReset);
-                    pw.print(" userId="); pw.print(userId);
-                    pw.print(" numFullscreen="); pw.println(numFullscreen);
+                    pw.print(" userId="); pw.println(userId);
         }
         if (affinity != null) {
             pw.print(prefix); pw.print("affinity="); pw.println(affinity);
@@ -192,7 +136,6 @@
             pw.print(prefix); pw.print("realActivity=");
             pw.println(realActivity.flattenToShortString());
         }
-        pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
         if (!askedCompatMode) {
             pw.print(prefix); pw.print("askedCompatMode="); pw.println(askedCompatMode);
         }
@@ -203,7 +146,6 @@
                 pw.print((getInactiveDuration()/1000)); pw.println("s)");
     }
 
-    @Override
     public String toString() {
         if (stringName != null) {
             return stringName;
@@ -214,21 +156,19 @@
         sb.append(" #");
         sb.append(taskId);
         if (affinity != null) {
-            sb.append(" A=");
+            sb.append(" A ");
             sb.append(affinity);
         } else if (intent != null) {
-            sb.append(" I=");
+            sb.append(" I ");
             sb.append(intent.getComponent().flattenToShortString());
         } else if (affinityIntent != null) {
-            sb.append(" aI=");
+            sb.append(" aI ");
             sb.append(affinityIntent.getComponent().flattenToShortString());
         } else {
             sb.append(" ??");
         }
-        sb.append(" U=");
+        sb.append(" U ");
         sb.append(userId);
-        sb.append(" sz=");
-        sb.append(mActivities.size());
         sb.append('}');
         return stringName = sb.toString();
     }
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 8cc1d02..fbb5013 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -30,10 +30,6 @@
 import android.view.WindowManager;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-
-class AppTokenList extends ArrayList<AppWindowToken> {
-}
 
 /**
  * Version of WindowToken that is specifically for a particular application (or
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 6aae202..59e4b0e 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -16,17 +16,11 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR;
-import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR;
-
-import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
 
 class DisplayContentList extends ArrayList<DisplayContent> {
 }
@@ -39,7 +33,6 @@
  * WindowManagerService.mWindowMap.
  */
 class DisplayContent {
-//    private final static String TAG = "DisplayContent";
 
     /** Unique identifier of this stack. */
     private final int mDisplayId;
@@ -74,26 +67,6 @@
     final boolean isDefaultDisplay;
 
     /**
-     * Window tokens that are in the process of exiting, but still
-     * on screen for animations.
-     */
-    final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
-
-    /**
-     * Application tokens that are in the process of exiting, but still
-     * on screen for animations.
-     */
-    final AppTokenList mExitingAppTokens = new AppTokenList();
-
-    /**
-     * Sorted most recent at top, oldest at [0].
-     */
-    ArrayList<TaskList> mTaskLists = new ArrayList<TaskList>();
-    SparseArray<TaskList> mTaskIdToTaskList = new SparseArray<TaskList>();
-
-    private final AppTokenIterator mTmpAppIterator = new AppTokenIterator();
-
-    /**
      * @param display May not be null.
      */
     DisplayContent(Display display) {
@@ -123,147 +96,6 @@
         mDisplay.getDisplayInfo(mDisplayInfo);
     }
 
-    /**
-     *  Find the location to insert a new AppWindowToken into the window-ordered app token list.
-     * @param addPos The location the token was inserted into in mAppTokens.
-     * @param wtoken The token to insert.
-     */
-    void addAppToken(final int addPos, final AppWindowToken wtoken) {
-        TaskList task = mTaskIdToTaskList.get(wtoken.groupId);
-        if (task == null) {
-            task = new TaskList(wtoken, this);
-            mTaskIdToTaskList.put(wtoken.groupId, task);
-            mTaskLists.add(task);
-        } else {
-            task.mAppTokens.add(addPos, wtoken);
-        }
-    }
-
-    void removeAppToken(final AppWindowToken wtoken) {
-        final int taskId = wtoken.groupId;
-        final TaskList task = mTaskIdToTaskList.get(taskId);
-        if (task != null) {
-            AppTokenList appTokens = task.mAppTokens;
-            appTokens.remove(wtoken);
-            if (appTokens.size() == 0) {
-                mTaskLists.remove(task);
-                mTaskIdToTaskList.delete(taskId);
-            }
-        }
-    }
-
-    void setAppTaskId(AppWindowToken wtoken, int newTaskId) {
-        final int taskId = wtoken.groupId;
-        TaskList task = mTaskIdToTaskList.get(taskId);
-        if (task != null) {
-            AppTokenList appTokens = task.mAppTokens;
-            appTokens.remove(wtoken);
-            if (appTokens.size() == 0) {
-                mTaskIdToTaskList.delete(taskId);
-            }
-        }
-
-        task = mTaskIdToTaskList.get(newTaskId);
-        if (task == null) {
-            task = new TaskList(wtoken, this);
-            mTaskIdToTaskList.put(newTaskId, task);
-        } else {
-            task.mAppTokens.add(wtoken);
-        }
-
-        wtoken.groupId = newTaskId;
-    }
-
-    /**
-     * Return the utility iterator so we don't have to construct new iterators every time we
-     * iterate.
-     * NOTE: Do not ever nest this call or you will have a bad time!
-     * @param reverse Direction of iterator.
-     * @return The utility iterator.
-     */
-    AppTokenIterator getTmpAppIterator(boolean reverse) {
-        mTmpAppIterator.reset(reverse);
-        return mTmpAppIterator;
-    }
-
-    class AppTokenIterator implements Iterator<AppWindowToken> {
-        boolean mReverse;
-        int mTasksNdx;
-        int mActivityNdx;
-        TaskList mTaskList;
-
-        public AppTokenIterator() {
-            this(FORWARD_ITERATOR);
-        }
-
-        public AppTokenIterator(boolean reverse) {
-            reset(reverse);
-        }
-
-        void reset(boolean reverse) {
-            mReverse = reverse;
-            mTasksNdx = reverse ? mTaskLists.size() - 1 : 0;
-            getNextTaskList();
-        }
-
-        private void getNextTaskList() {
-            if (mReverse) {
-                if (mTasksNdx >= 0) {
-                    mTaskList = mTaskLists.get(mTasksNdx);
-                    --mTasksNdx;
-                    mActivityNdx = mTaskList.mAppTokens.size() - 1;
-                }
-            } else {
-                if (mTasksNdx < mTaskLists.size()) {
-                    mTaskList = mTaskLists.get(mTasksNdx);
-                    ++mTasksNdx;
-                    mActivityNdx = 0;
-                }
-            }
-        }
-
-        @Override
-        public boolean hasNext() {
-            if (mTaskList == null) {
-                return false;
-            }
-            if (mReverse) {
-                return mActivityNdx >= 0;
-            }
-            return mActivityNdx < mTaskList.mAppTokens.size();
-        }
-
-        @Override
-        public AppWindowToken next() {
-            if (hasNext()) {
-                AppWindowToken wtoken = mTaskList.mAppTokens.get(mActivityNdx);
-                mActivityNdx += mReverse ? -1 : 1;
-                if (!hasNext()) {
-                    getNextTaskList();
-                }
-                return wtoken;
-            }
-            throw new NoSuchElementException();
-        }
-
-        @Override
-        public void remove() {
-            throw new IllegalArgumentException();
-        }
-
-        int size() {
-            int size = 0;
-            for (int i = mTaskLists.size() - 1; i >= 0; --i) {
-                size += mTaskLists.get(i).mAppTokens.size();
-            }
-            return size;
-        }
-
-        @Override public String toString() {
-            return mTaskLists.toString();
-        }
-    }
-
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
         final String subPrefix = "  " + prefix;
@@ -287,51 +119,7 @@
             pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
             pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
             pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
-            pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
-            AppTokenIterator iterator = getTmpAppIterator(REVERSE_ITERATOR);
-            int ndx = iterator.size() - 1;
-            if (ndx >= 0) {
-                pw.println();
-                pw.println("  Application tokens in Z order:");
-                while (iterator.hasNext()) {
-                    AppWindowToken wtoken = iterator.next();
-                    pw.print("  App #"); pw.print(ndx--);
-                            pw.print(' '); pw.print(wtoken); pw.println(":");
-                    wtoken.dump(pw, "    ");
-                }
-            }
-            if (mExitingTokens.size() > 0) {
-                pw.println();
-                pw.println("  Exiting tokens:");
-                for (int i=mExitingTokens.size()-1; i>=0; i--) {
-                    WindowToken token = mExitingTokens.get(i);
-                    pw.print("  Exiting #"); pw.print(i);
-                    pw.print(' '); pw.print(token);
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                }
-            }
-            if (mExitingAppTokens.size() > 0) {
-                pw.println();
-                pw.println("  Exiting application tokens:");
-                for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
-                    WindowToken token = mExitingAppTokens.get(i);
-                    pw.print("  Exiting App #"); pw.print(i);
-                      pw.print(' '); pw.print(token);
-                      pw.println(':');
-                      token.dump(pw, "    ");
-                }
-            }
-            if (mTaskIdToTaskList.size() > 0) {
-                pw.println();
-                for (int i = 0; i < mTaskIdToTaskList.size(); ++i) {
-                    pw.print("  TaskList #"); pw.print(i);
-                      pw.print(" taskId="); pw.println(mTaskIdToTaskList.keyAt(i));
-                    pw.print("    mAppTokens=");
-                      pw.println(mTaskIdToTaskList.valueAt(i).mAppTokens);
-                    pw.println();
-                }
-            }
+        pw.print(subPrefix); pw.print("layoutNeeded="); pw.print(layoutNeeded);
         pw.println();
     }
 }
diff --git a/services/java/com/android/server/wm/TaskGroup.java b/services/java/com/android/server/wm/TaskGroup.java
deleted file mode 100644
index 1f1dd58..0000000
--- a/services/java/com/android/server/wm/TaskGroup.java
+++ /dev/null
@@ -1,31 +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.server.wm;
-
-import android.view.IApplicationToken;
-
-import java.util.ArrayList;
-
-public class TaskGroup {
-    public int taskId = -1;
-    public ArrayList<IApplicationToken> tokens = new ArrayList<IApplicationToken>();
-
-    @Override
-    public String toString() {
-        return "id=" + taskId + " tokens=" + tokens;
-    }
-}
diff --git a/services/java/com/android/server/wm/TaskList.java b/services/java/com/android/server/wm/TaskList.java
deleted file mode 100644
index 67dfa4f..0000000
--- a/services/java/com/android/server/wm/TaskList.java
+++ /dev/null
@@ -1,35 +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.server.wm;
-
-class TaskList {
-//    private final String TAG = "TaskGroup";
-    DisplayContent mDisplayContent;
-    final AppTokenList mAppTokens = new AppTokenList();
-    final int taskId;
-
-    TaskList(AppWindowToken wtoken, DisplayContent displayContent) {
-        taskId = wtoken.groupId;
-        mAppTokens.add(wtoken);
-        mDisplayContent = displayContent;
-    }
-
-    @Override
-    public String toString() {
-        return "id=" + taskId + " appTokens=" + mAppTokens;
-    }
-}
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 67daf75..3964782 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -10,8 +10,6 @@
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
-import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR;
-import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR;
 
 import android.content.Context;
 import android.os.Debug;
@@ -28,7 +26,6 @@
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 
-import com.android.server.wm.DisplayContent.AppTokenIterator;
 import com.android.server.wm.WindowManagerService.DisplayContentsIterator;
 import com.android.server.wm.WindowManagerService.LayoutFields;
 
@@ -175,12 +172,12 @@
         }
     }
 
-    private void updateAppWindowsLocked(int displayId) {
+    private void updateAppWindowsLocked() {
         int i;
-        final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
-        while (iterator.hasNext()) {
-            final AppWindowAnimator appAnimator = iterator.next().mAppAnimator;
+        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+        final int NAT = appTokens.size();
+        for (i=0; i<NAT; i++) {
+            final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
             final boolean wasAnimating = appAnimator.animation != null
                     && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
             if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -194,10 +191,9 @@
             }
         }
 
-        final AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
-        final int NEAT = exitingAppTokens.size();
+        final int NEAT = mService.mExitingAppTokens.size();
         for (i=0; i<NEAT; i++) {
-            final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
+            final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator;
             final boolean wasAnimating = appAnimator.animation != null
                     && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
             if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -458,13 +454,13 @@
 
     /** See if any windows have been drawn, so they (and others associated with them) can now be
      *  shown. */
-    private void testTokenMayBeDrawnLocked(int displayId) {
+    private void testTokenMayBeDrawnLocked() {
         // See if any windows have been drawn, so they (and others
         // associated with them) can now be shown.
-        AppTokenIterator iterator =
-                mService.getDisplayContentLocked(displayId).getTmpAppIterator(FORWARD_ITERATOR);
-        while (iterator.hasNext()) {
-            AppWindowToken wtoken = iterator.next();
+        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+        final int NT = appTokens.size();
+        for (int i=0; i<NT; i++) {
+            AppWindowToken wtoken = appTokens.get(i);
             AppWindowAnimator appAnimator = wtoken.mAppAnimator;
             final boolean allDrawn = wtoken.allDrawn;
             if (allDrawn != appAnimator.allDrawn) {
@@ -534,10 +530,11 @@
         SurfaceControl.openTransaction();
         SurfaceControl.setAnimationTransaction();
         try {
+            updateAppWindowsLocked();
+
             final int numDisplays = mDisplayContentsAnimators.size();
             for (int i = 0; i < numDisplays; i++) {
                 final int displayId = mDisplayContentsAnimators.keyAt(i);
-                updateAppWindowsLocked(displayId);
                 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
 
                 final ScreenRotationAnimation screenRotationAnimation =
@@ -563,11 +560,10 @@
                 }
             }
 
+            testTokenMayBeDrawnLocked();
+
             for (int i = 0; i < numDisplays; i++) {
                 final int displayId = mDisplayContentsAnimators.keyAt(i);
-
-                testTokenMayBeDrawnLocked(displayId);
-
                 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
 
                 final ScreenRotationAnimation screenRotationAnimation =
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 086da37..a6ce54c 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -58,7 +58,6 @@
 import com.android.server.input.InputManagerService;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
-import com.android.server.wm.DisplayContent.AppTokenIterator;
 
 import android.Manifest;
 import android.app.ActivityManagerNative;
@@ -182,7 +181,7 @@
     static final boolean DEBUG_INPUT_METHOD = false;
     static final boolean DEBUG_VISIBILITY = false;
     static final boolean DEBUG_WINDOW_MOVEMENT = false;
-    static final boolean DEBUG_TOKEN_MOVEMENT = true;
+    static final boolean DEBUG_TOKEN_MOVEMENT = false;
     static final boolean DEBUG_ORIENTATION = false;
     static final boolean DEBUG_APP_ORIENTATION = false;
     static final boolean DEBUG_CONFIGURATION = false;
@@ -198,7 +197,6 @@
     static final boolean DEBUG_LAYOUT_REPEATS = true;
     static final boolean DEBUG_SURFACE_TRACE = false;
     static final boolean DEBUG_WINDOW_TRACE = false;
-    static final boolean DEBUG_TASK_MOVEMENT = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -208,9 +206,6 @@
     static final boolean PROFILE_ORIENTATION = false;
     static final boolean localLOGV = DEBUG;
 
-    final static boolean REVERSE_ITERATOR = true;
-    final static boolean FORWARD_ITERATOR = false;
-
     /** How much to multiply the policy's type layer, to reserve room
      * for multiple windows of the same type and Z-ordering adjustment
      * with TYPE_LAYER_OFFSET. */
@@ -337,7 +332,34 @@
     /**
      * Mapping from a token IBinder to a WindowToken object.
      */
-    final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>();
+    final HashMap<IBinder, WindowToken> mTokenMap =
+            new HashMap<IBinder, WindowToken>();
+
+    /**
+     * Window tokens that are in the process of exiting, but still
+     * on screen for animations.
+     */
+    final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
+
+    /**
+     * List controlling the ordering of windows in different applications which must
+     * be kept in sync with ActivityManager.
+     */
+    final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
+
+    /**
+     * AppWindowTokens in the Z order they were in at the start of an animation. Between
+     * animations this list is maintained in the exact order of mAppTokens. If tokens
+     * are added to mAppTokens during an animation an attempt is made to insert them at the same
+     * logical location in this list. Note that this list is always in sync with mWindows.
+     */
+    ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
+
+    /**
+     * Application tokens that are in the process of exiting, but still
+     * on screen for animations.
+     */
+    final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
 
     /**
      * List of window tokens that have finished starting their application,
@@ -422,12 +444,8 @@
 
     String mLastANRState;
 
-    /** All DisplayContents in the world, kept here */
+    /** All DisplayDontents in the world, kept here */
     private SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
-    private SparseArray<DisplayContent> mTaskIdToDisplayContents =
-            new SparseArray<DisplayContent>();
-
-    private final AllWindowsIterator mTmpWindowsIterator = new AllWindowsIterator();
 
     int mRotation = 0;
     int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -901,6 +919,7 @@
         final WindowList windows = win.getWindowList();
         final int N = windows.size();
         final WindowState attached = win.mAttachedWindow;
+        int i;
         WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
         if (attached == null) {
             int tokenWindowsPos = 0;
@@ -950,11 +969,12 @@
                         + client.asBinder() + " (token=" + token + ")");
                     // Figure out where the window should go, based on the
                     // order of applications.
+                    final int NA = mAnimatingAppTokens.size();
                     WindowState pos = null;
-                    AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-                    while (iterator.hasNext()) {
-                        AppWindowToken t = iterator.next();
+                    for (i=NA-1; i>=0; i--) {
+                        AppWindowToken t = mAnimatingAppTokens.get(i);
                         if (t == token) {
+                            i--;
                             break;
                         }
 
@@ -987,14 +1007,15 @@
                     } else {
                         // Continue looking down until we find the first
                         // token that has windows on this display.
-                        while (iterator.hasNext()) {
-                            AppWindowToken t = iterator.next();
-                            tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
+                        while (i >= 0) {
+                            AppWindowToken t = mAnimatingAppTokens.get(i);
+                            tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
                             final int NW = tokenWindowList.size();
                             if (NW > 0) {
                                 pos = tokenWindowList.get(NW-1);
                                 break;
                             }
+                            i--;
                         }
                         if (pos != null) {
                             // Move in front of any windows attached to this
@@ -1013,8 +1034,7 @@
                         } else {
                             // Just search for the start of this layer.
                             final int myLayer = win.mBaseLayer;
-                            int i;
-                            for (i = 0; i < N; i++) {
+                            for (i=0; i<N; i++) {
                                 WindowState w = windows.get(i);
                                 if (w.mBaseLayer > myLayer) {
                                     break;
@@ -1032,8 +1052,7 @@
             } else {
                 // Figure out where window should go, based on layer.
                 final int myLayer = win.mBaseLayer;
-                int i;
-                for (i = N - 1; i >= 0; i--) {
+                for (i=N-1; i>=0; i--) {
                     if (windows.get(i).mBaseLayer <= myLayer) {
                         break;
                     }
@@ -1058,8 +1077,7 @@
             final int sublayer = win.mSubLayer;
             int largestSublayer = Integer.MIN_VALUE;
             WindowState windowWithLargestSublayer = null;
-            int i;
-            for (i = 0; i < NA; i++) {
+            for (i=0; i<NA; i++) {
                 WindowState w = tokenWindowList.get(i);
                 final int wSublayer = w.mSubLayer;
                 if (wSublayer >= largestSublayer) {
@@ -2464,15 +2482,22 @@
 
     public void updateAppOpsState() {
         synchronized(mWindowMap) {
-            mTmpWindowsIterator.reset(FORWARD_ITERATOR);
-            while (mTmpWindowsIterator.hasNext()) {
-                final WindowState win = mTmpWindowsIterator.next();
-                if (win.mAppOp != AppOpsManager.OP_NONE) {
-                    final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
-                            win.getOwningPackage());
-                    win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED);
+            boolean changed = false;
+            for (int i=0; i<mDisplayContents.size(); i++) {
+                DisplayContent display = mDisplayContents.valueAt(i);
+                WindowList windows = display.getWindowList();
+                for (int j=0; j<windows.size(); j++) {
+                    final WindowState win = windows.get(j);
+                    if (win.mAppOp != AppOpsManager.OP_NONE) {
+                        changed |= win.setAppOpVisibilityLw(mAppOps.checkOpNoThrow(win.mAppOp,
+                                win.getOwningUid(),
+                                win.getOwningPackage()) == AppOpsManager.MODE_ALLOWED);
+                    }
                 }
             }
+            if (changed) {
+                scheduleAnimationLocked();
+            }
         }
     }
 
@@ -3112,58 +3137,32 @@
     // Application Window Tokens
     // -------------------------------------------------------------
 
-    public void validateAppTokens(List<TaskGroup> tasks) {
-        synchronized (mWindowMap) {
-            int t = tasks.size() - 1;
-            if (t < 0) {
-                Slog.w(TAG, "validateAppTokens: empty task list");
-                return;
+    public void validateAppTokens(List<IBinder> tokens) {
+        int v = tokens.size()-1;
+        int m = mAppTokens.size()-1;
+        while (v >= 0 && m >= 0) {
+            AppWindowToken atoken = mAppTokens.get(m);
+            if (atoken.removed) {
+                m--;
+                continue;
             }
-
-            TaskGroup task = tasks.get(0);
-            int taskId = task.taskId;
-            DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId);
-            if (displayContent == null) {
-                Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
-                return;
+            if (tokens.get(v) != atoken.token) {
+                Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
+                      + " @ " + v + ", internal is " + atoken.token + " @ " + m);
             }
-
-            boolean mismatch = false;
-            AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-            for ( ; t >= 0 && !mismatch; --t) {
-                task = tasks.get(t);
-                List<IApplicationToken> tokens = task.tokens;
-                int v = task.tokens.size() - 1;
-
-                DisplayContent lastDisplayContent = displayContent;
-                displayContent = mTaskIdToDisplayContents.get(taskId);
-                if (displayContent != lastDisplayContent) {
-                    Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
-                    return;
-                }
-
-                while (v >= 0) {
-                    if (!iterator.hasNext()) {
-                        mismatch = true;
-                        break;
-                    }
-                    AppWindowToken atoken = iterator.next();
-                    if (atoken.removed) {
-                        continue;
-                    }
-                    if (tokens.get(v) != atoken.token) {
-                        mismatch = true;
-                        break;
-                    }
-                    v--;
-                }
+            v--;
+            m--;
+        }
+        while (v >= 0) {
+            Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
+            v--;
+        }
+        while (m >= 0) {
+            AppWindowToken atoken = mAppTokens.get(m);
+            if (!atoken.removed) {
+                Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m);
             }
-
-            if (mismatch || iterator.hasNext()) {
-                Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
-                Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + iterator);
-                Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
-            }
+            m--;
         }
     }
 
@@ -3227,7 +3226,6 @@
 
         final long origId = Binder.clearCallingIdentity();
         synchronized(mWindowMap) {
-            DisplayContent displayContent = null;
             WindowToken wtoken = mTokenMap.remove(token);
             if (wtoken != null) {
                 boolean delayed = false;
@@ -3237,7 +3235,6 @@
 
                     for (int i=0; i<N; i++) {
                         WindowState win = wtoken.windows.get(i);
-                        displayContent = win.mDisplayContent;
 
                         if (win.mWinAnimator.isAnimating()) {
                             delayed = true;
@@ -3247,12 +3244,13 @@
                             win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
                                     false);
                             //TODO (multidisplay): Magnification is supported only for the default
-                            if (mDisplayMagnifier != null && win.isDefaultDisplay()) {
+                            if (mDisplayMagnifier != null
+                                    && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
                                 mDisplayMagnifier.onWindowTransitionLocked(win,
                                         WindowManagerPolicy.TRANSIT_EXIT);
                             }
                             changed = true;
-                            displayContent.layoutNeeded = true;
+                            win.mDisplayContent.layoutNeeded = true;
                         }
                     }
 
@@ -3265,7 +3263,7 @@
                     }
 
                     if (delayed) {
-                        displayContent.mExitingTokens.add(wtoken);
+                        mExitingTokens.add(wtoken);
                     } else if (wtoken.windowType == TYPE_WALLPAPER) {
                         mWallpaperTokens.remove(wtoken);
                     }
@@ -3279,9 +3277,27 @@
         Binder.restoreCallingIdentity(origId);
     }
 
+    /**
+     *  Find the location to insert a new AppWindowToken into the window-ordered app token list.
+     *  Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
+     * @param addPos The location the token was inserted into in mAppTokens.
+     * @param atoken The token to insert.
+     */
+    private void addAppTokenToAnimating(final int addPos, final AppWindowToken atoken) {
+        if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
+            // It was inserted into the beginning or end of mAppTokens. Honor that.
+            mAnimatingAppTokens.add(addPos, atoken);
+            return;
+        }
+        // Find the item immediately above the mAppTokens insertion point and put the token
+        // immediately below that one in mAnimatingAppTokens.
+        final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
+        mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), atoken);
+    }
+
     @Override
     public void addAppToken(int addPos, IApplicationToken token,
-            int taskId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
+            int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "addAppToken()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3309,21 +3325,15 @@
             }
             atoken = new AppWindowToken(this, token);
             atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
-            atoken.groupId = taskId;
+            atoken.groupId = groupId;
             atoken.appFullscreen = fullscreen;
             atoken.showWhenLocked = showWhenLocked;
             atoken.requestedOrientation = requestedOrientation;
             if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
                     + " at " + addPos);
-
-            DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId);
-            if (displayContent == null) {
-                displayContent = getDefaultDisplayContentLocked();
-                mTaskIdToDisplayContents.put(taskId, displayContent);
-            }
-            displayContent.addAppToken(addPos, atoken);
+            mAppTokens.add(addPos, atoken);
+            addAppTokenToAnimating(addPos, atoken);
             mTokenMap.put(token.asBinder(), atoken);
-            mTaskIdToDisplayContents.put(taskId, displayContent);
 
             // Application tokens start out hidden.
             atoken.hidden = true;
@@ -3341,17 +3351,12 @@
         }
 
         synchronized(mWindowMap) {
-            final AppWindowToken atoken = findAppWindowToken(token);
+            AppWindowToken atoken = findAppWindowToken(token);
             if (atoken == null) {
                 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
                 return;
             }
-            DisplayContent displayContent = mTaskIdToDisplayContents.get(atoken.groupId);
-            if (displayContent == null) {
-                Slog.w(TAG, "setAppGroupId: No DisplayContent for taskId=" + atoken.groupId);
-                displayContent = getDefaultDisplayContentLocked();
-            }
-            displayContent.setAppTaskId(atoken, groupId);
+            atoken.groupId = groupId;
         }
     }
 
@@ -3397,11 +3402,8 @@
         boolean findingBehind = false;
         boolean haveGroup = false;
         boolean lastFullscreen = false;
-        // TODO: Multi window.
-        DisplayContent displayContent = getDefaultDisplayContentLocked();
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-        while (iterator.hasNext()) {
-            AppWindowToken atoken = iterator.next();
+        for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
+            AppWindowToken atoken = mAppTokens.get(pos);
 
             if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
 
@@ -4316,12 +4318,11 @@
                         TAG, "Removing app " + wtoken + " delayed=" + delayed
                         + " animation=" + wtoken.mAppAnimator.animation
                         + " animating=" + wtoken.mAppAnimator.animating);
-                DisplayContent displayContent = mTaskIdToDisplayContents.get(wtoken.groupId);
                 if (delayed) {
                     // set the token aside because it has an active animation to be finished
                     if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                             "removeAppToken make exiting: " + wtoken);
-                    displayContent.mExitingAppTokens.add(wtoken);
+                    mExitingAppTokens.add(wtoken);
                 } else {
                     // Make sure there is no animation running on this token,
                     // so any windows associated with it will be removed as
@@ -4331,7 +4332,8 @@
                 }
                 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                         "removeAppToken: " + wtoken);
-                displayContent.removeAppToken(wtoken);
+                mAppTokens.remove(wtoken);
+                mAnimatingAppTokens.remove(wtoken);
                 wtoken.removed = true;
                 if (wtoken.startingData != null) {
                     startingToken = wtoken;
@@ -4383,74 +4385,78 @@
     }
 
     void dumpAppTokensLocked() {
-        DisplayContentsIterator iterator = new DisplayContentsIterator();
-        while (iterator.hasNext()) {
-            DisplayContent displayContent = iterator.next();
-            Slog.v(TAG, "  Display " + displayContent.getDisplayId());
-            AppTokenIterator appIterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-            int i = appIterator.size();
-            while (appIterator.hasNext()) {
-                Slog.v(TAG, "  #" + --i + ": " + appIterator.next().token);
-            }
+        for (int i=mAppTokens.size()-1; i>=0; i--) {
+            Slog.v(TAG, "  #" + i + ": " + mAppTokens.get(i).token);
+        }
+    }
+
+    void dumpAnimatingAppTokensLocked() {
+        for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
+            Slog.v(TAG, "  #" + i + ": " + mAnimatingAppTokens.get(i).token);
         }
     }
 
     void dumpWindowsLocked() {
         int i = 0;
-        mTmpWindowsIterator.reset(REVERSE_ITERATOR);
-        while (mTmpWindowsIterator.hasNext()) {
-            final WindowState w = mTmpWindowsIterator.next();
+        final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
+        while (iterator.hasNext()) {
+            final WindowState w = iterator.next();
             Slog.v(TAG, "  #" + i++ + ": " + w);
         }
     }
 
-    private int findAppWindowInsertionPointLocked(AppWindowToken target) {
-        final int taskId = target.groupId;
-        DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId);
-        if (displayContent == null) {
-            Slog.w(TAG, "findTopAppWindowLocked: no DisplayContent for " + target);
-            return 0;
-        }
-        final WindowList windows = displayContent.getWindowList();
+    private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
         final int NW = windows.size();
 
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-        while (iterator.hasNext()) {
-            if (iterator.next() == target) {
-                break;
+        if (tokenPos >= mAnimatingAppTokens.size()) {
+            int i = NW;
+            while (i > 0) {
+                i--;
+                WindowState win = windows.get(i);
+                if (win.getAppToken() != null) {
+                    return i+1;
+                }
             }
         }
 
-        while (iterator.hasNext()) {
+        while (tokenPos > 0) {
             // Find the first app token below the new position that has
             // a window displayed.
-            final AppWindowToken wtoken = iterator.next();
-            if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
+            final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
+            if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
+                    + tokenPos + " -- " + wtoken.token);
             if (wtoken.sendingToBottom) {
-                if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
+                if (DEBUG_REORDER) Slog.v(TAG,
+                        "Skipping token -- currently sending to bottom");
+                tokenPos--;
                 continue;
             }
-            for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
+            int i = wtoken.windows.size();
+            while (i > 0) {
+                i--;
                 WindowState win = wtoken.windows.get(i);
-                for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
+                int j = win.mChildWindows.size();
+                while (j > 0) {
+                    j--;
                     WindowState cwin = win.mChildWindows.get(j);
                     if (cwin.mSubLayer >= 0) {
-                        for (int pos = NW - 1; pos >= 0; pos--) {
+                        for (int pos=NW-1; pos>=0; pos--) {
                             if (windows.get(pos) == cwin) {
                                 if (DEBUG_REORDER) Slog.v(TAG,
-                                        "Found child win @" + (pos + 1));
-                                return pos + 1;
+                                        "Found child win @" + (pos+1));
+                                return pos+1;
                             }
                         }
                     }
                 }
-                for (int pos = NW - 1; pos >= 0; pos--) {
+                for (int pos=NW-1; pos>=0; pos--) {
                     if (windows.get(pos) == win) {
-                        if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
-                        return pos + 1;
+                        if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
+                        return pos+1;
                     }
                 }
             }
+            tokenPos--;
         }
 
         return 0;
@@ -4499,104 +4505,198 @@
         return index;
     }
 
-    private void moveTaskWindowsLocked(int taskId) {
-        DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId);
-        if (displayContent == null) {
-            Slog.w(TAG, "moveTaskWindowsLocked: can't find DisplayContent for taskId=" + taskId);
-            return;
+    @Override
+    public void moveAppToken(int index, IBinder token) {
+        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
+                "moveAppToken()")) {
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
-        TaskList taskList = displayContent.mTaskIdToTaskList.get(taskId);
-        if (taskList == null) {
-            Slog.w(TAG, "moveTaskWindowsLocked: can't find TaskList for taskId=" + taskId);
-            return;
-        }
+        synchronized(mWindowMap) {
+            if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
+            if (DEBUG_REORDER) dumpAppTokensLocked();
+            final AppWindowToken wtoken = findAppWindowToken(token);
+            final int oldIndex = mAppTokens.indexOf(wtoken);
+            if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
+                    "Start moving token " + wtoken + " initially at "
+                    + oldIndex);
+            if (oldIndex > index && mAppTransition.isTransitionSet()) {
+                // animation towards back has not started, copy old list for duration of animation.
+                mAnimatingAppTokens.clear();
+                mAnimatingAppTokens.addAll(mAppTokens);
+            }
+            if (wtoken == null || !mAppTokens.remove(wtoken)) {
+                Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
+                      + token + " (" + wtoken + ")");
+                return;
+            }
+            mAppTokens.add(index, wtoken);
+            if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
+            else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
+            if (DEBUG_REORDER) dumpAppTokensLocked();
+            if (!mAppTransition.isTransitionSet()) {
+                // Not animating, bring animating app list in line with mAppTokens.
+                mAnimatingAppTokens.clear();
+                mAnimatingAppTokens.addAll(mAppTokens);
 
+                // Bring window ordering, window focus and input window in line with new app token
+                final long origId = Binder.clearCallingIdentity();
+                if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
+                if (DEBUG_REORDER) dumpWindowsLocked();
+                if (tmpRemoveAppWindowsLocked(wtoken)) {
+                    if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
+                    if (DEBUG_REORDER) dumpWindowsLocked();
+                    DisplayContentsIterator iterator = new DisplayContentsIterator();
+                    while(iterator.hasNext()) {
+                        final DisplayContent displayContent = iterator.next();
+                        final WindowList windows = displayContent.getWindowList();
+                        final int pos = findWindowOffsetLocked(windows, index);
+                        final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
+                        if (pos != newPos) {
+                            displayContent.layoutNeeded = true;
+                        }
+                    }
+                    if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
+                    if (DEBUG_REORDER) dumpWindowsLocked();
+                    updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
+                            false /*updateInputWindows*/);
+                    mInputMonitor.setUpdateInputWindowsNeededLw();
+                    performLayoutAndPlaceSurfacesLocked();
+                    mInputMonitor.updateInputWindowsLw(false /*force*/);
+                }
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
+    private void removeAppTokensLocked(List<IBinder> tokens) {
+        // XXX This should be done more efficiently!
+        // (take advantage of the fact that both lists should be
+        // ordered in the same way.)
+        int N = tokens.size();
+        for (int i=0; i<N; i++) {
+            IBinder token = tokens.get(i);
+            final AppWindowToken wtoken = findAppWindowToken(token);
+            if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+                    "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
+            if (!mAppTokens.remove(wtoken)) {
+                Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
+                      + token + " (" + wtoken + ")");
+                i--;
+                N--;
+            }
+        }
+    }
+
+    private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
         // First remove all of the windows from the list.
-        for (AppWindowToken wtoken : taskList.mAppTokens) {
-            tmpRemoveAppWindowsLocked(wtoken);
+        final int N = tokens.size();
+        int i;
+        for (i=0; i<N; i++) {
+            WindowToken token = mTokenMap.get(tokens.get(i));
+            if (token != null) {
+                tmpRemoveAppWindowsLocked(token);
+            }
         }
 
         // And now add them back at the correct place.
-        // Where to start adding?
-        int pos = findAppWindowInsertionPointLocked(taskList.mAppTokens.get(0));
-        for (AppWindowToken wtoken : taskList.mAppTokens) {
-            if (wtoken != null) {
-                final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
-                if (newPos != pos) {
-                    displayContent.layoutNeeded = true;
+        DisplayContentsIterator iterator = new DisplayContentsIterator();
+        while (iterator.hasNext()) {
+            final DisplayContent displayContent = iterator.next();
+            final WindowList windows = displayContent.getWindowList();
+            // Where to start adding?
+            int pos = findWindowOffsetLocked(windows, tokenPos);
+            for (i=0; i<N; i++) {
+                WindowToken token = mTokenMap.get(tokens.get(i));
+                if (token != null) {
+                    final int newPos = reAddAppWindowsLocked(displayContent, pos, token);
+                    if (newPos != pos) {
+                        displayContent.layoutNeeded = true;
+                    }
+                    pos = newPos;
                 }
-                pos = newPos;
+            }
+            if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
+                    false /*updateInputWindows*/)) {
+                assignLayersLocked(windows);
             }
         }
-        if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-            false /*updateInputWindows*/)) {
-            assignLayersLocked(displayContent.getWindowList());
-        }
 
-        updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-                false /*updateInputWindows*/);
         mInputMonitor.setUpdateInputWindowsNeededLw();
+
+        // Note that the above updateFocusedWindowLocked used to sit here.
+
         performLayoutAndPlaceSurfacesLocked();
         mInputMonitor.updateInputWindowsLw(false /*force*/);
 
         //dump();
     }
 
-    public void moveTaskToTop(int taskId) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized(mWindowMap) {
-                DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId);
-                if (displayContent == null) {
-                    Slog.e(TAG, "moveTaskToTop: taskId=" + taskId
-                            + " not found in mTaskIdToDisplayContents");
-                    return;
-                }
-                TaskList taskList = displayContent.mTaskIdToTaskList.get(taskId);
-                if (taskList == null) {
-                    Slog.e(TAG, "moveTaskToTop: taskId=" + taskId
-                            + " not found in mTaskIdToTaskLists");
-                    return;
-                }
-                if (!displayContent.mTaskLists.remove(taskList)) {
-                    Slog.e(TAG, "moveTaskToTop: taskId=" + taskId + " not found in mTaskLists");
-                }
-                displayContent.mTaskLists.add(taskList);
-
-                moveTaskWindowsLocked(taskId);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
+    @Override
+    public void moveAppTokensToTop(List<IBinder> tokens) {
+        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
+                "moveAppTokensToTop()")) {
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
+
+        final long origId = Binder.clearCallingIdentity();
+        synchronized(mWindowMap) {
+            removeAppTokensLocked(tokens);
+            final int N = tokens.size();
+            for (int i=0; i<N; i++) {
+                AppWindowToken wt = findAppWindowToken(tokens.get(i));
+                if (wt != null) {
+                    if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
+                            "Adding next to top: " + wt);
+                    mAppTokens.add(wt);
+                    if (mAppTransition.isTransitionSet()) {
+                        wt.sendingToBottom = false;
+                    }
+                }
+            }
+
+            mAnimatingAppTokens.clear();
+            mAnimatingAppTokens.addAll(mAppTokens);
+            moveAppWindowsLocked(tokens, mAppTokens.size());
+        }
+        Binder.restoreCallingIdentity(origId);
     }
 
-    public void moveTaskToBottom(int taskId) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized(mWindowMap) {
-                DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId);
-                if (displayContent == null) {
-                    Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
-                            + " not found in mTaskIdToDisplayContents");
-                    return;
-                }
-                TaskList taskList = displayContent.mTaskIdToTaskList.get(taskId);
-                if (taskList == null) {
-                    Slog.e(TAG, "moveTaskToTopBottom: taskId=" + taskId
-                            + " not found in mTaskIdToTaskLists");
-                    return;
-                }
-                if (!displayContent.mTaskLists.remove(taskList)) {
-                    Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId + " not found in mTaskLists");
-                }
-                displayContent.mTaskLists.add(0, taskList);
-
-                moveTaskWindowsLocked(taskId);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
+    @Override
+    public void moveAppTokensToBottom(List<IBinder> tokens) {
+        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
+                "moveAppTokensToBottom()")) {
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
+
+        final long origId = Binder.clearCallingIdentity();
+        synchronized(mWindowMap) {
+            final int N = tokens.size();
+            if (N > 0) {
+                // animating towards back, hang onto old list for duration of animation.
+                mAnimatingAppTokens.clear();
+                mAnimatingAppTokens.addAll(mAppTokens);
+            }
+            removeAppTokensLocked(tokens);
+            int pos = 0;
+            for (int i=0; i<N; i++) {
+                AppWindowToken wt = findAppWindowToken(tokens.get(i));
+                if (wt != null) {
+                    if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+                            "Adding next to bottom: " + wt + " at " + pos);
+                    mAppTokens.add(pos, wt);
+                    if (mAppTransition.isTransitionSet()) {
+                        wt.sendingToBottom = true;
+                    }
+                    pos++;
+                }
+            }
+
+            mAnimatingAppTokens.clear();
+            mAnimatingAppTokens.addAll(mAppTokens);
+            moveAppWindowsLocked(tokens, 0);
+        }
+        Binder.restoreCallingIdentity(origId);
     }
 
     // -------------------------------------------------------------
@@ -4717,9 +4817,9 @@
     @Override
     public void closeSystemDialogs(String reason) {
         synchronized(mWindowMap) {
-            mTmpWindowsIterator.reset(FORWARD_ITERATOR);
-            while (mTmpWindowsIterator.hasNext()) {
-                final WindowState w = mTmpWindowsIterator.next();
+            final AllWindowsIterator iterator = new AllWindowsIterator();
+            while (iterator.hasNext()) {
+                final WindowState w = iterator.next();
                 if (w.mHasSurface) {
                     try {
                         w.mClient.closeSystemDialogs(reason);
@@ -5113,9 +5213,9 @@
             // the background..)
             if (on) {
                 boolean isVisible = false;
-                mTmpWindowsIterator.reset(FORWARD_ITERATOR);
-                while (mTmpWindowsIterator.hasNext()) {
-                    final WindowState ws = mTmpWindowsIterator.next();
+                final AllWindowsIterator iterator = new AllWindowsIterator();
+                while (iterator.hasNext()) {
+                    final WindowState ws = iterator.next();
                     if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
                         isVisible = true;
                         break;
@@ -6010,9 +6110,9 @@
         }
 
         synchronized (mWindowMap) {
-            mTmpWindowsIterator.reset(FORWARD_ITERATOR);
-            while (mTmpWindowsIterator.hasNext()) {
-                final WindowState w = mTmpWindowsIterator.next();
+            final AllWindowsIterator iterator = new AllWindowsIterator();
+            while (iterator.hasNext()) {
+                final WindowState w = iterator.next();
                 if (System.identityHashCode(w) == hashCode) {
                     return w;
                 }
@@ -6561,10 +6661,10 @@
     // TODO(multidisplay): Call isScreenOn for each display.
     private void sendScreenStatusToClientsLocked() {
         final boolean on = mPowerManager.isScreenOn();
-        mTmpWindowsIterator.reset(FORWARD_ITERATOR);
-        while (mTmpWindowsIterator.hasNext()) {
+        final AllWindowsIterator iterator = new AllWindowsIterator();
+        while (iterator.hasNext()) {
             try {
-                mTmpWindowsIterator.next().mClient.dispatchScreenState(on);
+                iterator.next().mClient.dispatchScreenState(on);
             } catch (RemoteException e) {
                 // Ignored
             }
@@ -6860,6 +6960,8 @@
                         if (mAppTransition.isTransitionSet()) {
                             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
                             mAppTransition.setTimeout();
+                            mAnimatingAppTokens.clear();
+                            mAnimatingAppTokens.addAll(mAppTokens);
                             performLayoutAndPlaceSurfacesLocked();
                         }
                     }
@@ -6904,11 +7006,10 @@
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
                         Slog.w(TAG, "App freeze timeout expired.");
-                        DisplayContent displayContent = getDefaultDisplayContentLocked();
-                        AppTokenIterator iterator =
-                                displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-                        while (iterator.hasNext()) {
-                            AppWindowToken tok = iterator.next();
+                        int i = mAppTokens.size();
+                        while (i > 0) {
+                            i--;
+                            AppWindowToken tok = mAppTokens.get(i);
                             if (tok.mAppAnimator.freezingScreen) {
                                 Slog.w(TAG, "Force clearing freeze: " + tok);
                                 unsetAppFreezingScreenLocked(tok, true, true);
@@ -7307,7 +7408,6 @@
         performLayoutAndPlaceSurfacesLocked();
     }
 
-    @Override
     public void setOverscan(int displayId, int left, int top, int right, int bottom) {
         if (mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
@@ -7426,16 +7526,15 @@
         // in the main app list, but still have windows shown.  We put them
         // in the back because now that the animation is over we no longer
         // will care about them.
-        AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
-        int NT = exitingAppTokens.size();
+        int NT = mExitingAppTokens.size();
         for (int j=0; j<NT; j++) {
-            i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j));
+            i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
         }
 
         // And add in the still active app tokens in Z order.
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
-        while (iterator.hasNext()) {
-            i = reAddAppWindowsLocked(displayContent, i, iterator.next());
+        NT = mAnimatingAppTokens.size();
+        for (int j=0; j<NT; j++) {
+            i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
         }
 
         i -= lastBelow;
@@ -7455,7 +7554,7 @@
                 }
             }
             Slog.w(TAG, "Current app token list:");
-            dumpAppTokensLocked();
+            dumpAnimatingAppTokensLocked();
             Slog.w(TAG, "Final window list:");
             dumpWindowsLocked();
         }
@@ -8105,11 +8204,11 @@
 
         mAppTransition.setIdle();
         // Restore window app tokens to the ActivityManager views
-        final DisplayContent displayContent = getDefaultDisplayContentLocked();
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
-        while (iterator.hasNext()) {
-            iterator.next().sendingToBottom = false;
+        for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
+            mAnimatingAppTokens.get(i).sendingToBottom = false;
         }
+        mAnimatingAppTokens.clear();
+        mAnimatingAppTokens.addAll(mAppTokens);
         rebuildAppWindowListLocked();
 
         changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
@@ -8266,12 +8365,13 @@
         }
     }
 
-    private void updateAllDrawnLocked(DisplayContent displayContent) {
+    private void updateAllDrawnLocked() {
         // See if any windows have been drawn, so they (and others
         // associated with them) can now be shown.
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
-        while (iterator.hasNext()) {
-            AppWindowToken wtoken = iterator.next();
+        final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
+        final int NT = appTokens.size();
+        for (int i=0; i<NT; i++) {
+            AppWindowToken wtoken = appTokens.get(i);
             if (!wtoken.allDrawn) {
                 int numInteresting = wtoken.numInterestingWindows;
                 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
@@ -8303,17 +8403,13 @@
         }
 
         // Initialize state of exiting tokens.
-        DisplayContentsIterator iterator = new DisplayContentsIterator();
-        while (iterator.hasNext()) {
-            final DisplayContent displayContent = iterator.next();
-            for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
-                displayContent.mExitingTokens.get(i).hasVisible = false;
-            }
+        for (i=mExitingTokens.size()-1; i>=0; i--) {
+            mExitingTokens.get(i).hasVisible = false;
+        }
 
-            // Initialize state of exiting applications.
-            for (i=displayContent.mExitingAppTokens.size()-1; i>=0; i--) {
-                displayContent.mExitingAppTokens.get(i).hasVisible = false;
-            }
+        // Initialize state of exiting applications.
+        for (i=mExitingAppTokens.size()-1; i>=0; i--) {
+            mExitingAppTokens.get(i).hasVisible = false;
         }
 
         mInnerFields.mHoldScreen = null;
@@ -8342,10 +8438,10 @@
             }
 
             boolean focusDisplayed = false;
+            boolean updateAllDrawn = false;
 
-            iterator = new DisplayContentsIterator();
+            DisplayContentsIterator iterator = new DisplayContentsIterator();
             while (iterator.hasNext()) {
-                boolean updateAllDrawn = false;
                 final DisplayContent displayContent = iterator.next();
                 WindowList windows = displayContent.getWindowList();
                 DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -8589,10 +8685,10 @@
                 if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
                     stopDimmingLocked(displayId);
                 }
+            }
 
-                if (updateAllDrawn) {
-                    updateAllDrawnLocked(displayContent);
-                }
+            if (updateAllDrawn) {
+                updateAllDrawnLocked();
             }
 
             if (focusDisplayed) {
@@ -8739,35 +8835,30 @@
         }
 
         // Time to remove any exiting tokens?
-        iterator = new DisplayContentsIterator();
-        while (iterator.hasNext()) {
-            final DisplayContent displayContent = iterator.next();
-            ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
-            for (i = exitingTokens.size() - 1; i >= 0; i--) {
-                WindowToken token = exitingTokens.get(i);
-                if (!token.hasVisible) {
-                    exitingTokens.remove(i);
-                    if (token.windowType == TYPE_WALLPAPER) {
-                        mWallpaperTokens.remove(token);
-                    }
+        for (i=mExitingTokens.size()-1; i>=0; i--) {
+            WindowToken token = mExitingTokens.get(i);
+            if (!token.hasVisible) {
+                mExitingTokens.remove(i);
+                if (token.windowType == TYPE_WALLPAPER) {
+                    mWallpaperTokens.remove(token);
                 }
             }
+        }
 
-            // Time to remove any exiting applications?
-            AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
-            for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
-                AppWindowToken token = exitingAppTokens.get(i);
-                if (!token.hasVisible && !mClosingApps.contains(token)) {
-                    // Make sure there is no animation running on this token,
-                    // so any windows associated with it will be removed as
-                    // soon as their animations are complete
-                    token.mAppAnimator.clearAnimation();
-                    token.mAppAnimator.animating = false;
-                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
-                            "performLayout: App token exiting now removed" + token);
-                    displayContent.removeAppToken(token);
-                    exitingAppTokens.remove(i);
-                }
+        // Time to remove any exiting applications?
+        for (i=mExitingAppTokens.size()-1; i>=0; i--) {
+            AppWindowToken token = mExitingAppTokens.get(i);
+            if (!token.hasVisible && !mClosingApps.contains(token)) {
+                // Make sure there is no animation running on this token,
+                // so any windows associated with it will be removed as
+                // soon as their animations are complete
+                token.mAppAnimator.clearAnimation();
+                token.mAppAnimator.animating = false;
+                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+                        "performLayout: App token exiting now removed" + token);
+                mAppTokens.remove(token);
+                mAnimatingAppTokens.remove(token);
+                mExitingAppTokens.remove(i);
             }
         }
 
@@ -8787,7 +8878,7 @@
             defaultDisplay.layoutNeeded = true;
         }
 
-        iterator = new DisplayContentsIterator();
+        DisplayContentsIterator iterator = new DisplayContentsIterator();
         while (iterator.hasNext()) {
             DisplayContent displayContent = iterator.next();
             if (displayContent.pendingLayoutChanges != 0) {
@@ -9038,10 +9129,10 @@
             // window list to make sure we haven't left any dangling surfaces
             // around.
 
-            mTmpWindowsIterator.reset(FORWARD_ITERATOR);
+            AllWindowsIterator iterator = new AllWindowsIterator();
             Slog.i(TAG, "Out of memory for surface!  Looking for leaks...");
-            while (mTmpWindowsIterator.hasNext()) {
-                WindowState ws = mTmpWindowsIterator.next();
+            while (iterator.hasNext()) {
+                WindowState ws = iterator.next();
                 WindowStateAnimator wsa = ws.mWinAnimator;
                 if (wsa.mSurfaceControl != null) {
                     if (!mSessions.contains(wsa.mSession)) {
@@ -9074,9 +9165,9 @@
             if (!leakedSurface) {
                 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
                 SparseIntArray pidCandidates = new SparseIntArray();
-                mTmpWindowsIterator.reset(FORWARD_ITERATOR);
-                while (mTmpWindowsIterator.hasNext()) {
-                    WindowState ws = mTmpWindowsIterator.next();
+                iterator = new AllWindowsIterator();
+                while (iterator.hasNext()) {
+                    WindowState ws = iterator.next();
                     if (mForceRemoves.contains(ws)) {
                         continue;
                     }
@@ -9202,8 +9293,8 @@
     }
 
     private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
-        AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
-        WindowToken nextApp = iterator.hasNext() ? iterator.next() : null;
+        int nextAppIndex = mAppTokens.size()-1;
+        WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
 
         final WindowList windows = displayContent.getWindowList();
         for (int i = windows.size() - 1; i >= 0; i--) {
@@ -9229,8 +9320,8 @@
             // through the app tokens until we find its app.
             if (thisApp != null && nextApp != null && thisApp != nextApp
                     && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
-                final WindowToken origAppToken = nextApp;
-                while (iterator.hasNext()) {
+                int origAppIndex = nextAppIndex;
+                while (nextAppIndex > 0) {
                     if (nextApp == mFocusedApp) {
                         // Whoops, we are below the focused app...  no focus
                         // for you!
@@ -9238,7 +9329,8 @@
                             TAG, "Reached focused app: " + mFocusedApp);
                         return null;
                     }
-                    nextApp = iterator.next();
+                    nextAppIndex--;
+                    nextApp = mAppTokens.get(nextAppIndex);
                     if (nextApp == thisApp) {
                         break;
                     }
@@ -9247,14 +9339,8 @@
                     // Uh oh, the app token doesn't exist!  This shouldn't
                     // happen, but if it does we can get totally hosed...
                     // so restart at the original app.
-                    nextApp = origAppToken;
-                    iterator = displayContent.new AppTokenIterator(true);
-                    while (iterator.hasNext()) {
-                        // return iterator to same place.
-                        if (iterator.next() == origAppToken) {
-                            break;
-                        }
-                    } 
+                    nextAppIndex = origAppIndex;
+                    nextApp = mAppTokens.get(nextAppIndex);
                 }
             }
 
@@ -9624,6 +9710,15 @@
                 }
             }
         }
+        if (mAppTokens.size() > 0) {
+            pw.println();
+            pw.println("  Application tokens in Z order:");
+            for (int i=mAppTokens.size()-1; i>=0; i--) {
+                pw.print("  App #"); pw.print(i);
+                        pw.print(' '); pw.print(mAppTokens.get(i)); pw.println(":");
+                mAppTokens.get(i).dump(pw, "    ");
+            }
+        }
         if (mFinishedStarting.size() > 0) {
             pw.println();
             pw.println("  Finishing start of application tokens:");
@@ -9639,6 +9734,51 @@
                 }
             }
         }
+        if (mExitingTokens.size() > 0) {
+            pw.println();
+            pw.println("  Exiting tokens:");
+            for (int i=mExitingTokens.size()-1; i>=0; i--) {
+                WindowToken token = mExitingTokens.get(i);
+                pw.print("  Exiting #"); pw.print(i);
+                        pw.print(' '); pw.print(token);
+                if (dumpAll) {
+                    pw.println(':');
+                    token.dump(pw, "    ");
+                } else {
+                    pw.println();
+                }
+            }
+        }
+        if (mExitingAppTokens.size() > 0) {
+            pw.println();
+            pw.println("  Exiting application tokens:");
+            for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
+                WindowToken token = mExitingAppTokens.get(i);
+                pw.print("  Exiting App #"); pw.print(i);
+                        pw.print(' '); pw.print(token);
+                if (dumpAll) {
+                    pw.println(':');
+                    token.dump(pw, "    ");
+                } else {
+                    pw.println();
+                }
+            }
+        }
+        if (mAppTransition.isRunning() && mAnimatingAppTokens.size() > 0) {
+            pw.println();
+            pw.println("  Application tokens during animation:");
+            for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
+                WindowToken token = mAnimatingAppTokens.get(i);
+                pw.print("  App moving to bottom #"); pw.print(i);
+                        pw.print(' '); pw.print(token);
+                if (dumpAll) {
+                    pw.println(':');
+                    token.dump(pw, "    ");
+                } else {
+                    pw.println();
+                }
+            }
+        }
         if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
             pw.println();
             if (mOpeningApps.size() > 0) {
@@ -9683,9 +9823,9 @@
     void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
             ArrayList<WindowState> windows) {
         int j = 0;
-        mTmpWindowsIterator.reset(REVERSE_ITERATOR);
-        while (mTmpWindowsIterator.hasNext()) {
-            final WindowState w = mTmpWindowsIterator.next();
+        final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
+        while (iterator.hasNext()) {
+            final WindowState w = iterator.next();
             if (windows == null || windows.contains(w)) {
                 pw.print("  Window #"); pw.print(j++); pw.print(' ');
                         pw.print(w); pw.println(":");
@@ -9871,9 +10011,9 @@
         WindowList windows = new WindowList();
         if ("visible".equals(name)) {
             synchronized(mWindowMap) {
-                mTmpWindowsIterator.reset(REVERSE_ITERATOR);
-                while (mTmpWindowsIterator.hasNext()) {
-                    final WindowState w = mTmpWindowsIterator.next();
+                final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
+                while (iterator.hasNext()) {
+                    final WindowState w = iterator.next();
                     if (w.mWinAnimator.mSurfaceShown) {
                         windows.add(w);
                     }
@@ -9888,9 +10028,9 @@
             } catch (RuntimeException e) {
             }
             synchronized(mWindowMap) {
-                mTmpWindowsIterator.reset(REVERSE_ITERATOR);
-                while (mTmpWindowsIterator.hasNext()) {
-                    final WindowState w = mTmpWindowsIterator.next();
+                final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
+                while (iterator.hasNext()) {
+                    final WindowState w = iterator.next();
                     if (name != null) {
                         if (w.mAttrs.getTitle().toString().contains(name)) {
                             windows.add(w);
@@ -10143,10 +10283,6 @@
     class DisplayContentsIterator implements Iterator<DisplayContent> {
         private int cur;
 
-        void reset() {
-            cur = 0;
-        }
-
         @Override
         public boolean hasNext() {
             return cur < mDisplayContents.size();
@@ -10166,6 +10302,7 @@
         }
     }
 
+    final static boolean REVERSE_ITERATOR = true;
     class AllWindowsIterator implements Iterator<WindowState> {
         private DisplayContent mDisplayContent;
         private DisplayContentsIterator mDisplayContentsIterator;
@@ -10174,33 +10311,19 @@
         private boolean mReverse;
 
         AllWindowsIterator() {
-            this(false);
+            mDisplayContentsIterator = new DisplayContentsIterator();
+            mDisplayContent = mDisplayContentsIterator.next();
+            mWindowList = mDisplayContent.getWindowList();
         }
 
         AllWindowsIterator(boolean reverse) {
-            mDisplayContentsIterator = new DisplayContentsIterator();
-            reset(reverse);
-        }
-
-        void reset(boolean reverse) {
+            this();
             mReverse = reverse;
-            mDisplayContentsIterator.reset();
-            if (mDisplayContentsIterator.hasNext()) {
-                mDisplayContent = mDisplayContentsIterator.next();
-                mWindowList = mDisplayContent.getWindowList();
-                mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
-            } else {
-                mDisplayContent = null;
-                mWindowList = null;
-                mWindowListIndex = 0;
-            }
+            mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
         }
 
         @Override
         public boolean hasNext() {
-            if (mDisplayContent == null) {
-                return false;
-            }
             if (mReverse) {
                 return mWindowListIndex >= 0;
             }
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 517c4e4..a600623 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -52,12 +52,6 @@
 import java.util.ArrayList;
 
 class WindowList extends ArrayList<WindowState> {
-    WindowList() {
-        super();
-    }
-    WindowList(WindowList windows) {
-        super(windows);
-    }
 }
 
 /**
@@ -1092,7 +1086,7 @@
         return true;
     }
 
-    public void setAppOpVisibilityLw(boolean state) {
+    public boolean setAppOpVisibilityLw(boolean state) {
         if (mAppOpVisibility != state) {
             mAppOpVisibility = state;
             if (state) {
@@ -1102,11 +1096,13 @@
                 // ops modifies they should only be hidden by policy due to the
                 // lock screen, and the user won't be changing this if locked.
                 // Plus it will quickly be fixed the next time we do a layout.
-                showLw(true, true);
+                showLw(true, false);
             } else {
-                hideLw(true, true);
+                hideLw(true, false);
             }
+            return true;
         }
+        return false;
     }
 
     @Override
diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/java/com/android/server/wm/WindowToken.java
index 2267123..bd0ace8 100644
--- a/services/java/com/android/server/wm/WindowToken.java
+++ b/services/java/com/android/server/wm/WindowToken.java
@@ -19,6 +19,7 @@
 import android.os.IBinder;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
 /**
  * Container of a set of related windows in the window manager.  Often this
