diff --git a/carousel/test/res/values-in/strings.xml b/carousel/test/res/values-in/strings.xml
index 40000e8..06c8812 100644
--- a/carousel/test/res/values-in/strings.xml
+++ b/carousel/test/res/values-in/strings.xml
@@ -21,7 +21,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="music_demo_activity_label" msgid="4382090808250495841">"KaruselMusik"</string>
     <string name="carousel_test_activity_label" msgid="6014624482213318747">"UjiKarusel"</string>
-    <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikasi untuk menampilkan penggunaan Karusel"</string>
+    <string name="carousel_test_activity_description" msgid="1632693812604375483">"Aplikasi untuk menampilkan penggunaan Korsel"</string>
     <string name="task_switcher_activity_label" msgid="714620143340933546">"PengubahTugas"</string>
     <string name="recent_tasks_title" msgid="1030287226205477117">"Aplikasi Terbaru"</string>
     <string name="no_recent_tasks" msgid="6884096266670555780">"Tidak ada tugas terbaru"</string>
diff --git a/chips/AndroidManifest.xml b/chips/AndroidManifest.xml
index e159fd2..fd7775d 100644
--- a/chips/AndroidManifest.xml
+++ b/chips/AndroidManifest.xml
@@ -1,5 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.ex.chips"
           android:versionCode="1">
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/chips/res/values-ko/strings.xml b/chips/res/values-ko/strings.xml
index 7423ce5..f7884bd 100644
--- a/chips/res/values-ko/strings.xml
+++ b/chips/res/values-ko/strings.xml
@@ -19,5 +19,5 @@
     <string name="more_string" msgid="8495478259330621990">"<xliff:g id="COUNT">%1$s</xliff:g>명 이상"</string>
     <string name="copy_email" msgid="7869435992461603532">"이메일 주소 복사"</string>
     <string name="copy_number" msgid="530057841276106843">"전화번호 복사"</string>
-    <string name="done" msgid="2356320650733788862">"Enter 키"</string>
+    <string name="done" msgid="2356320650733788862">"입력"</string>
 </resources>
diff --git a/chips/res/values-pt-rPT/strings.xml b/chips/res/values-pt-rPT/strings.xml
index bfbe1ca..fc991b1 100644
--- a/chips/res/values-pt-rPT/strings.xml
+++ b/chips/res/values-pt-rPT/strings.xml
@@ -19,5 +19,5 @@
     <string name="more_string" msgid="8495478259330621990">"+<xliff:g id="COUNT">%1$s</xliff:g>"</string>
     <string name="copy_email" msgid="7869435992461603532">"Copiar endereço de email"</string>
     <string name="copy_number" msgid="530057841276106843">"Copiar número de telefone"</string>
-    <string name="done" msgid="2356320650733788862">"Regressar"</string>
+    <string name="done" msgid="2356320650733788862">"Voltar"</string>
 </resources>
diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java
index 9576d68..7be2f52 100644
--- a/chips/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java
@@ -407,6 +407,44 @@
         }
     }
 
+    private int getExcessTopPadding() {
+        if (sExcessTopPadding == -1) {
+            sExcessTopPadding = (int) (mChipHeight + mLineSpacingExtra);
+        }
+        return sExcessTopPadding;
+    }
+
+    public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
+        super.setAdapter(adapter);
+        ((BaseRecipientAdapter) adapter)
+                .registerUpdateObserver(new BaseRecipientAdapter.EntriesUpdatedObserver() {
+                    @Override
+                    public void onChanged(List<RecipientEntry> entries) {
+                        // Scroll the chips field to the top of the screen so
+                        // that the user can see as many results as possible.
+                        if (entries != null && entries.size() > 0) {
+                            scrollBottomIntoView();
+                        }
+                    }
+                });
+    }
+
+    private void scrollBottomIntoView() {
+        if (mScrollView != null && mShouldShrink) {
+            int[] location = new int[2];
+            getLocationOnScreen(location);
+            int height = getHeight();
+            int currentPos = location[1] + height;
+            // Desired position shows at least 1 line of chips below the action
+            // bar. We add excess padding to make sure this is always below other
+            // content.
+            int desiredPos = (int) mChipHeight + mActionBarHeight + getExcessTopPadding();
+            if (currentPos > desiredPos) {
+                mScrollView.scrollBy(0, currentPos - desiredPos);
+            }
+        }
+    }
+
     @Override
     public void performValidation() {
         // Do nothing. Chips handles its own validation.
@@ -2243,45 +2281,7 @@
         }
     }
 
-    @Override
-    public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
-        super.setAdapter(adapter);
-        ((BaseRecipientAdapter) adapter)
-                .registerUpdateObserver(new BaseRecipientAdapter.EntriesUpdatedObserver() {
-                    @Override
-                    public void onChanged(List<RecipientEntry> entries) {
-                        if (entries != null && entries.size() > 0) {
-                            scrollBottomIntoView();
-                        }
-                    }
-                });
-    }
-
-    private void scrollBottomIntoView() {
-        if (mScrollView != null && mShouldShrink) {
-            int[] location = new int[2];
-            getLocationOnScreen(location);
-            int height = getHeight();
-            int currentPos = location[1] + height;
-            // Desired position shows at least 1 line of chips below the action
-            // bar.
-            // We add excess padding to make sure this is always below other
-            // content.
-            int desiredPos = (int) mChipHeight + mActionBarHeight + getExcessTopPadding();
-            if (currentPos > desiredPos) {
-                mScrollView.scrollBy(0, currentPos - desiredPos);
-            }
-        }
-    }
-
-    private int getExcessTopPadding() {
-        if (sExcessTopPadding == -1) {
-            sExcessTopPadding = (int) (mChipHeight + mLineSpacingExtra);
-        }
-        return sExcessTopPadding;
-    }
-
-    public boolean lastCharacterIsCommitCharacter(CharSequence s) {
+   public boolean lastCharacterIsCommitCharacter(CharSequence s) {
         char last;
         int end = getSelectionEnd() == 0 ? 0 : getSelectionEnd() - 1;
         int len = length() - 1;
@@ -2360,6 +2360,9 @@
                 prevTokenStart = tokenStart;
                 tokenStart = mTokenizer.findTokenStart(text, tokenStart);
                 findChip = findChip(tokenStart);
+                if (tokenStart == originalTokenStart && findChip == null) {
+                    break;
+                }
             }
             if (tokenStart != originalTokenStart) {
                 if (findChip != null) {
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index b8fc7bc..261b15d 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -42,6 +42,9 @@
         /** Wait this long times the number of consecutive errors so far before retrying. */
         public long backoffIncrementalMillis = 5000;
 
+        /** Wait this long times 2^(number of consecutive errors so far) before retrying. */
+        public int backoffExponentialMillis = 0;
+
         /** Maximum duration of moratorium to honor.  Mostly an issue for clock rollbacks. */
         public long maxMoratoriumMillis = 24 * 3600 * 1000;
 
@@ -53,11 +56,20 @@
 
         @Override
         public String toString() {
-            return String.format(
+            if (backoffExponentialMillis > 0) {
+                return String.format(
+                    "OperationScheduler.Options[backoff=%.1f+%.1f+%.1f max=%.1f min=%.1f period=%.1f]",
+                    backoffFixedMillis / 1000.0, backoffIncrementalMillis / 1000.0,
+                    backoffExponentialMillis / 1000.0,
+                    maxMoratoriumMillis / 1000.0, minTriggerMillis / 1000.0,
+                    periodicIntervalMillis / 1000.0);
+            } else {
+                return String.format(
                     "OperationScheduler.Options[backoff=%.1f+%.1f max=%.1f min=%.1f period=%.1f]",
                     backoffFixedMillis / 1000.0, backoffIncrementalMillis / 1000.0,
                     maxMoratoriumMillis / 1000.0, minTriggerMillis / 1000.0,
                     periodicIntervalMillis / 1000.0);
+            }
         }
     }
 
@@ -76,7 +88,7 @@
      * Parse scheduler options supplied in this string form:
      *
      * <pre>
-     * backoff=(fixed)+(incremental) max=(maxmoratorium) min=(mintrigger) [period=](interval)
+     * backoff=(fixed)+(incremental)[+(exponential)] max=(maxmoratorium) min=(mintrigger) [period=](interval)
      * </pre>
      *
      * All values are times in (possibly fractional) <em>seconds</em> (not milliseconds).
@@ -97,14 +109,18 @@
         for (String param : spec.split(" +")) {
             if (param.length() == 0) continue;
             if (param.startsWith("backoff=")) {
-                int plus = param.indexOf('+', 8);
-                if (plus < 0) {
-                    options.backoffFixedMillis = parseSeconds(param.substring(8));
-                } else {
-                    if (plus > 8) {
-                        options.backoffFixedMillis = parseSeconds(param.substring(8, plus));
-                    }
-                    options.backoffIncrementalMillis = parseSeconds(param.substring(plus + 1));
+                String[] pieces = param.substring(8).split("\\+");
+                if (pieces.length > 3) {
+                    throw new IllegalArgumentException("bad value for backoff: [" + spec + "]");
+                }
+                if (pieces.length > 0 && pieces[0].length() > 0) {
+                    options.backoffFixedMillis = parseSeconds(pieces[0]);
+                }
+                if (pieces.length > 1 && pieces[1].length() > 0) {
+                    options.backoffIncrementalMillis = parseSeconds(pieces[1]);
+                }
+                if (pieces.length > 2 && pieces[2].length() > 0) {
+                    options.backoffExponentialMillis = (int)parseSeconds(pieces[2]);
                 }
             } else if (param.startsWith("max=")) {
                 options.maxMoratoriumMillis = parseSeconds(param.substring(4));
@@ -160,8 +176,21 @@
         time = Math.max(time, moratoriumTimeMillis);
         time = Math.max(time, lastSuccessTimeMillis + options.minTriggerMillis);
         if (errorCount > 0) {
-            time = Math.max(time, lastErrorTimeMillis + options.backoffFixedMillis +
-                    options.backoffIncrementalMillis * errorCount);
+            int shift = errorCount-1;
+            // backoffExponentialMillis is an int, so we can safely
+            // double it 30 times without overflowing a long.
+            if (shift > 30) shift = 30;
+            long backoff = options.backoffFixedMillis +
+                (options.backoffIncrementalMillis * errorCount) +
+                (((long)options.backoffExponentialMillis) << shift);
+
+            // Treat backoff like a moratorium: don't let the backoff
+            // time grow too large.
+            if (moratoriumTimeMillis > 0 && backoff > moratoriumTimeMillis) {
+                backoff = moratoriumTimeMillis;
+            }
+
+            time = Math.max(time, lastErrorTimeMillis + backoff);
         }
         return time;
     }
diff --git a/common/tests/src/com/android/common/OperationSchedulerTest.java b/common/tests/src/com/android/common/OperationSchedulerTest.java
index 955508f..87e2cd8 100644
--- a/common/tests/src/com/android/common/OperationSchedulerTest.java
+++ b/common/tests/src/com/android/common/OperationSchedulerTest.java
@@ -119,6 +119,42 @@
         assertEquals(beforeSuccess + 1000000, scheduler.getNextTimeMillis(options));
     }
 
+    @MediumTest
+    public void testExponentialBackoff() throws Exception {
+        TimeTravelScheduler scheduler = new TimeTravelScheduler();
+        OperationScheduler.Options options = new OperationScheduler.Options();
+        options.backoffFixedMillis = 100;
+        options.backoffIncrementalMillis = 1000;
+        options.backoffExponentialMillis = 10000;
+        scheduler.setTriggerTimeMillis(0);
+        scheduler.setEnabledState(true);
+
+        // Backoff interval after an error
+        long beforeError = (scheduler.timeMillis += 10);
+        scheduler.onTransientError();
+        assertEquals(0, scheduler.getLastSuccessTimeMillis());
+        assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
+        assertEquals(beforeError + 11100, scheduler.getNextTimeMillis(options));
+
+        // Second error
+        beforeError = (scheduler.timeMillis += 10);
+        scheduler.onTransientError();
+        assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
+        assertEquals(beforeError + 22100, scheduler.getNextTimeMillis(options));
+
+        // Third error
+        beforeError = (scheduler.timeMillis += 10);
+        scheduler.onTransientError();
+        assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
+        assertEquals(beforeError + 43100, scheduler.getNextTimeMillis(options));
+
+        // Fourth error
+        beforeError = (scheduler.timeMillis += 10);
+        scheduler.onTransientError();
+        assertEquals(beforeError, scheduler.getLastAttemptTimeMillis());
+        assertEquals(beforeError + 84100, scheduler.getNextTimeMillis(options));
+    }
+
     @SmallTest
     public void testParseOptions() throws Exception {
          OperationScheduler.Options options = new OperationScheduler.Options();
@@ -138,6 +174,10 @@
          assertEquals(
                 "OperationScheduler.Options[backoff=10.0+2.5 max=12345.6 min=7.0 period=3800.0]",
                  OperationScheduler.parseOptions("", options).toString());
+
+         assertEquals(
+                 "OperationScheduler.Options[backoff=5.0+2.5+10.0 max=12345.6 min=7.0 period=3600.0]",
+                 OperationScheduler.parseOptions("backoff=5.0++10.0 3600", options).toString());
     }
 
     @SmallTest
diff --git a/photoviewer/.gitignore b/photoviewer/.gitignore
new file mode 100644
index 0000000..ff7ef7d
--- /dev/null
+++ b/photoviewer/.gitignore
@@ -0,0 +1,8 @@
+*~
+*.bak
+*.class
+bin/
+gen/
+*.properties
+.classpath
+.project
diff --git a/variablespeed/jni/variablespeed.cc b/variablespeed/jni/variablespeed.cc
index ea134ec..73ac609 100644
--- a/variablespeed/jni/variablespeed.cc
+++ b/variablespeed/jni/variablespeed.cc
@@ -582,7 +582,7 @@
   const size_t playerInterfaceCount = 2;
   const SLInterfaceID iids[playerInterfaceCount] = {
       SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
-  const SLboolean reqs[playerInterfaceCount] = { SL_BOOLEAN_TRUE };
+  const SLboolean reqs[playerInterfaceCount] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
   OpenSL(engineInterface, CreateAudioPlayer, &audioPlayer, &playingSrc,
       &audioSnk, playerInterfaceCount, iids, reqs);
   setAudioStreamType(audioPlayer, audioStreamType);
@@ -619,7 +619,7 @@
       SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_PREFETCHSTATUS, SL_IID_SEEK,
       SL_IID_METADATAEXTRACTION, SL_IID_ANDROIDCONFIGURATION };
   const SLboolean decodePlayerRequired[decoderInterfaceCount] = {
-      SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
+      SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
   SLDataSource sourceCopy(audioSrc);
   OpenSL(engineInterface, CreateAudioPlayer, &decoder, &sourceCopy, &decDest,
       decoderInterfaceCount, decodePlayerInterfaces, decodePlayerRequired);
diff --git a/widget/java/com/android/ex/widget/StaggeredGridView.java b/widget/java/com/android/ex/widget/StaggeredGridView.java
new file mode 100644
index 0000000..6b6b938
--- /dev/null
+++ b/widget/java/com/android/ex/widget/StaggeredGridView.java
@@ -0,0 +1,1621 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ex.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.v4.util.SparseArrayCompat;
+import android.support.v4.view.MotionEventCompat;
+import android.support.v4.view.VelocityTrackerCompat;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.widget.ListAdapter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * ListView and GridView just not complex enough? Try StaggeredGridView!
+ *
+ * <p>StaggeredGridView presents a multi-column grid with consistent column sizes
+ * but varying row sizes between the columns. Each successive item from a
+ * {@link android.widget.ListAdapter ListAdapter} will be arranged from top to bottom,
+ * left to right. The largest vertical gap is always filled first.</p>
+ *
+ * <p>Item views may span multiple columns as specified by their {@link LayoutParams}.
+ * The attribute <code>android:layout_span</code> may be used when inflating
+ * item views from xml.</p>
+ *
+ * <p>This class is still under development and is not fully functional yet.</p>
+ */
+public class StaggeredGridView extends ViewGroup {
+    private static final String TAG = "StaggeredGridView";
+    private static final boolean DEBUG = false;
+
+    /*
+     * There are a few things you should know if you're going to make modifications
+     * to StaggeredGridView.
+     *
+     * Like ListView, SGV populates from an adapter and recycles views that fall out
+     * of the visible boundaries of the grid. A few invariants always hold:
+     *
+     * - mFirstPosition is the adapter position of the View returned by getChildAt(0).
+     * - Any child index can be translated to an adapter position by adding mFirstPosition.
+     * - Any adapter position can be translated to a child index by subtracting mFirstPosition.
+     * - Views for items in the range [mFirstPosition, mFirstPosition + getChildCount()) are
+     *   currently attached to the grid as children. All other adapter positions do not have
+     *   active views.
+     *
+     * This means a few things thanks to the staggered grid's nature. Some views may stay attached
+     * long after they have scrolled offscreen if removing and recycling them would result in
+     * breaking one of the invariants above.
+     *
+     * LayoutRecords are used to track data about a particular item's layout after the associated
+     * view has been removed. These let positioning and the choice of column for an item
+     * remain consistent even though the rules for filling content up vs. filling down vary.
+     *
+     * Whenever layout parameters for a known LayoutRecord change, other LayoutRecords before
+     * or after it may need to be invalidated. e.g. if the item's height or the number
+     * of columns it spans changes, all bets for other items in the same direction are off
+     * since the cached information no longer applies.
+     */
+
+    private ListAdapter mAdapter;
+
+    public static final int COLUMN_COUNT_AUTO = -1;
+
+    private int mColCountSetting = 2;
+    private int mColCount = 2;
+    private int mMinColWidth = 0;
+    private int mItemMargin;
+
+    private int[] mItemTops;
+    private int[] mItemBottoms;
+
+    private boolean mFastChildLayout;
+    private boolean mPopulating;
+    private boolean mForcePopulateOnLayout;
+    private boolean mInLayout;
+    private int mRestoreOffset;
+
+    private final RecycleBin mRecycler = new RecycleBin();
+
+    private final AdapterDataSetObserver mObserver = new AdapterDataSetObserver();
+
+    private boolean mDataChanged;
+    private int mOldItemCount;
+    private int mItemCount;
+    private boolean mHasStableIds;
+
+    private int mFirstPosition;
+
+    private int mTouchSlop;
+    private int mMaximumVelocity;
+    private int mFlingVelocity;
+    private float mLastTouchY;
+    private float mTouchRemainderY;
+    private int mActivePointerId;
+
+    private static final int TOUCH_MODE_IDLE = 0;
+    private static final int TOUCH_MODE_DRAGGING = 1;
+    private static final int TOUCH_MODE_FLINGING = 2;
+
+    private int mTouchMode;
+    private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
+    private final ScrollerCompat mScroller;
+
+    private final EdgeEffectCompat mTopEdge;
+    private final EdgeEffectCompat mBottomEdge;
+
+    private static final class LayoutRecord {
+        public int column;
+        public long id = -1;
+        public int height;
+        public int span;
+        private int[] mMargins;
+
+        private final void ensureMargins() {
+            if (mMargins == null) {
+                // Don't need to confirm length;
+                // all layoutrecords are purged when column count changes.
+                mMargins = new int[span * 2];
+            }
+        }
+
+        public final int getMarginAbove(int col) {
+            if (mMargins == null) {
+                return 0;
+            }
+            return mMargins[col * 2];
+        }
+
+        public final int getMarginBelow(int col) {
+            if (mMargins == null) {
+                return 0;
+            }
+            return mMargins[col * 2 + 1];
+        }
+
+        public final void setMarginAbove(int col, int margin) {
+            if (mMargins == null && margin == 0) {
+                return;
+            }
+            ensureMargins();
+            mMargins[col * 2] = margin;
+        }
+
+        public final void setMarginBelow(int col, int margin) {
+            if (mMargins == null && margin == 0) {
+                return;
+            }
+            ensureMargins();
+            mMargins[col * 2 + 1] = margin;
+        }
+
+        @Override
+        public String toString() {
+            String result = "LayoutRecord{c=" + column + ", id=" + id + " h=" + height +
+                    " s=" + span;
+            if (mMargins != null) {
+                result += " margins[above, below](";
+                for (int i = 0; i < mMargins.length; i += 2) {
+                    result += "[" + mMargins[i] + ", " + mMargins[i+1] + "]";
+                }
+                result += ")";
+            }
+            return result + "}";
+        }
+    }
+    private final SparseArrayCompat<LayoutRecord> mLayoutRecords =
+            new SparseArrayCompat<LayoutRecord>();
+
+    public StaggeredGridView(Context context) {
+        this(context, null);
+    }
+
+    public StaggeredGridView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public StaggeredGridView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final ViewConfiguration vc = ViewConfiguration.get(context);
+        mTouchSlop = vc.getScaledTouchSlop();
+        mMaximumVelocity = vc.getScaledMaximumFlingVelocity();
+        mFlingVelocity = vc.getScaledMinimumFlingVelocity();
+        mScroller = ScrollerCompat.from(context);
+
+        mTopEdge = new EdgeEffectCompat(context);
+        mBottomEdge = new EdgeEffectCompat(context);
+        setWillNotDraw(false);
+        setClipToPadding(false);
+    }
+
+    /**
+     * Set a fixed number of columns for this grid. Space will be divided evenly
+     * among all columns, respecting the item margin between columns.
+     * The default is 2. (If it were 1, perhaps you should be using a
+     * {@link android.widget.ListView ListView}.)
+     *
+     * @param colCount Number of columns to display.
+     * @see #setMinColumnWidth(int)
+     */
+    public void setColumnCount(int colCount) {
+        if (colCount < 1 && colCount != COLUMN_COUNT_AUTO) {
+            throw new IllegalArgumentException("Column count must be at least 1 - received " +
+                    colCount);
+        }
+        final boolean needsPopulate = colCount != mColCount;
+        mColCount = mColCountSetting = colCount;
+        if (needsPopulate) {
+            populate();
+        }
+    }
+
+    public int getColumnCount() {
+        return mColCount;
+    }
+
+    /**
+     * Set a minimum column width for
+     * @param minColWidth
+     */
+    public void setMinColumnWidth(int minColWidth) {
+        mMinColWidth = minColWidth;
+        setColumnCount(COLUMN_COUNT_AUTO);
+    }
+
+    /**
+     * Set the margin between items in pixels. This margin is applied
+     * both vertically and horizontally.
+     *
+     * @param marginPixels Spacing between items in pixels
+     */
+    public void setItemMargin(int marginPixels) {
+        final boolean needsPopulate = marginPixels != mItemMargin;
+        mItemMargin = marginPixels;
+        if (needsPopulate) {
+            populate();
+        }
+    }
+
+    /**
+     * Return the first adapter position with a view currently attached as
+     * a child view of this grid.
+     *
+     * @return the adapter position represented by the view at getChildAt(0).
+     */
+    public int getFirstPosition() {
+        return mFirstPosition;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        mVelocityTracker.addMovement(ev);
+        final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mVelocityTracker.clear();
+                mScroller.abortAnimation();
+                mLastTouchY = ev.getY();
+                mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
+                mTouchRemainderY = 0;
+                if (mTouchMode == TOUCH_MODE_FLINGING) {
+                    // Catch!
+                    mTouchMode = TOUCH_MODE_DRAGGING;
+                    return true;
+                }
+                break;
+
+            case MotionEvent.ACTION_MOVE: {
+                final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+                if (index < 0) {
+                    Log.e(TAG, "onInterceptTouchEvent could not find pointer with id " +
+                            mActivePointerId + " - did StaggeredGridView receive an inconsistent " +
+                            "event stream?");
+                    return false;
+                }
+                final float y = MotionEventCompat.getY(ev, index);
+                final float dy = y - mLastTouchY + mTouchRemainderY;
+                final int deltaY = (int) dy;
+                mTouchRemainderY = dy - deltaY;
+
+                if (Math.abs(dy) > mTouchSlop) {
+                    mTouchMode = TOUCH_MODE_DRAGGING;
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        mVelocityTracker.addMovement(ev);
+        final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mVelocityTracker.clear();
+                mScroller.abortAnimation();
+                mLastTouchY = ev.getY();
+                mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
+                mTouchRemainderY = 0;
+                break;
+
+            case MotionEvent.ACTION_MOVE: {
+                final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+                if (index < 0) {
+                    Log.e(TAG, "onInterceptTouchEvent could not find pointer with id " +
+                            mActivePointerId + " - did StaggeredGridView receive an inconsistent " +
+                            "event stream?");
+                    return false;
+                }
+                final float y = MotionEventCompat.getY(ev, index);
+                final float dy = y - mLastTouchY + mTouchRemainderY;
+                final int deltaY = (int) dy;
+                mTouchRemainderY = dy - deltaY;
+
+                if (Math.abs(dy) > mTouchSlop) {
+                    mTouchMode = TOUCH_MODE_DRAGGING;
+                }
+
+                if (mTouchMode == TOUCH_MODE_DRAGGING) {
+                    mLastTouchY = y;
+
+                    if (!trackMotionScroll(deltaY, true)) {
+                        // Break fling velocity if we impacted an edge.
+                        mVelocityTracker.clear();
+                    }
+                }
+            } break;
+
+            case MotionEvent.ACTION_CANCEL:
+                mTouchMode = TOUCH_MODE_IDLE;
+                break;
+
+            case MotionEvent.ACTION_UP: {
+                mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                final float velocity = VelocityTrackerCompat.getYVelocity(mVelocityTracker,
+                        mActivePointerId);
+                if (Math.abs(velocity) > mFlingVelocity) { // TODO
+                    mTouchMode = TOUCH_MODE_FLINGING;
+                    mScroller.fling(0, 0, 0, (int) velocity, 0, 0,
+                            Integer.MIN_VALUE, Integer.MAX_VALUE);
+                    mLastTouchY = 0;
+                    ViewCompat.postInvalidateOnAnimation(this);
+                } else {
+                    mTouchMode = TOUCH_MODE_IDLE;
+                }
+
+            } break;
+        }
+        return true;
+    }
+
+    /**
+     *
+     * @param deltaY Pixels that content should move by
+     * @return true if the movement completed, false if it was stopped prematurely.
+     */
+    private boolean trackMotionScroll(int deltaY, boolean allowOverScroll) {
+        final boolean contentFits = contentFits();
+        final int allowOverhang = Math.abs(deltaY);
+
+        final int overScrolledBy;
+        final int movedBy;
+        if (!contentFits) {
+            final int overhang;
+            final boolean up;
+            mPopulating = true;
+            if (deltaY > 0) {
+                overhang = fillUp(mFirstPosition - 1, allowOverhang);
+                up = true;
+            } else {
+                overhang = fillDown(mFirstPosition + getChildCount(), allowOverhang) + mItemMargin;
+                up = false;
+            }
+            movedBy = Math.min(overhang, allowOverhang);
+            offsetChildren(up ? movedBy : -movedBy);
+            recycleOffscreenViews();
+            mPopulating = false;
+            overScrolledBy = allowOverhang - overhang;
+        } else {
+            overScrolledBy = allowOverhang;
+            movedBy = 0;
+        }
+
+        if (allowOverScroll) {
+            final int overScrollMode = ViewCompat.getOverScrollMode(this);
+
+            if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS ||
+                    (overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits)) {
+
+                if (overScrolledBy > 0) {
+                    EdgeEffectCompat edge = deltaY > 0 ? mTopEdge : mBottomEdge;
+                    edge.onPull((float) Math.abs(deltaY) / getHeight());
+                    ViewCompat.postInvalidateOnAnimation(this);
+                }
+            }
+        }
+
+        return deltaY == 0 || movedBy != 0;
+    }
+
+    private final boolean contentFits() {
+        if (mFirstPosition != 0 || getChildCount() != mItemCount) {
+            return false;
+        }
+
+        int topmost = Integer.MAX_VALUE;
+        int bottommost = Integer.MIN_VALUE;
+        for (int i = 0; i < mColCount; i++) {
+            if (mItemTops[i] < topmost) {
+                topmost = mItemTops[i];
+            }
+            if (mItemBottoms[i] > bottommost) {
+                bottommost = mItemBottoms[i];
+            }
+        }
+
+        return topmost >= getPaddingTop() && bottommost <= getHeight() - getPaddingBottom();
+    }
+
+    private void recycleAllViews() {
+        for (int i = 0; i < getChildCount(); i++) {
+            mRecycler.addScrap(getChildAt(i));
+        }
+
+        if (mInLayout) {
+            removeAllViewsInLayout();
+        } else {
+            removeAllViews();
+        }
+    }
+
+    /**
+     * Important: this method will leave offscreen views attached if they
+     * are required to maintain the invariant that child view with index i
+     * is always the view corresponding to position mFirstPosition + i.
+     */
+    private void recycleOffscreenViews() {
+        final int height = getHeight();
+        final int clearAbove = -mItemMargin;
+        final int clearBelow = height + mItemMargin;
+        for (int i = getChildCount() - 1; i >= 0; i--) {
+            final View child = getChildAt(i);
+            if (child.getTop() <= clearBelow)  {
+                // There may be other offscreen views, but we need to maintain
+                // the invariant documented above.
+                break;
+            }
+
+            if (mInLayout) {
+                removeViewsInLayout(i, 1);
+            } else {
+                removeViewAt(i);
+            }
+
+            mRecycler.addScrap(child);
+        }
+
+        while (getChildCount() > 0) {
+            final View child = getChildAt(0);
+            if (child.getBottom() >= clearAbove) {
+                // There may be other offscreen views, but we need to maintain
+                // the invariant documented above.
+                break;
+            }
+
+            if (mInLayout) {
+                removeViewsInLayout(0, 1);
+            } else {
+                removeViewAt(0);
+            }
+
+            mRecycler.addScrap(child);
+            mFirstPosition++;
+        }
+
+        final int childCount = getChildCount();
+        if (childCount > 0) {
+            // Repair the top and bottom column boundaries from the views we still have
+            Arrays.fill(mItemTops, Integer.MAX_VALUE);
+            Arrays.fill(mItemBottoms, Integer.MIN_VALUE);
+
+            for (int i = 0; i < childCount; i++){
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                final int top = child.getTop() - mItemMargin;
+                final int bottom = child.getBottom();
+                final LayoutRecord rec = mLayoutRecords.get(mFirstPosition + i);
+
+                final int colEnd = lp.column + Math.min(mColCount, lp.span);
+                for (int col = lp.column; col < colEnd; col++) {
+                    final int colTop = top - rec.getMarginAbove(col - lp.column);
+                    final int colBottom = bottom + rec.getMarginBelow(col - lp.column);
+                    if (colTop < mItemTops[col]) {
+                        mItemTops[col] = colTop;
+                    }
+                    if (colBottom > mItemBottoms[col]) {
+                        mItemBottoms[col] = colBottom;
+                    }
+                }
+            }
+
+            for (int col = 0; col < mColCount; col++) {
+                if (mItemTops[col] == Integer.MAX_VALUE) {
+                    // If one was untouched, both were.
+                    mItemTops[col] = 0;
+                    mItemBottoms[col] = 0;
+                }
+            }
+        }
+    }
+
+    public void computeScroll() {
+        if (mScroller.computeScrollOffset()) {
+            final int y = mScroller.getCurrY();
+            final int dy = (int) (y - mLastTouchY);
+            mLastTouchY = y;
+            final boolean stopped = !trackMotionScroll(dy, false);
+
+            if (!stopped && !mScroller.isFinished()) {
+                ViewCompat.postInvalidateOnAnimation(this);
+            } else {
+                if (stopped) {
+                    final int overScrollMode = ViewCompat.getOverScrollMode(this);
+                    if (overScrollMode != ViewCompat.OVER_SCROLL_NEVER) {
+                        final EdgeEffectCompat edge;
+                        if (dy > 0) {
+                            edge = mTopEdge;
+                        } else {
+                            edge = mBottomEdge;
+                        }
+                        edge.onAbsorb(Math.abs((int) mScroller.getCurrVelocity()));
+                        ViewCompat.postInvalidateOnAnimation(this);
+                    }
+                    mScroller.abortAnimation();
+                }
+                mTouchMode = TOUCH_MODE_IDLE;
+            }
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        if (mTopEdge != null) {
+            boolean needsInvalidate = false;
+            if (!mTopEdge.isFinished()) {
+                mTopEdge.draw(canvas);
+                needsInvalidate = true;
+            }
+            if (!mBottomEdge.isFinished()) {
+                final int restoreCount = canvas.save();
+                final int width = getWidth();
+                canvas.translate(-width, getHeight());
+                canvas.rotate(180, width, 0);
+                mBottomEdge.draw(canvas);
+                canvas.restoreToCount(restoreCount);
+                needsInvalidate = true;
+            }
+
+            if (needsInvalidate) {
+                ViewCompat.postInvalidateOnAnimation(this);
+            }
+        }
+    }
+
+    public void beginFastChildLayout() {
+        mFastChildLayout = true;
+    }
+
+    public void endFastChildLayout() {
+        mFastChildLayout = false;
+        populate();
+    }
+
+    @Override
+    public void requestLayout() {
+        if (!mPopulating && !mFastChildLayout) {
+            super.requestLayout();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+        if (widthMode != MeasureSpec.EXACTLY) {
+            Log.e(TAG, "onMeasure: must have an exact width or match_parent! " +
+                    "Using fallback spec of EXACTLY " + widthSize);
+            widthMode = MeasureSpec.EXACTLY;
+        }
+        if (heightMode != MeasureSpec.EXACTLY) {
+            Log.e(TAG, "onMeasure: must have an exact height or match_parent! " +
+                    "Using fallback spec of EXACTLY " + heightSize);
+            heightMode = MeasureSpec.EXACTLY;
+        }
+
+        setMeasuredDimension(widthSize, heightSize);
+
+        if (mColCountSetting == COLUMN_COUNT_AUTO) {
+            final int colCount = widthSize / mMinColWidth;
+            if (colCount != mColCount) {
+                mColCount = colCount;
+                mForcePopulateOnLayout = true;
+            }
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        mInLayout = true;
+        populate();
+        mInLayout = false;
+        mForcePopulateOnLayout = false;
+
+        final int width = r - l;
+        final int height = b - t;
+        mTopEdge.setSize(width, height);
+        mBottomEdge.setSize(width, height);
+    }
+
+    private void populate() {
+        if (getWidth() == 0 || getHeight() == 0) {
+            return;
+        }
+
+        if (mColCount == COLUMN_COUNT_AUTO) {
+            final int colCount = getWidth() / mMinColWidth;
+            if (colCount != mColCount) {
+                mColCount = colCount;
+            }
+        }
+
+        final int colCount = mColCount;
+        if (mItemTops == null || mItemTops.length != colCount) {
+            mItemTops = new int[colCount];
+            mItemBottoms = new int[colCount];
+            final int top = getPaddingTop();
+            final int offset = top + Math.min(mRestoreOffset, 0);
+            Arrays.fill(mItemTops, offset);
+            Arrays.fill(mItemBottoms, offset);
+            mLayoutRecords.clear();
+            if (mInLayout) {
+                removeAllViewsInLayout();
+            } else {
+                removeAllViews();
+            }
+            mRestoreOffset = 0;
+        }
+
+        mPopulating = true;
+        layoutChildren(mDataChanged);
+        fillDown(mFirstPosition + getChildCount(), 0);
+        fillUp(mFirstPosition - 1, 0);
+        mPopulating = false;
+        mDataChanged = false;
+    }
+
+    private void dumpItemPositions() {
+        final int childCount = getChildCount();
+        Log.d(TAG, "dumpItemPositions:");
+        Log.d(TAG, " => Tops:");
+        for (int i = 0; i < mColCount; i++) {
+            Log.d(TAG, "  => " + mItemTops[i]);
+            boolean found = false;
+            for (int j = 0; j < childCount; j++) {
+                final View child = getChildAt(j);
+                if (mItemTops[i] == child.getTop() - mItemMargin) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                Log.d(TAG, "!!! No top item found for column " + i + " value " + mItemTops[i]);
+            }
+        }
+        Log.d(TAG, " => Bottoms:");
+        for (int i = 0; i < mColCount; i++) {
+            Log.d(TAG, "  => " + mItemBottoms[i]);
+            boolean found = false;
+            for (int j = 0; j < childCount; j++) {
+                final View child = getChildAt(j);
+                if (mItemBottoms[i] == child.getBottom()) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                Log.d(TAG, "!!! No bottom item found for column " + i + " value " + mItemBottoms[i]);
+            }
+        }
+    }
+
+    final void offsetChildren(int offset) {
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            child.layout(child.getLeft(), child.getTop() + offset,
+                    child.getRight(), child.getBottom() + offset);
+        }
+
+        final int colCount = mColCount;
+        for (int i = 0; i < colCount; i++) {
+            mItemTops[i] += offset;
+            mItemBottoms[i] += offset;
+        }
+    }
+
+    /**
+     * Measure and layout all currently visible children.
+     *
+     * @param queryAdapter true to requery the adapter for view data
+     */
+    final void layoutChildren(boolean queryAdapter) {
+        final int paddingLeft = getPaddingLeft();
+        final int paddingRight = getPaddingRight();
+        final int itemMargin = mItemMargin;
+        final int colWidth =
+                (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount;
+        int rebuildLayoutRecordsBefore = -1;
+        int rebuildLayoutRecordsAfter = -1;
+
+        Arrays.fill(mItemBottoms, Integer.MIN_VALUE);
+
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            final int col = lp.column;
+            final int position = mFirstPosition + i;
+            final boolean needsLayout = queryAdapter || child.isLayoutRequested();
+
+            if (queryAdapter) {
+                View newView = obtainView(position, child);
+                if (newView != child) {
+                    removeViewAt(i);
+                    addView(newView, i);
+                    child = newView;
+                }
+                lp = (LayoutParams) child.getLayoutParams(); // Might have changed
+            }
+
+            final int span = Math.min(mColCount, lp.span);
+            final int widthSize = colWidth * span + itemMargin * (span - 1);
+
+            if (needsLayout) {
+                final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
+
+                final int heightSpec;
+                if (lp.height == LayoutParams.WRAP_CONTENT) {
+                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+                } else {
+                    heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
+                }
+
+                child.measure(widthSpec, heightSpec);
+            }
+
+            int childTop = mItemBottoms[col] > Integer.MIN_VALUE ?
+                    mItemBottoms[col] + mItemMargin : child.getTop();
+            if (span > 1) {
+                int lowest = childTop;
+                for (int j = col + 1; j < col + span; j++) {
+                    final int bottom = mItemBottoms[j] + mItemMargin;
+                    if (bottom > lowest) {
+                        lowest = bottom;
+                    }
+                }
+                childTop = lowest;
+            }
+            final int childHeight = child.getMeasuredHeight();
+            final int childBottom = childTop + childHeight;
+            final int childLeft = paddingLeft + col * (colWidth + itemMargin);
+            final int childRight = childLeft + child.getMeasuredWidth();
+            child.layout(childLeft, childTop, childRight, childBottom);
+
+            for (int j = col; j < col + span; j++) {
+                mItemBottoms[j] = childBottom;
+            }
+
+            final LayoutRecord rec = mLayoutRecords.get(position);
+            if (rec != null && rec.height != childHeight) {
+                // Invalidate our layout records for everything before this.
+                rec.height = childHeight;
+                rebuildLayoutRecordsBefore = position;
+            }
+
+            if (rec != null && rec.span != span) {
+                // Invalidate our layout records for everything after this.
+                rec.span = span;
+                rebuildLayoutRecordsAfter = position;
+            }
+        }
+
+        // Update mItemBottoms for any empty columns
+        for (int i = 0; i < mColCount; i++) {
+            if (mItemBottoms[i] == Integer.MIN_VALUE) {
+                mItemBottoms[i] = mItemTops[i];
+            }
+        }
+
+        if (rebuildLayoutRecordsBefore >= 0 || rebuildLayoutRecordsAfter >= 0) {
+            if (rebuildLayoutRecordsBefore >= 0) {
+                invalidateLayoutRecordsBeforePosition(rebuildLayoutRecordsBefore);
+            }
+            if (rebuildLayoutRecordsAfter >= 0) {
+                invalidateLayoutRecordsAfterPosition(rebuildLayoutRecordsAfter);
+            }
+            for (int i = 0; i < childCount; i++) {
+                final int position = mFirstPosition + i;
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                LayoutRecord rec = mLayoutRecords.get(position);
+                if (rec == null) {
+                    rec = new LayoutRecord();
+                    mLayoutRecords.put(position, rec);
+                }
+                rec.column = lp.column;
+                rec.height = child.getHeight();
+                rec.id = lp.id;
+                rec.span = Math.min(mColCount, lp.span);
+            }
+        }
+    }
+
+    final void invalidateLayoutRecordsBeforePosition(int position) {
+        int endAt = 0;
+        while (endAt < mLayoutRecords.size() && mLayoutRecords.keyAt(endAt) < position) {
+            endAt++;
+        }
+        mLayoutRecords.removeAtRange(0, endAt);
+    }
+
+    final void invalidateLayoutRecordsAfterPosition(int position) {
+        int beginAt = mLayoutRecords.size() - 1;
+        while (beginAt >= 0 && mLayoutRecords.keyAt(beginAt) > position) {
+            beginAt--;
+        }
+        beginAt++;
+        mLayoutRecords.removeAtRange(beginAt + 1, mLayoutRecords.size() - beginAt);
+    }
+
+    /**
+     * Should be called with mPopulating set to true
+     *
+     * @param fromPosition Position to start filling from
+     * @param overhang the number of extra pixels to fill beyond the current top edge
+     * @return the max overhang beyond the beginning of the view of any added items at the top
+     */
+    final int fillUp(int fromPosition, int overhang) {
+        final int paddingLeft = getPaddingLeft();
+        final int paddingRight = getPaddingRight();
+        final int itemMargin = mItemMargin;
+        final int colWidth =
+                (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount;
+        final int gridTop = getPaddingTop();
+        final int fillTo = gridTop - overhang;
+        int nextCol = getNextColumnUp();
+        int position = fromPosition;
+
+        while (nextCol >= 0 && mItemTops[nextCol] > fillTo && position >= 0) {
+            final View child = obtainView(position, null);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (child.getParent() != this) {
+                if (mInLayout) {
+                    addViewInLayout(child, 0, lp);
+                } else {
+                    addView(child, 0);
+                }
+            }
+
+            final int span = Math.min(mColCount, lp.span);
+            final int widthSize = colWidth * span + itemMargin * (span - 1);
+            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
+
+            LayoutRecord rec;
+            if (span > 1) {
+                rec = getNextRecordUp(position, span);
+                nextCol = rec.column;
+            } else {
+                rec = mLayoutRecords.get(position);
+            }
+
+            boolean invalidateBefore = false;
+            if (rec == null) {
+                rec = new LayoutRecord();
+                mLayoutRecords.put(position, rec);
+                rec.column = nextCol;
+                rec.span = span;
+            } else if (span != rec.span) {
+                rec.span = span;
+                rec.column = nextCol;
+                invalidateBefore = true;
+            } else {
+                nextCol = rec.column;
+            }
+
+            if (mHasStableIds) {
+                final long id = mAdapter.getItemId(position);
+                rec.id = id;
+                lp.id = id;
+            }
+
+            lp.column = nextCol;
+
+            final int heightSpec;
+            if (lp.height == LayoutParams.WRAP_CONTENT) {
+                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            } else {
+                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
+            }
+            child.measure(widthSpec, heightSpec);
+
+            final int childHeight = child.getMeasuredHeight();
+            if (invalidateBefore || (childHeight != rec.height && rec.height > 0)) {
+                invalidateLayoutRecordsBeforePosition(position);
+            }
+            rec.height = childHeight;
+
+            final int startFrom;
+            if (span > 1) {
+                int highest = mItemTops[nextCol];
+                for (int i = nextCol + 1; i < nextCol + span; i++) {
+                    final int top = mItemTops[i];
+                    if (top < highest) {
+                        highest = top;
+                    }
+                }
+                startFrom = highest;
+            } else {
+                startFrom = mItemTops[nextCol];
+            }
+            final int childBottom = startFrom;
+            final int childTop = childBottom - childHeight;
+            final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin);
+            final int childRight = childLeft + child.getMeasuredWidth();
+            child.layout(childLeft, childTop, childRight, childBottom);
+
+            for (int i = nextCol; i < nextCol + span; i++) {
+                mItemTops[i] = childTop - rec.getMarginAbove(i - nextCol) - itemMargin;
+            }
+
+            nextCol = getNextColumnUp();
+            mFirstPosition = position--;
+        }
+
+        int highestView = getHeight();
+        for (int i = 0; i < mColCount; i++) {
+            if (mItemTops[i] < highestView) {
+                highestView = mItemTops[i];
+            }
+        }
+        return gridTop - highestView;
+    }
+
+    /**
+     * Should be called with mPopulating set to true
+     *
+     * @param fromPosition Position to start filling from
+     * @param overhang the number of extra pixels to fill beyond the current bottom edge
+     * @return the max overhang beyond the end of the view of any added items at the bottom
+     */
+    final int fillDown(int fromPosition, int overhang) {
+        final int paddingLeft = getPaddingLeft();
+        final int paddingRight = getPaddingRight();
+        final int itemMargin = mItemMargin;
+        final int colWidth =
+                (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount;
+        final int gridBottom = getHeight() - getPaddingBottom();
+        final int fillTo = gridBottom + overhang;
+        int nextCol = getNextColumnDown();
+        int position = fromPosition;
+
+        while (nextCol >= 0 && mItemBottoms[nextCol] < fillTo && position < mItemCount) {
+            final View child = obtainView(position, null);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (child.getParent() != this) {
+                if (mInLayout) {
+                    addViewInLayout(child, -1, lp);
+                } else {
+                    addView(child);
+                }
+            }
+
+            final int span = Math.min(mColCount, lp.span);
+            final int widthSize = colWidth * span + itemMargin * (span - 1);
+            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
+
+            LayoutRecord rec;
+            if (span > 1) {
+                rec = getNextRecordDown(position, span);
+                nextCol = rec.column;
+            } else {
+                rec = mLayoutRecords.get(position);
+            }
+
+            boolean invalidateAfter = false;
+            if (rec == null) {
+                rec = new LayoutRecord();
+                mLayoutRecords.put(position, rec);
+                rec.column = nextCol;
+                rec.span = span;
+            } else if (span != rec.span) {
+                rec.span = span;
+                rec.column = nextCol;
+                invalidateAfter = true;
+            } else {
+                nextCol = rec.column;
+            }
+
+            if (mHasStableIds) {
+                final long id = mAdapter.getItemId(position);
+                rec.id = id;
+                lp.id = id;
+            }
+
+            lp.column = nextCol;
+
+            final int heightSpec;
+            if (lp.height == LayoutParams.WRAP_CONTENT) {
+                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            } else {
+                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
+            }
+            child.measure(widthSpec, heightSpec);
+
+            final int childHeight = child.getMeasuredHeight();
+            if (invalidateAfter || (childHeight != rec.height && rec.height > 0)) {
+                invalidateLayoutRecordsAfterPosition(position);
+            }
+            rec.height = childHeight;
+
+            final int startFrom;
+            if (span > 1) {
+                int lowest = mItemBottoms[nextCol];
+                for (int i = nextCol + 1; i < nextCol + span; i++) {
+                    final int bottom = mItemBottoms[i];
+                    if (bottom > lowest) {
+                        lowest = bottom;
+                    }
+                }
+                startFrom = lowest;
+            } else {
+                startFrom = mItemBottoms[nextCol];
+            }
+            final int childTop = startFrom + itemMargin;
+            final int childBottom = childTop + childHeight;
+            final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin);
+            final int childRight = childLeft + child.getMeasuredWidth();
+            child.layout(childLeft, childTop, childRight, childBottom);
+
+            for (int i = nextCol; i < nextCol + span; i++) {
+                mItemBottoms[i] = childBottom + rec.getMarginBelow(i - nextCol);
+            }
+
+            nextCol = getNextColumnDown();
+            position++;
+        }
+
+        int lowestView = 0;
+        for (int i = 0; i < mColCount; i++) {
+            if (mItemBottoms[i] > lowestView) {
+                lowestView = mItemBottoms[i];
+            }
+        }
+        return lowestView - gridBottom;
+    }
+
+    /**
+     * @return column that the next view filling upwards should occupy. This is the bottom-most
+     *         position available for a single-column item.
+     */
+    final int getNextColumnUp() {
+        int result = -1;
+        int bottomMost = Integer.MIN_VALUE;
+
+        final int colCount = mColCount;
+        for (int i = colCount - 1; i >= 0; i--) {
+            final int top = mItemTops[i];
+            if (top > bottomMost) {
+                bottomMost = top;
+                result = i;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Return a LayoutRecord for the given position
+     * @param position
+     * @param span
+     * @return
+     */
+    final LayoutRecord getNextRecordUp(int position, int span) {
+        LayoutRecord rec = mLayoutRecords.get(position);
+        if (rec == null) {
+            rec = new LayoutRecord();
+            rec.span = span;
+            mLayoutRecords.put(position, rec);
+        } else if (rec.span != span) {
+            throw new IllegalStateException("Invalid LayoutRecord! Record had span=" + rec.span +
+                    " but caller requested span=" + span + " for position=" + position);
+        }
+        int targetCol = -1;
+        int bottomMost = Integer.MIN_VALUE;
+
+        final int colCount = mColCount;
+        for (int i = colCount - span; i >= 0; i--) {
+            int top = Integer.MAX_VALUE;
+            for (int j = i; j < i + span; j++) {
+                final int singleTop = mItemTops[j];
+                if (singleTop < top) {
+                    top = singleTop;
+                }
+            }
+            if (top > bottomMost) {
+                bottomMost = top;
+                targetCol = i;
+            }
+        }
+
+        rec.column = targetCol;
+
+        for (int i = 0; i < span; i++) {
+            rec.setMarginBelow(i, mItemTops[i + targetCol] - bottomMost);
+        }
+
+        return rec;
+    }
+
+    /**
+     * @return column that the next view filling downwards should occupy. This is the top-most
+     *         position available.
+     */
+    final int getNextColumnDown() {
+        int result = -1;
+        int topMost = Integer.MAX_VALUE;
+
+        final int colCount = mColCount;
+        for (int i = 0; i < colCount; i++) {
+            final int bottom = mItemBottoms[i];
+            if (bottom < topMost) {
+                topMost = bottom;
+                result = i;
+            }
+        }
+        return result;
+    }
+
+    final LayoutRecord getNextRecordDown(int position, int span) {
+        LayoutRecord rec = mLayoutRecords.get(position);
+        if (rec == null) {
+            rec = new LayoutRecord();
+            rec.span = span;
+            mLayoutRecords.put(position, rec);
+        } else if (rec.span != span) {
+            throw new IllegalStateException("Invalid LayoutRecord! Record had span=" + rec.span +
+                    " but caller requested span=" + span + " for position=" + position);
+        }
+        int targetCol = -1;
+        int topMost = Integer.MAX_VALUE;
+
+        final int colCount = mColCount;
+        for (int i = 0; i <= colCount - span; i++) {
+            int bottom = Integer.MIN_VALUE;
+            for (int j = i; j < i + span; j++) {
+                final int singleBottom = mItemBottoms[j];
+                if (singleBottom > bottom) {
+                    bottom = singleBottom;
+                }
+            }
+            if (bottom < topMost) {
+                topMost = bottom;
+                targetCol = i;
+            }
+        }
+
+        rec.column = targetCol;
+
+        for (int i = 0; i < span; i++) {
+            rec.setMarginAbove(i, topMost - mItemBottoms[i + targetCol]);
+        }
+
+        return rec;
+    }
+
+    /**
+     * Obtain a populated view from the adapter. If optScrap is non-null and is not
+     * reused it will be placed in the recycle bin.
+     *
+     * @param position position to get view for
+     * @param optScrap Optional scrap view; will be reused if possible
+     * @return A new view, a recycled view from mRecycler, or optScrap
+     */
+    final View obtainView(int position, View optScrap) {
+        View view = mRecycler.getTransientStateView(position);
+        if (view != null) {
+            return view;
+        }
+
+        // Reuse optScrap if it's of the right type (and not null)
+        final int optType = optScrap != null ?
+                ((LayoutParams) optScrap.getLayoutParams()).viewType : -1;
+        final int positionViewType = mAdapter.getItemViewType(position);
+        final View scrap = optType == positionViewType ?
+                optScrap : mRecycler.getScrapView(positionViewType);
+
+        view = mAdapter.getView(position, scrap, this);
+
+        if (view != scrap && scrap != null) {
+            // The adapter didn't use it; put it back.
+            mRecycler.addScrap(scrap);
+        }
+
+        ViewGroup.LayoutParams lp = view.getLayoutParams();
+
+        if (view.getParent() != this) {
+            if (lp == null) {
+                lp = generateDefaultLayoutParams();
+            } else if (!checkLayoutParams(lp)) {
+                lp = generateLayoutParams(lp);
+            }
+        }
+
+        final LayoutParams sglp = (LayoutParams) lp;
+        sglp.position = position;
+        sglp.viewType = positionViewType;
+
+        return view;
+    }
+
+    public ListAdapter getAdapter() {
+        return mAdapter;
+    }
+
+    public void setAdapter(ListAdapter adapter) {
+        if (mAdapter != null) {
+            mAdapter.unregisterDataSetObserver(mObserver);
+        }
+        // TODO: If the new adapter says that there are stable IDs, remove certain layout records
+        // and onscreen views if they have changed instead of removing all of the state here.
+        clearAllState();
+        mAdapter = adapter;
+        mDataChanged = true;
+        mOldItemCount = mItemCount = adapter != null ? adapter.getCount() : 0;
+        if (adapter != null) {
+            adapter.registerDataSetObserver(mObserver);
+            mRecycler.setViewTypeCount(adapter.getViewTypeCount());
+            mHasStableIds = adapter.hasStableIds();
+        } else {
+            mHasStableIds = false;
+        }
+        populate();
+    }
+
+    /**
+     * Clear all state because the grid will be used for a completely different set of data.
+     */
+    private void clearAllState() {
+        // Clear all layout records and views
+        mLayoutRecords.clear();
+        removeAllViews();
+
+        // Reset to the top of the grid
+        resetStateForGridTop();
+
+        // Clear recycler because there could be different view types now
+        mRecycler.clear();
+    }
+
+    /**
+     * Reset all internal state to be at the top of the grid.
+     */
+    private void resetStateForGridTop() {
+        // Reset mItemTops and mItemBottoms
+        final int colCount = mColCount;
+        if (mItemTops == null || mItemTops.length != colCount) {
+            mItemTops = new int[colCount];
+            mItemBottoms = new int[colCount];
+        }
+        final int top = getPaddingTop();
+        Arrays.fill(mItemTops, top);
+        Arrays.fill(mItemBottoms, top);
+
+        // Reset the first visible position in the grid to be item 0
+        mFirstPosition = 0;
+        mRestoreOffset = 0;
+    }
+
+    /**
+     * Scroll the list so the first visible position in the grid is the first item in the adapter.
+     */
+    public void setSelectionToTop() {
+        // Clear out the views (but don't clear out the layout records or recycler because the data
+        // has not changed)
+        removeAllViews();
+
+        // Reset to top of grid
+        resetStateForGridTop();
+
+        // Start populating again
+        populate();
+    }
+
+    @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams(LayoutParams.WRAP_CONTENT);
+    }
+
+    @Override
+    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
+        return new LayoutParams(lp);
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams lp) {
+        return lp instanceof LayoutParams;
+    }
+
+    @Override
+    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        final Parcelable superState = super.onSaveInstanceState();
+        final SavedState ss = new SavedState(superState);
+        final int position = mFirstPosition;
+        ss.position = position;
+        if (position >= 0 && mAdapter != null && position < mAdapter.getCount()) {
+            ss.firstId = mAdapter.getItemId(position);
+        }
+        if (getChildCount() > 0) {
+            ss.topOffset = getChildAt(0).getTop() - mItemMargin - getPaddingTop();
+        }
+        return ss;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mDataChanged = true;
+        mFirstPosition = ss.position;
+        mRestoreOffset = ss.topOffset;
+        requestLayout();
+    }
+
+    public static class LayoutParams extends ViewGroup.LayoutParams {
+        private static final int[] LAYOUT_ATTRS = new int[] {
+            android.R.attr.layout_span
+        };
+
+        private static final int SPAN_INDEX = 0;
+
+        /**
+         * The number of columns this item should span
+         */
+        public int span = 1;
+
+        /**
+         * Item position this view represents
+         */
+        int position;
+
+        /**
+         * Type of this view as reported by the adapter
+         */
+        int viewType;
+
+        /**
+         * The column this view is occupying
+         */
+        int column;
+
+        /**
+         * The stable ID of the item this view displays
+         */
+        long id = -1;
+
+        public LayoutParams(int height) {
+            super(FILL_PARENT, height);
+
+            if (this.height == FILL_PARENT) {
+                Log.w(TAG, "Constructing LayoutParams with height FILL_PARENT - " +
+                        "impossible! Falling back to WRAP_CONTENT");
+                this.height = WRAP_CONTENT;
+            }
+        }
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+
+            if (this.width != FILL_PARENT) {
+                Log.w(TAG, "Inflation setting LayoutParams width to " + this.width +
+                        " - must be MATCH_PARENT");
+                this.width = FILL_PARENT;
+            }
+            if (this.height == FILL_PARENT) {
+                Log.w(TAG, "Inflation setting LayoutParams height to MATCH_PARENT - " +
+                        "impossible! Falling back to WRAP_CONTENT");
+                this.height = WRAP_CONTENT;
+            }
+
+            TypedArray a = c.obtainStyledAttributes(attrs, LAYOUT_ATTRS);
+            span = a.getInteger(SPAN_INDEX, 1);
+            a.recycle();
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams other) {
+            super(other);
+
+            if (this.width != FILL_PARENT) {
+                Log.w(TAG, "Constructing LayoutParams with width " + this.width +
+                        " - must be MATCH_PARENT");
+                this.width = FILL_PARENT;
+            }
+            if (this.height == FILL_PARENT) {
+                Log.w(TAG, "Constructing LayoutParams with height MATCH_PARENT - " +
+                        "impossible! Falling back to WRAP_CONTENT");
+                this.height = WRAP_CONTENT;
+            }
+        }
+    }
+
+    private class RecycleBin {
+        private ArrayList<View>[] mScrapViews;
+        private int mViewTypeCount;
+        private int mMaxScrap;
+
+        private SparseArray<View> mTransientStateViews;
+
+        public void setViewTypeCount(int viewTypeCount) {
+            if (viewTypeCount < 1) {
+                throw new IllegalArgumentException("Must have at least one view type (" +
+                        viewTypeCount + " types reported)");
+            }
+            if (viewTypeCount == mViewTypeCount) {
+                return;
+            }
+
+            ArrayList<View>[] scrapViews = new ArrayList[viewTypeCount];
+            for (int i = 0; i < viewTypeCount; i++) {
+                scrapViews[i] = new ArrayList<View>();
+            }
+            mViewTypeCount = viewTypeCount;
+            mScrapViews = scrapViews;
+        }
+
+        public void clear() {
+            final int typeCount = mViewTypeCount;
+            for (int i = 0; i < typeCount; i++) {
+                mScrapViews[i].clear();
+            }
+            if (mTransientStateViews != null) {
+                mTransientStateViews.clear();
+            }
+        }
+
+        public void clearTransientViews() {
+            if (mTransientStateViews != null) {
+                mTransientStateViews.clear();
+            }
+        }
+
+        public void addScrap(View v) {
+            final LayoutParams lp = (LayoutParams) v.getLayoutParams();
+            if (ViewCompat.hasTransientState(v)) {
+                if (mTransientStateViews == null) {
+                    mTransientStateViews = new SparseArray<View>();
+                }
+                mTransientStateViews.put(lp.position, v);
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount > mMaxScrap) {
+                mMaxScrap = childCount;
+            }
+
+            ArrayList<View> scrap = mScrapViews[lp.viewType];
+            if (scrap.size() < mMaxScrap) {
+                scrap.add(v);
+            }
+        }
+
+        public View getTransientStateView(int position) {
+            if (mTransientStateViews == null) {
+                return null;
+            }
+
+            final View result = mTransientStateViews.get(position);
+            if (result != null) {
+                mTransientStateViews.remove(position);
+            }
+            return result;
+        }
+
+        public View getScrapView(int type) {
+            ArrayList<View> scrap = mScrapViews[type];
+            if (scrap.isEmpty()) {
+                return null;
+            }
+
+            final int index = scrap.size() - 1;
+            final View result = scrap.get(index);
+            scrap.remove(index);
+            return result;
+        }
+    }
+
+    private class AdapterDataSetObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            mDataChanged = true;
+            mOldItemCount = mItemCount;
+            mItemCount = mAdapter.getCount();
+
+            // TODO: Consider matching these back up if we have stable IDs.
+            mRecycler.clearTransientViews();
+
+            if (!mHasStableIds) {
+                // Clear all layout records and recycle the views
+                mLayoutRecords.clear();
+                recycleAllViews();
+
+                // Reset item bottoms to be equal to item tops
+                final int colCount = mColCount;
+                for (int i = 0; i < colCount; i++) {
+                    mItemBottoms[i] = mItemTops[i];
+                }
+            }
+
+            // TODO: consider repopulating in a deferred runnable instead
+            // (so that successive changes may still be batched)
+            requestLayout();
+        }
+
+        @Override
+        public void onInvalidated() {
+        }
+    }
+
+    static class SavedState extends BaseSavedState {
+        long firstId = -1;
+        int position;
+        int topOffset;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            firstId = in.readLong();
+            position = in.readInt();
+            topOffset = in.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeLong(firstId);
+            out.writeInt(position);
+            out.writeInt(topOffset);
+        }
+
+        @Override
+        public String toString() {
+            return "StaggereGridView.SavedState{"
+			+ Integer.toHexString(System.identityHashCode(this))
+			+ " firstId=" + firstId
+			+ " position=" + position + "}";
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+}
