am 6e21ec3f: am 9811d58e: Merge "Add the "Abort message:" line to the preserved stack output."

* commit '6e21ec3fc9df759c1dd61408247847547f3501da':
  Add the "Abort message:" line to the preserved stack output.
diff --git a/build/Android.mk b/build/Android.mk
index f8578d2..117e3e0 100644
--- a/build/Android.mk
+++ b/build/Android.mk
@@ -139,11 +139,14 @@
 endef
 
 ANDROID_SUPPORT_LIBRARIES := \
+    android-support-annotations \
     android-support-v4 \
     android-support-v7-gridlayout \
     android-support-v7-appcompat \
     android-support-v7-mediarouter \
-    android-support-v13
+    android-support-v7-recyclerview \
+    android-support-v13 \
+    android-support-v17-leanback
 
 $(foreach lib, $(ANDROID_SUPPORT_LIBRARIES), $(eval $(call _package_sdk_library,$(lib))))
 
diff --git a/build/sdk.atree b/build/sdk.atree
index 91442be..dbc8a0c 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -170,8 +170,7 @@
 docs/features.txt                         platforms/${PLATFORM_NAME}/data/features.txt
 
 # fonts for layoutlib.
-frameworks/base/data/fonts                platforms/${PLATFORM_NAME}/data/fonts
-external/noto-fonts                       platforms/${PLATFORM_NAME}/data/fonts
+${FONT_OUT}                               platforms/${PLATFORM_NAME}/data/fonts
 
 # NOTICE files are copied by build/core/Makefile from sdk.git
 development/sdk/sdk_files_NOTICE.txt      platforms/${PLATFORM_NAME}/templates/NOTICE.txt
@@ -264,10 +263,13 @@
 developers/build/prebuilts/gradle/DisplayingBitmaps                          samples/${PLATFORM_NAME}/ui/DisplayingBitmaps
 developers/build/prebuilts/gradle/BasicTransition                            samples/${PLATFORM_NAME}/ui/BasicTransition
 developers/build/prebuilts/gradle/AdapterTransition                          samples/${PLATFORM_NAME}/ui/AdapterTransition
+developers/build/prebuilts/gradle/CustomTransition                           samples/${PLATFORM_NAME}/ui/CustomTransition
+developers/build/prebuilts/gradle/FragmentTransition                         samples/${PLATFORM_NAME}/ui/FragmentTransition
+developers/build/prebuilts/gradle/SwipeRefreshLayoutBasic                    samples/${PLATFORM_NAME}/ui/SwipeRefreshLayoutBasic
+developers/build/prebuilts/gradle/SwipeRefreshListFragment                   samples/${PLATFORM_NAME}/ui/SwipeRefreshListFragment
+developers/build/prebuilts/gradle/SwipeRefreshMultipleViews                  samples/${PLATFORM_NAME}/ui/SwipeRefreshMultipleViews
 developers/build/prebuilts/gradle/MediaRouter                                samples/${PLATFORM_NAME}/media/MediaRouter
 
-
-
 # Old sample tree
 development/samples/AccelerometerPlay          samples/${PLATFORM_NAME}/legacy/AccelerometerPlay
 development/samples/ActionBarCompat            samples/${PLATFORM_NAME}/legacy/ActionBarCompat
@@ -337,6 +339,8 @@
 development/sdk/support_README.txt                                                                extras/android/support/README.txt
 development/sdk/sdk_files_NOTICE.txt                                                              extras/android/support/NOTICE.txt
 
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-annotations_intermediates/android-support-annotations.jar extras/android/support/annotations/android-support-annotations.jar
+
 ${OUT_DIR}/target/common/obj/PACKAGING/android-support-v4_intermediates/android-support-v4.jar    extras/android/support/v4/android-support-v4.jar
 frameworks/support/v4                                                                             extras/android/support/v4/src
 development/samples/Support4Demos                                                                 extras/android/support/samples/Support4Demos
@@ -380,5 +384,6 @@
 # Tests Component
 ##############################################################################
 framework/layoutlib-tests.jar tests/libtests/layoutlib-tests.jar
-system/app/EmulatorSmokeTests.apk tests/emulator-test-apps/EmulatorSmokeTests.apk
+system/app/ConnectivityTest.apk tests/emulator-test-apps/ConnectivityTest.apk
+system/app/GpsLocationTest.apk tests/emulator-test-apps/GpsLocationTest.apk
 
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index dda0606..af99325 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -65,7 +65,12 @@
 	<classpathentry kind="src" path="frameworks/base/packages/SystemUI/src"/>
 	<classpathentry kind="src" path="frameworks/base/policy/src"/>
 	<classpathentry kind="src" path="frameworks/base/sax/java"/>
-	<classpathentry kind="src" path="frameworks/base/services/java"/>
+	<classpathentry kind="src" path="frameworks/base/services/core/java"/>
+        <classpathentry kind="src" path="frameworks/base/services/accessibility/java"/>
+        <classpathentry kind="src" path="frameworks/base/services/print/java"/>
+        <classpathentry kind="src" path="frameworks/base/services/backup/java"/>
+        <classpathentry kind="src" path="frameworks/base/services/devicepolicy/java"/>
+        <classpathentry kind="src" path="frameworks/base/services/appwidget/java"/>
 	<classpathentry kind="src" path="frameworks/base/telephony/java"/>
 	<classpathentry kind="src" path="frameworks/base/test-runner/src"/>
 	<classpathentry kind="src" path="frameworks/base/wifi/java"/>
diff --git a/samples/BluetoothChat/AndroidManifest.xml b/samples/BluetoothChat/AndroidManifest.xml
index 895e633..4726670 100644
--- a/samples/BluetoothChat/AndroidManifest.xml
+++ b/samples/BluetoothChat/AndroidManifest.xml
@@ -17,7 +17,7 @@
       package="com.example.android.BluetoothChat"
       android:versionCode="1"
       android:versionName="1.0">
-    <uses-sdk minSdkVersion="6" />
+    <uses-sdk android:minSdkVersion="11" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
 
diff --git a/samples/Support7Demos/Android.mk b/samples/Support7Demos/Android.mk
index 0e43e3d..ca8310f 100644
--- a/samples/Support7Demos/Android.mk
+++ b/samples/Support7Demos/Android.mk
@@ -26,7 +26,8 @@
         android-support-v4 \
         android-support-v7-appcompat \
         android-support-v7-gridlayout \
-        android-support-v7-mediarouter
+        android-support-v7-mediarouter \
+        android-support-v7-recyclerview
 LOCAL_RESOURCE_DIR = \
         $(LOCAL_PATH)/res \
         frameworks/support/v7/appcompat/res \
diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index 4735433..6f9b237 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -38,6 +38,7 @@
             android:compatibleWidthLimitDp="480" />
 
     <application android:label="@string/activity_sample_code"
+            android:supportsRtl="true"
             android:icon="@drawable/app_sample_code"
             android:hardwareAccelerated="true">
 
@@ -172,5 +173,33 @@
             </intent-filter>
         </activity>
 
+        <!-- RecyclerView samples -->
+        <activity android:name=".widget.RecyclerViewActivity"
+                  android:label="@string/recycler_view"
+                  android:theme="@style/Theme.AppCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".widget.AnimatedRecyclerView"
+                  android:label="@string/animated_recycler_view"
+                  android:theme="@style/Theme.AppCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".widget.LinearLayoutManagerActivity"
+                  android:label="@string/linear_layout_manager"
+                  android:theme="@style/Theme.AppCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
     </application>
 </manifest>
diff --git a/samples/Support7Demos/res/layout/activity_linear_layout_manager.xml b/samples/Support7Demos/res/layout/activity_linear_layout_manager.xml
new file mode 100644
index 0000000..d671c73
--- /dev/null
+++ b/samples/Support7Demos/res/layout/activity_linear_layout_manager.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+        <EditText
+                android:id="@+id/scroll_offset"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:inputType="numberSigned"
+                android:hint="offset"/>
+        <Spinner
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/spinner"/>
+        <CheckBox
+                android:id="@+id/enable_smooth_scroll"
+                android:text="smooth scroll"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"/>
+    </LinearLayout>
+
+    <android.support.v7.widget.RecyclerView
+            android:layout_width="fill_parent"
+            android:layout_height="60dp"
+            android:scrollbars="horizontal"
+            android:id="@+id/config_recycler_view"/>
+    <android.support.v7.widget.RecyclerView
+            android:background="#ff0099cc"
+            android:scrollbarStyle="insideOverlay"
+            android:scrollbars="horizontal|vertical"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:id="@+id/recycler_view"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/Support7Demos/res/layout/animated_recycler_view.xml b/samples/Support7Demos/res/layout/animated_recycler_view.xml
new file mode 100644
index 0000000..188a154
--- /dev/null
+++ b/samples/Support7Demos/res/layout/animated_recycler_view.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <CheckBox
+            android:id="@+id/enableAnimations"
+            android:checked="true"
+            android:text="@string/enableAnimations"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content">
+
+        <Button
+                android:id="@+id/deleteButton"
+                android:layout_weight=".5"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:onClick="deleteItem"
+                android:text="@string/delete_item"/>
+
+        <Button
+                android:layout_weight=".5"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:onClick="addItem"
+                android:text="@string/add_item"/>
+
+        <Button
+                android:layout_weight=".5"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:onClick="addDeleteItem"
+                android:text="@string/add_delete_item"/>
+
+        <Button
+                android:layout_weight=".5"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:onClick="deleteAddItem"
+                android:text="@string/delete_add_item"/>
+
+        <Button
+                android:layout_weight=".5"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:onClick="d1a2d3"
+                android:text="@string/d1a2d3"/>
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/Support7Demos/res/layout/selectable_item.xml b/samples/Support7Demos/res/layout/selectable_item.xml
new file mode 100644
index 0000000..65a23cc
--- /dev/null
+++ b/samples/Support7Demos/res/layout/selectable_item.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <CheckBox
+            android:id="@+id/selected"
+            android:onClick="checkboxClicked"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+    <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index 1b13623..7e4e03c 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -95,4 +95,18 @@
     <string name="sample_media_route_activity_local">Local Playback</string>
     <string name="sample_media_route_activity_presentation">Local Playback on Presentation Display</string>
 
+    <string name="recycler_view">RecyclerView/RecyclerViewActivity</string>
+    <string name="animated_recycler_view">RecyclerView/AnimatedRecyclerView</string>
+    <string name="linear_layout_manager">Linear Layout Manager</string>
+    <string name="checkbox_orientation">Horz.</string>
+    <string name="checkbox_reverse">Rev.</string>
+    <string name="checkbox_layout_dir">Layout Dir</string>
+    <string name="checkbox_stack_from_end">Stack From End</string>
+    <string name="enableAnimations">Animate Changes</string>
+    <string name="add_item">Add</string>
+    <string name="delete_item">Delete</string>
+    <string name="add_delete_item">A+D</string>
+    <string name="delete_add_item">D+A</string>
+    <string name="d1a2d3">d1a2d3</string>
+
 </resources>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/Cheeses.java b/samples/Support7Demos/src/com/example/android/supportv7/Cheeses.java
new file mode 100644
index 0000000..a66b1d6
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/Cheeses.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv7;
+
+public class Cheeses {
+
+    public static final String[] sCheeseStrings = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+    };
+
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
new file mode 100644
index 0000000..83cf4d3
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2014 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.example.android.supportv7.widget;
+
+import android.widget.CompoundButton;
+import com.example.android.supportv7.R;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.RecyclerView;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class AnimatedRecyclerView extends Activity {
+
+    private static final int SCROLL_DISTANCE = 80; // dp
+
+    private RecyclerView mRecyclerView;
+
+    private int mNumItemsAdded = 0;
+    ArrayList<String> mItems = new ArrayList<String>();
+    MyAdapter mAdapter;
+
+    static final boolean USE_CUSTOM_ANIMATIONS = false;
+
+    boolean mAnimationsEnabled = true;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animated_recycler_view);
+
+        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        mRecyclerView = new RecyclerView(this);
+        mRecyclerView.setLayoutManager(new MyLayoutManager(this));
+        mRecyclerView.setHasFixedSize(true);
+        mRecyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+        for (int i = 0; i < 6; ++i) {
+            mItems.add("Item #" + i);
+        }
+        mAdapter = new MyAdapter(mItems);
+        mRecyclerView.setAdapter(mAdapter);
+        container.addView(mRecyclerView);
+
+        CheckBox enableAnimations = (CheckBox) findViewById(R.id.enableAnimations);
+        enableAnimations.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                mAnimationsEnabled = isChecked;
+            }
+        });
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        MenuItemCompat.setShowAsAction(menu.add("Layout"), MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        mRecyclerView.requestLayout();
+        return super.onOptionsItemSelected(item);
+    }
+
+    public void checkboxClicked(View view) {
+        ViewGroup parent = (ViewGroup) view.getParent();
+        boolean selected = ((CheckBox) view).isChecked();
+        MyViewHolder holder = (MyViewHolder) mRecyclerView.getChildViewHolder(parent);
+        mAdapter.selectItem(holder, selected);
+    }
+
+    public void deleteItem(View view) {
+        int numItems = mItems.size();
+        if (numItems > 0) {
+            for (int i = numItems - 1; i >= 0; --i) {
+                final String itemText = mItems.get(i);
+                boolean selected = mAdapter.mSelected.get(itemText);
+                if (selected) {
+                    removeAtPosition(i);
+                }
+            }
+        }
+    }
+
+    private String generateNewText() {
+        return "Added Item #" + mNumItemsAdded++;
+    }
+
+    public void d1a2d3(View view) {
+        removeAtPosition(1);
+        addAtPosition(2, "Added Item #" + mNumItemsAdded++);
+        removeAtPosition(3);
+    }
+
+    private void removeAtPosition(int position) {
+        mItems.remove(position);
+        mAdapter.notifyItemRemoved(position);
+    }
+
+    private void addAtPosition(int position, String text) {
+        mItems.add(position, text);
+        mAdapter.mSelected.put(text, Boolean.FALSE);
+        mAdapter.notifyItemInserted(position);
+    }
+
+    public void addDeleteItem(View view) {
+        addItem(view);
+        deleteItem(view);
+    }
+
+    public void deleteAddItem(View view) {
+        deleteItem(view);
+        addItem(view);
+    }
+
+    public void addItem(View view) {
+        addAtPosition(3, "Added Item #" + mNumItemsAdded++);
+    }
+
+    /**
+     * A basic ListView-style LayoutManager.
+     */
+    class MyLayoutManager extends RecyclerView.LayoutManager {
+        private static final String TAG = "MyLayoutManager";
+        private int mFirstPosition;
+        private final int mScrollDistance;
+
+        public MyLayoutManager(Context c) {
+            final DisplayMetrics dm = c.getResources().getDisplayMetrics();
+            mScrollDistance = (int) (SCROLL_DISTANCE * dm.density + 0.5f);
+        }
+
+        @Override
+        public boolean supportsItemAnimations() {
+            return mAnimationsEnabled;
+        }
+
+        @Override
+        public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+            int parentBottom = getHeight() - getPaddingBottom();
+
+            final View oldTopView = getChildCount() > 0 ? getChildAt(0) : null;
+            int oldTop = getPaddingTop();
+            if (oldTopView != null) {
+                oldTop = Math.min(oldTopView.getTop(), oldTop);
+            }
+
+            // Note that we add everything to the scrap, but we do not clean it up;
+            // that is handled by the RecyclerView after this method returns
+            detachAndScrapAttachedViews(recycler);
+
+            int top = oldTop;
+            int bottom = top;
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+
+            int count = state.getItemCount();
+            for (int i = 0; mFirstPosition + i < count && top < parentBottom; i++, top = bottom) {
+                View v = recycler.getViewForPosition(mFirstPosition + i);
+
+                RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) v.getLayoutParams();
+                if (!params.isItemRemoved()) {
+                    addView(v);
+                }
+                measureChild(v, 0, 0);
+                bottom = top + v.getMeasuredHeight();
+                v.layout(left, top, right, bottom);
+                if (params.isItemRemoved()) {
+                    parentBottom += v.getHeight();
+                }
+            }
+
+            // Now that we've run a full layout, figure out which views were not used
+            // (cached in previousViews). For each of these views, position it where
+            // it would go, according to its position relative to the visible
+            // positions in the list. This information will be used by RecyclerView to
+            // record post-layout positions of these items for the purposes of animating them
+            // out of view
+
+            View lastVisibleView = getChildAt(getChildCount() - 1);
+            if (lastVisibleView != null) {
+                RecyclerView.LayoutParams lastParams =
+                        (RecyclerView.LayoutParams) lastVisibleView.getLayoutParams();
+                int lastPosition = lastParams.getViewPosition();
+                final List<RecyclerView.ViewHolder> previousViews = recycler.getScrapList();
+                count = previousViews.size();
+                for (int i = 0; i < count; ++i) {
+                    View view = previousViews.get(i).itemView;
+                    RecyclerView.LayoutParams params =
+                            (RecyclerView.LayoutParams) view.getLayoutParams();
+                    int position = params.getViewPosition();
+                    int newTop;
+                    if (position < mFirstPosition) {
+                        newTop = view.getHeight() * (position - mFirstPosition);
+                    } else {
+                        newTop = lastVisibleView.getTop() + view.getHeight() *
+                                (position - lastPosition);
+                    }
+                    view.offsetTopAndBottom(newTop - view.getTop());
+                }
+            }
+        }
+
+        @Override
+        public RecyclerView.LayoutParams generateDefaultLayoutParams() {
+            return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT);
+        }
+
+        @Override
+        public boolean canScrollVertically() {
+            return true;
+        }
+
+        @Override
+        public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
+                RecyclerView.State state) {
+            if (getChildCount() == 0) {
+                return 0;
+            }
+
+            int scrolled = 0;
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+            if (dy < 0) {
+                while (scrolled > dy) {
+                    final View topView = getChildAt(0);
+                    final int hangingTop = Math.max(-topView.getTop(), 0);
+                    final int scrollBy = Math.min(scrolled - dy, hangingTop);
+                    scrolled -= scrollBy;
+                    offsetChildrenVertical(scrollBy);
+                    if (mFirstPosition > 0 && scrolled > dy) {
+                        mFirstPosition--;
+                        View v = recycler.getViewForPosition(mFirstPosition);
+                        addView(v, 0);
+                        measureChild(v, 0, 0);
+                        final int bottom = topView.getTop(); // TODO decorated top?
+                        final int top = bottom - v.getMeasuredHeight();
+                        v.layout(left, top, right, bottom);
+                    } else {
+                        break;
+                    }
+                }
+            } else if (dy > 0) {
+                final int parentHeight = getHeight();
+                while (scrolled < dy) {
+                    final View bottomView = getChildAt(getChildCount() - 1);
+                    final int hangingBottom = Math.max(bottomView.getBottom() - parentHeight, 0);
+                    final int scrollBy = -Math.min(dy - scrolled, hangingBottom);
+                    scrolled -= scrollBy;
+                    offsetChildrenVertical(scrollBy);
+                    if (scrolled < dy && getItemCount() > mFirstPosition + getChildCount()) {
+                        View v = recycler.getViewForPosition(mFirstPosition + getChildCount());
+                        final int top = getChildAt(getChildCount() - 1).getBottom();
+                        addView(v);
+                        measureChild(v, 0, 0);
+                        final int bottom = top + v.getMeasuredHeight();
+                        v.layout(left, top, right, bottom);
+                    } else {
+                        break;
+                    }
+                }
+            }
+            recycleViewsOutOfBounds(recycler);
+            return scrolled;
+        }
+
+        @Override
+        public View onFocusSearchFailed(View focused, int direction,
+                RecyclerView.Recycler recycler, RecyclerView.State state) {
+            final int oldCount = getChildCount();
+
+            if (oldCount == 0) {
+                return null;
+            }
+
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+
+            View toFocus = null;
+            int newViewsHeight = 0;
+            if (direction == View.FOCUS_UP || direction == View.FOCUS_BACKWARD) {
+                while (mFirstPosition > 0 && newViewsHeight < mScrollDistance) {
+                    mFirstPosition--;
+                    View v = recycler.getViewForPosition(mFirstPosition);
+                    final int bottom = getChildAt(0).getTop(); // TODO decorated top?
+                    addView(v, 0);
+                    measureChild(v, 0, 0);
+                    final int top = bottom - v.getMeasuredHeight();
+                    v.layout(left, top, right, bottom);
+                    if (v.isFocusable()) {
+                        toFocus = v;
+                        break;
+                    }
+                }
+            }
+            if (direction == View.FOCUS_DOWN || direction == View.FOCUS_FORWARD) {
+                while (mFirstPosition + getChildCount() < getItemCount() &&
+                        newViewsHeight < mScrollDistance) {
+                    View v = recycler.getViewForPosition(mFirstPosition + getChildCount());
+                    final int top = getChildAt(getChildCount() - 1).getBottom();
+                    addView(v);
+                    measureChild(v, 0, 0);
+                    final int bottom = top + v.getMeasuredHeight();
+                    v.layout(left, top, right, bottom);
+                    if (v.isFocusable()) {
+                        toFocus = v;
+                        break;
+                    }
+                }
+            }
+
+            return toFocus;
+        }
+
+        public void recycleViewsOutOfBounds(RecyclerView.Recycler recycler) {
+            final int childCount = getChildCount();
+            final int parentWidth = getWidth();
+            final int parentHeight = getHeight();
+            boolean foundFirst = false;
+            int first = 0;
+            int last = 0;
+            for (int i = 0; i < childCount; i++) {
+                final View v = getChildAt(i);
+                if (v.hasFocus() || (v.getRight() >= 0 && v.getLeft() <= parentWidth &&
+                        v.getBottom() >= 0 && v.getTop() <= parentHeight)) {
+                    if (!foundFirst) {
+                        first = i;
+                        foundFirst = true;
+                    }
+                    last = i;
+                }
+            }
+            for (int i = childCount - 1; i > last; i--) {
+                removeAndRecycleViewAt(i, recycler);
+            }
+            for (int i = first - 1; i >= 0; i--) {
+                removeAndRecycleViewAt(i, recycler);
+            }
+            if (getChildCount() == 0) {
+                mFirstPosition = 0;
+            } else {
+                mFirstPosition += first;
+            }
+        }
+
+        @Override
+        public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) {
+            if (positionStart < mFirstPosition) {
+                mFirstPosition += itemCount;
+            }
+        }
+
+        @Override
+        public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) {
+            if (positionStart < mFirstPosition) {
+                mFirstPosition -= itemCount;
+            }
+        }
+    }
+
+    class MyAdapter extends RecyclerView.Adapter {
+        private int mBackground;
+        List<String> mData;
+        HashMap<String, Boolean> mSelected = new HashMap<String, Boolean>();
+
+        public MyAdapter(List<String> data) {
+            TypedValue val = new TypedValue();
+            AnimatedRecyclerView.this.getTheme().resolveAttribute(
+                    R.attr.selectableItemBackground, val, true);
+            mBackground = val.resourceId;
+            mData = data;
+            for (String itemText : mData) {
+                mSelected.put(itemText, Boolean.FALSE);
+            }
+        }
+
+        @Override
+        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            MyViewHolder h = new MyViewHolder(getLayoutInflater().inflate(R.layout.selectable_item,
+                    null));
+            h.textView.setMinimumHeight(128);
+            h.textView.setFocusable(true);
+            h.textView.setBackgroundResource(mBackground);
+            return h;
+        }
+
+        @Override
+        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+            String itemText = mData.get(position);
+            ((MyViewHolder) holder).textView.setText(itemText);
+            boolean selected = false;
+            if (mSelected.get(itemText) != null) {
+                selected = mSelected.get(itemText);
+            }
+            ((MyViewHolder) holder).checkBox.setChecked(selected);
+        }
+
+        @Override
+        public int getItemCount() {
+            return mData.size();
+        }
+
+        public void selectItem(String itemText, boolean selected) {
+            mSelected.put(itemText, selected);
+        }
+
+        public void selectItem(MyViewHolder holder, boolean selected) {
+            mSelected.put((String) holder.textView.getText(), selected);
+        }
+    }
+
+    static class MyViewHolder extends RecyclerView.ViewHolder {
+        public TextView textView;
+        public CheckBox checkBox;
+
+        public MyViewHolder(View v) {
+            super(v);
+            textView = (TextView) v.findViewById(R.id.text);
+            checkBox = (CheckBox) v.findViewById(R.id.selected);
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + " \"" + textView.getText() + "\"";
+        }
+    }}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/LinearLayoutManagerActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/LinearLayoutManagerActivity.java
new file mode 100644
index 0000000..8c2caa9
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/LinearLayoutManagerActivity.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2014 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.example.android.supportv7.widget;
+
+import com.example.android.supportv7.Cheeses;
+import com.example.android.supportv7.widget.adapter.SimpleStringAdapter;
+import com.example.android.supportv7.widget.decorator.DividerItemDecoration;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.example.android.supportv7.R;
+
+/**
+ * A sample activity that uses {@link android.support.v7.widget.LinearLayoutManager}.
+ */
+public class LinearLayoutManagerActivity extends Activity {
+
+    private RecyclerView.LayoutManager mListLayoutManager;
+
+    private ListWrapper mListWrapper;
+
+    private RecyclerView mRecyclerView;
+
+    private DividerItemDecoration mDividerItemDecoration;
+
+    private ConfigToggle[] mConfigToggles;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_linear_layout_manager);
+        initConfig();
+        initRecyclerView();
+        initSpinner();
+    }
+
+    private void initRecyclerView() {
+        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
+        mRecyclerView.setHasFixedSize(true);
+        mListLayoutManager = new LinearLayoutManager(this);
+        mRecyclerView.setLayoutManager(mListLayoutManager);
+        mRecyclerView.setAdapter(new SimpleStringAdapter(this, Cheeses.sCheeseStrings) {
+            @Override
+            public SimpleStringAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
+                    int viewType) {
+                final SimpleStringAdapter.ViewHolder vh = super
+                        .onCreateViewHolder(parent, viewType);
+                vh.itemView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        final int pos = vh.getPosition();
+                        if (pos + 1 < getItemCount()) {
+                            swap(pos, pos + 1);
+                        }
+                        notifyItemChanged(pos);
+                    }
+                });
+                return vh;
+            }
+        });
+        initListForLayoutManager();
+    }
+
+    private void initListForLayoutManager() {
+        mListWrapper = new ListWrapper() {
+            @Override
+            public int getOrientation() {
+                return lm().getOrientation();
+            }
+
+            @Override
+            public void setOrientation(int orientation) {
+                lm().setOrientation(orientation);
+            }
+
+            @Override
+            public boolean getReverseLayout() {
+                return lm().getReverseLayout();
+            }
+
+            @Override
+            public void setReverseLayout(boolean newValue) {
+                lm().setReverseLayout(newValue);
+            }
+
+            @Override
+            public boolean getStackFromEnd() {
+                return lm().getStackFromEnd();
+            }
+
+            @Override
+            public void setStackFromEnd(boolean newValue) {
+                lm().setStackFromEnd(newValue);
+            }
+
+            private LinearLayoutManager lm() {
+                return (LinearLayoutManager) mListLayoutManager;
+            }
+        };
+        if (mDividerItemDecoration != null) {
+            mRecyclerView.removeItemDecoration(mDividerItemDecoration);
+        }
+        mDividerItemDecoration = new DividerItemDecoration(this, mListWrapper.getOrientation());
+        mRecyclerView.addItemDecoration(mDividerItemDecoration);
+    }
+
+    private void initConfig() {
+        RecyclerView configView = (RecyclerView) findViewById(R.id.config_recycler_view);
+        initToggles();
+        configView.setAdapter(mConfigAdapter);
+        configView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,
+                false));
+        configView.setHasFixedSize(true);
+    }
+
+    private void initSpinner() {
+        final CheckBox checkBox = (CheckBox)
+                findViewById(R.id.enable_smooth_scroll);
+
+        final Spinner spinner = (Spinner) findViewById(R.id.spinner);
+        final EditText scrollOffset = (EditText) findViewById(R.id.scroll_offset);
+        spinner.setAdapter(new BaseAdapter() {
+            @Override
+            public int getCount() {
+                return mRecyclerView.getAdapter().getItemCount();
+            }
+
+            @Override
+            public Integer getItem(int position) {
+                return position;
+            }
+
+            @Override
+            public long getItemId(int position) {
+                return position;
+            }
+
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                if (convertView == null) {
+                    convertView = new TextView(parent.getContext());
+                }
+                ((TextView) convertView).setText("" + position);
+                return convertView;
+            }
+        });
+        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                int offset = Integer.MIN_VALUE;
+                String offsetString = scrollOffset.getText().toString();
+                try {
+                    offset = Integer.parseInt(offsetString);
+                } catch (NumberFormatException ex) {
+
+                }
+
+                if (offset == Integer.MIN_VALUE) {
+                    if (checkBox.isChecked()) {
+                        mRecyclerView.smoothScrollToPosition(position);
+                    } else {
+                        mRecyclerView.scrollToPosition(position);
+                    }
+                } else {
+                    // ignore offset until we add recycling list view with smooth scroll to offset
+                    mRecyclerView.smoothScrollToPosition(position);
+                }
+
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+
+            }
+        });
+    }
+
+    private void initToggles() {
+        mConfigToggles = new ConfigToggle[]{
+                new ConfigToggle(R.string.checkbox_orientation) {
+                    @Override
+                    public boolean isChecked() {
+                        return mListWrapper.getOrientation() == LinearLayoutManager.HORIZONTAL;
+                    }
+
+                    @Override
+                    public void onChange(boolean newValue) {
+                        mListWrapper.setOrientation(newValue ? LinearLayoutManager.HORIZONTAL
+                                : LinearLayoutManager.VERTICAL);
+                        if (mDividerItemDecoration != null) {
+                            mDividerItemDecoration.setOrientation(mListWrapper.getOrientation());
+                        }
+
+                    }
+                },
+                new ConfigToggle(R.string.checkbox_reverse) {
+                    @Override
+                    public boolean isChecked() {
+                        return mListWrapper.getReverseLayout();
+                    }
+
+                    @Override
+                    public void onChange(boolean newValue) {
+                        mListWrapper.setReverseLayout(newValue);
+                    }
+                },
+                new ConfigToggle(R.string.checkbox_layout_dir) {
+                    @Override
+                    public boolean isChecked() {
+                        return ViewCompat.getLayoutDirection(mRecyclerView) ==
+                                ViewCompat.LAYOUT_DIRECTION_RTL;
+                    }
+
+                    @Override
+                    public void onChange(boolean newValue) {
+                        ViewCompat.setLayoutDirection(mRecyclerView, newValue ?
+                                ViewCompat.LAYOUT_DIRECTION_RTL : ViewCompat.LAYOUT_DIRECTION_LTR);
+                    }
+                },
+                new ConfigToggle(R.string.checkbox_stack_from_end) {
+                    @Override
+                    public boolean isChecked() {
+                        return mListWrapper.getStackFromEnd();
+                    }
+
+                    @Override
+                    public void onChange(boolean newValue) {
+                        mListWrapper.setStackFromEnd(newValue);
+                    }
+                }
+        };
+    }
+
+    private class ConfigViewHolder extends RecyclerView.ViewHolder
+            implements CompoundButton.OnCheckedChangeListener {
+
+        private CheckBox mCheckBox;
+
+        private ConfigToggle mConfigToggle;
+
+        public ConfigViewHolder(View itemView) {
+            super(itemView);
+            mCheckBox = (CheckBox) itemView;
+            mCheckBox.setOnCheckedChangeListener(this);
+        }
+
+        public void render(ConfigToggle toggle) {
+            mConfigToggle = toggle;
+            mCheckBox.setText(toggle.getText());
+            mCheckBox.setChecked(toggle.isChecked());
+        }
+
+        @Override
+        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+            if (mConfigToggle != null) {
+                mConfigToggle.onChange(isChecked);
+            }
+        }
+    }
+
+
+    private abstract class ConfigToggle {
+
+        private String mLabel;
+
+        protected ConfigToggle(int labelId) {
+            mLabel = getResources().getString(labelId);
+        }
+
+        public String getText() {
+            return mLabel;
+        }
+
+        abstract public boolean isChecked();
+
+        abstract public void onChange(boolean newValue);
+    }
+
+
+    private RecyclerView.Adapter mConfigAdapter = new RecyclerView.Adapter<ConfigViewHolder>() {
+        @Override
+        public ConfigViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            return new ConfigViewHolder(new CheckBox(parent.getContext()));
+        }
+
+        @Override
+        public void onBindViewHolder(ConfigViewHolder holder, int position) {
+            ConfigToggle toggle = mConfigToggles[position];
+            holder.render(toggle);
+        }
+
+        @Override
+        public int getItemCount() {
+            return mConfigToggles.length;
+        }
+    };
+
+
+    /**
+     * To avoid adding interfaces to LayoutManager for the demo, we use this wrapper class to
+     * call different LayoutManagers
+     */
+    private static interface ListWrapper {
+
+        int getOrientation();
+
+        void setOrientation(int orientation);
+
+        boolean getReverseLayout();
+
+        void setReverseLayout(boolean newValue);
+
+        boolean getStackFromEnd();
+
+        void setStackFromEnd(boolean newValue);
+    }
+
+
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java
new file mode 100644
index 0000000..baecf86
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/RecyclerViewActivity.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.example.android.supportv7.widget;
+
+import com.example.android.supportv7.Cheeses;
+import com.example.android.supportv7.widget.adapter.SimpleStringAdapter;
+import com.example.android.supportv7.widget.decorator.DividerItemDecoration;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.RecyclerView;
+import android.util.DisplayMetrics;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class RecyclerViewActivity extends Activity {
+
+    private static final String TAG = "RecyclerViewActivity";
+
+    private RecyclerView mRecyclerView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final RecyclerView rv = new RecyclerView(this);
+        rv.setLayoutManager(new MyLayoutManager(this));
+        rv.setHasFixedSize(true);
+        rv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+        rv.setAdapter(new SimpleStringAdapter(this, Cheeses.sCheeseStrings) {
+            @Override
+            public SimpleStringAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
+                    int viewType) {
+                final SimpleStringAdapter.ViewHolder vh = super
+                        .onCreateViewHolder(parent, viewType);
+                vh.itemView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        final int pos = vh.getPosition();
+                        if (pos + 1 < getItemCount()) {
+                            swap(pos, pos + 1);
+                        }
+                    }
+                });
+                return vh;
+            }
+        });
+        rv.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
+        setContentView(rv);
+        mRecyclerView = rv;
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        MenuItemCompat.setShowAsAction(menu.add("Layout"), MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        mRecyclerView.requestLayout();
+        return super.onOptionsItemSelected(item);
+    }
+
+    private static final int SCROLL_DISTANCE = 80; // dp
+
+    /**
+     * A basic ListView-style LayoutManager.
+     */
+    class MyLayoutManager extends RecyclerView.LayoutManager {
+
+        private static final String TAG = "MyLayoutManager";
+
+        private int mFirstPosition;
+
+        private final int mScrollDistance;
+
+        public MyLayoutManager(Context c) {
+            final DisplayMetrics dm = c.getResources().getDisplayMetrics();
+            mScrollDistance = (int) (SCROLL_DISTANCE * dm.density + 0.5f);
+        }
+
+        @Override
+        public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+            final int parentBottom = getHeight() - getPaddingBottom();
+            final View oldTopView = getChildCount() > 0 ? getChildAt(0) : null;
+            int oldTop = getPaddingTop();
+            if (oldTopView != null) {
+                oldTop = oldTopView.getTop();
+            }
+
+            detachAndScrapAttachedViews(recycler);
+
+            int top = oldTop;
+            int bottom;
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+
+            final int count = state.getItemCount();
+            for (int i = 0; mFirstPosition + i < count && top < parentBottom; i++, top = bottom) {
+                View v = recycler.getViewForPosition(mFirstPosition + i);
+                addView(v, i);
+                measureChildWithMargins(v, 0, 0);
+                bottom = top + getDecoratedMeasuredHeight(v);
+                layoutDecorated(v, left, top, right, bottom);
+            }
+        }
+
+        @Override
+        public RecyclerView.LayoutParams generateDefaultLayoutParams() {
+            return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT);
+        }
+
+        @Override
+        public boolean canScrollVertically() {
+            return true;
+        }
+
+        @Override
+        public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
+                RecyclerView.State state) {
+            if (getChildCount() == 0) {
+                return 0;
+            }
+
+            int scrolled = 0;
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+            if (dy < 0) {
+                while (scrolled > dy) {
+                    final View topView = getChildAt(0);
+                    final int hangingTop = Math.max(-getDecoratedTop(topView), 0);
+                    final int scrollBy = Math.min(scrolled - dy, hangingTop);
+                    scrolled -= scrollBy;
+                    offsetChildrenVertical(scrollBy);
+                    if (mFirstPosition > 0 && scrolled > dy) {
+                        mFirstPosition--;
+                        View v = recycler.getViewForPosition(mFirstPosition);
+                        addView(v, 0);
+                        measureChildWithMargins(v, 0, 0);
+                        final int bottom = getDecoratedTop(topView);
+                        final int top = bottom - getDecoratedMeasuredHeight(v);
+                        layoutDecorated(v, left, top, right, bottom);
+                    } else {
+                        break;
+                    }
+                }
+            } else if (dy > 0) {
+                final int parentHeight = getHeight();
+                while (scrolled < dy) {
+                    final View bottomView = getChildAt(getChildCount() - 1);
+                    final int hangingBottom =
+                            Math.max(getDecoratedBottom(bottomView) - parentHeight, 0);
+                    final int scrollBy = -Math.min(dy - scrolled, hangingBottom);
+                    scrolled -= scrollBy;
+                    offsetChildrenVertical(scrollBy);
+                    if (scrolled < dy && getItemCount() > mFirstPosition + getChildCount()) {
+                        View v = recycler.getViewForPosition(mFirstPosition + getChildCount());
+                        final int top = getDecoratedBottom(getChildAt(getChildCount() - 1));
+                        addView(v);
+                        measureChildWithMargins(v, 0, 0);
+                        final int bottom = top + getDecoratedMeasuredHeight(v);
+                        layoutDecorated(v, left, top, right, bottom);
+                    } else {
+                        break;
+                    }
+                }
+            }
+            recycleViewsOutOfBounds(recycler);
+            return scrolled;
+        }
+
+        @Override
+        public View onFocusSearchFailed(View focused, int direction,
+                RecyclerView.Recycler recycler, RecyclerView.State state) {
+            final int oldCount = getChildCount();
+
+            if (oldCount == 0) {
+                return null;
+            }
+
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+
+            View toFocus = null;
+            int newViewsHeight = 0;
+            if (direction == View.FOCUS_UP || direction == View.FOCUS_BACKWARD) {
+                while (mFirstPosition > 0 && newViewsHeight < mScrollDistance) {
+                    mFirstPosition--;
+                    View v = recycler.getViewForPosition(mFirstPosition);
+                    final int bottom = getDecoratedTop(getChildAt(0));
+                    addView(v, 0);
+                    measureChildWithMargins(v, 0, 0);
+                    final int top = bottom - getDecoratedMeasuredHeight(v);
+                    layoutDecorated(v, left, top, right, bottom);
+                    if (v.isFocusable()) {
+                        toFocus = v;
+                        break;
+                    }
+                }
+            }
+            if (direction == View.FOCUS_DOWN || direction == View.FOCUS_FORWARD) {
+                while (mFirstPosition + getChildCount() < getItemCount() &&
+                        newViewsHeight < mScrollDistance) {
+                    View v = recycler.getViewForPosition(mFirstPosition + getChildCount());
+                    final int top = getDecoratedBottom(getChildAt(getChildCount() - 1));
+                    addView(v);
+                    measureChildWithMargins(v, 0, 0);
+                    final int bottom = top + getDecoratedMeasuredHeight(v);
+                    layoutDecorated(v, left, top, right, bottom);
+                    if (v.isFocusable()) {
+                        toFocus = v;
+                        break;
+                    }
+                }
+            }
+
+            return toFocus;
+        }
+
+        public void recycleViewsOutOfBounds(RecyclerView.Recycler recycler) {
+            final int childCount = getChildCount();
+            final int parentWidth = getWidth();
+            final int parentHeight = getHeight();
+            boolean foundFirst = false;
+            int first = 0;
+            int last = 0;
+            for (int i = 0; i < childCount; i++) {
+                final View v = getChildAt(i);
+                if (v.hasFocus() || (getDecoratedRight(v) >= 0 &&
+                        getDecoratedLeft(v) <= parentWidth &&
+                        getDecoratedBottom(v) >= 0 &&
+                        getDecoratedTop(v) <= parentHeight)) {
+                    if (!foundFirst) {
+                        first = i;
+                        foundFirst = true;
+                    }
+                    last = i;
+                }
+            }
+            for (int i = childCount - 1; i > last; i--) {
+                removeAndRecycleViewAt(i, recycler);
+            }
+            for (int i = first - 1; i >= 0; i--) {
+                removeAndRecycleViewAt(i, recycler);
+            }
+            if (getChildCount() == 0) {
+                mFirstPosition = 0;
+            } else {
+                mFirstPosition += first;
+            }
+        }
+    }
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/adapter/SimpleStringAdapter.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/adapter/SimpleStringAdapter.java
new file mode 100644
index 0000000..a12e79d
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/adapter/SimpleStringAdapter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 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.example.android.supportv7.widget.adapter;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.support.v7.widget.RecyclerView;
+import android.util.TypedValue;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class SimpleStringAdapter extends RecyclerView.Adapter<SimpleStringAdapter.ViewHolder> {
+
+    private int mBackground;
+
+    private ArrayList<String> mValues;
+
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+
+        public TextView mTextView;
+
+        public ViewHolder(TextView v) {
+            super(v);
+            mTextView = v;
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + " '" + mTextView.getText();
+        }
+    }
+
+    public SimpleStringAdapter(Context context, String[] strings) {
+        TypedValue val = new TypedValue();
+        if (context.getTheme() != null) {
+            context.getTheme().resolveAttribute(
+                    android.R.attr.selectableItemBackground, val, true);
+        }
+        mBackground = val.resourceId;
+        mValues = new ArrayList<String>();
+        Collections.addAll(mValues, strings);
+    }
+
+    public void swap(int pos1, int pos2) {
+        String tmp = mValues.get(pos1);
+        mValues.set(pos1, mValues.get(pos2));
+        mValues.set(pos2, tmp);
+        notifyItemRemoved(pos1);
+        notifyItemInserted(pos2);
+    }
+
+    @Override
+    public SimpleStringAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        final ViewHolder h = new ViewHolder(new TextView(parent.getContext()));
+        h.mTextView.setMinimumHeight(128);
+        h.mTextView.setPadding(20, 0, 20, 0);
+        h.mTextView.setFocusable(true);
+        h.mTextView.setBackgroundResource(mBackground);
+        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        lp.leftMargin = 10;
+        lp.rightMargin = 5;
+        lp.topMargin = 20;
+        lp.bottomMargin = 15;
+        h.mTextView.setLayoutParams(lp);
+        return h;
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        holder.mTextView.setText(position + ":" + mValues.get(position));
+        holder.mTextView.setMinHeight((200 + mValues.get(position).length() * 10));
+        holder.mTextView.setBackgroundColor(getBackgroundColor(position));
+    }
+
+    private int getBackgroundColor(int position) {
+        switch (position % 4) {
+            case 0: return Color.BLACK;
+            case 1: return Color.RED;
+            case 2: return Color.GREEN;
+            case 3: return Color.BLUE;
+        }
+        return Color.TRANSPARENT;
+    }
+
+    @Override
+    public int getItemCount() {
+        return mValues.size();
+    }
+}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/decorator/DividerItemDecoration.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/decorator/DividerItemDecoration.java
new file mode 100644
index 0000000..4d5d208
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/decorator/DividerItemDecoration.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 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.example.android.supportv7.widget.decorator;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+public class DividerItemDecoration extends RecyclerView.ItemDecoration {
+
+    private static final int[] ATTRS = new int[]{
+            android.R.attr.listDivider
+    };
+
+    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
+
+    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
+
+    private Drawable mDivider;
+
+    private int mOrientation;
+
+    public DividerItemDecoration(Context context, int orientation) {
+        final TypedArray a = context.obtainStyledAttributes(ATTRS);
+        mDivider = a.getDrawable(0);
+        a.recycle();
+        setOrientation(orientation);
+    }
+
+    public void setOrientation(int orientation) {
+        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
+            throw new IllegalArgumentException("invalid orientation");
+        }
+        mOrientation = orientation;
+    }
+
+    @Override
+    public void onDraw(Canvas c, RecyclerView parent) {
+        if (mOrientation == VERTICAL_LIST) {
+            drawVertical(c, parent);
+        } else {
+            drawHorizontal(c, parent);
+        }
+    }
+
+    public void drawVertical(Canvas c, RecyclerView parent) {
+        final int left = parent.getPaddingLeft();
+        final int right = parent.getWidth() - parent.getPaddingRight();
+
+        final int childCount = parent.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = parent.getChildAt(i);
+            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
+                    .getLayoutParams();
+            final int top = child.getBottom() + params.bottomMargin;
+            final int bottom = top + mDivider.getIntrinsicHeight();
+            mDivider.setBounds(left, top, right, bottom);
+            mDivider.draw(c);
+        }
+    }
+
+    public void drawHorizontal(Canvas c, RecyclerView parent) {
+        final int top = parent.getPaddingTop();
+        final int bottom = parent.getHeight() - parent.getPaddingBottom();
+
+        final int childCount = parent.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = parent.getChildAt(i);
+            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
+                    .getLayoutParams();
+            final int left = child.getRight() + params.rightMargin;
+            final int right = left + mDivider.getIntrinsicHeight();
+            mDivider.setBounds(left, top, right, bottom);
+            mDivider.draw(c);
+        }
+    }
+
+    @Override
+    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
+        if (mOrientation == VERTICAL_LIST) {
+            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
+        } else {
+            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
+        }
+    }
+}
diff --git a/samples/SupportLeanbackDemos/Android.mk b/samples/SupportLeanbackDemos/Android.mk
new file mode 100644
index 0000000..41424a7
--- /dev/null
+++ b/samples/SupportLeanbackDemos/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# Build the samples.
+# We need to add some special AAPT flags to generate R classes
+# for resources that are included from the libraries.
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := SupportLeanbackDemos
+LOCAL_MODULE_TAGS := samples tests
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        android-support-v4 \
+        android-support-v7-recyclerview \
+        android-support-v17-leanback
+LOCAL_RESOURCE_DIR = \
+        $(LOCAL_PATH)/res \
+        frameworks/support/v17/leanback/res
+LOCAL_AAPT_FLAGS := \
+        --auto-add-overlay \
+        --extra-packages android.support.v17.leanback
+include $(BUILD_PACKAGE)
diff --git a/samples/SupportLeanbackDemos/AndroidManifest.xml b/samples/SupportLeanbackDemos/AndroidManifest.xml
new file mode 100644
index 0000000..ee0707d
--- /dev/null
+++ b/samples/SupportLeanbackDemos/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.leanback"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="19" />
+
+    <application
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/Theme.Leanback">
+
+        <activity android:name="MainActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="DetailsActivity"
+            android:exported="true" />
+
+        <activity android:name="VerticalGridActivity"
+            android:exported="true" />
+
+        <activity android:name="SearchActivity"
+            android:exported="true" />
+
+    </application>
+</manifest>
diff --git a/samples/SupportLeanbackDemos/res/drawable-hdpi/ic_launcher.png b/samples/SupportLeanbackDemos/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable-ldpi/ic_launcher.png b/samples/SupportLeanbackDemos/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..9923872
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable-mdpi/ic_launcher.png b/samples/SupportLeanbackDemos/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable-xhdpi/grid_bg.png b/samples/SupportLeanbackDemos/res/drawable-xhdpi/grid_bg.png
new file mode 100644
index 0000000..476c698
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable-xhdpi/grid_bg.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable-xhdpi/ic_launcher.png b/samples/SupportLeanbackDemos/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable/details_img.png b/samples/SupportLeanbackDemos/res/drawable/details_img.png
new file mode 100644
index 0000000..7ea688b
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable/details_img.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable/ic_action_a.png b/samples/SupportLeanbackDemos/res/drawable/ic_action_a.png
new file mode 100644
index 0000000..3d555ef
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable/ic_action_a.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable/ic_title.png b/samples/SupportLeanbackDemos/res/drawable/ic_title.png
new file mode 100644
index 0000000..1c62b2e
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable/ic_title.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable/text_bg.xml b/samples/SupportLeanbackDemos/res/drawable/text_bg.xml
new file mode 100644
index 0000000..c67924c
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable/text_bg.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#FFFF0000"
+        android:endColor="#80FF00FF"
+        android:angle="45" />
+    <padding
+        android:left="7dp"
+        android:top="7dp"
+        android:right="7dp"
+        android:bottom="7dp" />
+</shape>
diff --git a/samples/SupportLeanbackDemos/res/layout/details.xml b/samples/SupportLeanbackDemos/res/layout/details.xml
new file mode 100644
index 0000000..4af4e6a
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/details.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="com.example.android.leanback.DetailsFragment"
+    android:id="@+id/details_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+/>
diff --git a/samples/SupportLeanbackDemos/res/layout/main.xml b/samples/SupportLeanbackDemos/res/layout/main.xml
new file mode 100644
index 0000000..b6b08b3
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/main.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="com.example.android.leanback.BrowseFragment"
+    android:id="@+id/main_browse_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+/>
diff --git a/samples/SupportLeanbackDemos/res/layout/search.xml b/samples/SupportLeanbackDemos/res/layout/search.xml
new file mode 100644
index 0000000..b65600c
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/search.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.example.android.leanback.SearchFragment"
+          android:id="@+id/search_fragment"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"
+        />
\ No newline at end of file
diff --git a/samples/SupportLeanbackDemos/res/layout/vertical_grid.xml b/samples/SupportLeanbackDemos/res/layout/vertical_grid.xml
new file mode 100644
index 0000000..1007042
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/layout/vertical_grid.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="com.example.android.leanback.VerticalGridFragment"
+    android:id="@+id/vertical_grid_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+/>
diff --git a/samples/SupportLeanbackDemos/res/values/strings.xml b/samples/SupportLeanbackDemos/res/values/strings.xml
new file mode 100644
index 0000000..e884043
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+
+<resources>
+    <string name="app_name">MainActivity</string>
+</resources>
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
new file mode 100644
index 0000000..2345ed0
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnItemClickedListener;
+import android.support.v17.leanback.widget.Row;
+import android.util.Log;
+import android.view.View;
+
+public class BrowseFragment extends android.support.v17.leanback.app.BrowseFragment {
+    private static final String TAG = "leanback.BrowseFragment";
+
+    private static final int NUM_ROWS = 3;
+    private ArrayObjectAdapter mRowsAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate");
+        super.onCreate(savedInstanceState);
+
+        Params p = new Params();
+        p.setBadgeImage(getActivity().getResources().getDrawable(R.drawable.ic_title));
+        p.setTitle("Leanback Sample App");
+        p.setHeadersState(HEADERS_ENABLED);
+        setBrowseParams(p);
+
+        setOnSearchClickedListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Intent intent = new Intent(getActivity(), SearchActivity.class);
+                startActivity(intent);
+            }
+        });
+
+        setupRows();
+        setOnItemClickedListener(new ItemClickedListener());
+    }
+
+    private void setupRows() {
+        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+        for (int i = 0; i < NUM_ROWS; ++i) {
+            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
+            listRowAdapter.add("Hello world");
+            listRowAdapter.add("This is a test");
+            HeaderItem header = new HeaderItem(i, "Row " + i, null);
+            mRowsAdapter.add(new ListRow(header, listRowAdapter));
+        }
+
+        setAdapter(mRowsAdapter);
+    }
+
+    private final class ItemClickedListener implements OnItemClickedListener {
+        public void onItemClicked(Object item, Row row) {
+            // TODO: use a fragment transaction instead of launching a new
+            // activity
+            Intent intent = new Intent(getActivity(), DetailsActivity.class);
+            startActivity(intent);
+        }
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/CardPresenter.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/CardPresenter.java
new file mode 100644
index 0000000..502c77a
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/CardPresenter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class CardPresenter extends Presenter {
+    private static final String TAG = "CardPresenter";
+
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        Log.d(TAG, "onCreateViewHolder");
+        ImageCardView v = new ImageCardView(parent.getContext());
+        v.setFocusable(true);
+        v.setFocusableInTouchMode(true);
+        v.setMainImage(
+                parent.getContext().getResources().getDrawable(R.drawable.text_bg));
+        return new ViewHolder(v);
+    }
+
+    public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+        Log.d(TAG, "onBindViewHolder for " + item.toString());
+        ((ImageCardView) viewHolder.view).setTitleText(item.toString());
+    }
+
+    public void onUnbindViewHolder(ViewHolder viewHolder) {
+        Log.d(TAG, "onUnbindViewHolder");
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java
new file mode 100644
index 0000000..082b134
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class DetailsActivity extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.details);
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java
new file mode 100644
index 0000000..6d376f0
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+
+public class DetailsDescriptionPresenter extends AbstractDetailsDescriptionPresenter {
+
+    @Override
+    protected void onBindDescription(ViewHolder vh, Object item) {
+        vh.getTitle().setText(item.toString());
+        vh.getSubtitle().setText("2013 - 2014   Drama   TV-14");
+        vh.getBody().setText("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
+                + "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
+                + "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo "
+                + "consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
+                + "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non "
+                + "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
new file mode 100644
index 0000000..c9a85f3
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.util.Log;
+import android.widget.Toast;
+
+public class DetailsFragment extends android.support.v17.leanback.app.DetailsFragment {
+    private static final String TAG = "leanback.BrowseFragment";
+
+    private static final int NUM_ROWS = 3;
+    private ArrayObjectAdapter mRowsAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate");
+        super.onCreate(savedInstanceState);
+
+        setupRows();
+    }
+
+    private void setupRows() {
+        ClassPresenterSelector ps = new ClassPresenterSelector();
+        DetailsOverviewRowPresenter dorPresenter =
+            new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
+        dorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
+            public void onActionClicked(Action action) {
+                Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
+            }
+        });
+
+        ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter);
+        ps.addClassPresenter(ListRow.class,
+                new ListRowPresenter());
+        mRowsAdapter = new ArrayObjectAdapter(ps);
+
+        Resources res = getActivity().getResources();
+        DetailsOverviewRow dor = new DetailsOverviewRow("Details Overview");
+        dor.setImageDrawable(res.getDrawable(R.drawable.details_img));
+        dor.addAction(new Action(1, "Buy $9.99"));
+        dor.addAction(new Action(2, "Rent", "$3.99", res.getDrawable(R.drawable.ic_action_a)));
+        mRowsAdapter.add(dor);
+
+        for (int i = 0; i < NUM_ROWS; ++i) {
+            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
+            listRowAdapter.add("Hello world");
+            listRowAdapter.add("This is a test");
+            HeaderItem header = new HeaderItem(i, "Row " + i, null);
+            mRowsAdapter.add(new ListRow(header, listRowAdapter));
+        }
+
+        setAdapter(mRowsAdapter);
+    }
+
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
new file mode 100644
index 0000000..74e7fb2
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchActivity.java
new file mode 100644
index 0000000..437bd72
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class SearchActivity extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search);
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java
new file mode 100644
index 0000000..0489196
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java
@@ -0,0 +1,85 @@
+package com.example.android.leanback;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.ObjectAdapter;
+import android.support.v17.leanback.widget.OnItemClickedListener;
+import android.support.v17.leanback.widget.Row;
+import android.text.TextUtils;
+import android.util.Log;
+
+public class SearchFragment extends android.support.v17.leanback.app.SearchFragment
+    implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider {
+    private static final String TAG = "leanback.SearchFragment";
+    private static final int NUM_ROWS = 3;
+    private static final int SEARCH_DELAY_MS = 300;
+
+    private ArrayObjectAdapter mRowsAdapter;
+    private Handler mHandler = new Handler();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+        setSearchResultProvider(this);
+        setOnItemClickedListener(new ItemClickedListener());
+    }
+
+    @Override
+    public ObjectAdapter getResultsAdapter() {
+        return mRowsAdapter;
+    }
+
+    @Override
+    public boolean onQueryTextChange(String newQuery) {
+        Log.i(TAG, String.format("Search Query Text Change %s", newQuery));
+        mRowsAdapter.clear();
+        if (!TextUtils.isEmpty(newQuery)) {
+            mHandler.removeCallbacks(mDelayedLoad);
+            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onQueryTextSubmit(String query) {
+        Log.i(TAG, String.format("Search Query Text Submit %s", query));
+        mRowsAdapter.clear();
+        if (!TextUtils.isEmpty(query)) {
+            mHandler.removeCallbacks(mDelayedLoad);
+            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+        }
+        return true;
+    }
+
+    private void loadRows() {
+        for (int i = 0; i < NUM_ROWS; ++i) {
+            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
+            listRowAdapter.add("Hello world");
+            listRowAdapter.add("This is a test");
+            HeaderItem header = new HeaderItem(i, "Row " + i, null);
+            mRowsAdapter.add(new ListRow(header, listRowAdapter));
+        }
+    }
+
+    private Runnable mDelayedLoad = new Runnable() {
+        @Override
+        public void run() {
+            loadRows();
+        }
+    };
+    private final class ItemClickedListener implements OnItemClickedListener {
+        public void onItemClicked(Object item, Row row) {
+            // TODO: use a fragment transaction instead of launching a new
+            // activity
+            Intent intent = new Intent(getActivity(), DetailsActivity.class);
+            startActivity(intent);
+        }
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/StringPresenter.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/StringPresenter.java
new file mode 100644
index 0000000..5c80e0b
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/StringPresenter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.support.v17.leanback.widget.Presenter;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class StringPresenter extends Presenter {
+    private static final String TAG = "StringPresenter";
+
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        Log.d(TAG, "onCreateViewHolder");
+        TextView tv = new TextView(parent.getContext());
+        tv.setFocusable(true);
+        tv.setFocusableInTouchMode(true);
+        tv.setBackground(
+                parent.getContext().getResources().getDrawable(R.drawable.text_bg));
+        return new ViewHolder(tv);
+    }
+
+    public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+        Log.d(TAG, "onBindViewHolder for " + item.toString());
+        ((TextView) viewHolder.view).setText(item.toString());
+    }
+
+    public void onUnbindViewHolder(ViewHolder viewHolder) {
+        Log.d(TAG, "onUnbindViewHolder"); 
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java
new file mode 100644
index 0000000..c5262b9
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class VerticalGridActivity extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.vertical_grid);
+        getWindow().setBackgroundDrawableResource(R.drawable.grid_bg);
+    }
+}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java
new file mode 100644
index 0000000..495bebe
--- /dev/null
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridFragment.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 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.example.android.leanback;
+
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.VerticalGridPresenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.OnItemClickedListener;
+import android.support.v17.leanback.widget.OnItemSelectedListener;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.Random;
+
+public class VerticalGridFragment extends android.support.v17.leanback.app.VerticalGridFragment {
+    private static final String TAG = "leanback.VerticalGridFragment";
+
+    private static final int NUM_COLUMNS = 3;
+    private static final int NUM_ITEMS = 50;
+    private static final int HEIGHT = 200;
+
+    private ArrayObjectAdapter mAdapter;
+    private Random mRandom;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate");
+        super.onCreate(savedInstanceState);
+
+        mRandom = new Random();
+
+        Params p = new Params();
+        p.setBadgeImage(getActivity().getResources().getDrawable(R.drawable.ic_title));
+        p.setTitle("Leanback Vertical Grid Demo");
+        setParams(p);
+
+        setupFragment();
+    }
+
+    private void setupFragment() {
+        VerticalGridPresenter gridPresenter = new VerticalGridPresenter();
+        gridPresenter.setNumberOfColumns(NUM_COLUMNS);
+        setGridPresenter(gridPresenter);
+
+        mAdapter = new ArrayObjectAdapter(new GridItemPresenter());
+        for (int i = 0; i < NUM_ITEMS; i++) {
+            mAdapter.add(new MyItem(i));
+        }
+        setAdapter(mAdapter);
+
+        setOnItemSelectedListener(new OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(Object item, Row row) {
+                Log.i(TAG, "item selected: " + ((MyItem) item).id);
+            }
+        });
+
+        setOnItemClickedListener(new OnItemClickedListener() {
+            @Override
+            public void onItemClicked(Object item, Row row) {
+                Log.i(TAG, "item clicked: " + ((MyItem) item).id);
+            }
+        });
+    }
+
+    private class GridItemPresenter extends Presenter {
+        public ViewHolder onCreateViewHolder(ViewGroup parent) {
+            TextView view = new TextView(parent.getContext());
+            // Choose a random height between HEIGHT and 1.5 * HEIGHT to
+            // demonstrate the staggered nature of the grid.
+            final int height = HEIGHT + mRandom.nextInt(HEIGHT / 2);
+            view.setLayoutParams(new ViewGroup.LayoutParams(200, height));
+            view.setFocusable(true);
+            view.setFocusableInTouchMode(true);
+            view.setBackgroundColor(Color.DKGRAY);
+            view.setGravity(Gravity.CENTER);
+            return new ViewHolder(view);
+        }
+
+        public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+            ((TextView) viewHolder.view).setText(Integer.toString(((MyItem) item).id));
+        }
+
+        public void onUnbindViewHolder(ViewHolder viewHolder) {}
+    }
+
+    static class MyItem {
+        int id;
+        MyItem(int id) {
+            this.id = id;
+        }
+    }
+}
diff --git a/samples/browseable/ActionBarCompat-Basic/res/values-v11/template-styles.xml b/samples/browseable/ActionBarCompat-Basic/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/ActionBarCompat-Basic/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/ActionBarCompat-Basic/res/values/template-styles.xml b/samples/browseable/ActionBarCompat-Basic/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/ActionBarCompat-Basic/res/values/template-styles.xml
+++ b/samples/browseable/ActionBarCompat-Basic/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/ActionBarCompat-ListPopupMenu/res/values-v11/template-styles.xml b/samples/browseable/ActionBarCompat-ListPopupMenu/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/ActionBarCompat-ListPopupMenu/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/ActionBarCompat-ListPopupMenu/res/values/template-styles.xml b/samples/browseable/ActionBarCompat-ListPopupMenu/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/ActionBarCompat-ListPopupMenu/res/values/template-styles.xml
+++ b/samples/browseable/ActionBarCompat-ListPopupMenu/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/ActionBarCompat-ShareActionProvider/res/values-v11/template-styles.xml b/samples/browseable/ActionBarCompat-ShareActionProvider/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/ActionBarCompat-ShareActionProvider/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/ActionBarCompat-ShareActionProvider/res/values/template-styles.xml b/samples/browseable/ActionBarCompat-ShareActionProvider/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/ActionBarCompat-ShareActionProvider/res/values/template-styles.xml
+++ b/samples/browseable/ActionBarCompat-ShareActionProvider/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/ActionBarCompat-Styled/res/values-v11/template-styles.xml b/samples/browseable/ActionBarCompat-Styled/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/ActionBarCompat-Styled/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/ActionBarCompat-Styled/res/values/template-styles.xml b/samples/browseable/ActionBarCompat-Styled/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/ActionBarCompat-Styled/res/values/template-styles.xml
+++ b/samples/browseable/ActionBarCompat-Styled/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/ActivityInstrumentation/res/values-v11/template-styles.xml b/samples/browseable/ActivityInstrumentation/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/ActivityInstrumentation/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/ActivityInstrumentation/res/values/template-styles.xml b/samples/browseable/ActivityInstrumentation/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/ActivityInstrumentation/res/values/template-styles.xml
+++ b/samples/browseable/ActivityInstrumentation/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/AdapterTransition/res/menu/fragment_adapter_transition.xml b/samples/browseable/AdapterTransition/res/menu/fragment_adapter_transition.xml
index 2a51b11..10057b8 100644
--- a/samples/browseable/AdapterTransition/res/menu/fragment_adapter_transition.xml
+++ b/samples/browseable/AdapterTransition/res/menu/fragment_adapter_transition.xml
@@ -18,6 +18,6 @@
     <item
         android:id="@+id/action_toggle"
         android:icon="@drawable/ic_action_grid"
-        android:showAsAction="always"
-        android:title="Toggle view"/>
+        android:showAsAction="always|withText"
+        android:title="@string/show_as_grid"/>
 </menu>
diff --git a/samples/browseable/AdapterTransition/res/values-v11/template-styles.xml b/samples/browseable/AdapterTransition/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/AdapterTransition/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/AdapterTransition/res/values-w820dp/dimens.xml b/samples/browseable/AdapterTransition/res/values-w820dp/dimens.xml
deleted file mode 100644
index 63fc816..0000000
--- a/samples/browseable/AdapterTransition/res/values-w820dp/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<resources>
-    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
-         (such as screen margins) for screens with more than 820dp of available width. This
-         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
-    <dimen name="activity_horizontal_margin">64dp</dimen>
-</resources>
diff --git a/samples/browseable/AdapterTransition/res/values/base-strings.xml b/samples/browseable/AdapterTransition/res/values/base-strings.xml
index 353c67e..ee0c4bd 100644
--- a/samples/browseable/AdapterTransition/res/values/base-strings.xml
+++ b/samples/browseable/AdapterTransition/res/values/base-strings.xml
@@ -23,7 +23,7 @@
         <![CDATA[
         
             
-	    Transition cannot be directly applied to AdapterViews. In this sample, we demonstrate how to create a overlay layout and run a Transition on it.
+	    Transition cannot be directly applied to AdapterViews. In this sample, we demonstrate how to create an overlay layout and run a Transition on it. Press the action bar button to toggle between ListView and GridView.
             
         
         ]]>
diff --git a/samples/browseable/AdapterTransition/res/values/dimens.xml b/samples/browseable/AdapterTransition/res/values/dimens.xml
deleted file mode 100644
index a0171a7..0000000
--- a/samples/browseable/AdapterTransition/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<resources>
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-
-    </resources>
diff --git a/samples/browseable/AdapterTransition/res/values/template-styles.xml b/samples/browseable/AdapterTransition/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/AdapterTransition/res/values/template-styles.xml
+++ b/samples/browseable/AdapterTransition/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java b/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java
index 525ed40..a949818 100644
--- a/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java
+++ b/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java
@@ -33,6 +33,7 @@
 import android.widget.FrameLayout;
 import android.widget.GridView;
 import android.widget.ListView;
+import android.widget.Toast;
 
 /**
  * Main screen for AdapterTransition sample.
@@ -46,6 +47,11 @@
     private static final int ROOT_ID = 1;
 
     /**
+     * A tag for saving state whether the mAbsListView is ListView or GridView.
+     */
+    private static final String STATE_IS_LISTVIEW = "is_listview";
+
+    /**
      * This is where we place our AdapterView (ListView / GridView).
      */
     private FrameLayout mContent;
@@ -80,20 +86,32 @@
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // We use a ListView at first
-        mAbsListView = (AbsListView) inflater.inflate(R.layout.fragment_meat_list, container, false);
-        mAdapter = new MeatAdapter(inflater, R.layout.item_meat_list);
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        // If savedInstanceState is available, we restore the state whether the list is a ListView
+        // or a GridView.
+        boolean isListView;
+        if (null == savedInstanceState) {
+            isListView = true;
+        } else {
+            isListView = savedInstanceState.getBoolean(STATE_IS_LISTVIEW, true);
+        }
+        inflateAbsList(inflater, container, isListView);
         return inflater.inflate(R.layout.fragment_adapter_transition, container, false);
     }
 
     @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(STATE_IS_LISTVIEW, mAbsListView instanceof ListView);
+    }
+
+    @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         // Retaining references for FrameLayouts that we use later.
         mContent = (FrameLayout) view.findViewById(R.id.content);
         mCover = (FrameLayout) view.findViewById(R.id.cover);
         // We are attaching the list to the screen here.
-        mAbsListView.setAdapter(mAdapter);
         mContent.addView(mAbsListView);
     }
 
@@ -109,8 +127,10 @@
         if (null != item) {
             if (mAbsListView instanceof ListView) {
                 item.setIcon(R.drawable.ic_action_grid);
+                item.setTitle(R.string.show_as_grid);
             } else {
                 item.setIcon(R.drawable.ic_action_list);
+                item.setTitle(R.string.show_as_list);
             }
         }
     }
@@ -152,6 +172,29 @@
     }
 
     /**
+     * Inflate a ListView or a GridView with a corresponding ListAdapter.
+     *
+     * @param inflater The LayoutInflater.
+     * @param container The ViewGroup that contains this AbsListView. The AbsListView won't be
+     *                  attached to it.
+     * @param inflateListView Pass true to inflate a ListView, or false to inflate a GridView.
+     */
+    private void inflateAbsList(LayoutInflater inflater, ViewGroup container,
+                                boolean inflateListView) {
+        if (inflateListView) {
+            mAbsListView = (AbsListView) inflater.inflate(R.layout.fragment_meat_list,
+                    container, false);
+            mAdapter = new MeatAdapter(inflater, R.layout.item_meat_list);
+        } else {
+            mAbsListView = (AbsListView) inflater.inflate(R.layout.fragment_meat_grid,
+                    container, false);
+            mAdapter = new MeatAdapter(inflater, R.layout.item_meat_grid);
+        }
+        mAbsListView.setAdapter(mAdapter);
+        mAbsListView.setOnItemClickListener(mAdapter);
+    }
+
+    /**
      * Toggle the UI between ListView and GridView.
      */
     private void toggle() {
@@ -190,15 +233,8 @@
         // If the current list is a GridView, we replace it with a ListView. If it is a ListView,
         // a GridView.
         LayoutInflater inflater = LayoutInflater.from(getActivity());
-        if (mAbsListView instanceof GridView) {
-            mAbsListView = (AbsListView) inflater.inflate(
-                    R.layout.fragment_meat_list, (ViewGroup) mAbsListView.getParent(), false);
-            mAdapter = new MeatAdapter(inflater, R.layout.item_meat_list);
-        } else {
-            mAbsListView = (AbsListView) inflater.inflate(
-                    R.layout.fragment_meat_grid, (ViewGroup) mAbsListView.getParent(), false);
-            mAdapter = new MeatAdapter(inflater, R.layout.item_meat_grid);
-        }
+        inflateAbsList(inflater, (ViewGroup) mAbsListView.getParent(),
+                mAbsListView instanceof GridView);
         mAbsListView.setAdapter(mAdapter);
         // We restore the scrolling position here.
         mAbsListView.setSelection(first);
diff --git a/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/MeatAdapter.java b/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/MeatAdapter.java
index c7630ce..dea4435 100644
--- a/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/MeatAdapter.java
+++ b/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/MeatAdapter.java
@@ -16,18 +16,22 @@
 
 package com.example.android.adaptertransition;
 
+import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.widget.Toast;
 
 /**
  * This class provides data as Views. It is designed to support both ListView and GridView by
  * changing a layout resource file to inflate.
  */
-public class MeatAdapter extends BaseAdapter {
+public class MeatAdapter extends BaseAdapter implements AbsListView.OnItemClickListener {
 
     private final LayoutInflater mLayoutInflater;
     private final int mResourceId;
@@ -80,6 +84,16 @@
         return view;
     }
 
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        ViewHolder holder = (ViewHolder) view.getTag();
+        Context context = view.getContext();
+        if (null != holder && null != holder.title && null != context) {
+            Toast.makeText(context, context.getString(R.string.item_clicked,
+                    holder.title.getText()), Toast.LENGTH_SHORT).show();
+        }
+    }
+
     private static class ViewHolder {
         public ImageView image;
         public TextView title;
diff --git a/samples/browseable/AdvancedImmersiveMode/res/values-v11/template-styles.xml b/samples/browseable/AdvancedImmersiveMode/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/AdvancedImmersiveMode/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/AdvancedImmersiveMode/res/values/template-styles.xml b/samples/browseable/AdvancedImmersiveMode/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/AdvancedImmersiveMode/res/values/template-styles.xml
+++ b/samples/browseable/AdvancedImmersiveMode/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/AppRestrictions/res/values-v11/template-styles.xml b/samples/browseable/AppRestrictions/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/AppRestrictions/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/AppRestrictions/res/values/template-styles.xml b/samples/browseable/AppRestrictions/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/AppRestrictions/res/values/template-styles.xml
+++ b/samples/browseable/AppRestrictions/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicAccessibility/res/values-v11/template-styles.xml b/samples/browseable/BasicAccessibility/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicAccessibility/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicAccessibility/res/values/template-styles.xml b/samples/browseable/BasicAccessibility/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicAccessibility/res/values/template-styles.xml
+++ b/samples/browseable/BasicAccessibility/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicAndroidKeyStore/res/values-v11/template-styles.xml b/samples/browseable/BasicAndroidKeyStore/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicAndroidKeyStore/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicContactables/res/values-v11/template-styles.xml b/samples/browseable/BasicContactables/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicContactables/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicContactables/res/values/template-styles.xml b/samples/browseable/BasicContactables/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicContactables/res/values/template-styles.xml
+++ b/samples/browseable/BasicContactables/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicGestureDetect/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/BasicGestureDetect/res/layout-sw600dp-land/activity_main.xml
new file mode 100755
index 0000000..653454b
--- /dev/null
+++ b/samples/browseable/BasicGestureDetect/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/sample_main_layout">
+    <TextView android:id="@+id/sample_output"
+              style="@style/Widget.SampleMessage"
+              android:background="@android:color/white"
+              android:layout_weight="1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:text="@string/intro_message"
+              android:layout_margin="16dp" />
+    <fragment
+            android:name="com.example.android.common.logger.LogFragment"
+            android:id="@+id/log_fragment"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/BasicGestureDetect/res/layout-sw600dp/activity_main.xml b/samples/browseable/BasicGestureDetect/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..f6f4157
--- /dev/null
+++ b/samples/browseable/BasicGestureDetect/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/sample_main_layout" >
+
+    <TextView android:id="@+id/sample_output"
+        style="@style/Widget.SampleMessage"
+        android:background="@android:color/white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/intro_message"
+        android:padding="16dp"
+        android:layout_margin="16dp"/>
+    <fragment
+        android:name="com.example.android.common.logger.LogFragment"
+        android:id="@+id/log_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/BasicGestureDetect/res/layout/activity_main.xml b/samples/browseable/BasicGestureDetect/res/layout/activity_main.xml
index bc5a575..6f41369 100755
--- a/samples/browseable/BasicGestureDetect/res/layout/activity_main.xml
+++ b/samples/browseable/BasicGestureDetect/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
               android:layout_weight="1"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:text="@string/intro_message" />
+              android:text="@string/intro_message"
+              android:padding="16dp" />
     <View
             android:layout_width="fill_parent"
             android:layout_height="1dp"
diff --git a/samples/browseable/BasicGestureDetect/res/values-sw600dp/template-styles.xml b/samples/browseable/BasicGestureDetect/res/values-sw600dp/template-styles.xml
index 03d1974..b6ea1a0 100644
--- a/samples/browseable/BasicGestureDetect/res/values-sw600dp/template-styles.xml
+++ b/samples/browseable/BasicGestureDetect/res/values-sw600dp/template-styles.xml
@@ -17,9 +17,17 @@
 <resources>
 
     <style name="Widget.SampleMessage">
-        <item name="android:textAppearance">?android:textAppearanceLarge</item>
-        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:padding">@dimen/margin_medium</item>
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+
+        <item name="android:layout_margin">16dp</item>
         <item name="android:shadowDy">-6.5</item>
     </style>
 
+    <style name="Log" parent="Widget.SampleOutput">
+        <item name="android:typeface">monospace</item>
+    </style>
+
+
 </resources>
diff --git a/samples/browseable/BasicGestureDetect/res/values-v11/template-styles.xml b/samples/browseable/BasicGestureDetect/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicGestureDetect/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicGestureDetect/src/com.example.android.basicgesturedetect/MainActivity.java b/samples/browseable/BasicGestureDetect/src/com.example.android.basicgesturedetect/MainActivity.java
index 1547807..de4a39f 100644
--- a/samples/browseable/BasicGestureDetect/src/com.example.android.basicgesturedetect/MainActivity.java
+++ b/samples/browseable/BasicGestureDetect/src/com.example.android.basicgesturedetect/MainActivity.java
@@ -19,6 +19,7 @@
 
 package com.example.android.basicgesturedetect;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.view.Menu;
@@ -74,6 +75,9 @@
         LogFragment logFragment = (LogFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.log_fragment);
         msgFilter.setNext(logFragment.getLogView());
+        logFragment.getLogView().setTextAppearance(this, R.style.Log);
+        logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
 
         Log.i(TAG, "Ready");
     }
diff --git a/samples/browseable/BasicImmersiveMode/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/BasicImmersiveMode/res/layout-sw600dp-land/activity_main.xml
new file mode 100755
index 0000000..653454b
--- /dev/null
+++ b/samples/browseable/BasicImmersiveMode/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/sample_main_layout">
+    <TextView android:id="@+id/sample_output"
+              style="@style/Widget.SampleMessage"
+              android:background="@android:color/white"
+              android:layout_weight="1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:text="@string/intro_message"
+              android:layout_margin="16dp" />
+    <fragment
+            android:name="com.example.android.common.logger.LogFragment"
+            android:id="@+id/log_fragment"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/BasicImmersiveMode/res/layout-sw600dp/activity_main.xml b/samples/browseable/BasicImmersiveMode/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..f6f4157
--- /dev/null
+++ b/samples/browseable/BasicImmersiveMode/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/sample_main_layout" >
+
+    <TextView android:id="@+id/sample_output"
+        style="@style/Widget.SampleMessage"
+        android:background="@android:color/white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/intro_message"
+        android:padding="16dp"
+        android:layout_margin="16dp"/>
+    <fragment
+        android:name="com.example.android.common.logger.LogFragment"
+        android:id="@+id/log_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/BasicImmersiveMode/res/layout/activity_main.xml b/samples/browseable/BasicImmersiveMode/res/layout/activity_main.xml
index bc5a575..6f41369 100755
--- a/samples/browseable/BasicImmersiveMode/res/layout/activity_main.xml
+++ b/samples/browseable/BasicImmersiveMode/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
               android:layout_weight="1"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:text="@string/intro_message" />
+              android:text="@string/intro_message"
+              android:padding="16dp" />
     <View
             android:layout_width="fill_parent"
             android:layout_height="1dp"
diff --git a/samples/browseable/BasicImmersiveMode/res/values-sw600dp/template-styles.xml b/samples/browseable/BasicImmersiveMode/res/values-sw600dp/template-styles.xml
index 03d1974..b6ea1a0 100644
--- a/samples/browseable/BasicImmersiveMode/res/values-sw600dp/template-styles.xml
+++ b/samples/browseable/BasicImmersiveMode/res/values-sw600dp/template-styles.xml
@@ -17,9 +17,17 @@
 <resources>
 
     <style name="Widget.SampleMessage">
-        <item name="android:textAppearance">?android:textAppearanceLarge</item>
-        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:padding">@dimen/margin_medium</item>
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+
+        <item name="android:layout_margin">16dp</item>
         <item name="android:shadowDy">-6.5</item>
     </style>
 
+    <style name="Log" parent="Widget.SampleOutput">
+        <item name="android:typeface">monospace</item>
+    </style>
+
+
 </resources>
diff --git a/samples/browseable/BasicImmersiveMode/res/values-v11/template-styles.xml b/samples/browseable/BasicImmersiveMode/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicImmersiveMode/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicImmersiveMode/src/com.example.android.basicimmersivemode/MainActivity.java b/samples/browseable/BasicImmersiveMode/src/com.example.android.basicimmersivemode/MainActivity.java
index 83e8f0e..0c1bcef 100644
--- a/samples/browseable/BasicImmersiveMode/src/com.example.android.basicimmersivemode/MainActivity.java
+++ b/samples/browseable/BasicImmersiveMode/src/com.example.android.basicimmersivemode/MainActivity.java
@@ -19,6 +19,7 @@
 
 package com.example.android.basicimmersivemode;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.view.Menu;
@@ -74,6 +75,9 @@
         LogFragment logFragment = (LogFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.log_fragment);
         msgFilter.setNext(logFragment.getLogView());
+        logFragment.getLogView().setTextAppearance(this, R.style.Log);
+        logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
 
         Log.i(TAG, "Ready");
     }
diff --git a/samples/browseable/BasicMediaDecoder/res/values-v11/template-styles.xml b/samples/browseable/BasicMediaDecoder/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicMediaDecoder/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicMediaDecoder/res/values/template-styles.xml b/samples/browseable/BasicMediaDecoder/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicMediaDecoder/res/values/template-styles.xml
+++ b/samples/browseable/BasicMediaDecoder/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicMediaRouter/res/values-v11/template-styles.xml b/samples/browseable/BasicMediaRouter/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicMediaRouter/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicMediaRouter/res/values/template-styles.xml b/samples/browseable/BasicMediaRouter/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicMediaRouter/res/values/template-styles.xml
+++ b/samples/browseable/BasicMediaRouter/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicMultitouch/res/values-v11/template-styles.xml b/samples/browseable/BasicMultitouch/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicMultitouch/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicMultitouch/res/values/template-styles.xml b/samples/browseable/BasicMultitouch/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicMultitouch/res/values/template-styles.xml
+++ b/samples/browseable/BasicMultitouch/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicNetworking/res/values-v11/template-styles.xml b/samples/browseable/BasicNetworking/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicNetworking/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicNetworking/res/values/template-styles.xml b/samples/browseable/BasicNetworking/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicNetworking/res/values/template-styles.xml
+++ b/samples/browseable/BasicNetworking/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicNotifications/res/values-v11/template-styles.xml b/samples/browseable/BasicNotifications/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicNotifications/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicNotifications/res/values/template-styles.xml b/samples/browseable/BasicNotifications/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicNotifications/res/values/template-styles.xml
+++ b/samples/browseable/BasicNotifications/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicRenderScript/res/values-v11/template-styles.xml b/samples/browseable/BasicRenderScript/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicRenderScript/res/values/template-styles.xml b/samples/browseable/BasicRenderScript/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicRenderScript/res/values/template-styles.xml
+++ b/samples/browseable/BasicRenderScript/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicRenderScript/src/rs/saturation.rs b/samples/browseable/BasicRenderScript/src/rs/saturation.rs
new file mode 100644
index 0000000..cf043d1
--- /dev/null
+++ b/samples/browseable/BasicRenderScript/src/rs/saturation.rs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.basicrenderscript)
+#pragma rs_fp_relaxed
+
+const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
+
+float saturationValue = 0.f;
+
+/*
+RenderScript kernel that performs saturation manipulation.
+*/
+uchar4 __attribute__((kernel)) saturation(uchar4 in)
+{
+    float4 f4 = rsUnpackColor8888(in);
+    float3 result = dot(f4.rgb, gMonoMult);
+    result = mix( result, f4.rgb, saturationValue );
+
+    return rsPackColorTo8888(result);
+}
+
diff --git a/samples/browseable/BasicSyncAdapter/res/values-v11/template-styles.xml b/samples/browseable/BasicSyncAdapter/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicSyncAdapter/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicSyncAdapter/res/values/template-styles.xml b/samples/browseable/BasicSyncAdapter/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicSyncAdapter/res/values/template-styles.xml
+++ b/samples/browseable/BasicSyncAdapter/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BasicTransition/res/layout/scene3.xml b/samples/browseable/BasicTransition/res/layout/scene3.xml
index 06246da..a4cac0f 100644
--- a/samples/browseable/BasicTransition/res/layout/scene3.xml
+++ b/samples/browseable/BasicTransition/res/layout/scene3.xml
@@ -48,7 +48,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_centerInParent="true"
-        android:text="@string/this_is_scene_3"
+        android:text="@string/additional_message"
         android:textAppearance="?android:attr/textAppearanceLarge"/>
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/samples/browseable/BasicTransition/res/values-v11/template-styles.xml b/samples/browseable/BasicTransition/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BasicTransition/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BasicTransition/res/values/template-styles.xml b/samples/browseable/BasicTransition/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BasicTransition/res/values/template-styles.xml
+++ b/samples/browseable/BasicTransition/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BatchStepSensor/res/layout/activity_main.xml b/samples/browseable/BatchStepSensor/res/layout/activity_main.xml
index b8a123e..63f1297 100755
--- a/samples/browseable/BatchStepSensor/res/layout/activity_main.xml
+++ b/samples/browseable/BatchStepSensor/res/layout/activity_main.xml
@@ -19,7 +19,7 @@
 
 <fragment
     android:id="@+id/fragment_cardstream"
-    android:name="com.example.android.batchstepsensor.CardStreamFragment"
+    android:name="com.example.android.batchstepsensor.cardstream.CardStreamFragment"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
diff --git a/samples/browseable/BatchStepSensor/res/layout/card.xml b/samples/browseable/BatchStepSensor/res/layout/card.xml
index 24bffeb..5deb6f5 100644
--- a/samples/browseable/BatchStepSensor/res/layout/card.xml
+++ b/samples/browseable/BatchStepSensor/res/layout/card.xml
@@ -17,7 +17,7 @@
 
 
 
-<com.example.android.batchstepsensor.CardLayout
+<com.example.android.batchstepsensor.cardstream.CardLayout
     android:id="@+id/card_layout"
     style="@style/Card"
     xmlns:android="http://schemas.android.com/apk/res/android"
@@ -71,4 +71,4 @@
         android:layout_alignWithParentIfMissing="false"
         android:visibility="invisible"/>
 
-</com.example.android.batchstepsensor.CardLayout>
+</com.example.android.batchstepsensor.cardstream.CardLayout>
diff --git a/samples/browseable/BatchStepSensor/res/layout/card_button_negative.xml b/samples/browseable/BatchStepSensor/res/layout/card_button_negative.xml
index bf66150..7ca9677 100644
--- a/samples/browseable/BatchStepSensor/res/layout/card_button_negative.xml
+++ b/samples/browseable/BatchStepSensor/res/layout/card_button_negative.xml
@@ -17,7 +17,7 @@
 
 
 
-<com.example.android.batchstepsensor.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
+<com.example.android.batchstepsensor.cardstream.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/card_button"
     style="@style/CardActionNegative"
     android:layout_width="match_parent"
diff --git a/samples/browseable/BatchStepSensor/res/layout/card_button_neutral.xml b/samples/browseable/BatchStepSensor/res/layout/card_button_neutral.xml
index 7f759fc..da74448 100644
--- a/samples/browseable/BatchStepSensor/res/layout/card_button_neutral.xml
+++ b/samples/browseable/BatchStepSensor/res/layout/card_button_neutral.xml
@@ -17,7 +17,7 @@
 
 
 
-<com.example.android.batchstepsensor.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
+<com.example.android.batchstepsensor.cardstream.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/card_button"
     style="@style/CardActionNeutral"
     android:layout_width="match_parent"
diff --git a/samples/browseable/BatchStepSensor/res/layout/card_button_positive.xml b/samples/browseable/BatchStepSensor/res/layout/card_button_positive.xml
index 2011f9c..afbda8a 100644
--- a/samples/browseable/BatchStepSensor/res/layout/card_button_positive.xml
+++ b/samples/browseable/BatchStepSensor/res/layout/card_button_positive.xml
@@ -17,7 +17,7 @@
 
 
 
-<com.example.android.batchstepsensor.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
+<com.example.android.batchstepsensor.cardstream.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/card_button"
     style="@style/CardActionPositive"
     android:layout_width="match_parent"
diff --git a/samples/browseable/BatchStepSensor/res/layout/cardstream.xml b/samples/browseable/BatchStepSensor/res/layout/cardstream.xml
index 463af5c..a6b917b 100644
--- a/samples/browseable/BatchStepSensor/res/layout/cardstream.xml
+++ b/samples/browseable/BatchStepSensor/res/layout/cardstream.xml
@@ -22,10 +22,10 @@
     android:layout_height="match_parent"
     android:fillViewport="true">
 
-    <com.example.android.batchstepsensor.CardStreamLinearLayout
+    <com.example.android.batchstepsensor.cardstream.CardStreamLinearLayout
         style="@style/CardStream"
         android:id="@+id/card_stream"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
-    </com.example.android.batchstepsensor.CardStreamLinearLayout>
+        android:layout_height="match_parent"/>
+
 </ScrollView>
diff --git a/samples/browseable/BatchStepSensor/res/values-v11/template-styles.xml b/samples/browseable/BatchStepSensor/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BatchStepSensor/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BatchStepSensor/res/values/template-styles.xml b/samples/browseable/BatchStepSensor/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BatchStepSensor/res/values/template-styles.xml
+++ b/samples/browseable/BatchStepSensor/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/BatchStepSensorFragment.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/BatchStepSensorFragment.java
index aab0fc3..467c427 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/BatchStepSensorFragment.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/BatchStepSensorFragment.java
@@ -26,6 +26,10 @@
 import android.support.v4.app.Fragment;
 
 import com.example.android.common.logger.Log;
+import com.example.android.batchstepsensor.cardstream.Card;
+import com.example.android.batchstepsensor.cardstream.CardStream;
+import com.example.android.batchstepsensor.cardstream.CardStreamFragment;
+import com.example.android.batchstepsensor.cardstream.OnCardClickListener;
 
 public class BatchStepSensorFragment extends Fragment implements OnCardClickListener {
 
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/MainActivity.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/MainActivity.java
index bb1f9a1..5e4f7e3 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/MainActivity.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/MainActivity.java
@@ -26,6 +26,12 @@
 import com.example.android.common.activities.SampleActivityBase;
 import com.example.android.common.logger.Log;
 
+import com.example.android.batchstepsensor.cardstream.CardStream;
+import com.example.android.batchstepsensor.cardstream.CardStreamFragment;
+import com.example.android.batchstepsensor.cardstream.CardStreamState;
+import com.example.android.batchstepsensor.cardstream.OnCardClickListener;
+import com.example.android.batchstepsensor.cardstream.StreamRetentionFragment;
+
 public class MainActivity extends SampleActivityBase implements CardStream {
     public static final String TAG = "MainActivity";
     public static final String FRAGTAG = "BatchStepSensorFragment";
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/Card.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/Card.java
similarity index 99%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/Card.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/Card.java
index fb885c7..a3723e8 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/Card.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/Card.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -31,6 +31,8 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import com.example.android.batchstepsensor.R;
+
 import java.util.ArrayList;
 
 /**
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardActionButton.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardActionButton.java
similarity index 97%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardActionButton.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardActionButton.java
index ea37e66..01c7094 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardActionButton.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardActionButton.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.content.Context;
 import android.util.AttributeSet;
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardLayout.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardLayout.java
similarity index 97%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardLayout.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardLayout.java
index 8215275..ce20f7f 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardLayout.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardLayout.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.content.Context;
 import android.util.AttributeSet;
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStream.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStream.java
similarity index 92%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStream.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStream.java
index 5de9852..70cc5dd 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStream.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStream.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 public interface CardStream {
     public CardStreamFragment getCardStream();
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamAnimator.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamAnimator.java
similarity index 98%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamAnimator.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamAnimator.java
index a22ddd7..de06cf6 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamAnimator.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamAnimator.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.animation.ObjectAnimator;
 import android.content.Context;
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamFragment.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamFragment.java
similarity index 98%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamFragment.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamFragment.java
index 9f8b7cb..5388cd9 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamFragment.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamFragment.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
@@ -30,6 +30,7 @@
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 
+import com.example.android.batchstepsensor.R;
 
 /**
  * A Fragment that handles a stream of cards.
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamLinearLayout.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamLinearLayout.java
similarity index 99%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamLinearLayout.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamLinearLayout.java
index aeab770..5e4ba15 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamLinearLayout.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamLinearLayout.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.animation.Animator;
 import android.animation.LayoutTransition;
@@ -38,6 +38,7 @@
 import android.widget.ScrollView;
 
 import com.example.android.common.logger.Log;
+import com.example.android.batchstepsensor.R;
 
 import java.util.ArrayList;
 
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamState.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamState.java
similarity index 92%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamState.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamState.java
index 08432a9..57ba177 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/CardStreamState.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/CardStreamState.java
@@ -17,14 +17,14 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import java.util.HashSet;
 
 /**
  * A struct object that holds the state of a {@link CardStreamFragment}.
  */
-class CardStreamState{
+public class CardStreamState {
     protected Card[] visibleCards;
     protected Card[] hiddenCards;
     protected HashSet<String> dismissibleCards;
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/DefaultCardStreamAnimator.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/DefaultCardStreamAnimator.java
similarity index 98%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/DefaultCardStreamAnimator.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/DefaultCardStreamAnimator.java
index 19ef43b..21e54d3 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/DefaultCardStreamAnimator.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/DefaultCardStreamAnimator.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/OnCardClickListener.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/OnCardClickListener.java
similarity index 92%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/OnCardClickListener.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/OnCardClickListener.java
index f024110..90ba21e 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/OnCardClickListener.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/OnCardClickListener.java
@@ -17,7 +17,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 public interface OnCardClickListener {
     public void onCardClick(int cardActionId, String cardTag);
diff --git a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/StreamRetentionFragment.java b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/StreamRetentionFragment.java
similarity index 94%
rename from samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/StreamRetentionFragment.java
rename to samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/StreamRetentionFragment.java
index 7cd7f2b..51d5428 100644
--- a/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/StreamRetentionFragment.java
+++ b/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/cardstream/StreamRetentionFragment.java
@@ -16,7 +16,7 @@
 
 
 
-package com.example.android.batchstepsensor;
+package com.example.android.batchstepsensor.cardstream;
 
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
diff --git a/samples/browseable/BluetoothLeGatt/res/values-v11/template-styles.xml b/samples/browseable/BluetoothLeGatt/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BluetoothLeGatt/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BluetoothLeGatt/res/values/template-styles.xml b/samples/browseable/BluetoothLeGatt/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BluetoothLeGatt/res/values/template-styles.xml
+++ b/samples/browseable/BluetoothLeGatt/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/BorderlessButtons/res/values-v11/template-styles.xml b/samples/browseable/BorderlessButtons/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/BorderlessButtons/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/BorderlessButtons/res/values/template-styles.xml b/samples/browseable/BorderlessButtons/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/BorderlessButtons/res/values/template-styles.xml
+++ b/samples/browseable/BorderlessButtons/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/CardEmulation/res/values-v11/template-styles.xml b/samples/browseable/CardEmulation/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/CardEmulation/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/CardEmulation/res/values/template-styles.xml b/samples/browseable/CardEmulation/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/CardEmulation/res/values/template-styles.xml
+++ b/samples/browseable/CardEmulation/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/CardReader/res/values-v11/template-styles.xml b/samples/browseable/CardReader/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/CardReader/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/CardReader/res/values/template-styles.xml b/samples/browseable/CardReader/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/CardReader/res/values/template-styles.xml
+++ b/samples/browseable/CardReader/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/CustomChoiceList/res/values-v11/template-styles.xml b/samples/browseable/CustomChoiceList/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/CustomChoiceList/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/CustomChoiceList/res/values/template-styles.xml b/samples/browseable/CustomChoiceList/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/CustomChoiceList/res/values/template-styles.xml
+++ b/samples/browseable/CustomChoiceList/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/CustomNotifications/res/values-v11/template-styles.xml b/samples/browseable/CustomNotifications/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/CustomNotifications/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/CustomNotifications/res/values/template-styles.xml b/samples/browseable/CustomNotifications/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/CustomNotifications/res/values/template-styles.xml
+++ b/samples/browseable/CustomNotifications/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/CustomTransition/AndroidManifest.xml b/samples/browseable/CustomTransition/AndroidManifest.xml
new file mode 100644
index 0000000..b3328f1
--- /dev/null
+++ b/samples/browseable/CustomTransition/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.customtransition"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+
+    <application android:allowBackup="true"
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/AppTheme">
+
+        <activity android:name=".MainActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/samples/browseable/CustomTransition/_index.jd b/samples/browseable/CustomTransition/_index.jd
new file mode 100644
index 0000000..c68a762
--- /dev/null
+++ b/samples/browseable/CustomTransition/_index.jd
@@ -0,0 +1,8 @@
+
+
+
+page.tags="CustomTransition"
+sample.group=UI
+@jd:body
+
+<p>This sample demonstrates how to create and use a custom {@link android.transition.Transition}.</p>
diff --git a/samples/browseable/CustomTransition/res/drawable-hdpi/ic_launcher.png b/samples/browseable/CustomTransition/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..846a7fe
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/CustomTransition/res/drawable-hdpi/tile.9.png b/samples/browseable/CustomTransition/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/CustomTransition/res/drawable-mdpi/ic_launcher.png b/samples/browseable/CustomTransition/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..7a21d06
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/CustomTransition/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/CustomTransition/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71734d7
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/CustomTransition/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/CustomTransition/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d6d9b26
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/CustomTransition/res/layout-w720dp/activity_main.xml b/samples/browseable/CustomTransition/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/CustomTransition/res/layout/activity_main.xml b/samples/browseable/CustomTransition/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/CustomTransition/res/layout/fragment_custom_transition.xml b/samples/browseable/CustomTransition/res/layout/fragment_custom_transition.xml
new file mode 100644
index 0000000..c48f270
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/layout/fragment_custom_transition.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context="com.example.android.customtransition.CustomTransitionFragment">
+
+    <Button
+        android:id="@+id/show_next_scene"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Show next scene"/>
+
+    <FrameLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+
+</LinearLayout>
diff --git a/samples/browseable/CustomTransition/res/layout/scene1.xml b/samples/browseable/CustomTransition/res/layout/scene1.xml
new file mode 100644
index 0000000..e686ff7
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/layout/scene1.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+    android:id="@+id/container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    tools:context="com.example.android.customtransition.CustomTransitionFragment">
+
+    <View
+        android:id="@+id/view_1"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#f00"/>
+
+    <View
+        android:id="@+id/view_2"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#0f0"/>
+
+    <View
+        android:id="@+id/view_3"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#00f"/>
+
+</LinearLayout>
diff --git a/samples/browseable/CustomTransition/res/layout/scene2.xml b/samples/browseable/CustomTransition/res/layout/scene2.xml
new file mode 100644
index 0000000..e37e8b0
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/layout/scene2.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+    android:id="@+id/container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    tools:context="com.example.android.customtransition.CustomTransitionFragment">
+
+    <View
+        android:id="@+id/view_1"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#0f0"/>
+
+    <View
+        android:id="@+id/view_2"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#00f"/>
+
+    <View
+        android:id="@+id/view_3"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#f00"/>
+
+</LinearLayout>
diff --git a/samples/browseable/CustomTransition/res/layout/scene3.xml b/samples/browseable/CustomTransition/res/layout/scene3.xml
new file mode 100644
index 0000000..e95fc3c
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/layout/scene3.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+    android:id="@+id/container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    tools:context="com.example.android.customtransition.CustomTransitionFragment">
+
+    <View
+        android:id="@+id/view_1"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#00f"/>
+
+    <View
+        android:id="@+id/view_2"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#f00"/>
+
+    <View
+        android:id="@+id/view_3"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:layout_margin="8dp"
+        android:background="#0f0"/>
+
+</LinearLayout>
diff --git a/samples/browseable/CustomTransition/res/menu/main.xml b/samples/browseable/CustomTransition/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/CustomTransition/res/values-sw600dp/template-dimens.xml b/samples/browseable/CustomTransition/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/CustomTransition/res/values-sw600dp/template-styles.xml b/samples/browseable/CustomTransition/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/CustomTransition/res/values-v11/template-styles.xml b/samples/browseable/CustomTransition/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/CustomTransition/res/values/base-strings.xml b/samples/browseable/CustomTransition/res/values/base-strings.xml
new file mode 100644
index 0000000..68c9c41
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<resources>
+    <string name="app_name">CustomTransition</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            This sample demonstrates how to create and use a custom Transition.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/CustomTransition/res/values/strings.xml b/samples/browseable/CustomTransition/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<resources>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/samples/browseable/CustomTransition/res/values/template-dimens.xml b/samples/browseable/CustomTransition/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/CustomTransition/res/values/template-styles.xml b/samples/browseable/CustomTransition/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/CustomTransition/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/CustomTransition/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/logger/Log.java b/samples/browseable/CustomTransition/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogNode.java b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogView.java b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/CustomTransition/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.customtransition/ChangeColor.java b/samples/browseable/CustomTransition/src/com.example.android.customtransition/ChangeColor.java
new file mode 100644
index 0000000..d36cfb4
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.customtransition/ChangeColor.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 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.example.android.customtransition;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.transition.ChangeBounds;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
+
+public class ChangeColor extends Transition {
+
+    /** Key to store a color value in TransitionValues object */
+    private static final String PROPNAME_BACKGROUND = "customtransition:change_color:background";
+
+    // BEGIN_INCLUDE (capture_values)
+    /**
+     * Convenience method: Add the background Drawable property value
+     * to the TransitionsValues.value Map for a target.
+     */
+    private void captureValues(TransitionValues values) {
+        // Capture the property values of views for later use
+        values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    // Capture the value of the background drawable property for a target in the ending Scene.
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+    // END_INCLUDE (capture_values)
+
+    // BEGIN_INCLUDE (create_animator)
+    // Create an animation for each target that is in both the starting and ending Scene. For each
+    // pair of targets, if their background property value is a color (rather than a graphic),
+    // create a ValueAnimator based on an ArgbEvaluator that interpolates between the starting and
+    // ending color. Also create an update listener that sets the View background color for each
+    // animation frame
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot,
+                                   TransitionValues startValues, TransitionValues endValues) {
+        // This transition can only be applied to views that are on both starting and ending scenes.
+        if (null == startValues || null == endValues) {
+            return null;
+        }
+        // Store a convenient reference to the target. Both the starting and ending layout have the
+        // same target.
+        final View view = endValues.view;
+        // Store the object containing the background property for both the starting and ending
+        // layouts.
+        Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
+        Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
+        // This transition changes background colors for a target. It doesn't animate any other
+        // background changes. If the property isn't a ColorDrawable, ignore the target.
+        if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
+            ColorDrawable startColor = (ColorDrawable) startBackground;
+            ColorDrawable endColor = (ColorDrawable) endBackground;
+            // If the background color for the target in the starting and ending layouts is
+            // different, create an animation.
+            if (startColor.getColor() != endColor.getColor()) {
+                // Create a new Animator object to apply to the targets as the transitions framework
+                // changes from the starting to the ending layout. Use the class ValueAnimator,
+                // which provides a timing pulse to change property values provided to it. The
+                // animation runs on the UI thread. The Evaluator controls what type of
+                // interpolation is done. In this case, an ArgbEvaluator interpolates between two
+                // #argb values, which are specified as the 2nd and 3rd input arguments.
+                ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),
+                        startColor.getColor(), endColor.getColor());
+                // Add an update listener to the Animator object.
+                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        Object value = animation.getAnimatedValue();
+                        // Each time the ValueAnimator produces a new frame in the animation, change
+                        // the background color of the target. Ensure that the value isn't null.
+                        if (null != value) {
+                            view.setBackgroundColor((Integer) value);
+                        }
+                    }
+                });
+                // Return the Animator object to the transitions framework. As the framework changes
+                // between the starting and ending layouts, it applies the animation you've created.
+                return animator;
+            }
+        }
+        // For non-ColorDrawable backgrounds, we just return null, and no animation will take place.
+        return null;
+    }
+    // END_INCLUDE (create_animator)
+
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.customtransition/CustomTransitionFragment.java b/samples/browseable/CustomTransition/src/com.example.android.customtransition/CustomTransitionFragment.java
new file mode 100644
index 0000000..8ef695a
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.customtransition/CustomTransitionFragment.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 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.example.android.customtransition;
+
+import com.example.android.common.logger.Log;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+public class CustomTransitionFragment extends Fragment implements View.OnClickListener {
+
+    private static final String STATE_CURRENT_SCENE = "current_scene";
+
+    /** Tag for the logger */
+    private static final String TAG = "CustomTransitionFragment";
+
+    /** These are the Scenes we use. */
+    private Scene[] mScenes;
+
+    /** The current index for mScenes. */
+    private int mCurrentScene;
+
+    /** This is the custom Transition we use in this sample. */
+    private Transition mTransition;
+
+    public CustomTransitionFragment() {
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_custom_transition, container, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        Context context = getActivity();
+        FrameLayout container = (FrameLayout) view.findViewById(R.id.container);
+        view.findViewById(R.id.show_next_scene).setOnClickListener(this);
+        if (null != savedInstanceState) {
+            mCurrentScene = savedInstanceState.getInt(STATE_CURRENT_SCENE);
+        }
+        // We set up the Scenes here.
+        mScenes = new Scene[] {
+                Scene.getSceneForLayout(container, R.layout.scene1, context),
+                Scene.getSceneForLayout(container, R.layout.scene2, context),
+                Scene.getSceneForLayout(container, R.layout.scene3, context),
+        };
+        // This is the custom Transition.
+        mTransition = new ChangeColor();
+        // Show the initial Scene.
+        TransitionManager.go(mScenes[mCurrentScene % mScenes.length]);
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(STATE_CURRENT_SCENE, mCurrentScene);
+    }
+
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.show_next_scene: {
+                mCurrentScene = (mCurrentScene + 1) % mScenes.length;
+                Log.i(TAG, "Transitioning to scene #" + mCurrentScene);
+                // Pass the custom Transition as second argument for TransitionManager.go
+                TransitionManager.go(mScenes[mCurrentScene], mTransition);
+                break;
+            }
+        }
+    }
+
+}
diff --git a/samples/browseable/CustomTransition/src/com.example.android.customtransition/MainActivity.java b/samples/browseable/CustomTransition/src/com.example.android.customtransition/MainActivity.java
new file mode 100644
index 0000000..04c4e4d
--- /dev/null
+++ b/samples/browseable/CustomTransition/src/com.example.android.customtransition/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+
+package com.example.android.customtransition;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    // Whether the Log Fragment is currently shown
+    private boolean mLogShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        CustomTransitionFragment fragment = new CustomTransitionFragment();
+        transaction.replace(R.id.sample_content_fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/DisplayingBitmaps/res/values-v11/template-styles.xml b/samples/browseable/DisplayingBitmaps/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/DisplayingBitmaps/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/DisplayingBitmaps/res/values/template-styles.xml b/samples/browseable/DisplayingBitmaps/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/DisplayingBitmaps/res/values/template-styles.xml
+++ b/samples/browseable/DisplayingBitmaps/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/DoneBar/res/values-v11/template-styles.xml b/samples/browseable/DoneBar/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/DoneBar/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/FragmentTransition/AndroidManifest.xml b/samples/browseable/FragmentTransition/AndroidManifest.xml
new file mode 100644
index 0000000..8d02eb0
--- /dev/null
+++ b/samples/browseable/FragmentTransition/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2014 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.example.android.fragmenttransition"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.example.android.fragmenttransition.MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/samples/browseable/FragmentTransition/_index.jd b/samples/browseable/FragmentTransition/_index.jd
new file mode 100644
index 0000000..f0efe32
--- /dev/null
+++ b/samples/browseable/FragmentTransition/_index.jd
@@ -0,0 +1,8 @@
+
+
+
+page.tags="FragmentTransition"
+sample.group=UI
+@jd:body
+
+<p>This sample demonstrates how to start a transition right after a fragment transaction.</p>
diff --git a/samples/browseable/FragmentTransition/res/drawable-hdpi/ic_launcher.png b/samples/browseable/FragmentTransition/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..dfa1b45
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-hdpi/tile.9.png b/samples/browseable/FragmentTransition/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-mdpi/ic_launcher.png b/samples/browseable/FragmentTransition/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..5f4ae7b
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p1.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p1.jpg
new file mode 100644
index 0000000..10f07ac
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p1.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p10.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p10.jpg
new file mode 100644
index 0000000..4272f4c
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p10.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p11.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p11.jpg
new file mode 100644
index 0000000..c5722b2
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p11.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p2.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p2.jpg
new file mode 100644
index 0000000..ca380ae
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p2.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p3.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p3.jpg
new file mode 100644
index 0000000..6fc71e7
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p3.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p4.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p4.jpg
new file mode 100644
index 0000000..153c1ff
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p4.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p5.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p5.jpg
new file mode 100644
index 0000000..46d6a13
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p5.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p6.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p6.jpg
new file mode 100644
index 0000000..89ccb83
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p6.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p7.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p7.jpg
new file mode 100644
index 0000000..7e9546d
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p7.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p8.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p8.jpg
new file mode 100644
index 0000000..21e25ba
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p8.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-nodpi/p9.jpg b/samples/browseable/FragmentTransition/res/drawable-nodpi/p9.jpg
new file mode 100644
index 0000000..79854cb
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-nodpi/p9.jpg
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/FragmentTransition/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5e00f33
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/FragmentTransition/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..e061498
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/FragmentTransition/res/layout-w720dp/activity_main.xml b/samples/browseable/FragmentTransition/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/FragmentTransition/res/layout/activity_main.xml b/samples/browseable/FragmentTransition/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/FragmentTransition/res/layout/fragment_detail.xml b/samples/browseable/FragmentTransition/res/layout/fragment_detail.xml
new file mode 100644
index 0000000..d94256f
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/layout/fragment_detail.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2014 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<FrameLayout
+    android:id="@+id/container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"/>
diff --git a/samples/browseable/FragmentTransition/res/layout/fragment_detail_content.xml b/samples/browseable/FragmentTransition/res/layout/fragment_detail_content.xml
new file mode 100644
index 0000000..2068460
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/layout/fragment_detail_content.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2014 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.
+-->
+<ScrollView
+    android:id="@+id/frame"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:scrollbars="none">
+
+    <RelativeLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <ImageView
+            android:id="@+id/image"
+            android:layout_width="match_parent"
+            android:layout_height="180dp"
+            android:scaleType="centerCrop"
+            tools:src="@drawable/p1"/>
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignBottom="@id/image"
+            android:layout_alignEnd="@id/image"
+            android:layout_marginEnd="16dp"
+            android:shadowColor="#000000"
+            android:shadowDx="0"
+            android:shadowDy="0"
+            android:shadowRadius="10"
+            android:textColor="#ffffff"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            tools:text="Image"/>
+
+        <TextView
+            android:id="@+id/body"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/image"
+            android:layout_marginBottom="16dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="16dp"
+            android:text="@string/lorem_ipsum"/>
+
+    </RelativeLayout>
+
+</ScrollView>
\ No newline at end of file
diff --git a/samples/browseable/FragmentTransition/res/layout/fragment_fragment_transition.xml b/samples/browseable/FragmentTransition/res/layout/fragment_fragment_transition.xml
new file mode 100644
index 0000000..6e1c7a1
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/layout/fragment_fragment_transition.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2014 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.
+-->
+<GridView
+    android:id="@+id/grid"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clipToPadding="false"
+    android:columnWidth="150dp"
+    android:horizontalSpacing="1dp"
+    android:numColumns="auto_fit"
+    android:padding="1dp"
+    android:scrollbars="none"
+    android:stretchMode="columnWidth"
+    android:verticalSpacing="1dp"
+    tools:context="com.example.android.fragmenttransition.FragmentTransitionFragment"/>
diff --git a/samples/browseable/FragmentTransition/res/layout/item_meat_grid.xml b/samples/browseable/FragmentTransition/res/layout/item_meat_grid.xml
new file mode 100644
index 0000000..df34883
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/layout/item_meat_grid.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2014 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<FrameLayout
+    android:id="@+id/frame"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <RelativeLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="150dp"
+        tools:ignore="UselessParent">
+
+        <ImageView
+            android:id="@+id/image"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"
+            tools:src="@drawable/p1"/>
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentEnd="true"
+            android:layout_gravity="bottom|end"
+            android:layout_marginEnd="16dp"
+            android:layout_marginStart="16dp"
+            android:gravity="center_horizontal"
+            android:shadowColor="#000000"
+            android:shadowDx="0"
+            android:shadowDy="0"
+            android:shadowRadius="10"
+            android:textColor="#ffffff"
+            android:textSize="24sp"
+            android:textStyle="bold"
+            tools:text="Hello"/>
+
+    </RelativeLayout>
+
+</FrameLayout>
diff --git a/samples/browseable/FragmentTransition/res/menu/main.xml b/samples/browseable/FragmentTransition/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/FragmentTransition/res/values-sw600dp/template-dimens.xml b/samples/browseable/FragmentTransition/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/FragmentTransition/res/values-sw600dp/template-styles.xml b/samples/browseable/FragmentTransition/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/FragmentTransition/res/values-v11/template-styles.xml b/samples/browseable/FragmentTransition/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/FragmentTransition/res/values/base-strings.xml b/samples/browseable/FragmentTransition/res/values/base-strings.xml
new file mode 100644
index 0000000..933e1f2
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<resources>
+    <string name="app_name">FragmentTransition</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+	    This sample demonstrates how to start a transition right after a fragment transaction.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/FragmentTransition/res/values/strings.xml b/samples/browseable/FragmentTransition/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<resources>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/samples/browseable/FragmentTransition/res/values/template-dimens.xml b/samples/browseable/FragmentTransition/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/FragmentTransition/res/values/template-styles.xml b/samples/browseable/FragmentTransition/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/FragmentTransition/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/FragmentTransition/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/logger/Log.java b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogNode.java b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogView.java b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/view/SlidingTabLayout.java b/samples/browseable/FragmentTransition/src/com.example.android.common/view/SlidingTabLayout.java
new file mode 100644
index 0000000..20049e3
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/view/SlidingTabLayout.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+
+    /**
+     * Allows complete control over the colors drawn in the tab layout. Set with
+     * {@link #setCustomTabColorizer(TabColorizer)}.
+     */
+    public interface TabColorizer {
+
+        /**
+         * @return return the color of the indicator used when {@code position} is selected.
+         */
+        int getIndicatorColor(int position);
+
+        /**
+         * @return return the color of the divider drawn to the right of {@code position}.
+         */
+        int getDividerColor(int position);
+
+    }
+
+    private static final int TITLE_OFFSET_DIPS = 24;
+    private static final int TAB_VIEW_PADDING_DIPS = 16;
+    private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+    private int mTitleOffset;
+
+    private int mTabViewLayoutId;
+    private int mTabViewTextViewId;
+
+    private ViewPager mViewPager;
+    private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+    private final SlidingTabStrip mTabStrip;
+
+    public SlidingTabLayout(Context context) {
+        this(context, null);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        // Disable the Scroll Bar
+        setHorizontalScrollBarEnabled(false);
+        // Make sure that the Tab Strips fills this View
+        setFillViewport(true);
+
+        mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+        mTabStrip = new SlidingTabStrip(context);
+        addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    /**
+     * Set the custom {@link TabColorizer} to be used.
+     *
+     * If you only require simple custmisation then you can use
+     * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+     * similar effects.
+     */
+    public void setCustomTabColorizer(TabColorizer tabColorizer) {
+        mTabStrip.setCustomTabColorizer(tabColorizer);
+    }
+
+    /**
+     * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+     * circular array. Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setSelectedIndicatorColors(int... colors) {
+        mTabStrip.setSelectedIndicatorColors(colors);
+    }
+
+    /**
+     * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+     * Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setDividerColors(int... colors) {
+        mTabStrip.setDividerColors(colors);
+    }
+
+    /**
+     * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+     * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+     * that the layout can update it's scroll position correctly.
+     *
+     * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+     */
+    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+        mViewPagerPageChangeListener = listener;
+    }
+
+    /**
+     * Set the custom layout to be inflated for the tab views.
+     *
+     * @param layoutResId Layout id to be inflated
+     * @param textViewId id of the {@link TextView} in the inflated view
+     */
+    public void setCustomTabView(int layoutResId, int textViewId) {
+        mTabViewLayoutId = layoutResId;
+        mTabViewTextViewId = textViewId;
+    }
+
+    /**
+     * Sets the associated view pager. Note that the assumption here is that the pager content
+     * (number of tabs and tab titles) does not change after this call has been made.
+     */
+    public void setViewPager(ViewPager viewPager) {
+        mTabStrip.removeAllViews();
+
+        mViewPager = viewPager;
+        if (viewPager != null) {
+            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+            populateTabStrip();
+        }
+    }
+
+    /**
+     * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+     * {@link #setCustomTabView(int, int)}.
+     */
+    protected TextView createDefaultTabView(Context context) {
+        TextView textView = new TextView(context);
+        textView.setGravity(Gravity.CENTER);
+        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+        textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            // If we're running on Honeycomb or newer, then we can use the Theme's
+            // selectableItemBackground to ensure that the View has a pressed state
+            TypedValue outValue = new TypedValue();
+            getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+                    outValue, true);
+            textView.setBackgroundResource(outValue.resourceId);
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+            textView.setAllCaps(true);
+        }
+
+        int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+        textView.setPadding(padding, padding, padding, padding);
+
+        return textView;
+    }
+
+    private void populateTabStrip() {
+        final PagerAdapter adapter = mViewPager.getAdapter();
+        final View.OnClickListener tabClickListener = new TabClickListener();
+
+        for (int i = 0; i < adapter.getCount(); i++) {
+            View tabView = null;
+            TextView tabTitleView = null;
+
+            if (mTabViewLayoutId != 0) {
+                // If there is a custom tab view layout id set, try and inflate it
+                tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+                        false);
+                tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+            }
+
+            if (tabView == null) {
+                tabView = createDefaultTabView(getContext());
+            }
+
+            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+                tabTitleView = (TextView) tabView;
+            }
+
+            tabTitleView.setText(adapter.getPageTitle(i));
+            tabView.setOnClickListener(tabClickListener);
+
+            mTabStrip.addView(tabView);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (mViewPager != null) {
+            scrollToTab(mViewPager.getCurrentItem(), 0);
+        }
+    }
+
+    private void scrollToTab(int tabIndex, int positionOffset) {
+        final int tabStripChildCount = mTabStrip.getChildCount();
+        if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+            return;
+        }
+
+        View selectedChild = mTabStrip.getChildAt(tabIndex);
+        if (selectedChild != null) {
+            int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+            if (tabIndex > 0 || positionOffset > 0) {
+                // If we're not at the first child and are mid-scroll, make sure we obey the offset
+                targetScrollX -= mTitleOffset;
+            }
+
+            scrollTo(targetScrollX, 0);
+        }
+    }
+
+    private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+        private int mScrollState;
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+            int tabStripChildCount = mTabStrip.getChildCount();
+            if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+                return;
+            }
+
+            mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+            View selectedTitle = mTabStrip.getChildAt(position);
+            int extraOffset = (selectedTitle != null)
+                    ? (int) (positionOffset * selectedTitle.getWidth())
+                    : 0;
+            scrollToTab(position, extraOffset);
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+                        positionOffsetPixels);
+            }
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            mScrollState = state;
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+            }
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+                mTabStrip.onViewPagerPageChanged(position, 0f);
+                scrollToTab(position, 0);
+            }
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageSelected(position);
+            }
+        }
+
+    }
+
+    private class TabClickListener implements View.OnClickListener {
+        @Override
+        public void onClick(View v) {
+            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+                if (v == mTabStrip.getChildAt(i)) {
+                    mViewPager.setCurrentItem(i);
+                    return;
+                }
+            }
+        }
+    }
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.common/view/SlidingTabStrip.java b/samples/browseable/FragmentTransition/src/com.example.android.common/view/SlidingTabStrip.java
new file mode 100644
index 0000000..d5bbbae
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.common/view/SlidingTabStrip.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+    private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+    private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+    private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+    private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+    private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+    private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+    private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+
+    private final int mBottomBorderThickness;
+    private final Paint mBottomBorderPaint;
+
+    private final int mSelectedIndicatorThickness;
+    private final Paint mSelectedIndicatorPaint;
+
+    private final int mDefaultBottomBorderColor;
+
+    private final Paint mDividerPaint;
+    private final float mDividerHeight;
+
+    private int mSelectedPosition;
+    private float mSelectionOffset;
+
+    private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+    private final SimpleTabColorizer mDefaultTabColorizer;
+
+    SlidingTabStrip(Context context) {
+        this(context, null);
+    }
+
+    SlidingTabStrip(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setWillNotDraw(false);
+
+        final float density = getResources().getDisplayMetrics().density;
+
+        TypedValue outValue = new TypedValue();
+        context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+        final int themeForegroundColor =  outValue.data;
+
+        mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+                DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+        mDefaultTabColorizer = new SimpleTabColorizer();
+        mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+        mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+                DEFAULT_DIVIDER_COLOR_ALPHA));
+
+        mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+        mBottomBorderPaint = new Paint();
+        mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+        mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+        mSelectedIndicatorPaint = new Paint();
+
+        mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+        mDividerPaint = new Paint();
+        mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+    }
+
+    void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+        mCustomTabColorizer = customTabColorizer;
+        invalidate();
+    }
+
+    void setSelectedIndicatorColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setIndicatorColors(colors);
+        invalidate();
+    }
+
+    void setDividerColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setDividerColors(colors);
+        invalidate();
+    }
+
+    void onViewPagerPageChanged(int position, float positionOffset) {
+        mSelectedPosition = position;
+        mSelectionOffset = positionOffset;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        final int height = getHeight();
+        final int childCount = getChildCount();
+        final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+        final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+                ? mCustomTabColorizer
+                : mDefaultTabColorizer;
+
+        // Thick colored underline below the current selection
+        if (childCount > 0) {
+            View selectedTitle = getChildAt(mSelectedPosition);
+            int left = selectedTitle.getLeft();
+            int right = selectedTitle.getRight();
+            int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+            if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+                int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+                if (color != nextColor) {
+                    color = blendColors(nextColor, color, mSelectionOffset);
+                }
+
+                // Draw the selection partway between the tabs
+                View nextTitle = getChildAt(mSelectedPosition + 1);
+                left = (int) (mSelectionOffset * nextTitle.getLeft() +
+                        (1.0f - mSelectionOffset) * left);
+                right = (int) (mSelectionOffset * nextTitle.getRight() +
+                        (1.0f - mSelectionOffset) * right);
+            }
+
+            mSelectedIndicatorPaint.setColor(color);
+
+            canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+                    height, mSelectedIndicatorPaint);
+        }
+
+        // Thin underline along the entire bottom edge
+        canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+        // Vertical separators between the titles
+        int separatorTop = (height - dividerHeightPx) / 2;
+        for (int i = 0; i < childCount - 1; i++) {
+            View child = getChildAt(i);
+            mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+            canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+                    separatorTop + dividerHeightPx, mDividerPaint);
+        }
+    }
+
+    /**
+     * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+     */
+    private static int setColorAlpha(int color, byte alpha) {
+        return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+    }
+
+    /**
+     * Blend {@code color1} and {@code color2} using the given ratio.
+     *
+     * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+     *              0.0 will return {@code color2}.
+     */
+    private static int blendColors(int color1, int color2, float ratio) {
+        final float inverseRation = 1f - ratio;
+        float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+        float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+        float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+        return Color.rgb((int) r, (int) g, (int) b);
+    }
+
+    private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+        private int[] mIndicatorColors;
+        private int[] mDividerColors;
+
+        @Override
+        public final int getIndicatorColor(int position) {
+            return mIndicatorColors[position % mIndicatorColors.length];
+        }
+
+        @Override
+        public final int getDividerColor(int position) {
+            return mDividerColors[position % mDividerColors.length];
+        }
+
+        void setIndicatorColors(int... colors) {
+            mIndicatorColors = colors;
+        }
+
+        void setDividerColors(int... colors) {
+            mDividerColors = colors;
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/DetailFragment.java b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/DetailFragment.java
new file mode 100644
index 0000000..81e7b46
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/DetailFragment.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2014 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.example.android.fragmenttransition;
+
+import com.example.android.common.logger.Log;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class DetailFragment extends Fragment implements Animation.AnimationListener {
+
+    private static final String TAG = "DetailFragment";
+
+    private static final String ARG_RESOURCE_ID = "resource_id";
+    private static final String ARG_TITLE = "title";
+    private static final String ARG_X = "x";
+    private static final String ARG_Y = "y";
+    private static final String ARG_WIDTH = "width";
+    private static final String ARG_HEIGHT = "height";
+
+    /**
+     * Create a new instance of DetailFragment.
+     *
+     * @param resourceId The resource ID of the Drawable image to show
+     * @param title The title of the image
+     * @param x The horizontal position of the grid item in pixel
+     * @param y The vertical position of the grid item in pixel
+     * @param width The width of the grid item in pixel
+     * @param height The height of the grid item in pixel
+     * @return a new instance of DetailFragment
+     */
+    public static DetailFragment newInstance(int resourceId, String title,
+                                             int x, int y, int width, int height) {
+        DetailFragment fragment = new DetailFragment();
+        Bundle args = new Bundle();
+        args.putInt(ARG_RESOURCE_ID, resourceId);
+        args.putString(ARG_TITLE, title);
+        args.putInt(ARG_X, x);
+        args.putInt(ARG_Y, y);
+        args.putInt(ARG_WIDTH, width);
+        args.putInt(ARG_HEIGHT, height);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    public DetailFragment() {
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_detail, container, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        FrameLayout root = (FrameLayout) view;
+        Context context = view.getContext();
+        assert context != null;
+        // This is how the fragment looks at first. Since the transition is one-way, we don't need to make
+        // this a Scene.
+        View item = LayoutInflater.from(context).inflate(R.layout.item_meat_grid, root, false);
+        assert item != null;
+        bind(item);
+        // We adjust the position of the initial image with LayoutParams using the values supplied
+        // as the fragment arguments.
+        Bundle args = getArguments();
+        FrameLayout.LayoutParams params = null;
+        if (args != null) {
+            params = new FrameLayout.LayoutParams(
+                    args.getInt(ARG_WIDTH), args.getInt(ARG_HEIGHT));
+            params.topMargin = args.getInt(ARG_Y);
+            params.leftMargin = args.getInt(ARG_X);
+        }
+        root.addView(item, params);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+    }
+
+    /**
+     * Bind the views inside of parent with the fragment arguments.
+     *
+     * @param parent The parent of views to bind.
+     */
+    private void bind(View parent) {
+        Bundle args = getArguments();
+        if (args == null) {
+            return;
+        }
+        ImageView image = (ImageView) parent.findViewById(R.id.image);
+        image.setImageResource(args.getInt(ARG_RESOURCE_ID));
+        TextView title = (TextView) parent.findViewById(R.id.title);
+        title.setText(args.getString(ARG_TITLE));
+    }
+
+    @Override
+    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
+        Animation animation = AnimationUtils.loadAnimation(getActivity(),
+                enter ? android.R.anim.fade_in : android.R.anim.fade_out);
+        // We bind a listener for the fragment transaction. We only bind it when
+        // this fragment is entering.
+        if (animation != null && enter) {
+            animation.setAnimationListener(this);
+        }
+        return animation;
+    }
+
+    @Override
+    public void onAnimationStart(Animation animation) {
+        // This method is called at the end of the animation for the fragment transaction.
+        // There is nothing we need to do in this sample.
+    }
+
+    @Override
+    public void onAnimationEnd(Animation animation) {
+        // This method is called at the end of the animation for the fragment transaction,
+        // which is perfect time to start our Transition.
+        Log.i(TAG, "Fragment animation ended. Starting a Transition.");
+        final Scene scene = Scene.getSceneForLayout((ViewGroup) getView(),
+                R.layout.fragment_detail_content, getActivity());
+        TransitionManager.go(scene);
+        // Note that we need to bind views with data after we call TransitionManager.go().
+        bind(scene.getSceneRoot());
+    }
+
+    @Override
+    public void onAnimationRepeat(Animation animation) {
+        // This method is never called in this sample because the animation doesn't repeat.
+    }
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/FragmentTransitionFragment.java b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/FragmentTransitionFragment.java
new file mode 100644
index 0000000..c072eb9
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/FragmentTransitionFragment.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2014 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.example.android.fragmenttransition;
+
+import com.example.android.common.logger.Log;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.AdapterView;
+import android.widget.GridView;
+
+public class FragmentTransitionFragment extends Fragment implements AdapterView.OnItemClickListener {
+
+    private static final String TAG = "FragmentTransitionFragment";
+
+    private MeatAdapter mAdapter;
+
+    public static FragmentTransitionFragment newInstance() {
+        return new FragmentTransitionFragment();
+    }
+
+    public FragmentTransitionFragment() {
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // This is the adapter we use to populate the grid.
+        mAdapter = new MeatAdapter(inflater, R.layout.item_meat_grid);
+        // Inflate the layout with a GridView in it.
+        return inflater.inflate(R.layout.fragment_fragment_transition, container, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        GridView grid = (GridView) view.findViewById(R.id.grid);
+        grid.setAdapter(mAdapter);
+        grid.setOnItemClickListener(this);
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        Meat meat = mAdapter.getItem(position);
+        Log.i(TAG, meat.title + " clicked. Replacing fragment.");
+        // We start the fragment transaction here. It is just an ordinary fragment transaction.
+        getActivity().getSupportFragmentManager()
+                .beginTransaction()
+                .replace(R.id.sample_content_fragment,
+                        DetailFragment.newInstance(meat.resourceId, meat.title,
+                                (int) view.getX(), (int) view.getY(),
+                                view.getWidth(), view.getHeight())
+                )
+                // We push the fragment transaction to back stack. User can go back to the
+                // previous fragment by pressing back button.
+                .addToBackStack("detail")
+                .commit();
+    }
+
+    @Override
+    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
+        return AnimationUtils.loadAnimation(getActivity(),
+                enter ? android.R.anim.fade_in : android.R.anim.fade_out);
+    }
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/MainActivity.java b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/MainActivity.java
new file mode 100644
index 0000000..7d6ca6f
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+
+package com.example.android.fragmenttransition;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    // Whether the Log Fragment is currently shown
+    private boolean mLogShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        FragmentTransitionFragment fragment = new FragmentTransitionFragment();
+        transaction.replace(R.id.sample_content_fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/Meat.java b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/Meat.java
new file mode 100644
index 0000000..2f2fdfa
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/Meat.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2014 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.example.android.fragmenttransition;
+
+/**
+ * This represents a sample data.
+ */
+public class Meat {
+
+    public int resourceId;
+    public String title;
+
+    public Meat(int resourceId, String title) {
+        this.resourceId = resourceId;
+        this.title = title;
+    }
+
+    public static final Meat[] MEATS = {
+            new Meat(R.drawable.p1, "First"),
+            new Meat(R.drawable.p2, "Second"),
+            new Meat(R.drawable.p3, "Third"),
+            new Meat(R.drawable.p4, "Fourth"),
+            new Meat(R.drawable.p5, "Fifth"),
+            new Meat(R.drawable.p6, "Sixth"),
+            new Meat(R.drawable.p7, "Seventh"),
+            new Meat(R.drawable.p8, "Eighth"),
+            new Meat(R.drawable.p9, "Ninth"),
+            new Meat(R.drawable.p10, "Tenth"),
+            new Meat(R.drawable.p11, "Eleventh"),
+    };
+
+}
diff --git a/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/MeatAdapter.java b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/MeatAdapter.java
new file mode 100644
index 0000000..307fd85
--- /dev/null
+++ b/samples/browseable/FragmentTransition/src/com.example.android.fragmenttransition/MeatAdapter.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2014 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.example.android.fragmenttransition;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+class MeatAdapter extends BaseAdapter {
+
+    private final LayoutInflater mLayoutInflater;
+    private final int mResourceId;
+
+    public MeatAdapter(LayoutInflater inflater, int resourceId) {
+        mLayoutInflater = inflater;
+        mResourceId = resourceId;
+    }
+
+    @Override
+    public int getCount() {
+        return Meat.MEATS.length;
+    }
+
+    @Override
+    public Meat getItem(int position) {
+        return Meat.MEATS[position];
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return Meat.MEATS[position].resourceId;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        final View view;
+        final ViewHolder holder;
+        if (null == convertView) {
+            view = mLayoutInflater.inflate(mResourceId, parent, false);
+            holder = new ViewHolder();
+            assert view != null;
+            holder.image = (ImageView) view.findViewById(R.id.image);
+            holder.title = (TextView) view.findViewById(R.id.title);
+            view.setTag(holder);
+        } else {
+            view = convertView;
+            holder = (ViewHolder) view.getTag();
+        }
+        bindView(holder, position);
+        return view;
+    }
+
+    public void bindView(ViewHolder holder, int position) {
+        Meat meat = getItem(position);
+        holder.image.setImageResource(meat.resourceId);
+        holder.title.setText(meat.title);
+    }
+
+    public static class ViewHolder {
+        public ImageView image;
+        public TextView title;
+    }
+
+}
diff --git a/samples/browseable/HorizontalPaging/res/values-v11/template-styles.xml b/samples/browseable/HorizontalPaging/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/HorizontalPaging/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/HorizontalPaging/res/values/template-styles.xml b/samples/browseable/HorizontalPaging/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/HorizontalPaging/res/values/template-styles.xml
+++ b/samples/browseable/HorizontalPaging/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/ImmersiveMode/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/ImmersiveMode/res/layout-sw600dp-land/activity_main.xml
new file mode 100755
index 0000000..653454b
--- /dev/null
+++ b/samples/browseable/ImmersiveMode/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/sample_main_layout">
+    <TextView android:id="@+id/sample_output"
+              style="@style/Widget.SampleMessage"
+              android:background="@android:color/white"
+              android:layout_weight="1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:text="@string/intro_message"
+              android:layout_margin="16dp" />
+    <fragment
+            android:name="com.example.android.common.logger.LogFragment"
+            android:id="@+id/log_fragment"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/ImmersiveMode/res/layout-sw600dp/activity_main.xml b/samples/browseable/ImmersiveMode/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..f6f4157
--- /dev/null
+++ b/samples/browseable/ImmersiveMode/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/sample_main_layout" >
+
+    <TextView android:id="@+id/sample_output"
+        style="@style/Widget.SampleMessage"
+        android:background="@android:color/white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/intro_message"
+        android:padding="16dp"
+        android:layout_margin="16dp"/>
+    <fragment
+        android:name="com.example.android.common.logger.LogFragment"
+        android:id="@+id/log_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/ImmersiveMode/res/layout/activity_main.xml b/samples/browseable/ImmersiveMode/res/layout/activity_main.xml
index bc5a575..6f41369 100755
--- a/samples/browseable/ImmersiveMode/res/layout/activity_main.xml
+++ b/samples/browseable/ImmersiveMode/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
               android:layout_weight="1"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:text="@string/intro_message" />
+              android:text="@string/intro_message"
+              android:padding="16dp" />
     <View
             android:layout_width="fill_parent"
             android:layout_height="1dp"
diff --git a/samples/browseable/ImmersiveMode/res/values-sw600dp/template-styles.xml b/samples/browseable/ImmersiveMode/res/values-sw600dp/template-styles.xml
index 03d1974..b6ea1a0 100644
--- a/samples/browseable/ImmersiveMode/res/values-sw600dp/template-styles.xml
+++ b/samples/browseable/ImmersiveMode/res/values-sw600dp/template-styles.xml
@@ -17,9 +17,17 @@
 <resources>
 
     <style name="Widget.SampleMessage">
-        <item name="android:textAppearance">?android:textAppearanceLarge</item>
-        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:padding">@dimen/margin_medium</item>
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+
+        <item name="android:layout_margin">16dp</item>
         <item name="android:shadowDy">-6.5</item>
     </style>
 
+    <style name="Log" parent="Widget.SampleOutput">
+        <item name="android:typeface">monospace</item>
+    </style>
+
+
 </resources>
diff --git a/samples/browseable/ImmersiveMode/res/values-v11/template-styles.xml b/samples/browseable/ImmersiveMode/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/ImmersiveMode/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/ImmersiveMode/src/com.example.android.immersivemode/MainActivity.java b/samples/browseable/ImmersiveMode/src/com.example.android.immersivemode/MainActivity.java
index fd02112..8fb6e34 100644
--- a/samples/browseable/ImmersiveMode/src/com.example.android.immersivemode/MainActivity.java
+++ b/samples/browseable/ImmersiveMode/src/com.example.android.immersivemode/MainActivity.java
@@ -19,6 +19,7 @@
 
 package com.example.android.immersivemode;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.view.Menu;
@@ -74,6 +75,9 @@
         LogFragment logFragment = (LogFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.log_fragment);
         msgFilter.setNext(logFragment.getLogView());
+        logFragment.getLogView().setTextAppearance(this, R.style.Log);
+        logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
 
         Log.i(TAG, "Ready");
     }
diff --git a/samples/browseable/MediaRecorder/res/values-v11/template-styles.xml b/samples/browseable/MediaRecorder/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/MediaRecorder/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/MediaRecorder/res/values/template-styles.xml b/samples/browseable/MediaRecorder/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/MediaRecorder/res/values/template-styles.xml
+++ b/samples/browseable/MediaRecorder/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/MediaRouter/res/values-v11/template-styles.xml b/samples/browseable/MediaRouter/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/MediaRouter/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/MediaRouter/res/values/template-styles.xml b/samples/browseable/MediaRouter/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/MediaRouter/res/values/template-styles.xml
+++ b/samples/browseable/MediaRouter/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/NetworkConnect/res/values-v11/template-styles.xml b/samples/browseable/NetworkConnect/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/NetworkConnect/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/NetworkConnect/res/values/template-styles.xml b/samples/browseable/NetworkConnect/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/NetworkConnect/res/values/template-styles.xml
+++ b/samples/browseable/NetworkConnect/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/RenderScriptIntrinsic/res/values-v11/template-styles.xml b/samples/browseable/RenderScriptIntrinsic/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/RenderScriptIntrinsic/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/RenderScriptIntrinsic/res/values/template-styles.xml b/samples/browseable/RenderScriptIntrinsic/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/RenderScriptIntrinsic/res/values/template-styles.xml
+++ b/samples/browseable/RenderScriptIntrinsic/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/RepeatingAlarm/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/RepeatingAlarm/res/layout-sw600dp-land/activity_main.xml
new file mode 100755
index 0000000..653454b
--- /dev/null
+++ b/samples/browseable/RepeatingAlarm/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/sample_main_layout">
+    <TextView android:id="@+id/sample_output"
+              style="@style/Widget.SampleMessage"
+              android:background="@android:color/white"
+              android:layout_weight="1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:text="@string/intro_message"
+              android:layout_margin="16dp" />
+    <fragment
+            android:name="com.example.android.common.logger.LogFragment"
+            android:id="@+id/log_fragment"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/RepeatingAlarm/res/layout-sw600dp/activity_main.xml b/samples/browseable/RepeatingAlarm/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..f6f4157
--- /dev/null
+++ b/samples/browseable/RepeatingAlarm/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/sample_main_layout" >
+
+    <TextView android:id="@+id/sample_output"
+        style="@style/Widget.SampleMessage"
+        android:background="@android:color/white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/intro_message"
+        android:padding="16dp"
+        android:layout_margin="16dp"/>
+    <fragment
+        android:name="com.example.android.common.logger.LogFragment"
+        android:id="@+id/log_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/RepeatingAlarm/res/layout/activity_main.xml b/samples/browseable/RepeatingAlarm/res/layout/activity_main.xml
index bc5a575..6f41369 100755
--- a/samples/browseable/RepeatingAlarm/res/layout/activity_main.xml
+++ b/samples/browseable/RepeatingAlarm/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
               android:layout_weight="1"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:text="@string/intro_message" />
+              android:text="@string/intro_message"
+              android:padding="16dp" />
     <View
             android:layout_width="fill_parent"
             android:layout_height="1dp"
diff --git a/samples/browseable/RepeatingAlarm/res/values-sw600dp/template-styles.xml b/samples/browseable/RepeatingAlarm/res/values-sw600dp/template-styles.xml
index 03d1974..b6ea1a0 100644
--- a/samples/browseable/RepeatingAlarm/res/values-sw600dp/template-styles.xml
+++ b/samples/browseable/RepeatingAlarm/res/values-sw600dp/template-styles.xml
@@ -17,9 +17,17 @@
 <resources>
 
     <style name="Widget.SampleMessage">
-        <item name="android:textAppearance">?android:textAppearanceLarge</item>
-        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:padding">@dimen/margin_medium</item>
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+
+        <item name="android:layout_margin">16dp</item>
         <item name="android:shadowDy">-6.5</item>
     </style>
 
+    <style name="Log" parent="Widget.SampleOutput">
+        <item name="android:typeface">monospace</item>
+    </style>
+
+
 </resources>
diff --git a/samples/browseable/RepeatingAlarm/res/values-v11/template-styles.xml b/samples/browseable/RepeatingAlarm/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/RepeatingAlarm/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/RepeatingAlarm/src/com.example.android.repeatingalarm/MainActivity.java b/samples/browseable/RepeatingAlarm/src/com.example.android.repeatingalarm/MainActivity.java
index 2d2a6aa..147f576 100644
--- a/samples/browseable/RepeatingAlarm/src/com.example.android.repeatingalarm/MainActivity.java
+++ b/samples/browseable/RepeatingAlarm/src/com.example.android.repeatingalarm/MainActivity.java
@@ -19,6 +19,7 @@
 
 package com.example.android.repeatingalarm;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.view.Menu;
@@ -74,6 +75,9 @@
         LogFragment logFragment = (LogFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.log_fragment);
         msgFilter.setNext(logFragment.getLogView());
+        logFragment.getLogView().setTextAppearance(this, R.style.Log);
+        logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
 
         Log.i(TAG, "Ready");
     }
diff --git a/samples/browseable/SlidingTabsBasic/res/values-v11/template-styles.xml b/samples/browseable/SlidingTabsBasic/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/SlidingTabsBasic/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/SlidingTabsBasic/res/values/template-styles.xml b/samples/browseable/SlidingTabsBasic/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/SlidingTabsBasic/res/values/template-styles.xml
+++ b/samples/browseable/SlidingTabsBasic/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/SlidingTabsColors/res/values-v11/template-styles.xml b/samples/browseable/SlidingTabsColors/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/SlidingTabsColors/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/SlidingTabsColors/res/values/template-styles.xml b/samples/browseable/SlidingTabsColors/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/SlidingTabsColors/res/values/template-styles.xml
+++ b/samples/browseable/SlidingTabsColors/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/StorageClient/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/StorageClient/res/layout-sw600dp-land/activity_main.xml
new file mode 100755
index 0000000..653454b
--- /dev/null
+++ b/samples/browseable/StorageClient/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/sample_main_layout">
+    <TextView android:id="@+id/sample_output"
+              style="@style/Widget.SampleMessage"
+              android:background="@android:color/white"
+              android:layout_weight="1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:text="@string/intro_message"
+              android:layout_margin="16dp" />
+    <fragment
+            android:name="com.example.android.common.logger.LogFragment"
+            android:id="@+id/log_fragment"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/StorageClient/res/layout-sw600dp/activity_main.xml b/samples/browseable/StorageClient/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..f6f4157
--- /dev/null
+++ b/samples/browseable/StorageClient/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/sample_main_layout" >
+
+    <TextView android:id="@+id/sample_output"
+        style="@style/Widget.SampleMessage"
+        android:background="@android:color/white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/intro_message"
+        android:padding="16dp"
+        android:layout_margin="16dp"/>
+    <fragment
+        android:name="com.example.android.common.logger.LogFragment"
+        android:id="@+id/log_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/StorageClient/res/layout/activity_main.xml b/samples/browseable/StorageClient/res/layout/activity_main.xml
index bc5a575..6f41369 100755
--- a/samples/browseable/StorageClient/res/layout/activity_main.xml
+++ b/samples/browseable/StorageClient/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
               android:layout_weight="1"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:text="@string/intro_message" />
+              android:text="@string/intro_message"
+              android:padding="16dp" />
     <View
             android:layout_width="fill_parent"
             android:layout_height="1dp"
diff --git a/samples/browseable/StorageClient/res/values-sw600dp/template-styles.xml b/samples/browseable/StorageClient/res/values-sw600dp/template-styles.xml
index 03d1974..b6ea1a0 100644
--- a/samples/browseable/StorageClient/res/values-sw600dp/template-styles.xml
+++ b/samples/browseable/StorageClient/res/values-sw600dp/template-styles.xml
@@ -17,9 +17,17 @@
 <resources>
 
     <style name="Widget.SampleMessage">
-        <item name="android:textAppearance">?android:textAppearanceLarge</item>
-        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:padding">@dimen/margin_medium</item>
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+
+        <item name="android:layout_margin">16dp</item>
         <item name="android:shadowDy">-6.5</item>
     </style>
 
+    <style name="Log" parent="Widget.SampleOutput">
+        <item name="android:typeface">monospace</item>
+    </style>
+
+
 </resources>
diff --git a/samples/browseable/StorageClient/res/values-v11/template-styles.xml b/samples/browseable/StorageClient/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/StorageClient/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/StorageClient/src/com.example.android.storageclient/MainActivity.java b/samples/browseable/StorageClient/src/com.example.android.storageclient/MainActivity.java
index 69c75eb..106f26b 100644
--- a/samples/browseable/StorageClient/src/com.example.android.storageclient/MainActivity.java
+++ b/samples/browseable/StorageClient/src/com.example.android.storageclient/MainActivity.java
@@ -19,6 +19,7 @@
 
 package com.example.android.storageclient;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.view.Menu;
@@ -74,6 +75,9 @@
         LogFragment logFragment = (LogFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.log_fragment);
         msgFilter.setNext(logFragment.getLogView());
+        logFragment.getLogView().setTextAppearance(this, R.style.Log);
+        logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
 
         Log.i(TAG, "Ready");
     }
diff --git a/samples/browseable/StorageProvider/res/layout-sw600dp-land/activity_main.xml b/samples/browseable/StorageProvider/res/layout-sw600dp-land/activity_main.xml
new file mode 100755
index 0000000..653454b
--- /dev/null
+++ b/samples/browseable/StorageProvider/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:id="@+id/sample_main_layout">
+    <TextView android:id="@+id/sample_output"
+              style="@style/Widget.SampleMessage"
+              android:background="@android:color/white"
+              android:layout_weight="1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:text="@string/intro_message"
+              android:layout_margin="16dp" />
+    <fragment
+            android:name="com.example.android.common.logger.LogFragment"
+            android:id="@+id/log_fragment"
+            android:layout_weight="1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/StorageProvider/res/layout-sw600dp/activity_main.xml b/samples/browseable/StorageProvider/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..f6f4157
--- /dev/null
+++ b/samples/browseable/StorageProvider/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/sample_main_layout" >
+
+    <TextView android:id="@+id/sample_output"
+        style="@style/Widget.SampleMessage"
+        android:background="@android:color/white"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/intro_message"
+        android:padding="16dp"
+        android:layout_margin="16dp"/>
+    <fragment
+        android:name="com.example.android.common.logger.LogFragment"
+        android:id="@+id/log_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/samples/browseable/StorageProvider/res/layout/activity_main.xml b/samples/browseable/StorageProvider/res/layout/activity_main.xml
index bc5a575..6f41369 100755
--- a/samples/browseable/StorageProvider/res/layout/activity_main.xml
+++ b/samples/browseable/StorageProvider/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
               android:layout_weight="1"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:text="@string/intro_message" />
+              android:text="@string/intro_message"
+              android:padding="16dp" />
     <View
             android:layout_width="fill_parent"
             android:layout_height="1dp"
diff --git a/samples/browseable/StorageProvider/res/values-sw600dp/template-styles.xml b/samples/browseable/StorageProvider/res/values-sw600dp/template-styles.xml
index 03d1974..b6ea1a0 100644
--- a/samples/browseable/StorageProvider/res/values-sw600dp/template-styles.xml
+++ b/samples/browseable/StorageProvider/res/values-sw600dp/template-styles.xml
@@ -17,9 +17,17 @@
 <resources>
 
     <style name="Widget.SampleMessage">
-        <item name="android:textAppearance">?android:textAppearanceLarge</item>
-        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:padding">@dimen/margin_medium</item>
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+
+        <item name="android:layout_margin">16dp</item>
         <item name="android:shadowDy">-6.5</item>
     </style>
 
+    <style name="Log" parent="Widget.SampleOutput">
+        <item name="android:typeface">monospace</item>
+    </style>
+
+
 </resources>
diff --git a/samples/browseable/StorageProvider/res/values-v11/template-styles.xml b/samples/browseable/StorageProvider/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/StorageProvider/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/StorageProvider/src/com.example.android.storageprovider/MainActivity.java b/samples/browseable/StorageProvider/src/com.example.android.storageprovider/MainActivity.java
index 5f04a62..3108c1f 100644
--- a/samples/browseable/StorageProvider/src/com.example.android.storageprovider/MainActivity.java
+++ b/samples/browseable/StorageProvider/src/com.example.android.storageprovider/MainActivity.java
@@ -19,6 +19,7 @@
 
 package com.example.android.storageprovider;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.view.Menu;
@@ -74,6 +75,9 @@
         LogFragment logFragment = (LogFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.log_fragment);
         msgFilter.setNext(logFragment.getLogView());
+        logFragment.getLogView().setTextAppearance(this, R.style.Log);
+        logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
 
         Log.i(TAG, "Ready");
     }
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/AndroidManifest.xml b/samples/browseable/SwipeRefreshLayoutBasic/AndroidManifest.xml
new file mode 100644
index 0000000..fa75453
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.swiperefreshlayoutbasic"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
+
+    <application android:allowBackup="true"
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/AppTheme">
+
+        <activity android:name=".MainActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/_index.jd b/samples/browseable/SwipeRefreshLayoutBasic/_index.jd
new file mode 100644
index 0000000..bfbaddb
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/_index.jd
@@ -0,0 +1,11 @@
+
+
+
+page.tags="SwipeRefreshLayoutBasic"
+sample.group=UI
+@jd:body
+
+<p>This sample demonstrates how to use {@link android.support.v4.widget.SwipeRefreshLayout} to add
+the <em>swipe-to-refresh</em> gesture to a {@link android.view.View}, which enables you to trigger
+a refresh by swiping down on the {@link android.view.View}. In this sample, the view that can
+be freshed is a {@link android.widget.ListView}.</p>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-hdpi/ic_launcher.png b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..da15ae2
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-hdpi/tile.9.png b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-mdpi/ic_launcher.png b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..34c3f1c
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..83ac286
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..02802a3
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/layout-w720dp/activity_main.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/layout/activity_main.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/layout/fragment_sample.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/layout/fragment_sample.xml
new file mode 100644
index 0000000..8900f82
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/layout/fragment_sample.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<android.support.v4.widget.SwipeRefreshLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:id="@+id/swiperefresh"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent">
+
+    <ListView
+          android:id="@android:id/list"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent" />
+
+</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/menu/main.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/menu/main_menu.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/menu/main_menu.xml
new file mode 100644
index 0000000..de0c5f2
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/menu/main_menu.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+          android:id="@+id/menu_refresh"
+          android:title="@string/menu_refresh"
+          android:showAsAction="never" />
+
+</menu>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values-sw600dp/template-dimens.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values-sw600dp/template-styles.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values-v11/template-styles.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values/base-strings.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values/base-strings.xml
new file mode 100644
index 0000000..665d16f
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<resources>
+    <string name="app_name">SwipeRefreshLayoutBasic</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            A basic sample which shows how to use SwipeRefreshLayout to add the \'swipe-to-refresh\'
+            gesture to a View, enabling the ability to trigger a refresh from swiping down on the view.
+            In this sample the View which can be refreshed is a ListView.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values/colors.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values/colors.xml
new file mode 100644
index 0000000..ae1119e
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values/colors.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <color name="swipe_color_1">#B6DB49</color>
+    <color name="swipe_color_2">#99CC00</color>
+    <color name="swipe_color_3">#8ABD00</color>
+    <color name="swipe_color_4">#7CAF00</color>
+
+</resources>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values/strings.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<resources>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values/template-dimens.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/res/values/template-styles.xml b/samples/browseable/SwipeRefreshLayoutBasic/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/dummydata/Cheeses.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/dummydata/Cheeses.java
new file mode 100644
index 0000000..783735c
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/dummydata/Cheeses.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.dummydata;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Random;
+
+/**
+ * Dummy data.
+ */
+public class Cheeses {
+    static final String[] CHEESES = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+    };
+
+    public static ArrayList<String> asList() {
+        ArrayList<String> items = new ArrayList<String>();
+        for (int i = 0, z = CHEESES.length ; i < z ; i++) {
+            items.add(CHEESES[i]);
+        }
+        return items;
+    }
+
+    /**
+     * Return a list of random cheeses.
+     *
+     * @param count the amount of cheeses to return.
+     */
+    public static ArrayList<String> randomList(int count) {
+        Random random = new Random();
+        HashSet<String> items = new HashSet<String>();
+
+        // Make sure that don't infinity loop
+        count = Math.min(count, CHEESES.length);
+
+        while (items.size() < count) {
+            items.add(CHEESES[random.nextInt(CHEESES.length)]);
+        }
+
+        return new ArrayList<String>(items);
+    }
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/Log.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogNode.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogView.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/view/SlidingTabLayout.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/view/SlidingTabLayout.java
new file mode 100644
index 0000000..20049e3
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/view/SlidingTabLayout.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+
+    /**
+     * Allows complete control over the colors drawn in the tab layout. Set with
+     * {@link #setCustomTabColorizer(TabColorizer)}.
+     */
+    public interface TabColorizer {
+
+        /**
+         * @return return the color of the indicator used when {@code position} is selected.
+         */
+        int getIndicatorColor(int position);
+
+        /**
+         * @return return the color of the divider drawn to the right of {@code position}.
+         */
+        int getDividerColor(int position);
+
+    }
+
+    private static final int TITLE_OFFSET_DIPS = 24;
+    private static final int TAB_VIEW_PADDING_DIPS = 16;
+    private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+    private int mTitleOffset;
+
+    private int mTabViewLayoutId;
+    private int mTabViewTextViewId;
+
+    private ViewPager mViewPager;
+    private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+    private final SlidingTabStrip mTabStrip;
+
+    public SlidingTabLayout(Context context) {
+        this(context, null);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        // Disable the Scroll Bar
+        setHorizontalScrollBarEnabled(false);
+        // Make sure that the Tab Strips fills this View
+        setFillViewport(true);
+
+        mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+        mTabStrip = new SlidingTabStrip(context);
+        addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    /**
+     * Set the custom {@link TabColorizer} to be used.
+     *
+     * If you only require simple custmisation then you can use
+     * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+     * similar effects.
+     */
+    public void setCustomTabColorizer(TabColorizer tabColorizer) {
+        mTabStrip.setCustomTabColorizer(tabColorizer);
+    }
+
+    /**
+     * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+     * circular array. Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setSelectedIndicatorColors(int... colors) {
+        mTabStrip.setSelectedIndicatorColors(colors);
+    }
+
+    /**
+     * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+     * Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setDividerColors(int... colors) {
+        mTabStrip.setDividerColors(colors);
+    }
+
+    /**
+     * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+     * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+     * that the layout can update it's scroll position correctly.
+     *
+     * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+     */
+    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+        mViewPagerPageChangeListener = listener;
+    }
+
+    /**
+     * Set the custom layout to be inflated for the tab views.
+     *
+     * @param layoutResId Layout id to be inflated
+     * @param textViewId id of the {@link TextView} in the inflated view
+     */
+    public void setCustomTabView(int layoutResId, int textViewId) {
+        mTabViewLayoutId = layoutResId;
+        mTabViewTextViewId = textViewId;
+    }
+
+    /**
+     * Sets the associated view pager. Note that the assumption here is that the pager content
+     * (number of tabs and tab titles) does not change after this call has been made.
+     */
+    public void setViewPager(ViewPager viewPager) {
+        mTabStrip.removeAllViews();
+
+        mViewPager = viewPager;
+        if (viewPager != null) {
+            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+            populateTabStrip();
+        }
+    }
+
+    /**
+     * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+     * {@link #setCustomTabView(int, int)}.
+     */
+    protected TextView createDefaultTabView(Context context) {
+        TextView textView = new TextView(context);
+        textView.setGravity(Gravity.CENTER);
+        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+        textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            // If we're running on Honeycomb or newer, then we can use the Theme's
+            // selectableItemBackground to ensure that the View has a pressed state
+            TypedValue outValue = new TypedValue();
+            getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+                    outValue, true);
+            textView.setBackgroundResource(outValue.resourceId);
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+            textView.setAllCaps(true);
+        }
+
+        int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+        textView.setPadding(padding, padding, padding, padding);
+
+        return textView;
+    }
+
+    private void populateTabStrip() {
+        final PagerAdapter adapter = mViewPager.getAdapter();
+        final View.OnClickListener tabClickListener = new TabClickListener();
+
+        for (int i = 0; i < adapter.getCount(); i++) {
+            View tabView = null;
+            TextView tabTitleView = null;
+
+            if (mTabViewLayoutId != 0) {
+                // If there is a custom tab view layout id set, try and inflate it
+                tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+                        false);
+                tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+            }
+
+            if (tabView == null) {
+                tabView = createDefaultTabView(getContext());
+            }
+
+            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+                tabTitleView = (TextView) tabView;
+            }
+
+            tabTitleView.setText(adapter.getPageTitle(i));
+            tabView.setOnClickListener(tabClickListener);
+
+            mTabStrip.addView(tabView);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (mViewPager != null) {
+            scrollToTab(mViewPager.getCurrentItem(), 0);
+        }
+    }
+
+    private void scrollToTab(int tabIndex, int positionOffset) {
+        final int tabStripChildCount = mTabStrip.getChildCount();
+        if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+            return;
+        }
+
+        View selectedChild = mTabStrip.getChildAt(tabIndex);
+        if (selectedChild != null) {
+            int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+            if (tabIndex > 0 || positionOffset > 0) {
+                // If we're not at the first child and are mid-scroll, make sure we obey the offset
+                targetScrollX -= mTitleOffset;
+            }
+
+            scrollTo(targetScrollX, 0);
+        }
+    }
+
+    private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+        private int mScrollState;
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+            int tabStripChildCount = mTabStrip.getChildCount();
+            if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+                return;
+            }
+
+            mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+            View selectedTitle = mTabStrip.getChildAt(position);
+            int extraOffset = (selectedTitle != null)
+                    ? (int) (positionOffset * selectedTitle.getWidth())
+                    : 0;
+            scrollToTab(position, extraOffset);
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+                        positionOffsetPixels);
+            }
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            mScrollState = state;
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+            }
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+                mTabStrip.onViewPagerPageChanged(position, 0f);
+                scrollToTab(position, 0);
+            }
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageSelected(position);
+            }
+        }
+
+    }
+
+    private class TabClickListener implements View.OnClickListener {
+        @Override
+        public void onClick(View v) {
+            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+                if (v == mTabStrip.getChildAt(i)) {
+                    mViewPager.setCurrentItem(i);
+                    return;
+                }
+            }
+        }
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/view/SlidingTabStrip.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/view/SlidingTabStrip.java
new file mode 100644
index 0000000..d5bbbae
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.common/view/SlidingTabStrip.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+    private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+    private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+    private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+    private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+    private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+    private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+    private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+
+    private final int mBottomBorderThickness;
+    private final Paint mBottomBorderPaint;
+
+    private final int mSelectedIndicatorThickness;
+    private final Paint mSelectedIndicatorPaint;
+
+    private final int mDefaultBottomBorderColor;
+
+    private final Paint mDividerPaint;
+    private final float mDividerHeight;
+
+    private int mSelectedPosition;
+    private float mSelectionOffset;
+
+    private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+    private final SimpleTabColorizer mDefaultTabColorizer;
+
+    SlidingTabStrip(Context context) {
+        this(context, null);
+    }
+
+    SlidingTabStrip(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setWillNotDraw(false);
+
+        final float density = getResources().getDisplayMetrics().density;
+
+        TypedValue outValue = new TypedValue();
+        context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+        final int themeForegroundColor =  outValue.data;
+
+        mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+                DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+        mDefaultTabColorizer = new SimpleTabColorizer();
+        mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+        mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+                DEFAULT_DIVIDER_COLOR_ALPHA));
+
+        mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+        mBottomBorderPaint = new Paint();
+        mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+        mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+        mSelectedIndicatorPaint = new Paint();
+
+        mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+        mDividerPaint = new Paint();
+        mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+    }
+
+    void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+        mCustomTabColorizer = customTabColorizer;
+        invalidate();
+    }
+
+    void setSelectedIndicatorColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setIndicatorColors(colors);
+        invalidate();
+    }
+
+    void setDividerColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setDividerColors(colors);
+        invalidate();
+    }
+
+    void onViewPagerPageChanged(int position, float positionOffset) {
+        mSelectedPosition = position;
+        mSelectionOffset = positionOffset;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        final int height = getHeight();
+        final int childCount = getChildCount();
+        final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+        final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+                ? mCustomTabColorizer
+                : mDefaultTabColorizer;
+
+        // Thick colored underline below the current selection
+        if (childCount > 0) {
+            View selectedTitle = getChildAt(mSelectedPosition);
+            int left = selectedTitle.getLeft();
+            int right = selectedTitle.getRight();
+            int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+            if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+                int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+                if (color != nextColor) {
+                    color = blendColors(nextColor, color, mSelectionOffset);
+                }
+
+                // Draw the selection partway between the tabs
+                View nextTitle = getChildAt(mSelectedPosition + 1);
+                left = (int) (mSelectionOffset * nextTitle.getLeft() +
+                        (1.0f - mSelectionOffset) * left);
+                right = (int) (mSelectionOffset * nextTitle.getRight() +
+                        (1.0f - mSelectionOffset) * right);
+            }
+
+            mSelectedIndicatorPaint.setColor(color);
+
+            canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+                    height, mSelectedIndicatorPaint);
+        }
+
+        // Thin underline along the entire bottom edge
+        canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+        // Vertical separators between the titles
+        int separatorTop = (height - dividerHeightPx) / 2;
+        for (int i = 0; i < childCount - 1; i++) {
+            View child = getChildAt(i);
+            mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+            canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+                    separatorTop + dividerHeightPx, mDividerPaint);
+        }
+    }
+
+    /**
+     * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+     */
+    private static int setColorAlpha(int color, byte alpha) {
+        return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+    }
+
+    /**
+     * Blend {@code color1} and {@code color2} using the given ratio.
+     *
+     * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+     *              0.0 will return {@code color2}.
+     */
+    private static int blendColors(int color1, int color2, float ratio) {
+        final float inverseRation = 1f - ratio;
+        float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+        float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+        float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+        return Color.rgb((int) r, (int) g, (int) b);
+    }
+
+    private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+        private int[] mIndicatorColors;
+        private int[] mDividerColors;
+
+        @Override
+        public final int getIndicatorColor(int position) {
+            return mIndicatorColors[position % mIndicatorColors.length];
+        }
+
+        @Override
+        public final int getDividerColor(int position) {
+            return mDividerColors[position % mDividerColors.length];
+        }
+
+        void setIndicatorColors(int... colors) {
+            mIndicatorColors = colors;
+        }
+
+        void setDividerColors(int... colors) {
+            mDividerColors = colors;
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.swiperefreshlayoutbasic/MainActivity.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.swiperefreshlayoutbasic/MainActivity.java
new file mode 100644
index 0000000..f90aed1
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.swiperefreshlayoutbasic/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+
+package com.example.android.swiperefreshlayoutbasic;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    // Whether the Log Fragment is currently shown
+    private boolean mLogShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        SwipeRefreshLayoutBasicFragment fragment = new SwipeRefreshLayoutBasicFragment();
+        transaction.replace(R.id.sample_content_fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.swiperefreshlayoutbasic/SwipeRefreshLayoutBasicFragment.java b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.swiperefreshlayoutbasic/SwipeRefreshLayoutBasicFragment.java
new file mode 100644
index 0000000..13b22f5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshLayoutBasic/src/com.example.android.swiperefreshlayoutbasic/SwipeRefreshLayoutBasicFragment.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2014 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.example.android.swiperefreshlayoutbasic;
+
+import com.example.android.common.dummydata.Cheeses;
+import com.example.android.common.logger.Log;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.List;
+
+/**
+ * A basic sample that shows how to use {@link android.support.v4.widget.SwipeRefreshLayout} to add
+ * the 'swipe-to-refresh' gesture to a layout. In this sample, SwipeRefreshLayout contains a
+ * scrollable {@link android.widget.ListView} as its only child.
+ *
+ * <p>To provide an accessible way to trigger the refresh, this app also provides a refresh
+ * action item.
+ *
+ * <p>In this sample app, the refresh updates the ListView with a random set of new items.
+ */
+public class SwipeRefreshLayoutBasicFragment extends Fragment {
+
+    private static final String LOG_TAG = SwipeRefreshLayoutBasicFragment.class.getSimpleName();
+
+    private static final int LIST_ITEM_COUNT = 20;
+
+    /**
+     * The {@link android.support.v4.widget.SwipeRefreshLayout} that detects swipe gestures and
+     * triggers callbacks in the app.
+     */
+    private SwipeRefreshLayout mSwipeRefreshLayout;
+
+    /**
+     * The {@link android.widget.ListView} that displays the content that should be refreshed.
+     */
+    private ListView mListView;
+
+    /**
+     * The {@link android.widget.ListAdapter} used to populate the {@link android.widget.ListView}
+     * defined in the previous statement.
+     */
+    private ArrayAdapter<String> mListAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Notify the system to allow an options menu for this fragment.
+        setHasOptionsMenu(true);
+    }
+
+    // BEGIN_INCLUDE (inflate_view)
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.fragment_sample, container, false);
+
+        // Retrieve the SwipeRefreshLayout and ListView instances
+        mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swiperefresh);
+
+        // BEGIN_INCLUDE (change_colors)
+        // Set the color scheme of the SwipeRefreshLayout by providing 4 color resource ids
+        mSwipeRefreshLayout.setColorScheme(
+                R.color.swipe_color_1, R.color.swipe_color_2,
+                R.color.swipe_color_3, R.color.swipe_color_4);
+        // END_INCLUDE (change_colors)
+
+        // Retrieve the ListView
+        mListView = (ListView) view.findViewById(android.R.id.list);
+
+        return view;
+    }
+    // END_INCLUDE (inflate_view)
+
+    // BEGIN_INCLUDE (setup_views)
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        /**
+         * Create an ArrayAdapter to contain the data for the ListView. Each item in the ListView
+         * uses the system-defined simple_list_item_1 layout that contains one TextView.
+         */
+        mListAdapter = new ArrayAdapter<String>(
+                getActivity(),
+                android.R.layout.simple_list_item_1,
+                android.R.id.text1,
+                Cheeses.randomList(LIST_ITEM_COUNT));
+
+        // Set the adapter between the ListView and its backing data.
+        mListView.setAdapter(mListAdapter);
+
+        // BEGIN_INCLUDE (setup_refreshlistener)
+        /**
+         * Implement {@link SwipeRefreshLayout.OnRefreshListener}. When users do the "swipe to
+         * refresh" gesture, SwipeRefreshLayout invokes
+         * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}. In
+         * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}, call a method that
+         * refreshes the content. Call the same method in response to the Refresh action from the
+         * action bar.
+         */
+        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                Log.i(LOG_TAG, "onRefresh called from SwipeRefreshLayout");
+
+                initiateRefresh();
+            }
+        });
+        // END_INCLUDE (setup_refreshlistener)
+    }
+    // END_INCLUDE (setup_views)
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.main_menu, menu);
+    }
+
+    // BEGIN_INCLUDE (setup_refresh_menu_listener)
+    /**
+     * Respond to the user's selection of the Refresh action item. Start the SwipeRefreshLayout
+     * progress bar, then initiate the background task that refreshes the content.
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_refresh:
+                Log.i(LOG_TAG, "Refresh menu item selected");
+
+                // We make sure that the SwipeRefreshLayout is displaying it's refreshing indicator
+                if (!mSwipeRefreshLayout.isRefreshing()) {
+                    mSwipeRefreshLayout.setRefreshing(true);
+                }
+
+                // Start our refresh background task
+                initiateRefresh();
+
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+    // END_INCLUDE (setup_refresh_menu_listener)
+
+    // BEGIN_INCLUDE (initiate_refresh)
+    /**
+     * By abstracting the refresh process to a single method, the app allows both the
+     * SwipeGestureLayout onRefresh() method and the Refresh action item to refresh the content.
+     */
+    private void initiateRefresh() {
+        Log.i(LOG_TAG, "initiateRefresh");
+
+        /**
+         * Execute the background task, which uses {@link android.os.AsyncTask} to load the data.
+         */
+        new DummyBackgroundTask().execute();
+    }
+    // END_INCLUDE (initiate_refresh)
+
+    // BEGIN_INCLUDE (refresh_complete)
+    /**
+     * When the AsyncTask finishes, it calls onRefreshComplete(), which updates the data in the
+     * ListAdapter and turns off the progress bar.
+     */
+    private void onRefreshComplete(List<String> result) {
+        Log.i(LOG_TAG, "onRefreshComplete");
+
+        // Remove all items from the ListAdapter, and then replace them with the new items
+        mListAdapter.clear();
+        for (String cheese : result) {
+            mListAdapter.add(cheese);
+        }
+
+        // Stop the refreshing indicator
+        mSwipeRefreshLayout.setRefreshing(false);
+    }
+    // END_INCLUDE (refresh_complete)
+
+    /**
+     * Dummy {@link AsyncTask} which simulates a long running task to fetch new cheeses.
+     */
+    private class DummyBackgroundTask extends AsyncTask<Void, Void, List<String>> {
+
+        static final int TASK_DURATION = 3 * 1000; // 3 seconds
+
+        @Override
+        protected List<String> doInBackground(Void... params) {
+            // Sleep for a small amount of time to simulate a background-task
+            try {
+                Thread.sleep(TASK_DURATION);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            // Return a new random list of cheeses
+            return Cheeses.randomList(LIST_ITEM_COUNT);
+        }
+
+        @Override
+        protected void onPostExecute(List<String> result) {
+            super.onPostExecute(result);
+
+            // Tell the Fragment that the refresh has completed
+            onRefreshComplete(result);
+        }
+
+    }
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/AndroidManifest.xml b/samples/browseable/SwipeRefreshListFragment/AndroidManifest.xml
new file mode 100644
index 0000000..be44930
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.swiperefreshlistfragment"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
+
+    <application android:allowBackup="true"
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/AppTheme">
+
+        <activity android:name=".MainActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/samples/browseable/SwipeRefreshListFragment/_index.jd b/samples/browseable/SwipeRefreshListFragment/_index.jd
new file mode 100644
index 0000000..3a34bb0
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/_index.jd
@@ -0,0 +1,12 @@
+
+
+
+page.tags="SwipeRefreshListFragment"
+sample.group=UI
+@jd:body
+
+<p>This sample demonstrates how to use {@link android.support.v4.widget.SwipeRefreshLayout} within
+{@link android.app.ListFragment} to add the <em>swipe-to-refresh</em> gesture to a
+{@link android.widget.ListView}, which enables you to trigger a refresh by swiping down on that
+view. This functionality is provided by the <code>SwipeRefreshListFragment</code> class, which you
+can reuse.</p>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/drawable-hdpi/ic_launcher.png b/samples/browseable/SwipeRefreshListFragment/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b10c5c1
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshListFragment/res/drawable-hdpi/tile.9.png b/samples/browseable/SwipeRefreshListFragment/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshListFragment/res/drawable-mdpi/ic_launcher.png b/samples/browseable/SwipeRefreshListFragment/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..001eed9
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshListFragment/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/SwipeRefreshListFragment/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6fe78cc
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshListFragment/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/SwipeRefreshListFragment/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..5f89875
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshListFragment/res/layout-w720dp/activity_main.xml b/samples/browseable/SwipeRefreshListFragment/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/SwipeRefreshListFragment/res/layout/activity_main.xml b/samples/browseable/SwipeRefreshListFragment/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/SwipeRefreshListFragment/res/menu/main.xml b/samples/browseable/SwipeRefreshListFragment/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/menu/main_menu.xml b/samples/browseable/SwipeRefreshListFragment/res/menu/main_menu.xml
new file mode 100644
index 0000000..c5e8954
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/menu/main_menu.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!--
+        A color scheme menu item used for demonstrating the use of SwipeRefreshLayout's color
+        scheme functionality. This kind of menu item should not be incorporated into your app,
+        it just to demonstrate the use of color. Instead you should choose a color scheme based
+        off of your application's branding.
+    -->
+    <item
+          android:id="@+id/menu_color_scheme"
+          android:title="@string/menu_color_scheme"
+          android:showAsAction="ifRoom">
+        <menu>
+            <group android:checkableBehavior="single">
+
+                <item
+                      android:id="@+id/menu_color_scheme_1"
+                      android:title="@string/menu_color_scheme_1" />
+
+                <item
+                      android:id="@+id/menu_color_scheme_2"
+                      android:title="@string/menu_color_scheme_2" />
+
+                <item
+                      android:id="@+id/menu_color_scheme_3"
+                      android:title="@string/menu_color_scheme_3" />
+
+            </group>
+        </menu>
+    </item>
+
+    <!--
+        Refresh action item which should be presented in the Action Bar's overflow area
+        by setting showAsAction='never'. This is so that users which are not using touch input
+        can still perform a refresh.
+    -->
+    <item
+          android:id="@+id/menu_refresh"
+          android:title="@string/menu_refresh"
+          android:showAsAction="never" />
+
+</menu>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values-sw600dp/template-dimens.xml b/samples/browseable/SwipeRefreshListFragment/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values-sw600dp/template-styles.xml b/samples/browseable/SwipeRefreshListFragment/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values-v11/template-styles.xml b/samples/browseable/SwipeRefreshListFragment/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values/base-strings.xml b/samples/browseable/SwipeRefreshListFragment/res/values/base-strings.xml
new file mode 100644
index 0000000..f84c807
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values/base-strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<resources>
+    <string name="app_name">SwipeRefreshListFragment</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            A sample which shows how to use SwipeRefreshLayout within a ListFragment to add the
+            \'swipe-to-refresh\' gesture to a ListView, enabling the ability to trigger a refresh
+            from swiping down on that view. This is provided through the re-usable
+            SwipeRefreshListFragment class.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values/colors.xml b/samples/browseable/SwipeRefreshListFragment/res/values/colors.xml
new file mode 100644
index 0000000..ae19990
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values/colors.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<resources>
+
+    <!--
+        These are the different color schemes to be displayed by the SwipeRefreshLayout's loading
+        indicator. It expects exactly four colors.
+
+        Color scheme #1: a selection of holo colors.
+        Color scheme #2: a graduation of holo blue.
+        Color scheme #3: a graduation of holo green.
+    -->
+
+    <color name="color_scheme_1_1">#33B5E5</color>
+    <color name="color_scheme_1_2">#99CC00</color>
+    <color name="color_scheme_1_3">#FFBB33</color>
+    <color name="color_scheme_1_4">#FF4444</color>
+
+    <color name="color_scheme_2_1">#6DCAEC</color>
+    <color name="color_scheme_2_2">#33B5E5</color>
+    <color name="color_scheme_2_3">#24ADDE</color>
+    <color name="color_scheme_2_4">#16A5D7</color>
+
+    <color name="color_scheme_3_1">#B6DB49</color>
+    <color name="color_scheme_3_2">#99CC00</color>
+    <color name="color_scheme_3_3">#8ABD00</color>
+    <color name="color_scheme_3_4">#7CAF00</color>
+
+</resources>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values/strings.xml b/samples/browseable/SwipeRefreshListFragment/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<resources>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values/template-dimens.xml b/samples/browseable/SwipeRefreshListFragment/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/res/values/template-styles.xml b/samples/browseable/SwipeRefreshListFragment/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/dummydata/Cheeses.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/dummydata/Cheeses.java
new file mode 100644
index 0000000..783735c
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/dummydata/Cheeses.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.dummydata;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Random;
+
+/**
+ * Dummy data.
+ */
+public class Cheeses {
+    static final String[] CHEESES = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+    };
+
+    public static ArrayList<String> asList() {
+        ArrayList<String> items = new ArrayList<String>();
+        for (int i = 0, z = CHEESES.length ; i < z ; i++) {
+            items.add(CHEESES[i]);
+        }
+        return items;
+    }
+
+    /**
+     * Return a list of random cheeses.
+     *
+     * @param count the amount of cheeses to return.
+     */
+    public static ArrayList<String> randomList(int count) {
+        Random random = new Random();
+        HashSet<String> items = new HashSet<String>();
+
+        // Make sure that don't infinity loop
+        count = Math.min(count, CHEESES.length);
+
+        while (items.size() < count) {
+            items.add(CHEESES[random.nextInt(CHEESES.length)]);
+        }
+
+        return new ArrayList<String>(items);
+    }
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/Log.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogNode.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogView.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/view/SlidingTabLayout.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/view/SlidingTabLayout.java
new file mode 100644
index 0000000..20049e3
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/view/SlidingTabLayout.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+
+    /**
+     * Allows complete control over the colors drawn in the tab layout. Set with
+     * {@link #setCustomTabColorizer(TabColorizer)}.
+     */
+    public interface TabColorizer {
+
+        /**
+         * @return return the color of the indicator used when {@code position} is selected.
+         */
+        int getIndicatorColor(int position);
+
+        /**
+         * @return return the color of the divider drawn to the right of {@code position}.
+         */
+        int getDividerColor(int position);
+
+    }
+
+    private static final int TITLE_OFFSET_DIPS = 24;
+    private static final int TAB_VIEW_PADDING_DIPS = 16;
+    private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+    private int mTitleOffset;
+
+    private int mTabViewLayoutId;
+    private int mTabViewTextViewId;
+
+    private ViewPager mViewPager;
+    private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+    private final SlidingTabStrip mTabStrip;
+
+    public SlidingTabLayout(Context context) {
+        this(context, null);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        // Disable the Scroll Bar
+        setHorizontalScrollBarEnabled(false);
+        // Make sure that the Tab Strips fills this View
+        setFillViewport(true);
+
+        mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+        mTabStrip = new SlidingTabStrip(context);
+        addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    /**
+     * Set the custom {@link TabColorizer} to be used.
+     *
+     * If you only require simple custmisation then you can use
+     * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+     * similar effects.
+     */
+    public void setCustomTabColorizer(TabColorizer tabColorizer) {
+        mTabStrip.setCustomTabColorizer(tabColorizer);
+    }
+
+    /**
+     * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+     * circular array. Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setSelectedIndicatorColors(int... colors) {
+        mTabStrip.setSelectedIndicatorColors(colors);
+    }
+
+    /**
+     * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+     * Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setDividerColors(int... colors) {
+        mTabStrip.setDividerColors(colors);
+    }
+
+    /**
+     * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+     * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+     * that the layout can update it's scroll position correctly.
+     *
+     * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+     */
+    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+        mViewPagerPageChangeListener = listener;
+    }
+
+    /**
+     * Set the custom layout to be inflated for the tab views.
+     *
+     * @param layoutResId Layout id to be inflated
+     * @param textViewId id of the {@link TextView} in the inflated view
+     */
+    public void setCustomTabView(int layoutResId, int textViewId) {
+        mTabViewLayoutId = layoutResId;
+        mTabViewTextViewId = textViewId;
+    }
+
+    /**
+     * Sets the associated view pager. Note that the assumption here is that the pager content
+     * (number of tabs and tab titles) does not change after this call has been made.
+     */
+    public void setViewPager(ViewPager viewPager) {
+        mTabStrip.removeAllViews();
+
+        mViewPager = viewPager;
+        if (viewPager != null) {
+            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+            populateTabStrip();
+        }
+    }
+
+    /**
+     * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+     * {@link #setCustomTabView(int, int)}.
+     */
+    protected TextView createDefaultTabView(Context context) {
+        TextView textView = new TextView(context);
+        textView.setGravity(Gravity.CENTER);
+        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+        textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            // If we're running on Honeycomb or newer, then we can use the Theme's
+            // selectableItemBackground to ensure that the View has a pressed state
+            TypedValue outValue = new TypedValue();
+            getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+                    outValue, true);
+            textView.setBackgroundResource(outValue.resourceId);
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+            textView.setAllCaps(true);
+        }
+
+        int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+        textView.setPadding(padding, padding, padding, padding);
+
+        return textView;
+    }
+
+    private void populateTabStrip() {
+        final PagerAdapter adapter = mViewPager.getAdapter();
+        final View.OnClickListener tabClickListener = new TabClickListener();
+
+        for (int i = 0; i < adapter.getCount(); i++) {
+            View tabView = null;
+            TextView tabTitleView = null;
+
+            if (mTabViewLayoutId != 0) {
+                // If there is a custom tab view layout id set, try and inflate it
+                tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+                        false);
+                tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+            }
+
+            if (tabView == null) {
+                tabView = createDefaultTabView(getContext());
+            }
+
+            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+                tabTitleView = (TextView) tabView;
+            }
+
+            tabTitleView.setText(adapter.getPageTitle(i));
+            tabView.setOnClickListener(tabClickListener);
+
+            mTabStrip.addView(tabView);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (mViewPager != null) {
+            scrollToTab(mViewPager.getCurrentItem(), 0);
+        }
+    }
+
+    private void scrollToTab(int tabIndex, int positionOffset) {
+        final int tabStripChildCount = mTabStrip.getChildCount();
+        if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+            return;
+        }
+
+        View selectedChild = mTabStrip.getChildAt(tabIndex);
+        if (selectedChild != null) {
+            int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+            if (tabIndex > 0 || positionOffset > 0) {
+                // If we're not at the first child and are mid-scroll, make sure we obey the offset
+                targetScrollX -= mTitleOffset;
+            }
+
+            scrollTo(targetScrollX, 0);
+        }
+    }
+
+    private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+        private int mScrollState;
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+            int tabStripChildCount = mTabStrip.getChildCount();
+            if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+                return;
+            }
+
+            mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+            View selectedTitle = mTabStrip.getChildAt(position);
+            int extraOffset = (selectedTitle != null)
+                    ? (int) (positionOffset * selectedTitle.getWidth())
+                    : 0;
+            scrollToTab(position, extraOffset);
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+                        positionOffsetPixels);
+            }
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            mScrollState = state;
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+            }
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+                mTabStrip.onViewPagerPageChanged(position, 0f);
+                scrollToTab(position, 0);
+            }
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageSelected(position);
+            }
+        }
+
+    }
+
+    private class TabClickListener implements View.OnClickListener {
+        @Override
+        public void onClick(View v) {
+            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+                if (v == mTabStrip.getChildAt(i)) {
+                    mViewPager.setCurrentItem(i);
+                    return;
+                }
+            }
+        }
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/view/SlidingTabStrip.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/view/SlidingTabStrip.java
new file mode 100644
index 0000000..d5bbbae
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.common/view/SlidingTabStrip.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+    private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+    private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+    private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+    private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+    private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+    private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+    private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+
+    private final int mBottomBorderThickness;
+    private final Paint mBottomBorderPaint;
+
+    private final int mSelectedIndicatorThickness;
+    private final Paint mSelectedIndicatorPaint;
+
+    private final int mDefaultBottomBorderColor;
+
+    private final Paint mDividerPaint;
+    private final float mDividerHeight;
+
+    private int mSelectedPosition;
+    private float mSelectionOffset;
+
+    private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+    private final SimpleTabColorizer mDefaultTabColorizer;
+
+    SlidingTabStrip(Context context) {
+        this(context, null);
+    }
+
+    SlidingTabStrip(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setWillNotDraw(false);
+
+        final float density = getResources().getDisplayMetrics().density;
+
+        TypedValue outValue = new TypedValue();
+        context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+        final int themeForegroundColor =  outValue.data;
+
+        mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+                DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+        mDefaultTabColorizer = new SimpleTabColorizer();
+        mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+        mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+                DEFAULT_DIVIDER_COLOR_ALPHA));
+
+        mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+        mBottomBorderPaint = new Paint();
+        mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+        mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+        mSelectedIndicatorPaint = new Paint();
+
+        mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+        mDividerPaint = new Paint();
+        mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+    }
+
+    void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+        mCustomTabColorizer = customTabColorizer;
+        invalidate();
+    }
+
+    void setSelectedIndicatorColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setIndicatorColors(colors);
+        invalidate();
+    }
+
+    void setDividerColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setDividerColors(colors);
+        invalidate();
+    }
+
+    void onViewPagerPageChanged(int position, float positionOffset) {
+        mSelectedPosition = position;
+        mSelectionOffset = positionOffset;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        final int height = getHeight();
+        final int childCount = getChildCount();
+        final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+        final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+                ? mCustomTabColorizer
+                : mDefaultTabColorizer;
+
+        // Thick colored underline below the current selection
+        if (childCount > 0) {
+            View selectedTitle = getChildAt(mSelectedPosition);
+            int left = selectedTitle.getLeft();
+            int right = selectedTitle.getRight();
+            int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+            if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+                int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+                if (color != nextColor) {
+                    color = blendColors(nextColor, color, mSelectionOffset);
+                }
+
+                // Draw the selection partway between the tabs
+                View nextTitle = getChildAt(mSelectedPosition + 1);
+                left = (int) (mSelectionOffset * nextTitle.getLeft() +
+                        (1.0f - mSelectionOffset) * left);
+                right = (int) (mSelectionOffset * nextTitle.getRight() +
+                        (1.0f - mSelectionOffset) * right);
+            }
+
+            mSelectedIndicatorPaint.setColor(color);
+
+            canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+                    height, mSelectedIndicatorPaint);
+        }
+
+        // Thin underline along the entire bottom edge
+        canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+        // Vertical separators between the titles
+        int separatorTop = (height - dividerHeightPx) / 2;
+        for (int i = 0; i < childCount - 1; i++) {
+            View child = getChildAt(i);
+            mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+            canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+                    separatorTop + dividerHeightPx, mDividerPaint);
+        }
+    }
+
+    /**
+     * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+     */
+    private static int setColorAlpha(int color, byte alpha) {
+        return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+    }
+
+    /**
+     * Blend {@code color1} and {@code color2} using the given ratio.
+     *
+     * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+     *              0.0 will return {@code color2}.
+     */
+    private static int blendColors(int color1, int color2, float ratio) {
+        final float inverseRation = 1f - ratio;
+        float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+        float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+        float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+        return Color.rgb((int) r, (int) g, (int) b);
+    }
+
+    private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+        private int[] mIndicatorColors;
+        private int[] mDividerColors;
+
+        @Override
+        public final int getIndicatorColor(int position) {
+            return mIndicatorColors[position % mIndicatorColors.length];
+        }
+
+        @Override
+        public final int getDividerColor(int position) {
+            return mDividerColors[position % mDividerColors.length];
+        }
+
+        void setIndicatorColors(int... colors) {
+            mIndicatorColors = colors;
+        }
+
+        void setDividerColors(int... colors) {
+            mDividerColors = colors;
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/MainActivity.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/MainActivity.java
new file mode 100644
index 0000000..7f7a7c8
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+
+package com.example.android.swiperefreshlistfragment;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    // Whether the Log Fragment is currently shown
+    private boolean mLogShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        SwipeRefreshListFragmentFragment fragment = new SwipeRefreshListFragmentFragment();
+        transaction.replace(R.id.sample_content_fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/SwipeRefreshListFragment.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/SwipeRefreshListFragment.java
new file mode 100644
index 0000000..5796976
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/SwipeRefreshListFragment.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2014 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.example.android.swiperefreshlistfragment;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+/**
+ * Subclass of {@link android.support.v4.app.ListFragment} which provides automatic support for
+ * providing the 'swipe-to-refresh' UX gesture by wrapping the the content view in a
+ * {@link android.support.v4.widget.SwipeRefreshLayout}.
+ */
+public class SwipeRefreshListFragment extends ListFragment {
+
+    private SwipeRefreshLayout mSwipeRefreshLayout;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+
+        // Create the list fragment's content view by calling the super method
+        final View listFragmentView = super.onCreateView(inflater, container, savedInstanceState);
+
+        // Now create a SwipeRefreshLayout to wrap the fragment's content view
+        mSwipeRefreshLayout = new ListFragmentSwipeRefreshLayout(container.getContext());
+
+        // Add the list fragment's content view to the SwipeRefreshLayout, making sure that it fills
+        // the SwipeRefreshLayout
+        mSwipeRefreshLayout.addView(listFragmentView,
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+
+        // Make sure that the SwipeRefreshLayout will fill the fragment
+        mSwipeRefreshLayout.setLayoutParams(
+                new ViewGroup.LayoutParams(
+                        ViewGroup.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.MATCH_PARENT));
+
+        // Now return the SwipeRefreshLayout as this fragment's content view
+        return mSwipeRefreshLayout;
+    }
+
+    /**
+     * Set the {@link android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener} to listen for
+     * initiated refreshes.
+     *
+     * @see android.support.v4.widget.SwipeRefreshLayout#setOnRefreshListener(android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener)
+     */
+    public void setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) {
+        mSwipeRefreshLayout.setOnRefreshListener(listener);
+    }
+
+    /**
+     * Returns whether the {@link android.support.v4.widget.SwipeRefreshLayout} is currently
+     * refreshing or not.
+     *
+     * @see android.support.v4.widget.SwipeRefreshLayout#isRefreshing()
+     */
+    public boolean isRefreshing() {
+        return mSwipeRefreshLayout.isRefreshing();
+    }
+
+    /**
+     * Set whether the {@link android.support.v4.widget.SwipeRefreshLayout} should be displaying
+     * that it is refreshing or not.
+     *
+     * @see android.support.v4.widget.SwipeRefreshLayout#setRefreshing(boolean)
+     */
+    public void setRefreshing(boolean refreshing) {
+        mSwipeRefreshLayout.setRefreshing(refreshing);
+    }
+
+    /**
+     * Set the color scheme for the {@link android.support.v4.widget.SwipeRefreshLayout}.
+     *
+     * @see android.support.v4.widget.SwipeRefreshLayout#setColorScheme(int, int, int, int)
+     */
+    public void setColorScheme(int colorRes1, int colorRes2, int colorRes3, int colorRes4) {
+        mSwipeRefreshLayout.setColorScheme(colorRes1, colorRes2, colorRes3, colorRes4);
+    }
+
+    /**
+     * @return the fragment's {@link android.support.v4.widget.SwipeRefreshLayout} widget.
+     */
+    public SwipeRefreshLayout getSwipeRefreshLayout() {
+        return mSwipeRefreshLayout;
+    }
+
+    /**
+     * Sub-class of {@link android.support.v4.widget.SwipeRefreshLayout} for use in this
+     * {@link android.support.v4.app.ListFragment}. The reason that this is needed is because
+     * {@link android.support.v4.widget.SwipeRefreshLayout} only supports a single child, which it
+     * expects to be the one which triggers refreshes. In our case the layout's child is the content
+     * view returned from
+     * {@link android.support.v4.app.ListFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)}
+     * which is a {@link android.view.ViewGroup}.
+     *
+     * <p>To enable 'swipe-to-refresh' support via the {@link android.widget.ListView} we need to
+     * override the default behavior and properly signal when a gesture is possible. This is done by
+     * overriding {@link #canChildScrollUp()}.
+     */
+    private class ListFragmentSwipeRefreshLayout extends SwipeRefreshLayout {
+
+        public ListFragmentSwipeRefreshLayout(Context context) {
+            super(context);
+        }
+
+        /**
+         * As mentioned above, we need to override this method to properly signal when a
+         * 'swipe-to-refresh' is possible.
+         *
+         * @return true if the {@link android.widget.ListView} is visible and can scroll up.
+         */
+        @Override
+        public boolean canChildScrollUp() {
+            final ListView listView = getListView();
+            if (listView.getVisibility() == View.VISIBLE) {
+                return canListViewScrollUp(listView);
+            } else {
+                return false;
+            }
+        }
+
+    }
+
+    // BEGIN_INCLUDE (check_list_can_scroll)
+    /**
+     * Utility method to check whether a {@link ListView} can scroll up from it's current position.
+     * Handles platform version differences, providing backwards compatible functionality where
+     * needed.
+     */
+    private static boolean canListViewScrollUp(ListView listView) {
+        if (android.os.Build.VERSION.SDK_INT >= 14) {
+            // For ICS and above we can call canScrollVertically() to determine this
+            return ViewCompat.canScrollVertically(listView, -1);
+        } else {
+            // Pre-ICS we need to manually check the first visible item and the child view's top
+            // value
+            return listView.getChildCount() > 0 &&
+                    (listView.getFirstVisiblePosition() > 0
+                            || listView.getChildAt(0).getTop() < listView.getPaddingTop());
+        }
+    }
+    // END_INCLUDE (check_list_can_scroll)
+
+}
diff --git a/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/SwipeRefreshListFragmentFragment.java b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/SwipeRefreshListFragmentFragment.java
new file mode 100644
index 0000000..1147ea8
--- /dev/null
+++ b/samples/browseable/SwipeRefreshListFragment/src/com.example.android.swiperefreshlistfragment/SwipeRefreshListFragmentFragment.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2014 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.example.android.swiperefreshlistfragment;
+
+import com.example.android.common.dummydata.Cheeses;
+import com.example.android.common.logger.Log;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+
+import java.util.List;
+
+/**
+ * A sample which shows how to use {@link android.support.v4.widget.SwipeRefreshLayout} within a
+ * {@link android.support.v4.app.ListFragment} to add the 'swipe-to-refresh' gesture to a
+ * {@link android.widget.ListView}. This is provided through the provided re-usable
+ * {@link SwipeRefreshListFragment} class.
+ *
+ * <p>To provide an accessible way to trigger the refresh, this app also provides a refresh
+ * action item. This item should be displayed in the Action Bar's overflow item.
+ *
+ * <p>In this sample app, the refresh updates the ListView with a random set of new items.
+ *
+ * <p>This sample also provides the functionality to change the colors displayed in the
+ * {@link android.support.v4.widget.SwipeRefreshLayout} through the options menu. This is meant to
+ * showcase the use of color rather than being something that should be integrated into apps.
+ */
+public class SwipeRefreshListFragmentFragment extends SwipeRefreshListFragment {
+
+    private static final String LOG_TAG = SwipeRefreshListFragmentFragment.class.getSimpleName();
+
+    private static final int LIST_ITEM_COUNT = 20;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Notify the system to allow an options menu for this fragment.
+        setHasOptionsMenu(true);
+    }
+
+    // BEGIN_INCLUDE (setup_views)
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        /**
+         * Create an ArrayAdapter to contain the data for the ListView. Each item in the ListView
+         * uses the system-defined simple_list_item_1 layout that contains one TextView.
+         */
+        ListAdapter adapter = new ArrayAdapter<String>(
+                getActivity(),
+                android.R.layout.simple_list_item_1,
+                android.R.id.text1,
+                Cheeses.randomList(LIST_ITEM_COUNT));
+
+        // Set the adapter between the ListView and its backing data.
+        setListAdapter(adapter);
+
+        // BEGIN_INCLUDE (setup_refreshlistener)
+        /**
+         * Implement {@link SwipeRefreshLayout.OnRefreshListener}. When users do the "swipe to
+         * refresh" gesture, SwipeRefreshLayout invokes
+         * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}. In
+         * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}, call a method that
+         * refreshes the content. Call the same method in response to the Refresh action from the
+         * action bar.
+         */
+        setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                Log.i(LOG_TAG, "onRefresh called from SwipeRefreshLayout");
+
+                initiateRefresh();
+            }
+        });
+        // END_INCLUDE (setup_refreshlistener)
+    }
+    // END_INCLUDE (setup_views)
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.main_menu, menu);
+    }
+
+    // BEGIN_INCLUDE (setup_refresh_menu_listener)
+    /**
+     * Respond to the user's selection of the Refresh action item. Start the SwipeRefreshLayout
+     * progress bar, then initiate the background task that refreshes the content.
+     *
+     * <p>A color scheme menu item used for demonstrating the use of SwipeRefreshLayout's color
+     * scheme functionality. This kind of menu item should not be incorporated into your app,
+     * it just to demonstrate the use of color. Instead you should choose a color scheme based
+     * off of your application's branding.
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_refresh:
+                Log.i(LOG_TAG, "Refresh menu item selected");
+
+                // We make sure that the SwipeRefreshLayout is displaying it's refreshing indicator
+                if (!isRefreshing()) {
+                    setRefreshing(true);
+                }
+
+                // Start our refresh background task
+                initiateRefresh();
+                return true;
+
+            case R.id.menu_color_scheme_1:
+                Log.i(LOG_TAG, "setColorScheme #1");
+                item.setChecked(true);
+
+                // Change the colors displayed by the SwipeRefreshLayout by providing it with 4
+                // color resource ids
+                setColorScheme(R.color.color_scheme_1_1, R.color.color_scheme_1_2,
+                        R.color.color_scheme_1_3, R.color.color_scheme_1_4);
+                return true;
+
+            case R.id.menu_color_scheme_2:
+                Log.i(LOG_TAG, "setColorScheme #2");
+                item.setChecked(true);
+
+                // Change the colors displayed by the SwipeRefreshLayout by providing it with 4
+                // color resource ids
+                setColorScheme(R.color.color_scheme_2_1, R.color.color_scheme_2_2,
+                        R.color.color_scheme_2_3, R.color.color_scheme_2_4);
+                return true;
+
+            case R.id.menu_color_scheme_3:
+                Log.i(LOG_TAG, "setColorScheme #3");
+                item.setChecked(true);
+
+                // Change the colors displayed by the SwipeRefreshLayout by providing it with 4
+                // color resource ids
+                setColorScheme(R.color.color_scheme_3_1, R.color.color_scheme_3_2,
+                        R.color.color_scheme_3_3, R.color.color_scheme_3_4);
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+    // END_INCLUDE (setup_refresh_menu_listener)
+
+    // BEGIN_INCLUDE (initiate_refresh)
+    /**
+     * By abstracting the refresh process to a single method, the app allows both the
+     * SwipeGestureLayout onRefresh() method and the Refresh action item to refresh the content.
+     */
+    private void initiateRefresh() {
+        Log.i(LOG_TAG, "initiateRefresh");
+
+        /**
+         * Execute the background task, which uses {@link android.os.AsyncTask} to load the data.
+         */
+        new DummyBackgroundTask().execute();
+    }
+    // END_INCLUDE (initiate_refresh)
+
+    // BEGIN_INCLUDE (refresh_complete)
+    /**
+     * When the AsyncTask finishes, it calls onRefreshComplete(), which updates the data in the
+     * ListAdapter and turns off the progress bar.
+     */
+    private void onRefreshComplete(List<String> result) {
+        Log.i(LOG_TAG, "onRefreshComplete");
+
+        // Remove all items from the ListAdapter, and then replace them with the new items
+        ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter();
+        adapter.clear();
+        for (String cheese : result) {
+            adapter.add(cheese);
+        }
+
+        // Stop the refreshing indicator
+        setRefreshing(false);
+    }
+    // END_INCLUDE (refresh_complete)
+
+    /**
+     * Dummy {@link AsyncTask} which simulates a long running task to fetch new cheeses.
+     */
+    private class DummyBackgroundTask extends AsyncTask<Void, Void, List<String>> {
+
+        static final int TASK_DURATION = 3 * 1000; // 3 seconds
+
+        @Override
+        protected List<String> doInBackground(Void... params) {
+            // Sleep for a small amount of time to simulate a background-task
+            try {
+                Thread.sleep(TASK_DURATION);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            // Return a new random list of cheeses
+            return Cheeses.randomList(LIST_ITEM_COUNT);
+        }
+
+        @Override
+        protected void onPostExecute(List<String> result) {
+            super.onPostExecute(result);
+
+            // Tell the Fragment that the refresh has completed
+            onRefreshComplete(result);
+        }
+
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/AndroidManifest.xml b/samples/browseable/SwipeRefreshMultipleViews/AndroidManifest.xml
new file mode 100644
index 0000000..aba15e0
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.swiperefreshmultipleviews"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
+
+    <application android:allowBackup="true"
+        android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/AppTheme">
+
+        <activity android:name=".MainActivity"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/_index.jd b/samples/browseable/SwipeRefreshMultipleViews/_index.jd
new file mode 100644
index 0000000..70ff8ea
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/_index.jd
@@ -0,0 +1,12 @@
+
+
+
+page.tags="SwipeRefreshMultipleViews"
+sample.group=UI
+@jd:body
+
+<p>This sample demonstrates how to use {@link android.support.v4.widget.SwipeRefreshLayout} to add
+the <em>swipe-to-refresh</em> gesture to a layout with multiple children, which enables you to
+trigger a refresh by swiping down on the view. In this sample
+{@link android.support.v4.widget.SwipeRefreshLayout} contains a scrollable
+{@link android.widget.GridView} with an empty {@link android.widget.TextView}.</p>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/drawable-hdpi/ic_launcher.png b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..9fbf7ab
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/drawable-hdpi/tile.9.png b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/drawable-mdpi/ic_launcher.png b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f834108
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/drawable-xhdpi/ic_launcher.png b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..3197133
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/drawable-xxhdpi/ic_launcher.png b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d19455c
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/layout-w720dp/activity_main.xml b/samples/browseable/SwipeRefreshMultipleViews/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <LinearLayout
+          android:id="@+id/sample_output"
+          android:layout_width="0px"
+          android:layout_height="match_parent"
+          android:layout_weight="1"
+          android:orientation="vertical">
+
+        <FrameLayout
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/margin_medium"
+                  android:paddingRight="@dimen/margin_medium"
+                  android:paddingTop="@dimen/margin_large"
+                  android:paddingBottom="@dimen/margin_large"
+                  android:text="@string/intro_message" />
+        </FrameLayout>
+
+        <View
+              android:layout_width="match_parent"
+              android:layout_height="1dp"
+              android:background="@android:color/darker_gray" />
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="0px"
+              android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <View
+          android:layout_width="1dp"
+          android:layout_height="match_parent"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="0px"
+          android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/layout/activity_main.xml b/samples/browseable/SwipeRefreshMultipleViews/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:orientation="vertical"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:id="@+id/sample_main_layout">
+
+    <ViewAnimator
+          android:id="@+id/sample_output"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+
+        <ScrollView
+              style="@style/Widget.SampleMessageTile"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+            <TextView
+                  style="@style/Widget.SampleMessage"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:paddingLeft="@dimen/horizontal_page_margin"
+                  android:paddingRight="@dimen/horizontal_page_margin"
+                  android:paddingTop="@dimen/vertical_page_margin"
+                  android:paddingBottom="@dimen/vertical_page_margin"
+                  android:text="@string/intro_message" />
+        </ScrollView>
+
+        <fragment
+              android:name="com.example.android.common.logger.LogFragment"
+              android:id="@+id/log_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    </ViewAnimator>
+
+    <View
+          android:layout_width="match_parent"
+          android:layout_height="1dp"
+          android:background="@android:color/darker_gray" />
+
+    <FrameLayout
+          android:id="@+id/sample_content_fragment"
+          android:layout_weight="2"
+          android:layout_width="match_parent"
+          android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/layout/fragment_sample.xml b/samples/browseable/SwipeRefreshMultipleViews/res/layout/fragment_sample.xml
new file mode 100644
index 0000000..077f3f1
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/layout/fragment_sample.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<com.example.android.swiperefreshmultipleviews.MultiSwipeRefreshLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
+      android:id="@+id/swiperefresh"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent">
+
+    <FrameLayout
+          android:layout_width="match_parent"
+          android:layout_height="match_parent">
+
+        <GridView
+              android:id="@android:id/list"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:numColumns="2" />
+
+        <TextView
+              android:id="@android:id/empty"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:text="@string/empty_text"
+              android:layout_gravity="center"/>
+
+    </FrameLayout>
+
+</com.example.android.swiperefreshmultipleviews.MultiSwipeRefreshLayout>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/menu/main.xml b/samples/browseable/SwipeRefreshMultipleViews/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_toggle_log"
+          android:showAsAction="always"
+          android:title="@string/sample_show_log" />
+</menu>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/menu/main_menu.xml b/samples/browseable/SwipeRefreshMultipleViews/res/menu/main_menu.xml
new file mode 100644
index 0000000..d8fa6e6
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/menu/main_menu.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+          android:id="@+id/menu_clear"
+          android:title="@string/menu_clear"
+          android:showAsAction="never" />
+
+    <item
+          android:id="@+id/menu_refresh"
+          android:title="@string/menu_refresh"
+          android:showAsAction="never" />
+
+</menu>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values-sw600dp/template-dimens.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values-sw600dp/template-styles.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values-v11/template-styles.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values/base-strings.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values/base-strings.xml
new file mode 100644
index 0000000..d7c1c9e
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values/base-strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<resources>
+    <string name="app_name">SwipeRefreshMultipleViews</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+            
+            A sample which shows how to use SwipeRefreshLayout to add the \'swipe-to-refresh\'
+            gesture to a layout with multiple children, enabling the ability to trigger a
+            refresh from swiping down on the visible view. In this sample, SwipeRefreshLayout
+            contains a scrollable GridView, along with a TextView empty view.
+            
+        
+        ]]>
+    </string>
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values/color.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values/color.xml
new file mode 100644
index 0000000..48039b0
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values/color.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 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.
+-->
+
+<resources>
+
+    <color name="swipe_color_1">#B6DB49</color>
+    <color name="swipe_color_2">#99CC00</color>
+    <color name="swipe_color_3">#8ABD00</color>
+    <color name="swipe_color_4">#7CAF00</color>
+
+</resources>
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values/strings.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<resources>
+    <string name="sample_show_log">Show Log</string>
+    <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values/template-dimens.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/res/values/template-styles.xml b/samples/browseable/SwipeRefreshMultipleViews/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/activities/SampleActivityBase.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+    public static final String TAG = "SampleActivityBase";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected  void onStart() {
+        super.onStart();
+        initializeLogging();
+    }
+
+    /** Set up targets to receive log data */
+    public void initializeLogging() {
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        // Wraps Android's native log framework
+        LogWrapper logWrapper = new LogWrapper();
+        Log.setLogNode(logWrapper);
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/dummydata/Cheeses.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/dummydata/Cheeses.java
new file mode 100644
index 0000000..783735c
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/dummydata/Cheeses.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.dummydata;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Random;
+
+/**
+ * Dummy data.
+ */
+public class Cheeses {
+    static final String[] CHEESES = {
+            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+            "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+            "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+            "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+            "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+            "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+            "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+            "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+            "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+            "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+            "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+            "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+            "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+            "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+            "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+            "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+            "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+            "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+            "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+            "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+            "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+            "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+            "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+            "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+            "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+            "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+            "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+            "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+            "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+            "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+            "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+            "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+            "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+            "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+            "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+            "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+            "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+            "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+            "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+            "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+            "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+            "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+            "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+            "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+            "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+            "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+            "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+            "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+            "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+            "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+            "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+            "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+            "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+            "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+            "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+            "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+            "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+            "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+            "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+            "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+            "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+            "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+            "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+            "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+            "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+            "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+            "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+            "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+            "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+            "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+            "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+            "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+            "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+            "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+            "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+            "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+            "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+            "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+            "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+            "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+            "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+            "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+            "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+            "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+            "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+            "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+            "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+            "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+            "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+            "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+            "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+            "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+            "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+            "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+            "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+            "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+            "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+            "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+            "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+            "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+            "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+            "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+            "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+            "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+            "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+            "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+            "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+            "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+            "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+            "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+            "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+            "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+            "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+            "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+            "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+            "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+            "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+            "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+            "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+            "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+            "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+            "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+            "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+            "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+            "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+            "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+    };
+
+    public static ArrayList<String> asList() {
+        ArrayList<String> items = new ArrayList<String>();
+        for (int i = 0, z = CHEESES.length ; i < z ; i++) {
+            items.add(CHEESES[i]);
+        }
+        return items;
+    }
+
+    /**
+     * Return a list of random cheeses.
+     *
+     * @param count the amount of cheeses to return.
+     */
+    public static ArrayList<String> randomList(int count) {
+        Random random = new Random();
+        HashSet<String> items = new HashSet<String>();
+
+        // Make sure that don't infinity loop
+        count = Math.min(count, CHEESES.length);
+
+        while (items.size() < count) {
+            items.add(CHEESES[random.nextInt(CHEESES.length)]);
+        }
+
+        return new ArrayList<String>(items);
+    }
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/Log.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+    // Grabbing the native values from Android's native logging facilities,
+    // to make for easy migration and interop.
+    public static final int NONE = -1;
+    public static final int VERBOSE = android.util.Log.VERBOSE;
+    public static final int DEBUG = android.util.Log.DEBUG;
+    public static final int INFO = android.util.Log.INFO;
+    public static final int WARN = android.util.Log.WARN;
+    public static final int ERROR = android.util.Log.ERROR;
+    public static final int ASSERT = android.util.Log.ASSERT;
+
+    // Stores the beginning of the LogNode topology.
+    private static LogNode mLogNode;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public static LogNode getLogNode() {
+        return mLogNode;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to.
+     */
+    public static void setLogNode(LogNode node) {
+        mLogNode = node;
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void println(int priority, String tag, String msg, Throwable tr) {
+        if (mLogNode != null) {
+            mLogNode.println(priority, tag, msg, tr);
+        }
+    }
+
+    /**
+     * Instructs the LogNode to print the log data provided. Other LogNodes can
+     * be chained to the end of the LogNode as desired.
+     *
+     * @param priority Log level of the data being logged. Verbose, Error, etc.
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     */
+    public static void println(int priority, String tag, String msg) {
+        println(priority, tag, msg, null);
+    }
+
+   /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void v(String tag, String msg, Throwable tr) {
+        println(VERBOSE, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at VERBOSE priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void v(String tag, String msg) {
+        v(tag, msg, null);
+    }
+
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void d(String tag, String msg, Throwable tr) {
+        println(DEBUG, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at DEBUG priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void d(String tag, String msg) {
+        d(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void i(String tag, String msg, Throwable tr) {
+        println(INFO, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at INFO priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void i(String tag, String msg) {
+        i(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, String msg, Throwable tr) {
+        println(WARN, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void w(String tag, String msg) {
+        w(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at WARN priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void w(String tag, Throwable tr) {
+        w(tag, null, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void e(String tag, String msg, Throwable tr) {
+        println(ERROR, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ERROR priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void e(String tag, String msg) {
+        e(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, String msg, Throwable tr) {
+        println(ASSERT, tag, msg, tr);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param msg The actual message to be logged.
+     */
+    public static void wtf(String tag, String msg) {
+        wtf(tag, msg, null);
+    }
+
+    /**
+     * Prints a message at ASSERT priority.
+     *
+     * @param tag Tag for for the log data. Can be used to organize log statements.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public static void wtf(String tag, Throwable tr) {
+        wtf(tag, null, tr);
+    }
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogFragment.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+    private LogView mLogView;
+    private ScrollView mScrollView;
+
+    public LogFragment() {}
+
+    public View inflateViews() {
+        mScrollView = new ScrollView(getActivity());
+        ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        mScrollView.setLayoutParams(scrollParams);
+
+        mLogView = new LogView(getActivity());
+        ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+        logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        mLogView.setLayoutParams(logParams);
+        mLogView.setClickable(true);
+        mLogView.setFocusable(true);
+        mLogView.setTypeface(Typeface.MONOSPACE);
+
+        // Want to set padding as 16 dips, setPadding takes pixels.  Hooray math!
+        int paddingDips = 16;
+        double scale = getResources().getDisplayMetrics().density;
+        int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+        mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+        mLogView.setCompoundDrawablePadding(paddingPixels);
+
+        mLogView.setGravity(Gravity.BOTTOM);
+        mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+        mScrollView.addView(mLogView);
+        return mScrollView;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        View result = inflateViews();
+
+        mLogView.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+            }
+        });
+        return result;
+    }
+
+    public LogView getLogView() {
+        return mLogView;
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogNode.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * 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.example.android.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+    /**
+     * Instructs first LogNode in the list to print the log data provided.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogView.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+    public LogView(Context context) {
+        super(context);
+    }
+
+    public LogView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public LogView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    /**
+     * Formats the log data and prints it out to the LogView.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+
+        
+        String priorityStr = null;
+
+        // For the purposes of this View, we want to print the priority as readable text.
+        switch(priority) {
+            case android.util.Log.VERBOSE:
+                priorityStr = "VERBOSE";
+                break;
+            case android.util.Log.DEBUG:
+                priorityStr = "DEBUG";
+                break;
+            case android.util.Log.INFO:
+                priorityStr = "INFO";
+                break;
+            case android.util.Log.WARN:
+                priorityStr = "WARN";
+                break;
+            case android.util.Log.ERROR:
+                priorityStr = "ERROR";
+                break;
+            case android.util.Log.ASSERT:
+                priorityStr = "ASSERT";
+                break;
+            default:
+                break;
+        }
+
+        // Handily, the Log class has a facility for converting a stack trace into a usable string.
+        String exceptionStr = null;
+        if (tr != null) {
+            exceptionStr = android.util.Log.getStackTraceString(tr);
+        }
+
+        // Take the priority, tag, message, and exception, and concatenate as necessary
+        // into one usable line of text.
+        final StringBuilder outputBuilder = new StringBuilder();
+
+        String delimiter = "\t";
+        appendIfNotNull(outputBuilder, priorityStr, delimiter);
+        appendIfNotNull(outputBuilder, tag, delimiter);
+        appendIfNotNull(outputBuilder, msg, delimiter);
+        appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+        // In case this was originally called from an AsyncTask or some other off-UI thread,
+        // make sure the update occurs within the UI thread.
+        ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+            @Override
+            public void run() {
+                // Display the text we just generated within the LogView.
+                appendToLog(outputBuilder.toString());
+            }
+        })));
+
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+     * the logger takes so many arguments that might be null, this method helps cut out some of the
+     * agonizing tedium of writing the same 3 lines over and over.
+     * @param source StringBuilder containing the text to append to.
+     * @param addStr The String to append
+     * @param delimiter The String to separate the source and appended strings. A tab or comma,
+     *                  for instance.
+     * @return The fully concatenated String as a StringBuilder
+     */
+    private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+        if (addStr != null) {
+            if (addStr.length() == 0) {
+                delimiter = "";
+            }
+
+            return source.append(addStr).append(delimiter);
+        }
+        return source;
+    }
+
+    // The next LogNode in the chain.
+    LogNode mNext;
+
+    /** Outputs the string as a new line of log data in the LogView. */
+    public void appendToLog(String s) {
+        append("\n" + s);
+    }
+
+
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogWrapper.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * 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.example.android.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface.  This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+    // For piping:  The next node to receive Log data after this one has done its work.
+    private LogNode mNext;
+
+    /**
+     * Returns the next LogNode in the linked list.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+    /**
+     * Prints data out to the console using Android's native log mechanism.
+     * @param priority Log level of the data being logged.  Verbose, Error, etc.
+     * @param tag Tag for for the log data.  Can be used to organize log statements.
+     * @param msg The actual message to be logged. The actual message to be logged.
+     * @param tr If an exception was thrown, this can be sent along for the logging facilities
+     *           to extract and print useful information.
+     */
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        // There actually are log methods that don't take a msg parameter.  For now,
+        // if that's the case, just convert null to the empty string and move on.
+        String useMsg = msg;
+        if (useMsg == null) {
+            useMsg = "";
+        }
+
+        // If an exeption was provided, convert that exception to a usable string and attach
+        // it to the end of the msg method.
+        if (tr != null) {
+            msg += "\n" + Log.getStackTraceString(tr);
+        }
+
+        // This is functionally identical to Log.x(tag, useMsg);
+        // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+        Log.println(priority, tag, useMsg);
+
+        // If this isn't the last node in the chain, move things along.
+        if (mNext != null) {
+            mNext.println(priority, tag, msg, tr);
+        }
+    }
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/MessageOnlyLogFilter.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+    LogNode mNext;
+
+    /**
+     * Takes the "next" LogNode as a parameter, to simplify chaining.
+     *
+     * @param next The next LogNode in the pipeline.
+     */
+    public MessageOnlyLogFilter(LogNode next) {
+        mNext = next;
+    }
+
+    public MessageOnlyLogFilter() {
+    }
+
+    @Override
+    public void println(int priority, String tag, String msg, Throwable tr) {
+        if (mNext != null) {
+            getNext().println(Log.NONE, null, msg, null);
+        }
+    }
+
+    /**
+     * Returns the next LogNode in the chain.
+     */
+    public LogNode getNext() {
+        return mNext;
+    }
+
+    /**
+     * Sets the LogNode data will be sent to..
+     */
+    public void setNext(LogNode node) {
+        mNext = node;
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/view/SlidingTabLayout.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/view/SlidingTabLayout.java
new file mode 100644
index 0000000..20049e3
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/view/SlidingTabLayout.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+
+    /**
+     * Allows complete control over the colors drawn in the tab layout. Set with
+     * {@link #setCustomTabColorizer(TabColorizer)}.
+     */
+    public interface TabColorizer {
+
+        /**
+         * @return return the color of the indicator used when {@code position} is selected.
+         */
+        int getIndicatorColor(int position);
+
+        /**
+         * @return return the color of the divider drawn to the right of {@code position}.
+         */
+        int getDividerColor(int position);
+
+    }
+
+    private static final int TITLE_OFFSET_DIPS = 24;
+    private static final int TAB_VIEW_PADDING_DIPS = 16;
+    private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+    private int mTitleOffset;
+
+    private int mTabViewLayoutId;
+    private int mTabViewTextViewId;
+
+    private ViewPager mViewPager;
+    private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+    private final SlidingTabStrip mTabStrip;
+
+    public SlidingTabLayout(Context context) {
+        this(context, null);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        // Disable the Scroll Bar
+        setHorizontalScrollBarEnabled(false);
+        // Make sure that the Tab Strips fills this View
+        setFillViewport(true);
+
+        mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+        mTabStrip = new SlidingTabStrip(context);
+        addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    /**
+     * Set the custom {@link TabColorizer} to be used.
+     *
+     * If you only require simple custmisation then you can use
+     * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+     * similar effects.
+     */
+    public void setCustomTabColorizer(TabColorizer tabColorizer) {
+        mTabStrip.setCustomTabColorizer(tabColorizer);
+    }
+
+    /**
+     * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+     * circular array. Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setSelectedIndicatorColors(int... colors) {
+        mTabStrip.setSelectedIndicatorColors(colors);
+    }
+
+    /**
+     * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+     * Providing one color will mean that all tabs are indicated with the same color.
+     */
+    public void setDividerColors(int... colors) {
+        mTabStrip.setDividerColors(colors);
+    }
+
+    /**
+     * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+     * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+     * that the layout can update it's scroll position correctly.
+     *
+     * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+     */
+    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+        mViewPagerPageChangeListener = listener;
+    }
+
+    /**
+     * Set the custom layout to be inflated for the tab views.
+     *
+     * @param layoutResId Layout id to be inflated
+     * @param textViewId id of the {@link TextView} in the inflated view
+     */
+    public void setCustomTabView(int layoutResId, int textViewId) {
+        mTabViewLayoutId = layoutResId;
+        mTabViewTextViewId = textViewId;
+    }
+
+    /**
+     * Sets the associated view pager. Note that the assumption here is that the pager content
+     * (number of tabs and tab titles) does not change after this call has been made.
+     */
+    public void setViewPager(ViewPager viewPager) {
+        mTabStrip.removeAllViews();
+
+        mViewPager = viewPager;
+        if (viewPager != null) {
+            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+            populateTabStrip();
+        }
+    }
+
+    /**
+     * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+     * {@link #setCustomTabView(int, int)}.
+     */
+    protected TextView createDefaultTabView(Context context) {
+        TextView textView = new TextView(context);
+        textView.setGravity(Gravity.CENTER);
+        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+        textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            // If we're running on Honeycomb or newer, then we can use the Theme's
+            // selectableItemBackground to ensure that the View has a pressed state
+            TypedValue outValue = new TypedValue();
+            getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+                    outValue, true);
+            textView.setBackgroundResource(outValue.resourceId);
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+            textView.setAllCaps(true);
+        }
+
+        int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+        textView.setPadding(padding, padding, padding, padding);
+
+        return textView;
+    }
+
+    private void populateTabStrip() {
+        final PagerAdapter adapter = mViewPager.getAdapter();
+        final View.OnClickListener tabClickListener = new TabClickListener();
+
+        for (int i = 0; i < adapter.getCount(); i++) {
+            View tabView = null;
+            TextView tabTitleView = null;
+
+            if (mTabViewLayoutId != 0) {
+                // If there is a custom tab view layout id set, try and inflate it
+                tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+                        false);
+                tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+            }
+
+            if (tabView == null) {
+                tabView = createDefaultTabView(getContext());
+            }
+
+            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+                tabTitleView = (TextView) tabView;
+            }
+
+            tabTitleView.setText(adapter.getPageTitle(i));
+            tabView.setOnClickListener(tabClickListener);
+
+            mTabStrip.addView(tabView);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (mViewPager != null) {
+            scrollToTab(mViewPager.getCurrentItem(), 0);
+        }
+    }
+
+    private void scrollToTab(int tabIndex, int positionOffset) {
+        final int tabStripChildCount = mTabStrip.getChildCount();
+        if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+            return;
+        }
+
+        View selectedChild = mTabStrip.getChildAt(tabIndex);
+        if (selectedChild != null) {
+            int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+            if (tabIndex > 0 || positionOffset > 0) {
+                // If we're not at the first child and are mid-scroll, make sure we obey the offset
+                targetScrollX -= mTitleOffset;
+            }
+
+            scrollTo(targetScrollX, 0);
+        }
+    }
+
+    private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+        private int mScrollState;
+
+        @Override
+        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+            int tabStripChildCount = mTabStrip.getChildCount();
+            if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+                return;
+            }
+
+            mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+            View selectedTitle = mTabStrip.getChildAt(position);
+            int extraOffset = (selectedTitle != null)
+                    ? (int) (positionOffset * selectedTitle.getWidth())
+                    : 0;
+            scrollToTab(position, extraOffset);
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+                        positionOffsetPixels);
+            }
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) {
+            mScrollState = state;
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+            }
+        }
+
+        @Override
+        public void onPageSelected(int position) {
+            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+                mTabStrip.onViewPagerPageChanged(position, 0f);
+                scrollToTab(position, 0);
+            }
+
+            if (mViewPagerPageChangeListener != null) {
+                mViewPagerPageChangeListener.onPageSelected(position);
+            }
+        }
+
+    }
+
+    private class TabClickListener implements View.OnClickListener {
+        @Override
+        public void onClick(View v) {
+            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+                if (v == mTabStrip.getChildAt(i)) {
+                    mViewPager.setCurrentItem(i);
+                    return;
+                }
+            }
+        }
+    }
+
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/view/SlidingTabStrip.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/view/SlidingTabStrip.java
new file mode 100644
index 0000000..d5bbbae
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.common/view/SlidingTabStrip.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.common.view;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+    private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+    private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+    private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+    private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+    private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+    private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+    private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+
+    private final int mBottomBorderThickness;
+    private final Paint mBottomBorderPaint;
+
+    private final int mSelectedIndicatorThickness;
+    private final Paint mSelectedIndicatorPaint;
+
+    private final int mDefaultBottomBorderColor;
+
+    private final Paint mDividerPaint;
+    private final float mDividerHeight;
+
+    private int mSelectedPosition;
+    private float mSelectionOffset;
+
+    private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+    private final SimpleTabColorizer mDefaultTabColorizer;
+
+    SlidingTabStrip(Context context) {
+        this(context, null);
+    }
+
+    SlidingTabStrip(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setWillNotDraw(false);
+
+        final float density = getResources().getDisplayMetrics().density;
+
+        TypedValue outValue = new TypedValue();
+        context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+        final int themeForegroundColor =  outValue.data;
+
+        mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+                DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+        mDefaultTabColorizer = new SimpleTabColorizer();
+        mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+        mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+                DEFAULT_DIVIDER_COLOR_ALPHA));
+
+        mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+        mBottomBorderPaint = new Paint();
+        mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+        mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+        mSelectedIndicatorPaint = new Paint();
+
+        mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+        mDividerPaint = new Paint();
+        mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+    }
+
+    void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+        mCustomTabColorizer = customTabColorizer;
+        invalidate();
+    }
+
+    void setSelectedIndicatorColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setIndicatorColors(colors);
+        invalidate();
+    }
+
+    void setDividerColors(int... colors) {
+        // Make sure that the custom colorizer is removed
+        mCustomTabColorizer = null;
+        mDefaultTabColorizer.setDividerColors(colors);
+        invalidate();
+    }
+
+    void onViewPagerPageChanged(int position, float positionOffset) {
+        mSelectedPosition = position;
+        mSelectionOffset = positionOffset;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        final int height = getHeight();
+        final int childCount = getChildCount();
+        final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+        final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+                ? mCustomTabColorizer
+                : mDefaultTabColorizer;
+
+        // Thick colored underline below the current selection
+        if (childCount > 0) {
+            View selectedTitle = getChildAt(mSelectedPosition);
+            int left = selectedTitle.getLeft();
+            int right = selectedTitle.getRight();
+            int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+            if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+                int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+                if (color != nextColor) {
+                    color = blendColors(nextColor, color, mSelectionOffset);
+                }
+
+                // Draw the selection partway between the tabs
+                View nextTitle = getChildAt(mSelectedPosition + 1);
+                left = (int) (mSelectionOffset * nextTitle.getLeft() +
+                        (1.0f - mSelectionOffset) * left);
+                right = (int) (mSelectionOffset * nextTitle.getRight() +
+                        (1.0f - mSelectionOffset) * right);
+            }
+
+            mSelectedIndicatorPaint.setColor(color);
+
+            canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+                    height, mSelectedIndicatorPaint);
+        }
+
+        // Thin underline along the entire bottom edge
+        canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+        // Vertical separators between the titles
+        int separatorTop = (height - dividerHeightPx) / 2;
+        for (int i = 0; i < childCount - 1; i++) {
+            View child = getChildAt(i);
+            mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+            canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+                    separatorTop + dividerHeightPx, mDividerPaint);
+        }
+    }
+
+    /**
+     * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+     */
+    private static int setColorAlpha(int color, byte alpha) {
+        return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+    }
+
+    /**
+     * Blend {@code color1} and {@code color2} using the given ratio.
+     *
+     * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+     *              0.0 will return {@code color2}.
+     */
+    private static int blendColors(int color1, int color2, float ratio) {
+        final float inverseRation = 1f - ratio;
+        float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+        float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+        float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+        return Color.rgb((int) r, (int) g, (int) b);
+    }
+
+    private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+        private int[] mIndicatorColors;
+        private int[] mDividerColors;
+
+        @Override
+        public final int getIndicatorColor(int position) {
+            return mIndicatorColors[position % mIndicatorColors.length];
+        }
+
+        @Override
+        public final int getDividerColor(int position) {
+            return mDividerColors[position % mDividerColors.length];
+        }
+
+        void setIndicatorColors(int... colors) {
+            mIndicatorColors = colors;
+        }
+
+        void setDividerColors(int... colors) {
+            mDividerColors = colors;
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/MainActivity.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/MainActivity.java
new file mode 100644
index 0000000..0191d87
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+
+package com.example.android.swiperefreshmultipleviews;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+    public static final String TAG = "MainActivity";
+
+    // Whether the Log Fragment is currently shown
+    private boolean mLogShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        SwipeRefreshMultipleViewsFragment fragment = new SwipeRefreshMultipleViewsFragment();
+        transaction.replace(R.id.sample_content_fragment, fragment);
+        transaction.commit();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+        logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+        logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_toggle_log:
+                mLogShown = !mLogShown;
+                ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+                if (mLogShown) {
+                    output.setDisplayedChild(1);
+                } else {
+                    output.setDisplayedChild(0);
+                }
+                supportInvalidateOptionsMenu();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /** Create a chain of targets that will receive log data */
+    @Override
+    public void initializeLogging() {
+        // Wraps Android's native log framework.
+        LogWrapper logWrapper = new LogWrapper();
+        // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+        Log.setLogNode(logWrapper);
+
+        // Filter strips out everything except the message text.
+        MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+        logWrapper.setNext(msgFilter);
+
+        // On screen logging via a fragment with a TextView.
+        LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+                .findFragmentById(R.id.log_fragment);
+        msgFilter.setNext(logFragment.getLogView());
+
+        Log.i(TAG, "Ready");
+    }
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/MultiSwipeRefreshLayout.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/MultiSwipeRefreshLayout.java
new file mode 100644
index 0000000..4e50145
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/MultiSwipeRefreshLayout.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 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.example.android.swiperefreshmultipleviews;
+
+import android.content.Context;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.AbsListView;
+
+/**
+ * A descendant of {@link android.support.v4.widget.SwipeRefreshLayout} which supports multiple
+ * child views triggering a refresh gesture. You set the views which can trigger the gesture via
+ * {@link #setSwipeableChildren(int...)}, providing it the child ids.
+ */
+public class MultiSwipeRefreshLayout extends SwipeRefreshLayout {
+
+    private View[] mSwipeableChildren;
+
+    public MultiSwipeRefreshLayout(Context context) {
+        super(context);
+    }
+
+    public MultiSwipeRefreshLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Set the children which can trigger a refresh by swiping down when they are visible. These
+     * views need to be a descendant of this view.
+     */
+    public void setSwipeableChildren(final int... ids) {
+        assert ids != null;
+
+        // Iterate through the ids and find the Views
+        mSwipeableChildren = new View[ids.length];
+        for (int i = 0; i < ids.length; i++) {
+            mSwipeableChildren[i] = findViewById(ids[i]);
+        }
+    }
+
+    // BEGIN_INCLUDE(can_child_scroll_up)
+    /**
+     * This method controls when the swipe-to-refresh gesture is triggered. By returning false here
+     * we are signifying that the view is in a state where a refresh gesture can start.
+     *
+     * <p>As {@link android.support.v4.widget.SwipeRefreshLayout} only supports one direct child by
+     * default, we need to manually iterate through our swipeable children to see if any are in a
+     * state to trigger the gesture. If so we return false to start the gesture.
+     */
+    @Override
+    public boolean canChildScrollUp() {
+        if (mSwipeableChildren != null && mSwipeableChildren.length > 0) {
+            // Iterate through the scrollable children and check if any of them can not scroll up
+            for (View view : mSwipeableChildren) {
+                if (view != null && view.isShown() && !canViewScrollUp(view)) {
+                    // If the view is shown, and can not scroll upwards, return false and start the
+                    // gesture.
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    // END_INCLUDE(can_child_scroll_up)
+
+    // BEGIN_INCLUDE(can_view_scroll_up)
+    /**
+     * Utility method to check whether a {@link View} can scroll up from it's current position.
+     * Handles platform version differences, providing backwards compatible functionality where
+     * needed.
+     */
+    private static boolean canViewScrollUp(View view) {
+        if (android.os.Build.VERSION.SDK_INT >= 14) {
+            // For ICS and above we can call canScrollVertically() to determine this
+            return ViewCompat.canScrollVertically(view, -1);
+        } else {
+            if (view instanceof AbsListView) {
+                // Pre-ICS we need to manually check the first visible item and the child view's top
+                // value
+                final AbsListView listView = (AbsListView) view;
+                return listView.getChildCount() > 0 &&
+                        (listView.getFirstVisiblePosition() > 0
+                                || listView.getChildAt(0).getTop() < listView.getPaddingTop());
+            } else {
+                // For all other view types we just check the getScrollY() value
+                return view.getScrollY() > 0;
+            }
+        }
+    }
+    // END_INCLUDE(can_view_scroll_up)
+}
diff --git a/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/SwipeRefreshMultipleViewsFragment.java b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/SwipeRefreshMultipleViewsFragment.java
new file mode 100644
index 0000000..e2b83d3
--- /dev/null
+++ b/samples/browseable/SwipeRefreshMultipleViews/src/com.example.android.swiperefreshmultipleviews/SwipeRefreshMultipleViewsFragment.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2014 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.example.android.swiperefreshmultipleviews;
+
+import com.example.android.common.dummydata.Cheeses;
+import com.example.android.common.logger.Log;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+
+import java.util.List;
+
+/**
+ * A sample which shows how to use {@link android.support.v4.widget.SwipeRefreshLayout} to add
+ * the 'swipe-to-refresh' gesture to a layout with multiple children. In this sample,
+ * SwipeRefreshLayout contains a scrollable {@link android.widget.GridView}, along with a
+ * {@link android.widget.TextView} empty view.
+ *
+ * <p>To provide an accessible way to trigger the refresh, this app also provides a refresh
+ * action item.
+ *
+ * <p>In this sample app, the refresh updates the GridView with a random set of new items.
+ */
+public class SwipeRefreshMultipleViewsFragment extends Fragment {
+
+    private static final String LOG_TAG = SwipeRefreshMultipleViewsFragment.class.getSimpleName();
+
+    private static final int LIST_ITEM_COUNT = 40;
+
+    /**
+     * The {@link MultiSwipeRefreshLayout} that detects swipe gestures and triggers callbacks in
+     * the app.
+     */
+    private MultiSwipeRefreshLayout mSwipeRefreshLayout;
+
+    /**
+     * The {@link android.widget.GridView} that displays the content that should be refreshed.
+     */
+    private GridView mGridView;
+
+    /**
+     * The {@link android.widget.ListAdapter} used to populate the {@link android.widget.GridView}
+     * defined in the previous statement.
+     */
+    private ArrayAdapter<String> mListAdapter;
+
+    /**
+     * The {@link View} which is displayed when the GridView is empty.
+     */
+    private View mEmptyView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Notify the system to allow an options menu for this fragment.
+        setHasOptionsMenu(true);
+    }
+
+    // BEGIN_INCLUDE (inflate_view)
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.fragment_sample, container, false);
+
+        // Retrieve the SwipeRefreshLayout and GridView instances
+        mSwipeRefreshLayout = (MultiSwipeRefreshLayout) view.findViewById(R.id.swiperefresh);
+
+        // BEGIN_INCLUDE (change_colors)
+        // Set the color scheme of the SwipeRefreshLayout by providing 4 color resource ids
+        mSwipeRefreshLayout.setColorScheme(
+                R.color.swipe_color_1, R.color.swipe_color_2,
+                R.color.swipe_color_3, R.color.swipe_color_4);
+        // END_INCLUDE (change_colors)
+
+        // Retrieve the GridView
+        mGridView = (GridView) view.findViewById(android.R.id.list);
+
+        // Retrieve the empty view
+        mEmptyView = view.findViewById(android.R.id.empty);
+
+        return view;
+    }
+    // END_INCLUDE (inflate_view)
+
+    // BEGIN_INCLUDE (setup_views)
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        /**
+         * Create an ArrayAdapter to contain the data for the GridView. Each item in the GridView
+         * uses the system-defined simple_list_item_1 layout that contains one TextView. Initially
+         */
+        mListAdapter = new ArrayAdapter<String>(
+                getActivity(),
+                android.R.layout.simple_list_item_1,
+                android.R.id.text1);
+
+        // Set the adapter between the GridView and its backing data.
+        mGridView.setAdapter(mListAdapter);
+
+        // Set the empty view so that it is displayed as needed
+        mGridView.setEmptyView(mEmptyView);
+
+        // BEGIN_INCLUDE (setup_swipeable_children)
+        // Tell the MultiSwipeRefreshLayout which views are swipeable. In this case, the GridView
+        // and empty view.
+        mSwipeRefreshLayout.setSwipeableChildren(android.R.id.list, android.R.id.empty);
+        // END_INCLUDE (setup_swipeable_children)
+
+        // BEGIN_INCLUDE (setup_refreshlistener)
+        /**
+         * Implement {@link SwipeRefreshLayout.OnRefreshListener}. When users do the "swipe to
+         * refresh" gesture, SwipeRefreshLayout invokes
+         * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}. In
+         * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}, call a method that
+         * refreshes the content. Call the same method in response to the Refresh action from the
+         * action bar.
+         */
+        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                Log.i(LOG_TAG, "onRefresh called from SwipeRefreshLayout");
+
+                initiateRefresh();
+            }
+        });
+        // END_INCLUDE (setup_refreshlistener)
+    }
+    // END_INCLUDE (setup_views)
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.main_menu, menu);
+    }
+
+    // BEGIN_INCLUDE (setup_refresh_menu_listener)
+    /**
+     * Respond to the user's selection of the Refresh action item. Start the SwipeRefreshLayout
+     * progress bar, then initiate the background task that refreshes the content.
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_clear:
+                Log.i(LOG_TAG, "Clear menu item selected");
+                mListAdapter.clear();
+                return true;
+
+            case R.id.menu_refresh:
+                Log.i(LOG_TAG, "Refresh menu item selected");
+
+                // We make sure that the SwipeRefreshLayout is displaying it's refreshing indicator
+                if (!mSwipeRefreshLayout.isRefreshing()) {
+                    mSwipeRefreshLayout.setRefreshing(true);
+                }
+
+                // Start our refresh background task
+                initiateRefresh();
+
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+    // END_INCLUDE (setup_refresh_menu_listener)
+
+    // BEGIN_INCLUDE (initiate_refresh)
+    /**
+     * By abstracting the refresh process to a single method, the app allows both the
+     * SwipeGestureLayout onRefresh() method and the Refresh action item to refresh the content.
+     */
+    private void initiateRefresh() {
+        Log.i(LOG_TAG, "initiateRefresh");
+
+        /**
+         * Execute the background task, which uses {@link android.os.AsyncTask} to load the data.
+         */
+        new DummyBackgroundTask().execute();
+    }
+    // END_INCLUDE (initiate_refresh)
+
+    // BEGIN_INCLUDE (refresh_complete)
+    /**
+     * When the AsyncTask finishes, it calls onRefreshComplete(), which updates the data in the
+     * ListAdapter and turns off the progress bar.
+     */
+    private void onRefreshComplete(List<String> result) {
+        Log.i(LOG_TAG, "onRefreshComplete");
+
+        // Remove all items from the ListAdapter, and then replace them with the new items
+        mListAdapter.clear();
+        for (String cheese : result) {
+            mListAdapter.add(cheese);
+        }
+
+        // Stop the refreshing indicator
+        mSwipeRefreshLayout.setRefreshing(false);
+    }
+    // END_INCLUDE (refresh_complete)
+
+    /**
+     * Dummy {@link AsyncTask} which simulates a long running task to fetch new cheeses.
+     */
+    private class DummyBackgroundTask extends AsyncTask<Void, Void, List<String>> {
+
+        static final int TASK_DURATION = 3 * 1000; // 3 seconds
+
+        @Override
+        protected List<String> doInBackground(Void... params) {
+            // Sleep for a small amount of time to simulate a background-task
+            try {
+                Thread.sleep(TASK_DURATION);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            // Return a new random list of cheeses
+            return Cheeses.randomList(LIST_ITEM_COUNT);
+        }
+
+        @Override
+        protected void onPostExecute(List<String> result) {
+            super.onPostExecute(result);
+
+            // Tell the Fragment that the refresh has completed
+            onRefreshComplete(result);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/samples/browseable/TextLinkify/res/values-v11/template-styles.xml b/samples/browseable/TextLinkify/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/TextLinkify/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/TextLinkify/res/values/template-styles.xml b/samples/browseable/TextLinkify/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/TextLinkify/res/values/template-styles.xml
+++ b/samples/browseable/TextLinkify/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/browseable/TextSwitcher/res/values-v11/template-styles.xml b/samples/browseable/TextSwitcher/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/samples/browseable/TextSwitcher/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/samples/browseable/TextSwitcher/res/values/template-styles.xml b/samples/browseable/TextSwitcher/res/values/template-styles.xml
index 404623e..6e7d593 100644
--- a/samples/browseable/TextSwitcher/res/values/template-styles.xml
+++ b/samples/browseable/TextSwitcher/res/values/template-styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Activity themes -->
 
-    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+    <style name="Theme.Base" parent="android:Theme.Light" />
 
     <style name="Theme.Sample" parent="Theme.Base" />
 
diff --git a/samples/samples_source.prop_template b/samples/samples_source.prop_template
index 315be08..d3cdfd5 100644
--- a/samples/samples_source.prop_template
+++ b/samples/samples_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=4
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/scripts/app_engine_server/redirects.yaml b/scripts/app_engine_server/redirects.yaml
index b7a90a5..c37ac00 100644
--- a/scripts/app_engine_server/redirects.yaml
+++ b/scripts/app_engine_server/redirects.yaml
@@ -77,6 +77,14 @@
   type: permanent
   comment: Redirect sdk reference to new location
 
+- src: /sdk/exploring.html
+  dst: /sdk/tools/help/sdk-manager.html
+  type: permanent
+
+- src: /sdk/installing/bundle.html
+  dst: /sdk/installing/index.html?pkg=adt
+  type: permanent
+
 - src: /sdk/compatibility-library.html
   dst: /tools/support-library/index.html
   type: permanent
diff --git a/sdk/build_tools_source.prop_template b/sdk/build_tools_source.prop_template
index c9bfc2f..5d62307 100644
--- a/sdk/build_tools_source.prop_template
+++ b/sdk/build_tools_source.prop_template
@@ -1,3 +1,3 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.2
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
 
diff --git a/sdk/doc_source.prop_template b/sdk/doc_source.prop_template
index 523d6bd..d3cdfd5 100644
--- a/sdk/doc_source.prop_template
+++ b/sdk/doc_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/sdk/plat_tools_source.prop_template b/sdk/plat_tools_source.prop_template
index b83af7f..5d62307 100644
--- a/sdk/plat_tools_source.prop_template
+++ b/sdk/plat_tools_source.prop_template
@@ -1,3 +1,3 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.1
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
 
diff --git a/sdk/platform_source.prop_template b/sdk/platform_source.prop_template
index 09a2d81..7ecb1e2 100644
--- a/sdk/platform_source.prop_template
+++ b/sdk/platform_source.prop_template
@@ -2,7 +2,7 @@
 Pkg.UserSrc=false
 Platform.Version=${PLATFORM_VERSION}
 Platform.CodeName=KitKat
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 Layoutlib.Api=10
diff --git a/sdk/source_source.prop_template b/sdk/source_source.prop_template
index 523d6bd..d3cdfd5 100644
--- a/sdk/source_source.prop_template
+++ b/sdk/source_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/sdk/support_source.prop_template b/sdk/support_source.prop_template
index f897712..f5b217e 100644
--- a/sdk/support_source.prop_template
+++ b/sdk/support_source.prop_template
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.1
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
 Extra.Vendor=android
 Extra.VendorId=android
 Extra.VendorDisplay=Android
diff --git a/sys-img/images_armeabi-v7a_source.prop_template b/sys-img/images_armeabi-v7a_source.prop_template
index 7d13fce..9c7a332 100644
--- a/sys-img/images_armeabi-v7a_source.prop_template
+++ b/sys-img/images_armeabi-v7a_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi-v7a
diff --git a/sys-img/images_armeabi_source.prop_template b/sys-img/images_armeabi_source.prop_template
index ef17ea6..91e9d21 100644
--- a/sys-img/images_armeabi_source.prop_template
+++ b/sys-img/images_armeabi_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi
diff --git a/sys-img/images_x86_source.prop_template b/sys-img/images_x86_source.prop_template
index d5f5610..1a18cf8 100644
--- a/sys-img/images_x86_source.prop_template
+++ b/sys-img/images_x86_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=${TARGET_CPU_ABI}
diff --git a/tools/emulator/test-apps/SmokeTests/Android.mk b/tools/emulator/test-apps/ConnectivityTest/Android.mk
similarity index 80%
copy from tools/emulator/test-apps/SmokeTests/Android.mk
copy to tools/emulator/test-apps/ConnectivityTest/Android.mk
index 41951dd..ca20d57 100644
--- a/tools/emulator/test-apps/SmokeTests/Android.mk
+++ b/tools/emulator/test-apps/ConnectivityTest/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# 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.
@@ -15,18 +15,18 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-test-lib
-
 LOCAL_MODULE_TAGS := optional
 
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := EmulatorSmokeTests
+LOCAL_PACKAGE_NAME := ConnectivityTest
 
 LOCAL_SDK_VERSION := 4
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-
 include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/emulator/test-apps/SmokeTests/AndroidManifest.xml b/tools/emulator/test-apps/ConnectivityTest/AndroidManifest.xml
similarity index 70%
rename from tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
rename to tools/emulator/test-apps/ConnectivityTest/AndroidManifest.xml
index 7066ca6..80f65cf 100644
--- a/tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
+++ b/tools/emulator/test-apps/ConnectivityTest/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- 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.
@@ -14,15 +14,14 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.android.emulator.smoketests">
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+      package="com.android.emulator.connectivity.test"
+      android:versionCode="1"
+      android:versionName="1.0">
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.READ_SMS" />
     <uses-sdk android:minSdkVersion="4" />
-    <instrumentation android:targetPackage="com.android.emulator.smoketests"
-                     android:name="com.android.test.runner.AndroidJUnitRunner" />
-    <application  android:label="Emulator Smoke Tests">
+    <instrumentation android:targetPackage="com.android.emulator.connectivity.test" android:name="android.test.InstrumentationTestRunner" />
+    <application  android:label="Connectivity Test">
+        <uses-library android:name="android.test.runner" />
     </application>
-</manifest>
-
+</manifest>
\ No newline at end of file
diff --git a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/connectivity/ConnectivityTest.java b/tools/emulator/test-apps/ConnectivityTest/src/com/android/emulator/connectivity/test/ConnectivityTest.java
similarity index 97%
rename from tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/connectivity/ConnectivityTest.java
rename to tools/emulator/test-apps/ConnectivityTest/src/com/android/emulator/connectivity/test/ConnectivityTest.java
index 9fe1ebe..9931eb8 100644
--- a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/connectivity/ConnectivityTest.java
+++ b/tools/emulator/test-apps/ConnectivityTest/src/com/android/emulator/connectivity/test/ConnectivityTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.emulator.smoketests.connectivity;
+package com.android.emulator.connectivity.test;
 
 import java.io.IOException;
 import java.net.URL;
diff --git a/tools/emulator/test-apps/SmokeTests/Android.mk b/tools/emulator/test-apps/GpsLocationTest/Android.mk
similarity index 80%
rename from tools/emulator/test-apps/SmokeTests/Android.mk
rename to tools/emulator/test-apps/GpsLocationTest/Android.mk
index 41951dd..5f90f3a 100644
--- a/tools/emulator/test-apps/SmokeTests/Android.mk
+++ b/tools/emulator/test-apps/GpsLocationTest/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# 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.
@@ -15,18 +15,18 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-test-lib
-
 LOCAL_MODULE_TAGS := optional
 
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := EmulatorSmokeTests
+LOCAL_PACKAGE_NAME := GpsLocationTest
 
 LOCAL_SDK_VERSION := 4
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-
 include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/emulator/test-apps/SmokeTests/AndroidManifest.xml b/tools/emulator/test-apps/GpsLocationTest/AndroidManifest.xml
similarity index 65%
copy from tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
copy to tools/emulator/test-apps/GpsLocationTest/AndroidManifest.xml
index 7066ca6..901855e 100644
--- a/tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
+++ b/tools/emulator/test-apps/GpsLocationTest/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- 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.
@@ -14,15 +14,14 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.android.emulator.smoketests">
+      package="com.android.emulator.gps.test"
+      android:versionCode="1"
+      android:versionName="1.0">
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.READ_SMS" />
     <uses-sdk android:minSdkVersion="4" />
-    <instrumentation android:targetPackage="com.android.emulator.smoketests"
-                     android:name="com.android.test.runner.AndroidJUnitRunner" />
-    <application  android:label="Emulator Smoke Tests">
+    <instrumentation android:targetPackage="com.android.emulator.gps.test"
+                     android:name="android.test.InstrumentationTestRunner" />
+    <application  android:label="GPS Location Test">
+        <uses-library android:name="android.test.runner" />
     </application>
-</manifest>
-
+</manifest>
\ No newline at end of file
diff --git a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/gps/GpsLocationTest.java b/tools/emulator/test-apps/GpsLocationTest/src/com/android/emulator/gps/test/GpsLocationTest.java
similarity index 98%
rename from tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/gps/GpsLocationTest.java
rename to tools/emulator/test-apps/GpsLocationTest/src/com/android/emulator/gps/test/GpsLocationTest.java
index 1e0258c..6eb3834 100644
--- a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/gps/GpsLocationTest.java
+++ b/tools/emulator/test-apps/GpsLocationTest/src/com/android/emulator/gps/test/GpsLocationTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.emulator.smoketests.gps;
+package com.android.emulator.gps.test;
 
 import android.content.Context;
 import android.location.Location;
diff --git a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
deleted file mode 100644
index bb1ce20..0000000
--- a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2014 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.emulator.smoketests.sms;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.os.HandlerThread;
-import com.android.test.InjectContext;
-
-import org.junit.Assert;
-import static junit.framework.Assert.assertEquals;
-
-import org.junit.Test;
-/**
- * Sms Test
- *
- * Test that an SMS message has been received
- */
-public class SmsTest {
-
-    /**
-     * Prior to running this test an sms must be sent
-     * via DDMS
-     */
-    public final static String NUMBER = "5551212";
-    public final static String BODY = "test sms";
-    private final static int SMS_POLL_TIME_MS = 10 * 1000;
-    private final static int SIXY_SECONDS_OF_LOOPS = 6;
-    @InjectContext
-    public Context mContext;
-
-    /**
-     * Verify that an SMS has been received with the correct number and body
-     */
-    @Test
-    public void testReceivedSms() throws java.lang.InterruptedException {
-        Cursor c = getSmsCursor();
-        c.moveToFirst();
-
-        String number = c.getString(c.getColumnIndexOrThrow("address"));
-        String body = c.getString(c.getColumnIndexOrThrow("body"));
-
-        c.close();
-
-        assertEquals(NUMBER, number);
-        assertEquals(BODY, body);
-    }
-
-    private Cursor getSmsCursor() throws java.lang.InterruptedException {
-        ContentResolver r = mContext.getContentResolver();
-        Uri message = Uri.parse("content://sms/");
-        Cursor c;
-
-        for(int i = 0; i < SIXY_SECONDS_OF_LOOPS; i++) {
-            c = r.query(message,null,null,null,null);
-
-            if(c.getCount() != 0) {
-                return c;
-            }
-
-            c.close();
-            Thread.sleep(SMS_POLL_TIME_MS);
-        }
-        Assert.fail("Did not find any SMS messages. Giving up");
-        // necessary for compilation
-        return null;
-    }
-
-}