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 cfd6b25..c786126 100644
--- a/chips/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java
@@ -406,6 +406,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.
@@ -2242,43 +2280,6 @@
         }
     }
 
-    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) {
         char last;
         int end = getSelectionEnd() == 0 ? 0 : getSelectionEnd() - 1;
@@ -2358,6 +2359,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];
+            }
+        };
+    }
+}
