Merge pull request #42 from alsutton/parameterised_keys

Parameterise keystore properties
diff --git a/.travis.yml b/.travis.yml
index 60d0d16..a64747a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,7 @@
 android:
   components:
     - build-tools-20.0.0
-    - andorid-19
+    - android-19
     - android-20
     - extra-google-m2repository
     - extra-android-m2repository
diff --git a/Wearable/build.gradle b/Wearable/build.gradle
index 3c37e6c..05a05a8 100644
--- a/Wearable/build.gradle
+++ b/Wearable/build.gradle
@@ -65,8 +65,8 @@
 }
 
 dependencies {
-    compile 'com.android.support:support-v13:+'
+    compile 'com.android.support:support-v13:21.+'
     compile 'com.google.android.support:wearable:+'
-    compile 'com.google.android.gms:play-services-wearable:+'
+    compile 'com.google.android.gms:play-services-wearable:6.1.+'
 } 
 
diff --git a/Wearable/src/main/java/com/google/samples/apps/iosched/iowear/Utils/Utils.java b/Wearable/src/main/java/com/google/samples/apps/iosched/iowear/utils/Utils.java
similarity index 100%
rename from Wearable/src/main/java/com/google/samples/apps/iosched/iowear/Utils/Utils.java
rename to Wearable/src/main/java/com/google/samples/apps/iosched/iowear/utils/Utils.java
diff --git a/android/build.gradle b/android/build.gradle
index b570079..cc7937b 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-lpreview = hasProperty('lpreview')
-
 apply plugin: 'com.android.application'
 
 repositories {
@@ -26,15 +24,12 @@
 }
 
 android {
-    compileSdkVersion lpreview ? "android-L" : 19
-    buildToolsVersion "20.0.0"
+    compileSdkVersion 21
+    buildToolsVersion "21.0.0"
 
-    productFlavors { lpreview ? lpreview{} : classic{} }
-
-    defaultConfig lpreview ? {} : {
-        // Non-L-preview configuration
+    defaultConfig {
         minSdkVersion 14
-        targetSdkVersion 19
+        targetSdkVersion 21
     }
 
     signingConfigs {
@@ -75,10 +70,10 @@
 
 dependencies {
     wearApp project(':Wearable')
-    compile 'com.google.android.gms:play-services:5+' 
-    compile 'com.android.support:support-v13:20.+'
-    compile 'com.android.support:support-v4:20.+'
-    compile 'com.google.android.apps.dashclock:dashclock-api:+'
+    compile 'com.google.android.gms:play-services:6.1.+'
+    compile 'com.android.support:support-v13:21.+'
+    compile 'com.android.support:appcompat-v7:21.+'
+    compile 'com.android.support:cardview-v7:21.+'
     compile 'com.google.code.gson:gson:2.+'
     compile('com.google.api-client:google-api-client:1.+') {
         exclude group: 'xpp3', module: 'shared'
diff --git a/android/src/classic/java/com/google/samples/apps/iosched/util/LPreviewUtils.java b/android/src/classic/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
deleted file mode 100644
index e9b622d..0000000
--- a/android/src/classic/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * 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.google.samples.apps.iosched.util;
-
-import android.app.Activity;
-
-public class LPreviewUtils {
-    private LPreviewUtils() {
-    }
-
-    public static LPreviewUtilsBase getInstance(Activity activity) {
-        return new LPreviewUtilsBase(activity);
-    }
-}
diff --git a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtils.java b/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
deleted file mode 100644
index 6503430..0000000
--- a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * 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.google.samples.apps.iosched.util;
-
-import android.app.Activity;
-import android.os.Build;
-
-public class LPreviewUtils {
-    private LPreviewUtils() {
-    }
-
-    public static LPreviewUtilsBase getInstance(Activity activity) {
-        if ("L".equals(Build.VERSION.CODENAME)) {
-            return new LPreviewUtilsImpl(activity);
-        } else {
-            return new LPreviewUtilsBase(activity);
-        }
-    }
-}
diff --git a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtilsImpl.java b/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtilsImpl.java
deleted file mode 100644
index d1023d8..0000000
--- a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtilsImpl.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * 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.google.samples.apps.iosched.util;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.app.SharedElementListener;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Typeface;
-import android.graphics.drawable.AnimatedStateListDrawable;
-import android.os.Build;
-import android.support.v4.widget.DrawerLayout;
-import android.text.TextUtils;
-import android.view.Gravity;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toolbar;
-
-import com.google.samples.apps.iosched.R;
-
-import java.lang.Override;
-import java.util.List;
-import java.util.Map;
-
-@TargetApi(Build.VERSION_CODES.L)
-public class LPreviewUtilsImpl extends LPreviewUtilsBase {
-    private static final int[] STATE_CHECKED = new int[]{android.R.attr.state_checked};
-    private static final int[] STATE_UNCHECKED = new int[]{};
-
-    private static Typeface sMediumTypeface;
-
-    private ActionBarDrawerToggleWrapper mDrawerToggleWrapper;
-    private DrawerLayout mDrawerLayout;
-    private Toolbar mActionBarToolbar;
-
-    LPreviewUtilsImpl(Activity activity) {
-        super(activity);
-    }
-
-    @Override
-    public ActionBarDrawerToggleWrapper setupDrawerToggle(DrawerLayout drawerLayout, DrawerLayout.DrawerListener drawerListener) {
-        // On L, use a different drawer indicator
-        if (mActionBarToolbar != null) {
-            mActionBarToolbar.setNavigationIcon(R.drawable.ic_drawer);
-            mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View view) {
-                    if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
-                        mDrawerLayout.closeDrawer(Gravity.START);
-                    } else {
-                        mDrawerLayout.openDrawer(Gravity.START);
-                    }
-                }
-            });
-        } else {
-            mActivity.getActionBar().setHomeAsUpIndicator(R.drawable.ic_drawer);
-        }
-        // On L, stub out the ActionBarDrawerToggle
-        mDrawerLayout = drawerLayout;
-        mDrawerLayout.setDrawerListener(drawerListener);
-        mDrawerToggleWrapper = new ActionBarDrawerToggleWrapper();
-        return mDrawerToggleWrapper;
-    }
-
-    public class ActionBarDrawerToggleWrapper extends LPreviewUtilsBase.ActionBarDrawerToggleWrapper {
-        public void syncState() {
-        }
-
-        public void onConfigurationChanged(Configuration newConfig) {
-        }
-
-        public boolean onOptionsItemSelected(MenuItem item) {
-            // Toggle drawer
-            if (item.getItemId() == android.R.id.home) {
-                if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
-                    mDrawerLayout.closeDrawer(Gravity.START);
-                } else {
-                    mDrawerLayout.openDrawer(Gravity.START);
-                }
-                return true;
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public void setViewElevation(View v, float elevation) {
-        v.setElevation(elevation);
-    }
-
-    @Override
-    public void trySetActionBar() {
-        mActionBarToolbar = (Toolbar) mActivity.findViewById(R.id.toolbar_actionbar);
-        if (mActionBarToolbar != null) {
-            mActivity.setActionBar(mActionBarToolbar);
-        }
-    }
-
-    @Override
-    public boolean hasLPreviewAPIs() {
-        return true;
-    }
-
-    public void startActivityWithTransition(Intent intent, final View clickedView,
-            final String sharedElementName) {
-        ActivityOptions options = null;
-        if (clickedView != null && !TextUtils.isEmpty(sharedElementName)) {
-            options = ActivityOptions.makeSceneTransitionAnimation(
-                    mActivity, clickedView, sharedElementName);
-        }
-
-        mActivity.setExitSharedElementListener(new SharedElementListener() {
-            @Override
-            public void remapSharedElements(List<String> names, Map<String, View> sharedElements) {
-                super.remapSharedElements(names, sharedElements);
-                sharedElements.put(sharedElementName, clickedView);
-            }
-        });
-
-        mActivity.startActivity(intent, (options != null) ? options.toBundle() : null);
-    }
-
-    @Override
-    public void setViewName(View v, String viewName) {
-        v.setViewName(viewName);
-    }
-
-    @Override
-    public void postponeEnterTransition() {
-        mActivity.postponeEnterTransition();
-    }
-
-    @Override
-    public void startPostponedEnterTransition() {
-        mActivity.startPostponedEnterTransition();
-    }
-
-    @Override
-    public void showHideActionBarIfPartOfDecor(boolean show) {
-        if (mActionBarToolbar != null) {
-            // Action bar is part of the layout
-            return;
-        }
-
-        // Action bar is part of window decor
-        super.showHideActionBarIfPartOfDecor(show);
-    }
-
-    public boolean shouldChangeActionBarForDrawer() {
-        return false;
-    }
-
-    @Override
-    public void setMediumTypeface(TextView textView) {
-        if (sMediumTypeface == null) {
-            sMediumTypeface = Typeface.create("sans-serif-medium", Typeface.NORMAL);
-        }
-
-        textView.setTypeface(sMediumTypeface);
-    }
-
-    @Override
-    public int getStatusBarColor() {
-        return mActivity.getWindow().getStatusBarColor();
-    }
-
-    @Override
-    public void setStatusBarColor(int color) {
-        mActivity.getWindow().setStatusBarColor(color);
-    }
-
-    @Override
-    public void setOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
-            boolean allowAnimate) {
-        AnimatedStateListDrawable drawable = (AnimatedStateListDrawable)
-                mActivity.getResources().getDrawable(R.drawable.add_schedule_fab_icon_anim);
-        imageView.setImageDrawable(drawable);
-        if (allowAnimate) {
-            // TODO: figure out if there's a way to always animate from current state
-            imageView.setImageState(isCheck ? STATE_UNCHECKED : STATE_CHECKED, false);
-            drawable.jumpToCurrentState();
-            imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
-        } else {
-            imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
-            drawable.jumpToCurrentState();
-        }
-    }
-}
diff --git a/android/src/lpreview/res/anim-v21/add_schedule_fab_state_list_anim.xml b/android/src/lpreview/res/anim-v21/add_schedule_fab_state_list_anim.xml
deleted file mode 100644
index 4e1d87c..0000000
--- a/android/src/lpreview/res/anim-v21/add_schedule_fab_state_list_anim.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Copyright 2014 Google Inc. All rights reserved.
-
-   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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="true" android:state_pressed="true">
-        <set>
-            <objectAnimator android:duration="@android:integer/config_shortAnimTime"
-                            android:propertyName="translationZ"
-                            android:valueTo="@dimen/fab_press_translation_z"
-                            android:valueType="floatType"/>
-        </set>
-    </item>
-    <item>
-        <set>
-            <objectAnimator android:duration="@android:integer/config_shortAnimTime"
-                            android:propertyName="translationZ"
-                            android:valueTo="0"
-                            android:valueType="floatType"/>
-        </set>
-    </item>
-</selector>
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_drawer.png b/android/src/lpreview/res/drawable-xxhdpi-v21/ic_drawer.png
deleted file mode 100644
index 19bae3e..0000000
--- a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_drawer.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_launcher.png b/android/src/lpreview/res/drawable-xxhdpi-v21/ic_launcher.png
deleted file mode 100644
index 32502c3..0000000
--- a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_up.png b/android/src/lpreview/res/drawable-xxhdpi-v21/ic_up.png
deleted file mode 100644
index 3396894..0000000
--- a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_up.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxxhdpi-v21/ic_launcher.png b/android/src/lpreview/res/drawable-xxxhdpi-v21/ic_launcher.png
deleted file mode 100644
index afae355..0000000
--- a/android/src/lpreview/res/drawable-xxxhdpi-v21/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/layout-v21/toolbar_actionbar.xml b/android/src/lpreview/res/layout-v21/toolbar_actionbar.xml
deleted file mode 100644
index 04af731..0000000
--- a/android/src/lpreview/res/layout-v21/toolbar_actionbar.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  Copyright 2014 Google Inc. All rights reserved.
-
-  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.
-  -->
-
-<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
-    android:theme="@style/ActionBarThemeOverlay"
-    android:id="@+id/toolbar_actionbar"
-    android:layout_width="match_parent"
-    android:layout_height="?android:actionBarSize" />
diff --git a/android/src/lpreview/res/values-sw600dp-v21/styles.xml b/android/src/lpreview/res/values-sw600dp-v21/styles.xml
deleted file mode 100644
index 8165a88..0000000
--- a/android/src/lpreview/res/values-sw600dp-v21/styles.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
-  Copyright 2014 Google Inc. All rights reserved.
-
-  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="Theme.IOSched.Sessions" parent="Theme.IOSched.Sessions.Base">
-        <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
-        <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowContentTransitions">false</item>
-    </style>
-
-    <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
-        <item name="android:windowContentTransitions">false</item>
-        <item name="android:actionBarStyle">@style/TransparentActionBar</item>
-        <item name="android:windowBackground">@android:color/transparent</item>
-        <item name="android:windowActionBarOverlay">true</item>
-        <item name="android:homeAsUpIndicator">@drawable/ic_ab_close</item>
-    </style>
-
-</resources>
diff --git a/android/src/lpreview/res/values-v21/attrs.xml b/android/src/lpreview/res/values-v21/attrs.xml
deleted file mode 100644
index 6661e6a..0000000
--- a/android/src/lpreview/res/values-v21/attrs.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  Copyright 2014 Google Inc. All rights reserved.
-
-  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>
-    <declare-styleable name="ThemeLPreview">
-        <attr name="actionBarIconColor" format="color" />
-    </declare-styleable>
-</resources>
diff --git a/android/src/lpreview/res/values-v21/styles.xml b/android/src/lpreview/res/values-v21/styles.xml
deleted file mode 100644
index 4d00ccf..0000000
--- a/android/src/lpreview/res/values-v21/styles.xml
+++ /dev/null
@@ -1,140 +0,0 @@
-<!--
-  Copyright 2014 Google Inc. All rights reserved.
-
-  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="FrameworkRoot.Theme" parent="android:Theme.Material.Light.DarkActionBar" />
-    <style name="FrameworkRoot.ActionBar" parent="android:Widget.Material.ActionBar" />
-    <style name="FrameworkRoot.ActionBar.TitleText" parent="android:TextAppearance.Material.Widget.ActionBar.Title" />
-    <style name="FrameworkRoot.ActionBar.TabBar" parent="android:Widget.Material.ActionBar.TabBar" />
-    <style name="FrameworkRoot.EditText" parent="android:Widget.Material.Light.EditText" />
-    <style name="FrameworkRoot.Widget" parent="android:Theme.Material" />
-    <style name="FrameworkRoot.Widget.ActionButton.Overflow" parent="android:Widget.Material.ActionButton.Overflow" />
-    <style name="FrameworkRoot.Widget.Spinner" parent="android:Widget.Material.Light.Spinner" />
-    <style name="FrameworkRoot.Widget.ListView.DropDown" parent="android:Widget.Material.Light.ListView.DropDown" />
-    <style name="FrameworkRoot.Widget.PopupMenu" parent="android:Widget.Material.Light.PopupMenu" />
-    <style name="FrameworkRoot.TextAppearance.Widget.PopupMenu.Large" parent="android:TextAppearance.Material.Widget.PopupMenu.Large" />
-
-    <style name="Theme" parent="FrameworkRoot.Theme" /> <!-- doesn't contain the pre-L code from the values/styles.xml -->
-
-    <style name="Theme.IOSched" parent="Theme.IOSched.Base">
-        <item name="actionBarIconColor">#fff</item>
-        <item name="actionBarOverlayTopOffset">0dp</item> <!-- action bars replaced by Toolbars -->
-        <item name="actionBarInsetStart">@dimen/keyline_2</item>
-        <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
-        <item name="selectableItemBackgroundBorderless">?android:selectableItemBackgroundBorderless</item>
-        <item name="popupItemBackground">@drawable/popup_item_background</item>
-        <item name="photoItemForeground">@drawable/photo_item_foreground</item>
-
-        <item name="android:colorPrimary">@color/theme_primary</item>
-        <item name="android:colorPrimaryDark">@color/theme_primary_dark</item>
-        <item name="android:colorAccent">@color/theme_accent_2</item>
-        <item name="android:navigationBarColor">#000</item>
-        <item name="android:actionBarTheme">@style/ActionBarThemeOverlay</item>
-        <item name="android:homeAsUpIndicator">@drawable/ic_up</item>
-
-        <!-- used only if windowContentTransitions is true -->
-        <item name="android:windowSharedElementEnterTransition">@transition/shared_element</item>
-        <item name="android:windowSharedElementExitTransition">@transition/shared_element</item>
-        <item name="android:windowEnterTransition">@android:transition/no_transition</item>
-        <item name="android:windowExitTransition">@android:transition/no_transition</item>
-        <item name="android:windowAllowExitTransitionOverlap">true</item>
-        <item name="android:windowAllowEnterTransitionOverlap">true</item>
-    </style>
-
-    <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
-        <item name="android:actionBarStyle">@style/TransparentActionBar</item>
-        <item name="android:windowActionBarOverlay">true</item>
-        <!--<item name="android:windowContentTransitions">true</item>-->
-    </style>
-
-    <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.Sessions.Base">
-        <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-        <!--<item name="android:windowContentTransitions">true</item>-->
-    </style>
-
-    <!-- Live stream -->
-    <style name="Theme.IOSched.Livestream" parent="Theme.IOSched">
-        <item name="android:windowBackground">@color/gray_background</item>
-        <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
-    </style>
-
-    <style name="Theme.IOSched.WithElevatedHeader" parent="Theme.IOSched">
-        <item name="android:actionBarStyle">@style/ElevatedActionBar</item>
-    </style>
-
-    <style name="Theme.IOSched.MySchedule" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-    </style>
-
-    <style name="Theme.IOSched.Map" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-    </style>
-
-    <style name="Theme.IOSched.PeopleIveMet" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-    </style>
-
-    <style name="Theme.IOSched.ExpertsDirectory" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-    </style>
-
-    <style name="Theme.IOSched.Social" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowBackground">@color/gray_background</item>
-    </style>
-
-    <style name="Theme.IOSched.VideoLibrary" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowActionBarOverlay">true</item>
-    </style>
-
-    <style name="Widget.IOSched.HeaderBar.Spinner" parent="Widget.IOSched.HeaderBar.Spinner.Base">
-        <item name="android:theme">@style/ActionBarThemeOverlay</item>
-    </style>
-
-    <style name="ActionBar" parent="ActionBar.Base">
-        <item name="android:displayOptions">homeAsUp|showTitle</item>
-        <item name="android:contentInsetStart">?actionBarInsetStart</item>
-    </style>
-
-    <style name="ElevatedActionBar" parent="ActionBar">
-        <item name="android:elevation">@dimen/headerbar_elevation</item>
-    </style>
-
-    <style name="TabIndicator">
-        <item name="android:theme">@style/ActionBarThemeOverlay</item>
-    </style>
-
-    <style name="ActionBarThemeOverlay" parent="">
-        <item name="android:textColorPrimary">#fff</item>
-        <item name="android:colorControlNormal">?actionBarIconColor</item>
-        <item name="android:colorControlHighlight">#3fff</item>
-    </style>
-
-    <style name="HeaderBar">
-        <item name="android:elevation">@dimen/headerbar_elevation</item>
-        <item name="android:background">?android:colorPrimary</item>
-    </style>
-</resources>
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 6c1bd36..beb8708 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -22,10 +22,9 @@
     android:versionName="2.2.3"
     android:installLocation="auto">
 
-    <!-- targetSdkVersion set to 19 from build.gradle on non-L-preview builds -->
     <uses-sdk
         android:minSdkVersion="14"
-        android:targetSdkVersion="L" />
+        android:targetSdkVersion="21" />
 
     <permission
         android:name="com.google.samples.apps.iosched.permission.WRITE_SCHEDULE"
@@ -80,7 +79,7 @@
 
     <application
         android:label="@string/app_name"
-        android:icon="@drawable/ic_launcher"
+        android:icon="@mipmap/ic_launcher"
         android:logo="@drawable/actionbar_logo"
         android:theme="@style/Theme.IOSched"
         android:hardwareAccelerated="true"
@@ -124,7 +123,6 @@
         <activity
             android:name=".ui.SettingsActivity"
             android:label="@string/title_settings"
-            android:theme="@style/Theme.IOSched.WithElevatedHeader"
             android:parentActivityName=".ui.MyScheduleActivity" />
 
         <activity
@@ -170,8 +168,7 @@
         </activity>
 
         <activity android:name=".ui.SessionFeedbackActivity"
-            android:label="@string/title_session_feedback"
-            android:theme="@style/Theme.IOSched.WithElevatedHeader">
+            android:label="@string/title_session_feedback">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -262,7 +259,7 @@
 
         <!-- People I've Met -->
         <activity android:name=".ui.PeopleIveMetActivity"
-            android:label="@string/app_name"
+            android:label="@string/title_people_ive_met"
             android:theme="@style/Theme.IOSched.PeopleIveMet"/>
 
 	    <!-- Session alarm/calendar integrating components. -->
@@ -367,9 +364,6 @@
             <intent-filter>
                 <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
             </intent-filter>
-            <intent-filter>
-                <action android:name="com.google.sample.apps.iosched.ACTION_NOTIFICATION_DISMISSAL"/>
-            </intent-filter>
         </service>
 
     </application>
diff --git a/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java b/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java
index f928e6d..2340454 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 
 /**
- * @author trevorjohns@google.com (Trevor Johns)
  */
 public class GCMRedirectedBroadcastReceiver extends GCMBroadcastReceiver {
 
diff --git a/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java b/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java
index 948e97f..91a5af1 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java
@@ -16,7 +16,11 @@
 
 package com.google.samples.apps.iosched.service;
 
-import android.app.*;
+import android.app.AlarmManager;
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -37,20 +41,21 @@
 import com.google.android.gms.wearable.Wearable;
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
 import com.google.samples.apps.iosched.ui.BrowseSessionsActivity;
-import com.google.samples.apps.iosched.ui.MapFragment;
 import com.google.samples.apps.iosched.ui.MyScheduleActivity;
 import com.google.samples.apps.iosched.ui.SessionFeedbackActivity;
-import com.google.samples.apps.iosched.ui.phone.MapActivity;
 import com.google.samples.apps.iosched.util.FeedbackUtils;
 import com.google.samples.apps.iosched.util.PrefUtils;
 import com.google.samples.apps.iosched.util.UIUtils;
 
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
 import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
 /**
@@ -140,6 +145,10 @@
             scheduleAllStarredBlocks();
             scheduleAllStarredSessionFeedbacks();
             return;
+        } else if (ACTION_NOTIFY_SESSION_FEEDBACK.equals(action)) {
+            LOGD(TAG, "Showing session feedback notification.");
+            notifySessionFeedback(DEBUG_SESSION_ID.equals(intent.getStringExtra(EXTRA_SESSION_ID)));
+            return;
         }
 
         final long sessionEnd = intent.getLongExtra(SessionAlarmService.EXTRA_SESSION_END,
@@ -155,30 +164,17 @@
         LOGD(TAG, "Session alarm offset is: " + sessionAlarmOffset);
 
         // Feedback notifications have a slightly different set of extras.
-        if (ACTION_SCHEDULE_FEEDBACK_NOTIFICATION.equals(action) ||
-                ACTION_NOTIFY_SESSION_FEEDBACK.equals(action)) {
+        if (ACTION_SCHEDULE_FEEDBACK_NOTIFICATION.equals(action)) {
             final String sessionId = intent.getStringExtra(SessionAlarmService.EXTRA_SESSION_ID);
             final String sessionTitle = intent.getStringExtra(
                     SessionAlarmService.EXTRA_SESSION_TITLE);
-            final String sessionRoom = intent.getStringExtra(
-                    SessionAlarmService.EXTRA_SESSION_ROOM);
-            final String sessionSpeakers = intent.getStringExtra(
-                    SessionAlarmService.EXTRA_SESSION_SPEAKERS);
             if (sessionTitle == null || sessionEnd == UNDEFINED_VALUE ||
                     sessionId == null) {
-                Log.e(TAG,
-                        "Attempted to schedule or notify for feedback without providing extras.");
+                LOGE(TAG, "Attempted to schedule for feedback without providing extras.");
                 return;
             }
-            if (ACTION_SCHEDULE_FEEDBACK_NOTIFICATION.equals(action)) {
-                LOGD(TAG, "Scheduling feedback alarm for session: " + sessionTitle);
-                scheduleFeedbackAlarm(sessionId, sessionEnd, sessionAlarmOffset, sessionTitle,
-                        sessionRoom, sessionSpeakers);
-            } else {
-                LOGD(TAG, "Notifying for feedback on session: " + sessionTitle);
-                notifySessionFeedback(sessionId, sessionEnd, sessionTitle, sessionRoom,
-                        sessionSpeakers);
-            }
+            LOGD(TAG, "Scheduling feedback alarm for session: " + sessionTitle);
+            scheduleFeedbackAlarm(sessionEnd, sessionAlarmOffset, sessionTitle);
             return;
         }
 
@@ -204,9 +200,8 @@
         }
     }
 
-    public void scheduleFeedbackAlarm(final String sessionId, final long sessionEnd,
-            final long alarmOffset, final String sessionTitle, String sessionRoom,
-            String sessionSpeakers) {
+    public void scheduleFeedbackAlarm(final long sessionEnd,
+            final long alarmOffset, final String sessionTitle) {
         // By default, feedback alarms fire 5 minutes before session end time. If alarm offset is
         // provided, alarm is set to go off that much time from now (useful for testing).
         long alarmTime;
@@ -219,24 +214,12 @@
         LOGD(TAG, "Scheduling session feedback alarm for session '" + sessionTitle + "'");
         LOGD(TAG, "  -> end time: " + sessionEnd + " = " + (new Date(sessionEnd)).toString());
         LOGD(TAG, "  -> alarm time: " + alarmTime + " = " + (new Date(alarmTime)).toString());
-        LOGD(TAG, "  -> room name: " + sessionRoom);
-        LOGD(TAG, "  -> speakers: " + sessionSpeakers);
 
         final Intent feedbackIntent = new Intent(
                 ACTION_NOTIFY_SESSION_FEEDBACK,
                 null,
                 this,
                 SessionAlarmService.class);
-        feedbackIntent.setData(
-                new Uri.Builder().authority("com.google.samples.apps.iosched")
-                        .path(sessionId).build()
-        );
-        feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, sessionEnd);
-        feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ALARM_OFFSET, alarmOffset);
-        feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ID, sessionId);
-        feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_TITLE, sessionTitle);
-        feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_SPEAKERS, sessionSpeakers);
-        feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ROOM, sessionRoom);
         PendingIntent pi = PendingIntent.getService(
                 this, 1, feedbackIntent, PendingIntent.FLAG_CANCEL_CURRENT);
         final AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
@@ -296,84 +279,116 @@
     // A starred session is about to end; notify the user to provide session feedback.
     // Constructs and triggers a system notification. Does nothing if the session has already
     // concluded.
-    private void notifySessionFeedback(final String sessionId, final long sessionEnd,
-            final String sessionTitle, final String sessionRoom, final String sessionSpeakers) {
-        LOGD(TAG, "Considering firing notification for feedback for session: " + sessionTitle);
-        boolean isDebug = DEBUG_SESSION_ID.equals(sessionId);
+    private void notifySessionFeedback(boolean debug) {
+        LOGD(TAG, "Considering firing notification for session feedback.");
 
-        if (isDebug) {
+        if (debug) {
             LOGD(TAG, "Note: this is a debug notification.");
         }
 
         // Don't fire notification if this feature is disabled in settings
         if (!PrefUtils.shouldShowSessionFeedbackReminders(this)) {
-            LOGD(TAG, "Skipping session feedback notification for session " + sessionId + " ("
-                    + sessionTitle + "). Disabled in settings.");
+            LOGD(TAG, "Skipping session feedback notification. Disabled in settings.");
             return;
         }
 
-        // Avoid repeated notifications.
-        if (!isDebug && UIUtils.isFeedbackNotificationFiredForSession(this, sessionId)) {
-            LOGD(TAG, "Skipping repeated session feedback notification for session '"
-                    + sessionTitle + "'");
-            return;
-        }
-
-        // If the session is no longer is MY_SCHEDULE, don't notify for it.
-        final Uri myScheduleUri = ScheduleContract.MySchedule.buildMyScheduleUri(this);
         final Cursor c = getContentResolver().query(
-                myScheduleUri, MySessionsExistenceQuery.PROJECTION,
-                MySessionsExistenceQuery.WHERE_CLAUSE, new String[]{sessionId}, null);
-        if (!isDebug && (c == null || !c.moveToFirst())) {
-            // no longer in MY_SCHEDULE
+                ScheduleContract.Sessions.CONTENT_MY_SCHEDULE_URI,
+                SessionsNeedingFeedbackQuery.PROJECTION,
+                SessionsNeedingFeedbackQuery.WHERE_CLAUSE, null, null);
+        if (c == null) {
             return;
         }
 
-        LOGD(TAG, "Going forward with session feedback notification for: " + sessionTitle);
-        final Uri sessionUri = ScheduleContract.Sessions.buildSessionUri(sessionId);
+        List<String> needFeedbackIds = new ArrayList<String>();
+        List<String> needFeedbackTitles = new ArrayList<String>();
+        while (c.moveToNext()) {
+            String sessionId = c.getString(SessionsNeedingFeedbackQuery.SESSION_ID);
+            String sessionTitle = c.getString(SessionsNeedingFeedbackQuery.SESSION_TITLE);
+
+            // Avoid repeated notifications.
+            if (UIUtils.isFeedbackNotificationFiredForSession(this, sessionId)) {
+                LOGD(TAG, "Skipping repeated session feedback notification for session '"
+                        + sessionTitle + "'");
+                continue;
+            }
+
+            needFeedbackIds.add(sessionId);
+            needFeedbackTitles.add(sessionTitle);
+        }
+
+        if (needFeedbackIds.size() == 0) {
+            // the user has already been notified of all sessions needing feedback
+            return;
+        }
+
+        LOGD(TAG, "Going forward with session feedback notification for "
+                + needFeedbackIds.size() + " session(s).");
 
         final Resources res = getResources();
-        String contentText = res.getString(R.string.session_feedback_notification_text,
-                sessionTitle);
-
-        PendingIntent pi = TaskStackBuilder.create(this)
-                .addNextIntent(new Intent(this, MyScheduleActivity.class))
-                .addNextIntent(new Intent(Intent.ACTION_VIEW, sessionUri, this,
-                        SessionFeedbackActivity.class))
-                .getPendingIntent(1, PendingIntent.FLAG_CANCEL_CURRENT);
 
         // this is used to synchronize deletion of notifications on phone and wear
         Intent dismissalIntent = new Intent(ACTION_NOTIFICATION_DISMISSAL);
-        dismissalIntent.putExtra(KEY_SESSION_ID, sessionId);
+        // TODO: fix Wear dismiss integration
+        //dismissalIntent.putExtra(KEY_SESSION_ID, sessionId);
         PendingIntent dismissalPendingIntent = PendingIntent
                 .getService(this, (int) new Date().getTime(), dismissalIntent,
                         PendingIntent.FLAG_UPDATE_CURRENT);
 
+        String provideFeedbackTicker = res.getString(R.string.session_feedback_notification_ticker);
         NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(this)
-                .setContentTitle(sessionTitle)
-                .setContentText(contentText)
-                //.setColor(getResources().getColor(R.color.theme_primary))
-                            // Note: setColor() is available in the support lib v21+.
-                            // We commented it out because we want the source to compile 
-                            // against support lib v20. If you are using support lib
-                            // v21 or above on Android L, uncomment this line.
-                .setTicker(res.getString(R.string.session_feedback_notification_ticker))
-                .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
+                .setColor(getResources().getColor(R.color.theme_primary))
+                .setContentText(provideFeedbackTicker)
+                .setTicker(provideFeedbackTicker)
                 .setLights(
                         SessionAlarmService.NOTIFICATION_ARGB_COLOR,
                         SessionAlarmService.NOTIFICATION_LED_ON_MS,
                         SessionAlarmService.NOTIFICATION_LED_OFF_MS)
                 .setSmallIcon(R.drawable.ic_stat_notification)
-                .setContentIntent(pi)
-                .setPriority(Notification.PRIORITY_MAX)
+                .setPriority(Notification.PRIORITY_LOW)
                 .setLocalOnly(true) // make it local to the phone
+                .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
                 .setDeleteIntent(dismissalPendingIntent)
                 .setAutoCancel(true);
+
+        if (needFeedbackIds.size() == 1) {
+            // Only 1 session needs feedback
+            Uri sessionUri = ScheduleContract.Sessions.buildSessionUri(needFeedbackIds.get(0));
+            PendingIntent pi = TaskStackBuilder.create(this)
+                    .addNextIntent(new Intent(this, MyScheduleActivity.class))
+                    .addNextIntent(new Intent(Intent.ACTION_VIEW, sessionUri, this,
+                            SessionFeedbackActivity.class))
+                    .getPendingIntent(1, PendingIntent.FLAG_CANCEL_CURRENT);
+
+            notifBuilder.setContentTitle(needFeedbackTitles.get(0))
+                    .setContentIntent(pi);
+        } else {
+            // Show information about several sessions that need feedback
+            PendingIntent pi = TaskStackBuilder.create(this)
+                    .addNextIntent(new Intent(this, MyScheduleActivity.class))
+                    .getPendingIntent(1, PendingIntent.FLAG_CANCEL_CURRENT);
+
+            NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
+            inboxStyle.setBigContentTitle(provideFeedbackTicker);
+            for (String title : needFeedbackTitles) {
+                inboxStyle.addLine(title);
+            }
+
+            notifBuilder.setContentTitle(
+                    getResources().getQuantityString(R.plurals.session_plurals,
+                            needFeedbackIds.size(), needFeedbackIds.size()))
+                    .setStyle(inboxStyle)
+                    .setContentIntent(pi);
+        }
+
         NotificationManager nm = (NotificationManager) getSystemService(
                 Context.NOTIFICATION_SERVICE);
         LOGD(TAG, "Now showing session feedback notification!");
-        nm.notify(sessionId, FEEDBACK_NOTIFICATION_ID, notifBuilder.build());
-        setupNotificationOnWear(sessionId, sessionRoom, sessionTitle, sessionSpeakers);
+        nm.notify(FEEDBACK_NOTIFICATION_ID, notifBuilder.build());
+
+        for (int i = 0; i < needFeedbackIds.size(); i++) {
+            setupNotificationOnWear(needFeedbackIds.get(i), null, needFeedbackTitles.get(i), null);
+        }
     }
 
     /**
@@ -494,11 +509,7 @@
         NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(this)
                 .setContentTitle(starredSessionTitles.get(0))
                 .setContentText(contentText)
-                //.setColor(getResources().getColor(R.color.theme_primary))
-                            // Note: setColor() is available in the support lib v21+.
-                            // We commented it out because we want the source to compile 
-                            // against support lib v20. If you are using support lib
-                            // v21 or above on Android L, uncomment this line.
+                .setColor(getResources().getColor(R.color.theme_primary))
                 .setTicker(res.getQuantityString(R.plurals.session_notification_ticker,
                         starredCount,
                         starredCount))
@@ -560,8 +571,8 @@
     private PendingIntent createRoomMapIntent(final String roomId) {
         Intent mapIntent = new Intent(getApplicationContext(),
                 UIUtils.getMapActivityClass(getApplicationContext()));
-        mapIntent.putExtra(MapFragment.EXTRA_ROOM, roomId);
-        mapIntent.putExtra(MapActivity.EXTRA_DETACHED_MODE, true);
+        mapIntent.putExtra(BaseMapActivity.EXTRA_ROOM, roomId);
+        mapIntent.putExtra(BaseMapActivity.EXTRA_DETACHED_MODE, true);
         return TaskStackBuilder
                 .create(getApplicationContext())
                 .addNextIntent(new Intent(this, BrowseSessionsActivity.class))
@@ -596,12 +607,9 @@
         // TODO: Should we also check that SESSION_IN_MY_SCHEDULE is true?
         final Cursor c = cr.query(ScheduleContract.Sessions.CONTENT_MY_SCHEDULE_URI,
                 new String[]{
-                        ScheduleContract.Sessions.SESSION_ID,
                         ScheduleContract.Sessions.SESSION_TITLE,
                         ScheduleContract.Sessions.SESSION_END,
                         ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
-                        ScheduleContract.Sessions.ROOM_NAME,
-                        ScheduleContract.Sessions.SESSION_SPEAKER_NAMES,
                 },
                 null,
                 null,
@@ -611,13 +619,9 @@
             return;
         }
         while (c.moveToNext()) {
-            final String sessionId = c.getString(0);
-            final String sessionTitle = c.getString(1);
-            final long sessionEnd = c.getLong(2);
-            final String sessionRoom = c.getString(3);
-            final String sessionSpeakers = c.getString(4);
-            scheduleFeedbackAlarm(sessionId, sessionEnd, UNDEFINED_ALARM_OFFSET, sessionTitle,
-                    sessionRoom, sessionSpeakers);
+            final String sessionTitle = c.getString(0);
+            final long sessionEnd = c.getLong(1);
+            scheduleFeedbackAlarm(sessionEnd, UNDEFINED_ALARM_OFFSET, sessionTitle);
         }
     }
 
@@ -635,16 +639,19 @@
         int ROOM_ID = 2;
     }
 
-    public interface MySessionsExistenceQuery {
-
+    public interface SessionsNeedingFeedbackQuery {
         String[] PROJECTION = {
-                ScheduleContract.MySchedule.SESSION_ID
+                ScheduleContract.Sessions.SESSION_ID,
+                ScheduleContract.Sessions.SESSION_TITLE,
+                ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
+                ScheduleContract.Sessions.HAS_GIVEN_FEEDBACK,
         };
 
         int SESSION_ID = 0;
+        int SESSION_TITLE = 1;
 
         public static final String WHERE_CLAUSE =
-                ScheduleContract.MySchedule.SESSION_ID + "=?";
+                ScheduleContract.Sessions.HAS_GIVEN_FEEDBACK + "=0";
     }
 
     @Override
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
index 681503c..ea4f2b8 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
@@ -18,28 +18,50 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.animation.*;
-import android.app.ActionBar;
-import android.app.Activity;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
 import android.app.AlertDialog;
-import android.content.*;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SyncStatusObserver;
 import android.content.pm.PackageManager;
-import android.content.res.Configuration;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.support.v4.view.ViewCompat;
 import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.Toolbar;
 import android.text.TextUtils;
-import android.view.*;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.DecelerateInterpolator;
-import android.widget.*;
+import android.widget.AbsListView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
 
 import com.google.android.gcm.GCMRegistrar;
 import com.google.android.gms.auth.GoogleAuthUtil;
@@ -53,21 +75,36 @@
 import com.google.samples.apps.iosched.sync.SyncHelper;
 import com.google.samples.apps.iosched.ui.debug.DebugActionRunnerActivity;
 import com.google.samples.apps.iosched.ui.widget.MultiSwipeRefreshLayout;
+import com.google.samples.apps.iosched.ui.widget.ScrimInsetsScrollView;
 import com.google.samples.apps.iosched.ui.widget.SwipeRefreshLayout;
-import com.google.samples.apps.iosched.util.*;
+import com.google.samples.apps.iosched.util.AccountUtils;
+import com.google.samples.apps.iosched.util.AnalyticsManager;
+import com.google.samples.apps.iosched.util.HelpUtils;
+import com.google.samples.apps.iosched.util.ImageLoader;
+import com.google.samples.apps.iosched.util.LUtils;
+import com.google.samples.apps.iosched.util.LoginAndAuthHelper;
+import com.google.samples.apps.iosched.util.PlayServicesUtils;
+import com.google.samples.apps.iosched.util.PrefUtils;
+import com.google.samples.apps.iosched.util.RecentTasksStyler;
+import com.google.samples.apps.iosched.util.UIUtils;
+import com.google.samples.apps.iosched.util.WiFiUtils;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGI;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
 /**
  * A base activity that handles common functionality in the app. This includes the
  * navigation drawer, login and authentication, Action Bar tweaks, amongst others.
  */
-public abstract class BaseActivity extends Activity implements
+public abstract class BaseActivity extends ActionBarActivity implements
         LoginAndAuthHelper.Callbacks,
         SharedPreferences.OnSharedPreferenceChangeListener,
         MultiSwipeRefreshLayout.CanChildScrollUpCallback {
@@ -78,11 +115,9 @@
 
     // Navigation drawer:
     private DrawerLayout mDrawerLayout;
-    private LPreviewUtilsBase.ActionBarDrawerToggleWrapper mDrawerToggle;
 
-    // allows access to L-Preview APIs through an abstract interface so we can compile with
-    // both the L Preview SDK and with the API 19 SDK
-    private LPreviewUtilsBase mLPreviewUtils;
+    // Helper methods for L APIs
+    private LUtils mLUtils;
 
     private ObjectAnimator mStatusBarColorAnimator;
     private LinearLayout mAccountListContainer;
@@ -160,6 +195,9 @@
     // SwipeRefreshLayout allows the user to swipe the screen down to trigger a manual refresh
     private SwipeRefreshLayout mSwipeRefreshLayout;
 
+    // Primary toolbar and drawer toggle
+    private Toolbar mActionBarToolbar;
+
     // asynctask that performs GCM registration in the backgorund
     private AsyncTask<Void, Void, Void> mGCMRegisterTask;
 
@@ -183,6 +221,7 @@
     private boolean mManualSyncRequest;
 
     private int mThemedStatusBarColor;
+    private int mNormalStatusBarColor;
     private int mProgressBarTopWhenActionBarShown;
     private static final TypeEvaluator ARGB_EVALUATOR = new ArgbEvaluator();
     private ImageLoader mImageLoader;
@@ -191,6 +230,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         AnalyticsManager.initializeAnalyticsTracker(getApplicationContext());
+        RecentTasksStyler.styleRecentTasksEntry(this);
 
         PrefUtils.init(this);
 
@@ -217,13 +257,14 @@
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
         sp.registerOnSharedPreferenceChangeListener(this);
 
-        ActionBar ab = getActionBar();
+        ActionBar ab = getSupportActionBar();
         if (ab != null) {
             ab.setDisplayHomeAsUpEnabled(true);
         }
 
-        mLPreviewUtils = LPreviewUtils.getInstance(this);
+        mLUtils = LUtils.getInstance(this);
         mThemedStatusBarColor = getResources().getColor(R.color.theme_primary_dark);
+        mNormalStatusBarColor = mThemedStatusBarColor;
     }
 
     private void trySetupSwipeRefresh() {
@@ -287,9 +328,12 @@
         if (mDrawerLayout == null) {
             return;
         }
+        mDrawerLayout.setStatusBarBackgroundColor(
+                getResources().getColor(R.color.theme_primary_dark));
+        ScrimInsetsScrollView navDrawer = (ScrimInsetsScrollView)
+                mDrawerLayout.findViewById(R.id.navdrawer);
         if (selfItem == NAVDRAWER_ITEM_INVALID) {
             // do not show a nav drawer
-            View navDrawer = mDrawerLayout.findViewById(R.id.navdrawer);
             if (navDrawer != null) {
                 ((ViewGroup) navDrawer.getParent()).removeView(navDrawer);
             }
@@ -297,7 +341,37 @@
             return;
         }
 
-        mDrawerToggle = mLPreviewUtils.setupDrawerToggle(mDrawerLayout, new DrawerLayout.DrawerListener() {
+        if (navDrawer != null) {
+            final View chosenAccountContentView = findViewById(R.id.chosen_account_content_view);
+            final View chosenAccountView = findViewById(R.id.chosen_account_view);
+            final int navDrawerChosenAccountHeight = getResources().getDimensionPixelSize(
+                    R.dimen.navdrawer_chosen_account_height);
+            navDrawer.setOnInsetsCallback(new ScrimInsetsScrollView.OnInsetsCallback() {
+                @Override
+                public void onInsetsChanged(Rect insets) {
+                    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
+                            chosenAccountContentView.getLayoutParams();
+                    lp.topMargin = insets.top;
+                    chosenAccountContentView.setLayoutParams(lp);
+
+                    ViewGroup.LayoutParams lp2 = chosenAccountView.getLayoutParams();
+                    lp2.height = navDrawerChosenAccountHeight + insets.top;
+                    chosenAccountView.setLayoutParams(lp2);
+                }
+            });
+        }
+
+        if (mActionBarToolbar != null) {
+            mActionBarToolbar.setNavigationIcon(R.drawable.ic_drawer);
+            mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    mDrawerLayout.openDrawer(Gravity.START);
+                }
+            });
+        }
+
+        mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
             @Override
             public void onDrawerClosed(View drawerView) {
                 // run deferred action, if we have one
@@ -309,40 +383,30 @@
                     mAccountBoxExpanded = false;
                     setupAccountBoxToggle();
                 }
-                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
-                updateStatusBarForNavDrawerSlide(0f);
                 onNavDrawerStateChanged(false, false);
             }
 
             @Override
             public void onDrawerOpened(View drawerView) {
-                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
-                updateStatusBarForNavDrawerSlide(1f);
                 onNavDrawerStateChanged(true, false);
             }
 
             @Override
             public void onDrawerStateChanged(int newState) {
-                invalidateOptionsMenu();
                 onNavDrawerStateChanged(isNavDrawerOpen(), newState != DrawerLayout.STATE_IDLE);
             }
 
             @Override
             public void onDrawerSlide(View drawerView, float slideOffset) {
-                updateStatusBarForNavDrawerSlide(slideOffset);
                 onNavDrawerSlide(slideOffset);
             }
         });
-        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
 
-        getActionBar().setDisplayHomeAsUpEnabled(true);
-        getActionBar().setHomeButtonEnabled(true);
+        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
 
         // populate the nav drawer with the correct items
         populateNavDrawer();
 
-        mDrawerToggle.syncState();
-
         // When the user runs the app for the first time, we want to land them with the
         // navigation drawer open. But just the first time.
         if (!PrefUtils.isWelcomeDone(this)) {
@@ -352,6 +416,12 @@
         }
     }
 
+    @Override
+    public void setContentView(int layoutResID) {
+        super.setContentView(layoutResID);
+        getActionBarToolbar();
+    }
+
     // Subclasses can override this for custom behavior
     protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
         if (mActionBarAutoHideEnabled && isOpen) {
@@ -507,6 +577,7 @@
         if (name == null) {
             nameTextView.setVisibility(View.GONE);
         } else {
+            nameTextView.setVisibility(View.VISIBLE);
             nameTextView.setText(name);
         }
 
@@ -557,6 +628,11 @@
             ((TextView) itemView.findViewById(R.id.profile_email_text))
                     .setText(account.name);
             final String accountName = account.name;
+            String imageUrl = AccountUtils.getPlusImageUrl(this, accountName);
+            if (!TextUtils.isEmpty(imageUrl)) {
+                mImageLoader.loadImage(imageUrl,
+                        (ImageView) itemView.findViewById(R.id.profile_image));
+            }
             itemView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View view) {
@@ -654,25 +730,8 @@
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        if (mDrawerToggle != null) {
-            mDrawerToggle.onConfigurationChanged(newConfig);
-        }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         int id = item.getItemId();
-        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
-            return true;
-        }
-
         switch (id) {
             case R.id.menu_about:
                 HelpUtils.showAbout(this);
@@ -1185,13 +1244,22 @@
         autoShowOrHideActionBar(shouldShow);
     }
 
+    protected Toolbar getActionBarToolbar() {
+        if (mActionBarToolbar == null) {
+            mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
+            if (mActionBarToolbar != null) {
+                setSupportActionBar(mActionBarToolbar);
+            }
+        }
+        return mActionBarToolbar;
+    }
+
     protected void autoShowOrHideActionBar(boolean show) {
         if (show == mActionBarShown) {
             return;
         }
 
         mActionBarShown = show;
-        getLPreviewUtils().showHideActionBarIfPartOfDecor(show);
         onActionBarAutoShowOrHide(show);
     }
 
@@ -1413,30 +1481,39 @@
         }
     }
 
-    public LPreviewUtilsBase getLPreviewUtils() {
-        return mLPreviewUtils;
+    public LUtils getLUtils() {
+        return mLUtils;
     }
 
-    private void updateStatusBarForNavDrawerSlide(float slideOffset) {
-        if (mStatusBarColorAnimator != null) {
-            mStatusBarColorAnimator.cancel();
-        }
+    public int getThemedStatusBarColor() {
+        return mThemedStatusBarColor;
+    }
 
-        if (!mActionBarShown) {
-            mLPreviewUtils.setStatusBarColor(Color.BLACK);
-            return;
+    public void setNormalStatusBarColor(int color) {
+        mNormalStatusBarColor = color;
+        if (mDrawerLayout != null) {
+            mDrawerLayout.setStatusBarBackgroundColor(mNormalStatusBarColor);
         }
-
-        mLPreviewUtils.setStatusBarColor((Integer) ARGB_EVALUATOR.evaluate(slideOffset,
-                mThemedStatusBarColor, Color.BLACK));
     }
 
     protected void onActionBarAutoShowOrHide(boolean shown) {
         if (mStatusBarColorAnimator != null) {
             mStatusBarColorAnimator.cancel();
         }
-        mStatusBarColorAnimator = ObjectAnimator.ofInt(mLPreviewUtils, "statusBarColor",
-                shown ? mThemedStatusBarColor : Color.BLACK).setDuration(250);
+        mStatusBarColorAnimator = ObjectAnimator.ofInt(
+                (mDrawerLayout != null) ? mDrawerLayout : mLUtils,
+                (mDrawerLayout != null) ? "statusBarBackgroundColor" : "statusBarColor",
+                shown ? Color.BLACK : mNormalStatusBarColor,
+                shown ? mNormalStatusBarColor : Color.BLACK)
+                .setDuration(250);
+        if (mDrawerLayout != null) {
+            mStatusBarColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                    ViewCompat.postInvalidateOnAnimation(mDrawerLayout);
+                }
+            });
+        }
         mStatusBarColorAnimator.setEvaluator(ARGB_EVALUATOR);
         mStatusBarColorAnimator.start();
 
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseMapActivity.java
similarity index 70%
rename from android/src/main/java/com/google/samples/apps/iosched/ui/NearbyActivity.java
rename to android/src/main/java/com/google/samples/apps/iosched/ui/BaseMapActivity.java
index 7affcc6..89edd17 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseMapActivity.java
@@ -25,16 +25,20 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.database.DataSetObserver;
+import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
+import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.Button;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.nearby.MetadataResolver;
 import com.google.samples.apps.iosched.nearby.NearbyDeviceManager;
+import com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout;
 import com.google.samples.apps.iosched.util.PrefUtils;
 
 import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
@@ -47,16 +51,27 @@
  *
  * This activity requires API level 18 because it utilizes BLE.
  */
-public abstract class NearbyActivity extends BaseActivity implements NearbyFragment.Callbacks {
-    private static final String TAG = makeLogTag(NearbyActivity.class);
+public abstract class BaseMapActivity extends BaseActivity implements NearbyFragment.Callbacks, ScrimInsetsFrameLayout.OnInsetsCallback {
+    private static final String TAG = makeLogTag(BaseMapActivity.class);
     private static final int REQUEST_ENABLE_BT = 500;
     private static final int REQUEST_ENABLE_NEARBY = 501;
     protected static final String NEARBY_FRAGMENT_TAG = "NEARBY_FRAGMENT";
 
+    /**
+     * When specified, will automatically point the map to the requested room.
+     */
+    public static final String EXTRA_ROOM = "com.google.android.iosched.extra.ROOM";
+
+    public static final String EXTRA_DETACHED_MODE
+            = "com.google.samples.apps.iosched.EXTRA_DETACHED_MODE";
+
     private boolean mNearbyCapable = false;
     private boolean mShouldShowNearbyFragment = false;
     private NearbyDeviceManager mDeviceManager;
     private Button mNearbyButton;
+    private boolean mDetachedMode;
+
+    protected MapFragment mMapFragment;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -66,6 +81,58 @@
                 && PrefUtils.isAttendeeAtVenue(this)) {
             mNearbyCapable = initNearby();
         }
+
+        FragmentManager fm = getFragmentManager();
+        mMapFragment = (MapFragment) fm.findFragmentByTag("map");
+
+        mDetachedMode = getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false);
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        if (mDetachedMode) {
+            final Toolbar toolbar = getActionBarToolbar();
+            toolbar.setNavigationIcon(R.drawable.ic_up);
+            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    finish();
+                }
+            });
+        }
+
+        if (mMapFragment == null) {
+            mMapFragment = MapFragment.newInstance();
+            mMapFragment.setArguments(intentToFragmentArguments(getIntent()));
+            getFragmentManager().beginTransaction()
+                    .add(R.id.fragment_container_map, mMapFragment, "map")
+                    .commit();
+        }
+
+        mDetachedMode = getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false);
+
+        ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
+                findViewById(R.id.capture_insets_frame_layout);
+        scrimInsetsFrameLayout.setOnInsetsCallback(this);
+    }
+
+    @Override
+    public void onInsetsChanged(Rect insets) {
+        Toolbar toolbar = getActionBarToolbar();
+        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
+                toolbar.getLayoutParams();
+        lp.topMargin = insets.top;
+        int top = insets.top;
+        insets.top += getActionBarToolbar().getHeight();
+        toolbar.setLayoutParams(lp);
+        mMapFragment.setMapInsets(insets);
+        insets.top = top; // revert
+    }
+
+    @Override
+    protected int getSelfNavDrawerItem() {
+        return mDetachedMode ? NAVDRAWER_ITEM_INVALID : NAVDRAWER_ITEM_MAP;
     }
 
     @Override
@@ -120,6 +187,15 @@
         return super.onCreateOptionsMenu(menu);
     }
 
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false)
+                && item.getItemId() == android.R.id.home) {
+            finish();
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
     protected abstract void showNearbyFragment(String tag);
 
     // Handles a click on the Nearby menu item. Recognizes several states:
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java
index adb7647..b687c82 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java
@@ -16,14 +16,19 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import android.app.ActionBar;
 import android.content.Intent;
 import android.graphics.Paint;
 import android.graphics.drawable.ShapeDrawable;
 import android.graphics.drawable.shapes.OvalShape;
 import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
 import android.text.TextUtils;
-import android.view.*;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.Spinner;
@@ -78,20 +83,20 @@
 
     // time when the user last clicked "refresh" from the stale data butter bar
     private long mLastDataStaleUserActionTime = 0L;
+    private int mHeaderColor = 0; // 0 means not customized
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.activity_browse_sessions);
-        getLPreviewUtils().trySetActionBar();
 
-        ActionBar ab = getActionBar();
+        Toolbar toolbar = getActionBarToolbar();
 
         long[] interval = ScheduleContract.Sessions.getInterval(getIntent().getData());
         if (interval != null) {
             String title = UIUtils.formatIntervalTimeString(interval[0], interval[1], null, this);
-            ab.setTitle(title);
+            toolbar.setTitle(title);
             mMode = MODE_TIME_FIT;
             /* [ANALYTICS:SCREEN]
              * TRIGGER:   View the Explore screen to find sessions fitting a time slot
@@ -121,8 +126,7 @@
         if (mMode == MODE_EXPLORE) {
             // no title (to make more room for navigation and actions)
             // unless Nav Drawer opens
-            ab.setTitle(getString(R.string.app_name));
-            ab.setDisplayShowTitleEnabled(false);
+            toolbar.setTitle(null);
         }
 
         mButterBar = findViewById(R.id.butter_bar);
@@ -201,12 +205,6 @@
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
-        updateActionBarNavigation();
-    }
-
-    @Override
     public void onTagMetadataLoaded(TagMetadata metadata) {
         mTagMetadata = metadata;
         if (mSpinnerConfigured) {
@@ -221,8 +219,8 @@
     }
 
     private void trySetUpActionBarSpinner() {
-        ActionBar ab = getActionBar();
-        if (mMode != MODE_EXPLORE || mSpinnerConfigured || mTagMetadata == null || ab == null) {
+        Toolbar toolbar = getActionBarToolbar();
+        if (mMode != MODE_EXPLORE || mSpinnerConfigured || mTagMetadata == null || toolbar == null) {
             // already done it, or not ready yet, or don't need to do
             LOGD(TAG, "Not configuring Action Bar spinner.");
             return;
@@ -246,8 +244,8 @@
                 mTopLevelSpinnerAdapter.addHeader(categoryTitle);
                 for (TagMetadata.Tag tag : mTagMetadata.getTagsInCategory(category)) {
                     LOGD(TAG, "Adding item to spinner: " + tag.getId() + " --> " + tag.getName());
-                    mTopLevelSpinnerAdapter.addItem(tag.getId(), tag.getName(), true,
-                            Config.Tags.CATEGORY_TOPIC.equals(category) ? tag.getColor() : 0);
+                    int tagColor = Config.Tags.CATEGORY_TOPIC.equals(category) ? tag.getColor() : 0;
+                    mTopLevelSpinnerAdapter.addItem(tag.getId(), tag.getName(), true, tagColor);
                     if (!TextUtils.isEmpty(mFilterTagsToRestore[0]) && tag.getId().equals(mFilterTagsToRestore[0])) {
                         mFilterTagsToRestore[0] = null;
                         itemToSelect = mTopLevelSpinnerAdapter.getCount() - 1;
@@ -259,11 +257,11 @@
         }
         mFilterTagsToRestore[0] = null;
 
-        View spinnerContainer = LayoutInflater.from(getActionBar().getThemedContext())
-                .inflate(R.layout.actionbar_spinner, null);
+        View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.actionbar_spinner,
+                toolbar, false);
         ActionBar.LayoutParams lp = new ActionBar.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-        ab.setCustomView(spinnerContainer, lp);
+        toolbar.addView(spinnerContainer, lp);
 
         Spinner spinner = (Spinner) spinnerContainer.findViewById(R.id.actionbar_spinner);
         spinner.setAdapter(mTopLevelSpinnerAdapter);
@@ -282,33 +280,28 @@
             spinner.setSelection(itemToSelect);
         }
 
+        updateHeaderColor();
         showSecondaryFilters();
-        updateActionBarNavigation();
     }
 
-    private void updateActionBarNavigation() {
-        boolean show = mSpinnerConfigured && !isNavDrawerOpen();
-
-        ActionBar ab = getActionBar();
-        if (mMode == MODE_TIME_FIT) {
-            ab.setDisplayShowCustomEnabled(false);
-            ab.setDisplayShowTitleEnabled(true);
-            ab.setDisplayUseLogoEnabled(false);
-        } else if (show) {
-            ab.setDisplayShowCustomEnabled(true);
-            ab.setDisplayShowTitleEnabled(false);
-            ab.setDisplayUseLogoEnabled(false);
-        } else if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ab.setDisplayShowCustomEnabled(false);
-            ab.setDisplayShowTitleEnabled(false);
-            ab.setDisplayUseLogoEnabled(true);
+    private void updateHeaderColor() {
+        mHeaderColor = 0;
+        for (String tag : mFilterTags) {
+            if (tag != null) {
+                TagMetadata.Tag tagObj = mTagMetadata.getTag(tag);
+                if (tagObj != null && Config.Tags.CATEGORY_TOPIC.equals(tagObj.getCategory())) {
+                    mHeaderColor = tagObj.getColor();
+                }
+            }
         }
-    }
-
-    @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
+        findViewById(R.id.headerbar).setBackgroundColor(
+                mHeaderColor == 0
+                        ? getResources().getColor(R.color.theme_primary)
+                        : mHeaderColor);
+        setNormalStatusBarColor(
+                mHeaderColor == 0
+                        ? getThemedStatusBarColor()
+                        : UIUtils.scaleColor(mHeaderColor, 0.8f, false));
     }
 
     private void onTopLevelTagSelected(String tag) {
@@ -323,6 +316,7 @@
             // nothing to do
             return;
         }
+
         /* [ANALYTICS:EVENT]
          * TRIGGER:   Select a top-level filter on the Explore screen.
          * CATEGORY:  'Explore'
@@ -339,6 +333,7 @@
         }
 
         showSecondaryFilters();
+        updateHeaderColor();
         reloadFromFilters();
     }
 
@@ -412,7 +407,7 @@
         Bundle args = BaseActivity.intentToFragmentArguments(
                 new Intent(Intent.ACTION_VIEW, ScheduleContract.Sessions.buildTagFilterUri(
                         mFilterTags))
-        );
+                        .putExtra(SessionsFragment.EXTRA_NO_TRACK_BRANDING, mHeaderColor != 0));
         frag.reloadFromArguments(args);
 
         frag.animateReload();
@@ -467,6 +462,7 @@
                      * [/ANALYTICS]
                      */
                     AnalyticsManager.sendEvent(SCREEN_LABEL, "secondaryfilter", tag);
+                    updateHeaderColor();
                     reloadFromFilters();
                 }
             }
@@ -489,11 +485,6 @@
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
 
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer() && isNavDrawerOpen()) {
-            // nothing to show if nav drawer is open or animating
-            return true;
-        }
-
         getMenuInflater().inflate(R.menu.browse_sessions, menu);
         // remove actions when in time interval mode:
         if (mMode != MODE_EXPLORE) {
@@ -536,12 +527,10 @@
          * [/ANALYTICS]
          */
         AnalyticsManager.sendEvent(SCREEN_LABEL, "selectsession", sessionId);
-        getLPreviewUtils().startActivityWithTransition(
-                new Intent(Intent.ACTION_VIEW,
+        getLUtils().startActivityWithTransition(new Intent(Intent.ACTION_VIEW,
                         ScheduleContract.Sessions.buildSessionUri(sessionId)),
                 clickedView,
-                SessionDetailFragment.VIEW_NAME_PHOTO
-        );
+                SessionDetailActivity.TRANSITION_NAME_PHOTO);
     }
 
     @Override
@@ -621,7 +610,7 @@
 
             TextView headerTextView = (TextView) view.findViewById(R.id.header_text);
             View dividerView = view.findViewById(R.id.divider_view);
-            TextView normalTextView = (TextView) view.findViewById(R.id.normal_text);
+            TextView normalTextView = (TextView) view.findViewById(android.R.id.text1);
 
             if (isHeader(position)) {
                 headerTextView.setText(getTitle(position));
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java
index c045ab7..897f93f 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java
@@ -73,7 +73,6 @@
         }
 
         setContentView(R.layout.activity_experts_directory);
-        getLPreviewUtils().trySetActionBar();
         AnalyticsManager.sendScreenView(SCREEN_LABEL);
 
         mDrawShadowFrameLayout = (DrawShadowFrameLayout) findViewById(R.id.main_content);
@@ -107,15 +106,6 @@
         }
     }
 
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ActionBar ab = getActionBar();
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
-        }
-    }
-
     @Override
     protected void onActionBarAutoShowOrHide(boolean shown) {
         super.onActionBarAutoShowOrHide(shown);
@@ -123,12 +113,6 @@
     }
 
     @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
-    @Override
     protected int getSelfNavDrawerItem() {
         return NAVDRAWER_ITEM_EXPERTS_DIRECTORY;
     }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java
index 14d1790..a24b540 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java
@@ -16,26 +16,24 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
-import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
-import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-
 import android.annotation.SuppressLint;
 import android.app.Activity;
-import android.app.DialogFragment;
-import android.content.*;
+import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.content.SharedPreferences;
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.preference.PreferenceManager;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.CursorLoader;
-import android.content.Loader;
 import android.text.format.DateUtils;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
@@ -45,15 +43,25 @@
 import android.widget.FrameLayout;
 
 import com.google.android.gms.maps.CameraUpdate;
-import com.google.samples.apps.iosched.R;
-import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.util.*;
 import com.google.android.gms.maps.CameraUpdateFactory;
 import com.google.android.gms.maps.GoogleMap;
 import com.google.android.gms.maps.Projection;
-import com.google.android.gms.maps.model.*;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.IndoorBuilding;
+import com.google.android.gms.maps.model.LatLng;
 import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+import com.google.android.gms.maps.model.TileOverlay;
+import com.google.android.gms.maps.model.TileOverlayOptions;
+import com.google.android.gms.maps.model.TileProvider;
 import com.google.maps.android.ui.IconGenerator;
+import com.google.samples.apps.iosched.R;
+import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.util.AnalyticsManager;
+import com.google.samples.apps.iosched.util.MapUtils;
+import com.google.samples.apps.iosched.util.PrefUtils;
+import com.google.samples.apps.iosched.util.UIUtils;
+import com.jakewharton.disklrucache.DiskLruCache;
 
 import java.io.File;
 import java.io.IOException;
@@ -62,7 +70,8 @@
 import java.util.HashMap;
 import java.util.Locale;
 
-import com.jakewharton.disklrucache.DiskLruCache;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
 /**
  * Shows a map of the conference venue.
@@ -87,12 +96,6 @@
     // Default level (index of level in IndoorBuilding object for Moscone)
     private static final int MOSCONE_DEFAULT_LEVEL_INDEX = 1;
 
-
-    /**
-     * When specified, will automatically point the map to the requested room.
-     */
-    public static final String EXTRA_ROOM = "com.google.android.iosched.extra.ROOM";
-
     private static final String TAG = makeLogTag(MapFragment.class);
 
     // Marker types
@@ -144,6 +147,7 @@
     private Marker mMosconeMaker = null;
 
     private GoogleMap mMap;
+    private Rect mMapInsets = new Rect();
 
     private MapInfoWindowAdapter mInfoAdapter;
 
@@ -243,8 +247,7 @@
             setupMap(true);
         }
 
-
-        mMap.setPadding(0, UIUtils.calculateActionBarSize(getActivity()), 0, 0);
+        setMapInsets(mMapInsets);
 
         // load all markers
         LoaderManager lm = getLoaderManager();
@@ -256,6 +259,13 @@
         return v;
     }
 
+    public void setMapInsets(Rect insets) {
+        mMapInsets.set(insets);
+        if (mMap != null) {
+            mMap.setPadding(mMapInsets.left, mMapInsets.top, mMapInsets.right, mMapInsets.bottom);
+        }
+    }
+
     @Override
     public void onStart() {
         super.onStart();
@@ -319,8 +329,8 @@
         mMap.setMyLocationEnabled(false);
 
         Bundle data = getArguments();
-        if (data != null && data.containsKey(EXTRA_ROOM)) {
-            mHighlightedRoom = data.getString(EXTRA_ROOM);
+        if (data != null && data.containsKey(BaseMapActivity.EXTRA_ROOM)) {
+            mHighlightedRoom = data.getString(BaseMapActivity.EXTRA_ROOM);
         }
 
         LOGD(TAG, "Map setup complete.");
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java
index 6e1a06d..de96869 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java
@@ -16,7 +16,6 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import android.app.ActionBar;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.ListFragment;
@@ -127,7 +126,6 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_my_schedule);
-        getLPreviewUtils().trySetActionBar();
 
         /* [ANALYTICS:SCREEN]
          * TRIGGER:   View the My Schedule screen.
@@ -142,7 +140,7 @@
 
         int i;
         for (i = 0; i < Config.CONFERENCE_DAYS.length; i++) {
-            mScheduleAdapters[i] = new MyScheduleAdapter(this, getLPreviewUtils());
+            mScheduleAdapters[i] = new MyScheduleAdapter(this, getLUtils());
         }
 
         mViewPagerAdapter = new OurViewPagerAdapter(getFragmentManager());
@@ -224,21 +222,6 @@
                         getResources().getDisplayMetrics()));
     }
 
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ActionBar ab = getActionBar();
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
-        }
-    }
-
-    @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
@@ -431,12 +414,6 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
-
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer() && isNavDrawerOpen()) {
-            // nothing to show if nav drawer is open or animating
-            return true;
-        }
-
         getMenuInflater().inflate(R.menu.my_schedule, menu);
         configureStandardMenuItems(menu);
         return true;
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java
index fd515fe..167ab88 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.database.DataSetObserver;
 import android.graphics.Color;
+import android.graphics.ColorFilter;
 import android.graphics.Typeface;
 import android.graphics.drawable.ColorDrawable;
 import android.net.Uri;
@@ -52,7 +53,7 @@
     private static final int VIEW_TYPE_PAST_DURING_CONFERENCE = 2;
 
     private final Context mContext;
-    private final LPreviewUtilsBase mLPreviewUtils;
+    private final LUtils mLUtils;
 
     // additional top padding to add to first item of list
     int mContentTopClearance = 0;
@@ -74,9 +75,9 @@
     // the data and thus shouldn't be used
     int mDataGeneration = 0;
 
-    public MyScheduleAdapter(Context context, LPreviewUtilsBase lPreviewUtils) {
+    public MyScheduleAdapter(Context context, LUtils lUtils) {
         mContext = context;
-        mLPreviewUtils = lPreviewUtils;
+        mLUtils = lUtils;
 
         mDefaultSessionColor = mContext.getResources().getColor(R.color.default_session_color);
         mDefaultStartTimeColor = mContext.getResources().getColor(R.color.body_text_2);
@@ -333,14 +334,13 @@
 
             final ColorDrawable colorDrawable = new ColorDrawable(color);
             bgImageView.setImageDrawable(colorDrawable);
-            bgImageView.setColorFilter(UIUtils.setColorAlpha(color,
-                    UIUtils.SESSION_PHOTO_SCRIM_ALPHA));
+            ColorFilter scrimFilter = UIUtils.makeSessionImageScrimColorFilter(color);
+            bgImageView.setColorFilter(scrimFilter);
 
             if (TextUtils.isEmpty(item.backgroundImageUrl)) {
                 sessionImageView.setVisibility(View.GONE);
             } else {
-                sessionImageView.setColorFilter(UIUtils.setColorAlpha(color,
-                        UIUtils.SESSION_PHOTO_SCRIM_ALPHA));
+                sessionImageView.setColorFilter(scrimFilter);
                 mImageLoader.loadImage(item.backgroundImageUrl, sessionImageView, null,
                         colorDrawable);
             }
@@ -348,7 +348,7 @@
             slotTitleView.setTextColor(isBlockNow
                     ? Color.WHITE
                     : res.getColor(R.color.body_text_1_inverse));
-            mLPreviewUtils.setMediumTypeface(slotTitleView);
+            mLUtils.setMediumTypeface(slotTitleView);
             if (slotSubtitleView != null) {
                 slotSubtitleView.setText(item.subtitle);
                 slotSubtitleView.setTextColor(res.getColor(R.color.body_text_2_inverse));
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java
index 730b000..fc0fa97 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java
@@ -51,9 +51,6 @@
         View rootView = inflater.inflate(R.layout.fragment_nearby, container, false);
         if (getArguments() != null && !getArguments().getBoolean(ARG_HAS_HEADER, true)) {
             rootView.findViewById(R.id.headerbar).setVisibility(View.GONE);
-        } else {
-            ((FrameLayout) rootView.findViewById(R.id.list_container))
-                    .setForeground(getResources().getDrawable(R.drawable.bottom_shadow));
         }
 
         Callbacks parentActivity = (Callbacks) getActivity();
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java
index 7309ac8..222ba53 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java
@@ -75,9 +75,6 @@
         View rootView = inflater.inflate(R.layout.fragment_partners, container, false);
         if (getArguments() != null && !getArguments().getBoolean(ARG_HAS_HEADER, true)) {
             rootView.findViewById(R.id.headerbar).setVisibility(View.GONE);
-        } else {
-            ((FrameLayout) rootView.findViewById(R.id.list_container))
-                    .setForeground(getResources().getDrawable(R.drawable.bottom_shadow));
         }
 
         rootView.findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java
index 2ca6ced..6f520d6 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java
@@ -16,16 +16,12 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import android.app.ActionBar;
-import android.content.*;
+import android.content.Intent;
 import android.os.Bundle;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.util.PrefUtils;
 
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
-import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-
 public class PeopleIveMetActivity extends BaseActivity {
 
     private static final String FRAGMENT_PEOPLE_IVE_MET = "people_ive_met";
@@ -39,7 +35,6 @@
         }
 
         setContentView(R.layout.activity_people_ive_met);
-        getLPreviewUtils().trySetActionBar();
 
         if (null == savedInstanceState) {
             getFragmentManager().beginTransaction()
@@ -48,25 +43,9 @@
                     .commit();
         }
 
-        setTitle(R.string.title_people_ive_met);
         overridePendingTransition(0, 0);
     }
 
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ActionBar ab = getActionBar();
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
-        }
-    }
-
-    @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
     @Override
     protected int getSelfNavDrawerItem() {
         return NAVDRAWER_ITEM_PEOPLE_IVE_MET;
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java
index 0eefe50..645a679 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java
@@ -17,14 +17,17 @@
 
 import android.app.FragmentManager;
 import android.app.SearchManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.v4.content.IntentCompat;
+import android.support.v7.widget.Toolbar;
 import android.text.TextUtils;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.SearchView;
+import android.support.v7.widget.SearchView;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.model.TagMetadata;
@@ -48,6 +51,19 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_search);
+
+        Toolbar toolbar = getActionBarToolbar();
+        toolbar.setTitle(R.string.title_search);
+        toolbar.setNavigationIcon(R.drawable.ic_up);
+        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                navigateUpToFromChild(SearchActivity.this,
+                        IntentCompat.makeMainActivity(new ComponentName(SearchActivity.this,
+                                BrowseSessionsActivity.class)));
+            }
+        });
+
         FragmentManager fm = getFragmentManager();
         mSessionsFragment = (SessionsFragment) fm.findFragmentById(R.id.fragment_container);
 
@@ -80,11 +96,11 @@
          * [/ANALYTICS]
          */
         AnalyticsManager.sendEvent(SCREEN_LABEL, "selectsession", sessionId);
-        getLPreviewUtils().startActivityWithTransition(
+        getLUtils().startActivityWithTransition(
                 new Intent(Intent.ACTION_VIEW,
                         ScheduleContract.Sessions.buildSessionUri(sessionId)),
                 clickedView,
-                SessionDetailFragment.VIEW_NAME_PHOTO);
+                SessionDetailActivity.TRANSITION_NAME_PHOTO);
     }
 
     @Override
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java
index f3f64e6..1a07743 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java
@@ -16,47 +16,279 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import android.app.Fragment;
+import android.app.LoaderManager;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.CursorLoader;
 import android.content.Intent;
+import android.content.Loader;
 import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Paint;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Pair;
 import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.Menu;
 import android.view.MenuItem;
-import android.view.Window;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 
+import com.bumptech.glide.request.bitmap.RequestListener;
+import com.bumptech.glide.request.target.Target;
+import com.google.android.gms.plus.PlusOneButton;
+import com.google.android.youtube.player.YouTubeIntents;
+import com.google.samples.apps.iosched.Config;
 import com.google.samples.apps.iosched.R;
+import com.google.samples.apps.iosched.model.TagMetadata;
+import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.service.SessionAlarmService;
+import com.google.samples.apps.iosched.service.SessionCalendarService;
+import com.google.samples.apps.iosched.ui.widget.CheckableFrameLayout;
+import com.google.samples.apps.iosched.ui.widget.MessageCardView;
+import com.google.samples.apps.iosched.ui.widget.ObservableScrollView;
+import com.google.samples.apps.iosched.util.AccountUtils;
+import com.google.samples.apps.iosched.util.AnalyticsManager;
 import com.google.samples.apps.iosched.util.BeamUtils;
+import com.google.samples.apps.iosched.util.ImageLoader;
+import com.google.samples.apps.iosched.util.LogUtils;
+import com.google.samples.apps.iosched.util.SessionsHelper;
+import com.google.samples.apps.iosched.util.TimeUtils;
 import com.google.samples.apps.iosched.util.UIUtils;
 
-public class SessionDetailActivity extends SimpleSinglePaneActivity {
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+
+/**
+ * An activity that shows detail information for a session, including session title, abstract,
+ * time information, speaker photos and bios, etc.
+ */
+public class SessionDetailActivity extends BaseActivity implements
+        LoaderManager.LoaderCallbacks<Cursor>,
+        ObservableScrollView.Callbacks {
+    private static final String TAG = LogUtils.makeLogTag(SessionDetailActivity.class);
+
+    private static final int[] SECTION_HEADER_RES_IDS = {
+            R.id.session_links_header,
+            R.id.session_speakers_header,
+            R.id.session_requirements_header,
+            R.id.related_videos_header,
+    };
+    private static final float PHOTO_ASPECT_RATIO = 1.7777777f;
+
+    public static final String TRANSITION_NAME_PHOTO = "photo";
+
+    private Handler mHandler = new Handler();
+    private static final int TIME_HINT_UPDATE_INTERVAL = 10000; // 10 sec
+
+    private TagMetadata mTagMetadata;
+
+    private String mSessionId;
+    private Uri mSessionUri;
+
+    private long mSessionStart;
+    private long mSessionEnd;
+    private String mTitleString;
+    private String mHashTag;
+    private String mUrl;
+    private String mRoomId;
+    private String mRoomName;
+    private String mTagsString;
+
+    // A comma-separated list of speakers to be passed to Android Wear
+    private String mSpeakers;
+
+    private boolean mStarred;
+    private boolean mInitStarred;
+    private boolean mDismissedWatchLivestreamCard = false;
+    private boolean mHasLivestream = false;
+    private MenuItem mSocialStreamMenuItem;
+    private MenuItem mShareMenuItem;
+
+    private View mScrollViewChild;
+    private TextView mTitle;
+    private TextView mSubtitle;
+    private PlusOneButton mPlusOneButton;
+
+    private ObservableScrollView mScrollView;
+    private CheckableFrameLayout mAddScheduleButton;
+
+    private TextView mAbstract;
+    private LinearLayout mTags;
+    private ViewGroup mTagsContainer;
+    private TextView mRequirements;
+    private View mHeaderBox;
+    private View mDetailsContainer;
+
+    private boolean mSessionCursor = false;
+    private boolean mSpeakersCursor = false;
+    private boolean mHasSummaryContent = false;
+
+    private ImageLoader mSpeakersImageLoader, mNoPlaceholderImageLoader;
+    private List<Runnable> mDeferredUiOperations = new ArrayList<Runnable>();
+
+    private StringBuilder mBuffer = new StringBuilder();
+
+    private int mPhotoHeightPixels;
+    private int mHeaderHeightPixels;
+    private int mAddScheduleButtonHeightPixels;
+
+    private boolean mHasPhoto;
+    private View mPhotoViewContainer;
+    private ImageView mPhotoView;
+    private int mSessionColor;
+    private String mLivestreamUrl;
+
+    private Runnable mTimeHintUpdaterRunnable = null;
+
+    private boolean mAlreadyGaveFeedback = false;
+    private boolean mIsKeynote = false;
+
+    // this set stores the session IDs for which the user has dismissed the
+    // "give feedback" card. This information is kept for the duration of the app's execution
+    // so that if they say "No, thanks", we don't show the card again for that session while
+    // the app is still executing.
+    private static HashSet<String> sDismissedFeedbackCard = new HashSet<String>();
+
+    private TextView mSubmitFeedbackView;
+    private float mMaxHeaderElevation;
+    private float mFABElevation;
+
+    private int mTagColorDotSize;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         UIUtils.tryTranslateHttpIntent(this);
         BeamUtils.tryUpdateIntentFromBeam(this);
-        requestWindowFeature(Window.FEATURE_ACTION_BAR);
-        if (shouldBeFloatingWindow()) {
+        boolean shouldBeFloatingWindow = shouldBeFloatingWindow();
+        if (shouldBeFloatingWindow) {
             setupFloatingWindow();
         }
+
         super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_session_detail);
+
+        final Toolbar toolbar = getActionBarToolbar();
+        toolbar.setNavigationIcon(shouldBeFloatingWindow
+                ? R.drawable.ic_ab_close : R.drawable.ic_up);
+        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                finish();
+            }
+        });
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                toolbar.setTitle("");
+            }
+        });
 
         if (savedInstanceState == null) {
             Uri sessionUri = getIntent().getData();
             BeamUtils.setBeamSessionUri(this, sessionUri);
         }
 
-        setTitle("");
-    }
+        mSessionUri = getIntent().getData();
 
-    @Override
-    protected Fragment onCreatePane() {
-        return new SessionDetailFragment();
+        if (mSessionUri == null) {
+            return;
+        }
+
+        mSessionId = ScheduleContract.Sessions.getSessionId(mSessionUri);
+
+        mFABElevation = getResources().getDimensionPixelSize(R.dimen.fab_elevation);
+        mMaxHeaderElevation = getResources().getDimensionPixelSize(
+                R.dimen.session_detail_max_header_elevation);
+
+        mTagColorDotSize = getResources().getDimensionPixelSize(R.dimen.tag_color_dot_size);
+
+        mHandler = new Handler();
+
+        if (mSpeakersImageLoader == null) {
+            mSpeakersImageLoader = new ImageLoader(this, R.drawable.person_image_empty);
+        }
+        if (mNoPlaceholderImageLoader == null) {
+            mNoPlaceholderImageLoader = new ImageLoader(this);
+        }
+
+        mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
+        mScrollView.addCallbacks(this);
+        ViewTreeObserver vto = mScrollView.getViewTreeObserver();
+        if (vto.isAlive()) {
+            vto.addOnGlobalLayoutListener(mGlobalLayoutListener);
+        }
+
+        mScrollViewChild = findViewById(R.id.scroll_view_child);
+        mScrollViewChild.setVisibility(View.INVISIBLE);
+
+        mDetailsContainer = findViewById(R.id.details_container);
+        mHeaderBox = findViewById(R.id.header_session);
+        mTitle = (TextView) findViewById(R.id.session_title);
+        mSubtitle = (TextView) findViewById(R.id.session_subtitle);
+        mPhotoViewContainer = findViewById(R.id.session_photo_container);
+        mPhotoView = (ImageView) findViewById(R.id.session_photo);
+
+        mPlusOneButton = (PlusOneButton) findViewById(R.id.plus_one_button);
+        mAbstract = (TextView) findViewById(R.id.session_abstract);
+        mRequirements = (TextView) findViewById(R.id.session_requirements);
+        mTags = (LinearLayout) findViewById(R.id.session_tags);
+        mTagsContainer = (ViewGroup) findViewById(R.id.session_tags_container);
+
+        mAddScheduleButton = (CheckableFrameLayout) findViewById(R.id.add_schedule_button);
+        mAddScheduleButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                boolean starred = !mStarred;
+                SessionsHelper helper = new SessionsHelper(SessionDetailActivity.this);
+                showStarred(starred, true);
+                helper.setSessionStarred(mSessionUri, starred, mTitleString);
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                    mAddScheduleButton.announceForAccessibility(starred ?
+                            getString(R.string.session_details_a11y_session_added) :
+                            getString(R.string.session_details_a11y_session_removed));
+                }
+
+                /* [ANALYTICS:EVENT]
+                 * TRIGGER:   Add or remove a session from My Schedule.
+                 * CATEGORY:  'Session'
+                 * ACTION:    'Starred' or 'Unstarred'
+                 * LABEL:     Session title/subtitle.
+                 * [/ANALYTICS]
+                 */
+                AnalyticsManager.sendEvent(
+                        "Session", starred ? "Starred" : "Unstarred", mTitleString, 0L);
+            }
+        });
+
+        ViewCompat.setTransitionName(mPhotoView, TRANSITION_NAME_PHOTO);
+
+        LoaderManager manager = getLoaderManager();
+        manager.initLoader(SessionsQuery._TOKEN, null, this);
+        manager.initLoader(SpeakersQuery._TOKEN, null, this);
+        manager.initLoader(TAG_METADATA_TOKEN, null, this);
     }
 
     @Override
     public Intent getParentActivityIntent() {
-        // TODO: make this Activity navigate up to the right screen depending on how it was launched
+        // TODO(mangini): make this Activity navigate up to the right screen depending on how it was launched
         return new Intent(this, MyScheduleActivity.class);
     }
 
@@ -66,8 +298,8 @@
         params.width = getResources().getDimensionPixelSize(R.dimen.session_details_floating_width);
         params.height = getResources().getDimensionPixelSize(R.dimen.session_details_floating_height);
         params.alpha = 1;
-        params.dimAmount = 0.7f;
-        params.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+        params.dimAmount = 0.4f;
+        params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
         getWindow().setAttributes(params);
     }
 
@@ -81,12 +313,972 @@
         return (floatingWindowFlag.data != 0);
     }
 
+    private void recomputePhotoAndScrollingMetrics() {
+        mHeaderHeightPixels = mHeaderBox.getHeight();
+
+        mPhotoHeightPixels = 0;
+        if (mHasPhoto) {
+            mPhotoHeightPixels = (int) (mPhotoView.getWidth() / PHOTO_ASPECT_RATIO);
+            mPhotoHeightPixels = Math.min(mPhotoHeightPixels, mScrollView.getHeight() * 2 / 3);
+        }
+
+        ViewGroup.LayoutParams lp;
+        lp = mPhotoViewContainer.getLayoutParams();
+        if (lp.height != mPhotoHeightPixels) {
+            lp.height = mPhotoHeightPixels;
+            mPhotoViewContainer.setLayoutParams(lp);
+        }
+
+        ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
+                mDetailsContainer.getLayoutParams();
+        if (mlp.topMargin != mHeaderHeightPixels + mPhotoHeightPixels) {
+            mlp.topMargin = mHeaderHeightPixels + mPhotoHeightPixels;
+            mDetailsContainer.setLayoutParams(mlp);
+        }
+
+        onScrollChanged(0, 0); // trigger scroll handling
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mScrollView == null) {
+            return;
+        }
+
+        ViewTreeObserver vto = mScrollView.getViewTreeObserver();
+        if (vto.isAlive()) {
+            vto.removeGlobalOnLayoutListener(mGlobalLayoutListener);
+        }
+    }
+
+    private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener
+            = new ViewTreeObserver.OnGlobalLayoutListener() {
+        @Override
+        public void onGlobalLayout() {
+            mAddScheduleButtonHeightPixels = mAddScheduleButton.getHeight();
+            recomputePhotoAndScrollingMetrics();
+        }
+    };
+
+    @Override
+    public void onScrollChanged(int deltaX, int deltaY) {
+        // Reposition the header bar -- it's normally anchored to the top of the content,
+        // but locks to the top of the screen on scroll
+        int scrollY = mScrollView.getScrollY();
+
+        float newTop = Math.max(mPhotoHeightPixels, scrollY);
+        mHeaderBox.setTranslationY(newTop);
+        mAddScheduleButton.setTranslationY(newTop + mHeaderHeightPixels
+                - mAddScheduleButtonHeightPixels / 2);
+
+        float gapFillProgress = 1;
+        if (mPhotoHeightPixels != 0) {
+            gapFillProgress = Math.min(Math.max(UIUtils.getProgress(scrollY,
+                    0,
+                    mPhotoHeightPixels), 0), 1);
+        }
+
+        ViewCompat.setElevation(mHeaderBox, gapFillProgress * mMaxHeaderElevation);
+        ViewCompat.setElevation(mAddScheduleButton, gapFillProgress * mMaxHeaderElevation
+                + mFABElevation);
+
+        // Move background photo (parallax effect)
+        mPhotoViewContainer.setTranslationY(scrollY * 0.5f);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updatePlusOneButton();
+        if (mTimeHintUpdaterRunnable != null) {
+            mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
+        }
+
+        // Refresh whether or not feedback has been submitted
+        getLoaderManager().restartLoader(FeedbackQuery._TOKEN, null, this);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        if (mInitStarred != mStarred) {
+            if (UIUtils.getCurrentTime(this) < mSessionStart) {
+                // Update Calendar event through the Calendar API on Android 4.0 or new versions.
+                Intent intent = null;
+                if (mStarred) {
+                    // Set up intent to add session to Calendar, if it doesn't exist already.
+                    intent = new Intent(SessionCalendarService.ACTION_ADD_SESSION_CALENDAR,
+                            mSessionUri);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
+                            mSessionStart);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
+                            mSessionEnd);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_ROOM, mRoomName);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
+                } else {
+                    // Set up intent to remove session from Calendar, if exists.
+                    intent = new Intent(SessionCalendarService.ACTION_REMOVE_SESSION_CALENDAR,
+                            mSessionUri);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
+                            mSessionStart);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
+                            mSessionEnd);
+                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
+                }
+                intent.setClass(this, SessionCalendarService.class);
+                startService(intent);
+
+                if (mStarred) {
+                    setupNotification();
+                }
+            }
+        }
+    }
+
+    private void setupNotification() {
+        Intent scheduleIntent;
+
+        // Schedule session notification
+        if (UIUtils.getCurrentTime(this) < mSessionStart) {
+            LOGD(TAG, "Scheduling notification about session start.");
+            scheduleIntent = new Intent(
+                    SessionAlarmService.ACTION_SCHEDULE_STARRED_BLOCK,
+                    null, this, SessionAlarmService.class);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
+            startService(scheduleIntent);
+        } else {
+            LOGD(TAG, "Not scheduling notification about session start, too late.");
+        }
+
+        // Schedule feedback notification
+        if (UIUtils.getCurrentTime(this) < mSessionEnd) {
+            LOGD(TAG, "Scheduling notification about session feedback.");
+            scheduleIntent = new Intent(
+                    SessionAlarmService.ACTION_SCHEDULE_FEEDBACK_NOTIFICATION,
+                    null, this, SessionAlarmService.class);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ID, mSessionId);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_TITLE, mTitleString);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ROOM, mRoomName);
+            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_SPEAKERS, mSpeakers);
+            startService(scheduleIntent);
+        } else {
+            LOGD(TAG, "Not scheduling feedback notification, too late.");
+        }
+    }
+
+    private void updateTimeBasedUi() {
+        long currentTimeMillis = UIUtils.getCurrentTime(this);
+        boolean canShowLivestream = mHasLivestream;
+
+        if (canShowLivestream && !mDismissedWatchLivestreamCard
+                && currentTimeMillis > mSessionStart
+                && currentTimeMillis <= mSessionEnd) {
+            // show the "watch now" card
+            showWatchNowCard();
+        } else if (!mAlreadyGaveFeedback && mInitStarred && currentTimeMillis >= (mSessionEnd -
+                Config.FEEDBACK_MILLIS_BEFORE_SESSION_END)
+                && !sDismissedFeedbackCard.contains(mSessionId)) {
+            // show the "give feedback" card
+            showGiveFeedbackCard();
+        }
+
+        String timeHint = "";
+        long countdownMillis = mSessionStart - currentTimeMillis;
+
+        if (TimeUtils.hasConferenceEnded(this)) {
+            // no time hint to display
+            timeHint = "";
+        } else if (currentTimeMillis >= mSessionEnd) {
+            timeHint = getString(R.string.time_hint_session_ended);
+        } else if (currentTimeMillis >= mSessionStart) {
+            long minutesAgo = (currentTimeMillis - mSessionStart) / 60000;
+            if (minutesAgo > 1) {
+                timeHint = getString(R.string.time_hint_started_min, minutesAgo);
+            } else {
+                timeHint = getString(R.string.time_hint_started_just);
+            }
+        } else if (countdownMillis > 0 && countdownMillis < Config.HINT_TIME_BEFORE_SESSION) {
+            long millisUntil = mSessionStart - currentTimeMillis;
+            long minutesUntil = millisUntil / 60000 + (millisUntil % 1000 > 0 ? 1 : 0);
+            if (minutesUntil > 1) {
+                timeHint = getString(R.string.time_hint_about_to_start_min, minutesUntil);
+            } else {
+                timeHint = getString(R.string.time_hint_about_to_start_shortly, minutesUntil);
+            }
+        }
+
+        final TextView timeHintView = (TextView) findViewById(R.id.time_hint);
+
+        if (!TextUtils.isEmpty(timeHint)) {
+            timeHintView.setVisibility(View.VISIBLE);
+            timeHintView.setText(timeHint);
+        } else {
+            timeHintView.setVisibility(View.GONE);
+        }
+    }
+
+    private void setTextSelectable(TextView tv) {
+        if (tv != null && !tv.isTextSelectable()) {
+            tv.setTextIsSelectable(true);
+        }
+    }
+
+    private void onFeedbackQueryComplete(Cursor cursor) {
+        // Is there existing feedback for this session?
+        mAlreadyGaveFeedback = cursor.getCount() > 0;
+
+        if (mAlreadyGaveFeedback) {
+            final MessageCardView giveFeedbackCardView = (MessageCardView) findViewById(R.id.give_feedback_card);
+            if (giveFeedbackCardView != null) {
+                giveFeedbackCardView.setVisibility(View.GONE);
+            }
+            if (mSubmitFeedbackView != null) {
+                mSubmitFeedbackView.setVisibility(View.GONE);
+            }
+        }
+        LOGD(TAG, "User " + (mAlreadyGaveFeedback ? "already gave" : "has not given") + " feedback for session.");
+        cursor.close();
+    }
+
+    /**
+     * Handle {@link SessionsQuery} {@link Cursor}.
+     */
+    private void onSessionQueryComplete(Cursor cursor) {
+        mSessionCursor = true;
+        if (!cursor.moveToFirst()) {
+            // TODO: Remove this in favor of a callbacks interface that the activity
+            // can implement.
+            finish();
+            return;
+        }
+
+        mTitleString = cursor.getString(SessionsQuery.TITLE);
+        mSessionColor = cursor.getInt(SessionsQuery.COLOR);
+
+        if (mSessionColor == 0) {
+            // no color -- use default
+            mSessionColor = getResources().getColor(R.color.default_session_color);
+        } else {
+            // make sure it's opaque
+            mSessionColor = UIUtils.setColorAlpha(mSessionColor, 255);
+        }
+
+        mHeaderBox.setBackgroundColor(mSessionColor);
+        getLUtils().setStatusBarColor(UIUtils.scaleColor(mSessionColor, 0.8f, false));
+
+        mLivestreamUrl = cursor.getString(SessionsQuery.LIVESTREAM_URL);
+        mHasLivestream = !TextUtils.isEmpty(mLivestreamUrl);
+
+        // Format the time this session occupies
+        mSessionStart = cursor.getLong(SessionsQuery.START);
+        mSessionEnd = cursor.getLong(SessionsQuery.END);
+        mRoomName = cursor.getString(SessionsQuery.ROOM_NAME);
+        mSpeakers = cursor.getString(SessionsQuery.SPEAKER_NAMES);
+        String subtitle = UIUtils.formatSessionSubtitle(
+                mSessionStart, mSessionEnd, mRoomName, mBuffer, this);
+        if (mHasLivestream) {
+            subtitle += " " + UIUtils.getLiveBadgeText(this, mSessionStart, mSessionEnd);
+        }
+
+        mTitle.setText(mTitleString);
+        mSubtitle.setText(subtitle);
+
+        for (int resId : SECTION_HEADER_RES_IDS) {
+            ((TextView) findViewById(resId)).setTextColor(mSessionColor);
+        }
+
+        mPhotoViewContainer.setBackgroundColor(UIUtils.scaleSessionColorToDefaultBG(mSessionColor));
+
+        String photo = cursor.getString(SessionsQuery.PHOTO_URL);
+        if (!TextUtils.isEmpty(photo)) {
+            mHasPhoto = true;
+            mNoPlaceholderImageLoader.loadImage(photo, mPhotoView, new RequestListener<String>() {
+                @Override
+                public void onException(Exception e, String url, Target target) {
+                    mHasPhoto = false;
+                    recomputePhotoAndScrollingMetrics();
+                }
+
+                @Override
+                public void onImageReady(String url, Target target, boolean b, boolean b2) {
+                    // Trigger image transition
+                    recomputePhotoAndScrollingMetrics();
+                }
+            });
+            recomputePhotoAndScrollingMetrics();
+        } else {
+            mHasPhoto = false;
+            recomputePhotoAndScrollingMetrics();
+        }
+
+        mUrl = cursor.getString(SessionsQuery.URL);
+        if (TextUtils.isEmpty(mUrl)) {
+            mUrl = "";
+        }
+
+        mHashTag = cursor.getString(SessionsQuery.HASHTAG);
+        if (!TextUtils.isEmpty(mHashTag)) {
+            enableSocialStreamMenuItemDeferred();
+        }
+
+        mRoomId = cursor.getString(SessionsQuery.ROOM_ID);
+
+        final boolean inMySchedule = cursor.getInt(SessionsQuery.IN_MY_SCHEDULE) != 0;
+
+        setupShareMenuItemDeferred();
+
+        // Handle Keynote as a special case, where the user cannot remove it
+        // from the schedule (it is auto added to schedule on sync)
+        mTagsString = cursor.getString(SessionsQuery.TAGS);
+        mIsKeynote = mTagsString.contains(Config.Tags.SPECIAL_KEYNOTE);
+        mAddScheduleButton.setVisibility(
+                (AccountUtils.hasActiveAccount(this) && !mIsKeynote)
+                        ? View.VISIBLE : View.INVISIBLE);
+
+        tryRenderTags();
+
+        if (!mIsKeynote) {
+            showStarredDeferred(mInitStarred = inMySchedule, false);
+        }
+
+        final String sessionAbstract = cursor.getString(SessionsQuery.ABSTRACT);
+        if (!TextUtils.isEmpty(sessionAbstract)) {
+            UIUtils.setTextMaybeHtml(mAbstract, sessionAbstract);
+            mAbstract.setVisibility(View.VISIBLE);
+            mHasSummaryContent = true;
+        } else {
+            mAbstract.setVisibility(View.GONE);
+        }
+
+        updatePlusOneButton();
+
+        // Build requirements section
+        final View requirementsBlock = findViewById(R.id.session_requirements_block);
+        final String sessionRequirements = cursor.getString(SessionsQuery.REQUIREMENTS);
+        if (!TextUtils.isEmpty(sessionRequirements)) {
+            UIUtils.setTextMaybeHtml(mRequirements, sessionRequirements);
+            requirementsBlock.setVisibility(View.VISIBLE);
+            mHasSummaryContent = true;
+        } else {
+            requirementsBlock.setVisibility(View.GONE);
+        }
+
+        // Build related videos section
+        final ViewGroup relatedVideosBlock = (ViewGroup) findViewById(R.id.related_videos_block);
+        relatedVideosBlock.setVisibility(View.GONE);
+
+        // Build links section
+        buildLinksSection(cursor);
+
+        updateEmptyView();
+
+        updateTimeBasedUi();
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                onScrollChanged(0, 0); // trigger scroll handling
+                mScrollViewChild.setVisibility(View.VISIBLE);
+                //mAbstract.setTextIsSelectable(true);
+            }
+        });
+
+        mTimeHintUpdaterRunnable = new Runnable() {
+            @Override
+            public void run() {
+                updateTimeBasedUi();
+                mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
+            }
+        };
+        mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
+    }
+
+    private void tryRenderTags() {
+        if (mTagMetadata == null || mTagsString == null) {
+            return;
+        }
+
+        if (TextUtils.isEmpty(mTagsString)) {
+            mTagsContainer.setVisibility(View.GONE);
+        } else {
+            mTagsContainer.setVisibility(View.VISIBLE);
+            mTags.removeAllViews();
+            LayoutInflater inflater = LayoutInflater.from(this);
+            String[] tagIds = mTagsString.split(",");
+
+            List<TagMetadata.Tag> tags = new ArrayList<TagMetadata.Tag>();
+            for (String tagId : tagIds) {
+                if (Config.Tags.SESSIONS.equals(tagId) ||
+                        Config.Tags.SPECIAL_KEYNOTE.equals(tagId)) {
+                    continue;
+                }
+
+                TagMetadata.Tag tag = mTagMetadata.getTag(tagId);
+                if (tag == null) {
+                    continue;
+                }
+
+                tags.add(tag);
+            }
+
+            if (tags.size() == 0) {
+                mTagsContainer.setVisibility(View.GONE);
+                return;
+            }
+
+            Collections.sort(tags, TagMetadata.TAG_DISPLAY_ORDER_COMPARATOR);
+
+            for (final TagMetadata.Tag tag : tags) {
+                TextView chipView = (TextView) inflater.inflate(
+                        R.layout.include_session_tag_chip, mTags, false);
+                chipView.setText(tag.getName());
+
+                if (Config.Tags.CATEGORY_TOPIC.equals(tag.getCategory())) {
+                    ShapeDrawable colorDrawable = new ShapeDrawable(new OvalShape());
+                    colorDrawable.setIntrinsicWidth(mTagColorDotSize);
+                    colorDrawable.setIntrinsicHeight(mTagColorDotSize);
+                    colorDrawable.getPaint().setStyle(Paint.Style.FILL);
+                    chipView.setCompoundDrawablesWithIntrinsicBounds(colorDrawable,
+                            null, null, null);
+                    colorDrawable.getPaint().setColor(tag.getColor());
+                }
+
+                chipView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        finish(); // TODO: better encapsulation
+                        Intent intent = new Intent(SessionDetailActivity.this, BrowseSessionsActivity.class)
+                                .putExtra(BrowseSessionsActivity.EXTRA_FILTER_TAG, tag.getId())
+                                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                        startActivity(intent);
+                    }
+                });
+
+                mTags.addView(chipView);
+            }
+        }
+    }
+
+    private void buildLinksSection(Cursor cursor) {
+        // Compile list of links (I/O live link, submit feedback, and normal links)
+        ViewGroup linkContainer = (ViewGroup) findViewById(R.id.links_container);
+        linkContainer.removeAllViews();
+
+
+        // Build links section
+        // the Object can be either a string URL or an Intent
+        List<Pair<Integer, Object>> links = new ArrayList<Pair<Integer, Object>>();
+
+        long currentTimeMillis = UIUtils.getCurrentTime(this);
+        if (mHasLivestream
+                && currentTimeMillis > mSessionStart
+                && currentTimeMillis <= mSessionEnd) {
+            links.add(new Pair<Integer, Object>(
+                    R.string.session_link_livestream,
+                    getWatchLiveIntent(this)));
+        }
+
+        // Add session feedback link, if appropriate
+        if (!mAlreadyGaveFeedback && currentTimeMillis > mSessionEnd
+                - Config.FEEDBACK_MILLIS_BEFORE_SESSION_END) {
+            links.add(new Pair<Integer, Object>(
+                    R.string.session_feedback_submitlink,
+                    getFeedbackIntent()
+            ));
+        }
+
+        for (int i = 0; i < SessionsQuery.LINKS_INDICES.length; i++) {
+            final String linkUrl = cursor.getString(SessionsQuery.LINKS_INDICES[i]);
+            if (TextUtils.isEmpty(linkUrl)) {
+                continue;
+            }
+
+            links.add(new Pair<Integer, Object>(
+                    SessionsQuery.LINKS_TITLES[i],
+                    new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl))
+                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
+            ));
+        }
+
+        // Render links
+        if (links.size() > 0) {
+            LayoutInflater inflater = LayoutInflater.from(this);
+            int columns = getResources().getInteger(R.integer.links_columns);
+
+            LinearLayout currentLinkRowView = null;
+            for (int i = 0; i < links.size(); i++) {
+                final Pair<Integer, Object> link = links.get(i);
+
+                // Create link view
+                TextView linkView = (TextView) inflater.inflate(R.layout.list_item_session_link,
+                        linkContainer, false);
+                if (link.first == R.string.session_feedback_submitlink) {
+                    mSubmitFeedbackView = linkView;
+                }
+                linkView.setText(getString(link.first));
+                linkView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        fireLinkEvent(link.first);
+                        Intent intent=null;
+                        if (link.second instanceof Intent) {
+                            intent = (Intent) link.second;
+                        } else if (link.second instanceof String) {
+                            intent = new Intent(Intent.ACTION_VIEW, Uri.parse((String) link.second))
+                                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                        }
+                        try {
+                            startActivity(intent);
+                        } catch (ActivityNotFoundException ignored) {
+                        }
+                    }
+                });
+
+                // Place it inside a container
+                if (columns == 1) {
+                    linkContainer.addView(linkView);
+                } else {
+                    // create a new link row
+                    if (i % columns == 0) {
+                        currentLinkRowView = (LinearLayout) inflater.inflate(
+                                R.layout.include_link_row, linkContainer, false);
+                        currentLinkRowView.setWeightSum(columns);
+                        linkContainer.addView(currentLinkRowView);
+                    }
+
+                    ((LinearLayout.LayoutParams) linkView.getLayoutParams()).width = 0;
+                    ((LinearLayout.LayoutParams) linkView.getLayoutParams()).weight = 1;
+                    currentLinkRowView.addView(linkView);
+                }
+            }
+
+            findViewById(R.id.session_links_header).setVisibility(View.VISIBLE);
+            findViewById(R.id.links_container).setVisibility(View.VISIBLE);
+
+        } else {
+            findViewById(R.id.session_links_header).setVisibility(View.GONE);
+            findViewById(R.id.links_container).setVisibility(View.GONE);
+        }
+
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (mTimeHintUpdaterRunnable != null) {
+            mHandler.removeCallbacks(mTimeHintUpdaterRunnable);
+        }
+    }
+
+    private Intent getWatchLiveIntent(Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+                YouTubeIntents.canResolvePlayVideoIntent(context)) {
+            String youtubeVideoId = SessionLivestreamActivity.getVideoIdFromUrl(mLivestreamUrl);
+            return YouTubeIntents.createPlayVideoIntentWithOptions(
+                    context, youtubeVideoId, true, false);
+        }
+        return new Intent(Intent.ACTION_VIEW, mSessionUri).setClass(context,
+                SessionLivestreamActivity.class);
+    }
+
+    private void updatePlusOneButton() {
+        if (mPlusOneButton == null) {
+            return;
+        }
+
+        if (!TextUtils.isEmpty(mUrl) && !mIsKeynote) {
+            mPlusOneButton.initialize(mUrl, 0);
+            mPlusOneButton.setVisibility(View.VISIBLE);
+        } else {
+            mPlusOneButton.setVisibility(View.GONE);
+        }
+    }
+
+    private void showWatchNowCard() {
+        final MessageCardView messageCardView = (MessageCardView) findViewById(R.id.live_now_card);
+        messageCardView.show();
+        messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
+            @Override
+            public void onMessageCardButtonClicked(String tag) {
+                if ("WATCH_NOW".equals(tag)) {
+                    Intent intent = getWatchLiveIntent(SessionDetailActivity.this);
+                    startActivity(intent);
+                } else {
+                    mDismissedWatchLivestreamCard = true;
+                    messageCardView.dismiss();
+                }
+            }
+        });
+    }
+
+    private void showGiveFeedbackCard() {
+        final MessageCardView messageCardView = (MessageCardView) findViewById(R.id.give_feedback_card);
+        messageCardView.show();
+        messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
+            @Override
+            public void onMessageCardButtonClicked(String tag) {
+                if ("GIVE_FEEDBACK".equals(tag)) {
+                    /* [ANALYTICS:EVENT]
+                     * TRIGGER:   Click on the Send Feedback action on the Session Details page.
+                     * CATEGORY:  'Session'
+                     * ACTION:    'Feedback'
+                     * LABEL:     session title/subtitle
+                     * [/ANALYTICS]
+                     */
+                    AnalyticsManager.sendEvent("Session", "Feedback", mTitleString, 0L);
+                    Intent intent = getFeedbackIntent();
+                    startActivity(intent);
+                } else {
+                    sDismissedFeedbackCard.add(mSessionId);
+                    messageCardView.dismiss();
+                }
+            }
+        });
+    }
+
+    private Intent getFeedbackIntent() {
+        return new Intent(Intent.ACTION_VIEW, mSessionUri, this,
+                SessionFeedbackActivity.class);
+    }
+
+    private void enableSocialStreamMenuItemDeferred() {
+        mDeferredUiOperations.add(new Runnable() {
+            @Override
+            public void run() {
+                mSocialStreamMenuItem.setVisible(true);
+            }
+        });
+        tryExecuteDeferredUiOperations();
+    }
+
+    private void showStarredDeferred(final boolean starred, final boolean allowAnimate) {
+        mDeferredUiOperations.add(new Runnable() {
+            @Override
+            public void run() {
+                showStarred(starred, allowAnimate);
+            }
+        });
+        tryExecuteDeferredUiOperations();
+    }
+
+    private void showStarred(boolean starred, boolean allowAnimate) {
+        mStarred = starred;
+
+        mAddScheduleButton.setChecked(mStarred, allowAnimate);
+
+        ImageView iconView = (ImageView) mAddScheduleButton.findViewById(R.id.add_schedule_icon);
+        getLUtils().setOrAnimatePlusCheckIcon(iconView, starred, allowAnimate);
+        mAddScheduleButton.setContentDescription(getString(starred
+                ? R.string.remove_from_schedule_desc
+                : R.string.add_to_schedule_desc));
+    }
+
+    private void setupShareMenuItemDeferred() {
+        mDeferredUiOperations.add(new Runnable() {
+            @Override
+            public void run() {
+                new SessionsHelper(SessionDetailActivity.this).tryConfigureShareMenuItem(mShareMenuItem,
+                        R.string.share_template, mTitleString, mHashTag, mUrl);
+            }
+        });
+        tryExecuteDeferredUiOperations();
+    }
+
+    private void tryExecuteDeferredUiOperations() {
+        if (mSocialStreamMenuItem != null) {
+            for (Runnable r : mDeferredUiOperations) {
+                r.run();
+            }
+            mDeferredUiOperations.clear();
+        }
+    }
+
+    private void onSpeakersQueryComplete(Cursor cursor) {
+        mSpeakersCursor = true;
+        final ViewGroup speakersGroup = (ViewGroup) findViewById(R.id.session_speakers_block);
+
+        // Remove all existing speakers (everything but first child, which is the header)
+        for (int i = speakersGroup.getChildCount() - 1; i >= 1; i--) {
+            speakersGroup.removeViewAt(i);
+        }
+
+        final LayoutInflater inflater = getLayoutInflater();
+
+        boolean hasSpeakers = false;
+
+        cursor.moveToPosition(-1); // move to just before first record
+        while (cursor.moveToNext()) {
+            final String speakerName = cursor.getString(SpeakersQuery.SPEAKER_NAME);
+            if (TextUtils.isEmpty(speakerName)) {
+                continue;
+            }
+
+            final String speakerImageUrl = cursor.getString(SpeakersQuery.SPEAKER_IMAGE_URL);
+            final String speakerCompany = cursor.getString(SpeakersQuery.SPEAKER_COMPANY);
+            final String speakerUrl = cursor.getString(SpeakersQuery.SPEAKER_URL);
+            final String speakerAbstract = cursor.getString(SpeakersQuery.SPEAKER_ABSTRACT);
+
+            String speakerHeader = speakerName;
+            if (!TextUtils.isEmpty(speakerCompany)) {
+                speakerHeader += ", " + speakerCompany;
+            }
+
+            final View speakerView = inflater
+                    .inflate(R.layout.speaker_detail, speakersGroup, false);
+            final TextView speakerHeaderView = (TextView) speakerView
+                    .findViewById(R.id.speaker_header);
+            final ImageView speakerImageView = (ImageView) speakerView
+                    .findViewById(R.id.speaker_image);
+            final TextView speakerAbstractView = (TextView) speakerView
+                    .findViewById(R.id.speaker_abstract);
+
+            if (!TextUtils.isEmpty(speakerImageUrl) && mSpeakersImageLoader != null) {
+                mSpeakersImageLoader.loadImage(speakerImageUrl, speakerImageView);
+            }
+
+            speakerHeaderView.setText(speakerHeader);
+            speakerImageView.setContentDescription(
+                    getString(R.string.speaker_googleplus_profile, speakerHeader));
+            UIUtils.setTextMaybeHtml(speakerAbstractView, speakerAbstract);
+
+            if (!TextUtils.isEmpty(speakerUrl)) {
+                speakerImageView.setEnabled(true);
+                speakerImageView.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        Intent speakerProfileIntent = new Intent(Intent.ACTION_VIEW,
+                                Uri.parse(speakerUrl));
+                        speakerProfileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                        UIUtils.preferPackageForIntent(SessionDetailActivity.this,
+                                speakerProfileIntent,
+                                UIUtils.GOOGLE_PLUS_PACKAGE_NAME);
+                        startActivity(speakerProfileIntent);
+                    }
+                });
+            } else {
+                speakerImageView.setEnabled(false);
+                speakerImageView.setOnClickListener(null);
+            }
+
+            speakersGroup.addView(speakerView);
+            hasSpeakers = true;
+            mHasSummaryContent = true;
+        }
+
+        speakersGroup.setVisibility(hasSpeakers ? View.VISIBLE : View.GONE);
+        updateEmptyView();
+    }
+
+    private void updateEmptyView() {
+        findViewById(android.R.id.empty).setVisibility(
+                (mSpeakersCursor && mSessionCursor && !mHasSummaryContent)
+                        ? View.VISIBLE
+                        : View.GONE);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        getMenuInflater().inflate(R.menu.session_detail, menu);
+        mSocialStreamMenuItem = menu.findItem(R.id.menu_social_stream);
+        mShareMenuItem = menu.findItem(R.id.menu_share);
+        tryExecuteDeferredUiOperations();
+        return true;
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if (item.getItemId() == android.R.id.home) {
-            finish();
-            return true;
+        SessionsHelper helper = new SessionsHelper(this);
+        switch (item.getItemId()) {
+            case R.id.menu_map_room:
+                /* [ANALYTICS:EVENT]
+                 * TRIGGER:   Click on the Map action on the Session Details page.
+                 * CATEGORY:  'Session'
+                 * ACTION:    'Map'
+                 * LABEL:     session title/subtitle
+                 * [/ANALYTICS]
+                 */
+                AnalyticsManager.sendEvent("Session", "Map", mTitleString, 0L);
+                helper.startMapActivity(mRoomId);
+                return true;
+
+            case R.id.menu_share:
+                // On ICS+ devices, we normally won't reach this as ShareActionProvider will handle
+                // sharing.
+                helper.shareSession(this, R.string.share_template, mTitleString,
+                        mHashTag, mUrl);
+                return true;
+
+            case R.id.menu_social_stream:
+                if (!TextUtils.isEmpty(mHashTag)) {
+                    /* [ANALYTICS:EVENT]
+                     * TRIGGER:   Click on the Social Stream action on the Session Details page.
+                     * CATEGORY:  'Session'
+                     * ACTION:    'Stream'
+                     * LABEL:     session title/subtitle
+                     * [/ANALYTICS]
+                     */
+                    AnalyticsManager.sendEvent("Session", "Stream", mTitleString, 0L);
+                    UIUtils.showHashtagStream(this, mHashTag);
+                }
+                return true;
         }
-        return super.onOptionsItemSelected(item);
+        return false;
     }
+
+    /*
+     * Event structure:
+     * Category -> "Session Details"
+     * Action -> Link Text
+     * Label -> Session's Title
+     * Value -> 0.
+     */
+    void fireLinkEvent(int actionId) {
+        /* [ANALYTICS:EVENT]
+         * TRIGGER:   Click on a link on the Session Details page.
+         * CATEGORY:  'Session'
+         * ACTION:    The link's name ("Watch Live", "Follow us on Google+", etc)
+         * LABEL:     The session's title/subtitle.
+         * [/ANALYTICS]
+         */
+        AnalyticsManager.sendEvent("Session", getString(actionId), mTitleString, 0L);
+    }
+
+    /**
+     * {@link com.google.samples.apps.iosched.provider.ScheduleContract.Sessions} query parameters.
+     */
+    private interface SessionsQuery {
+        int _TOKEN = 0x1;
+
+        String[] PROJECTION = {
+                ScheduleContract.Sessions.SESSION_START,
+                ScheduleContract.Sessions.SESSION_END,
+                ScheduleContract.Sessions.SESSION_LEVEL,
+                ScheduleContract.Sessions.SESSION_TITLE,
+                ScheduleContract.Sessions.SESSION_ABSTRACT,
+                ScheduleContract.Sessions.SESSION_REQUIREMENTS,
+                ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
+                ScheduleContract.Sessions.SESSION_HASHTAG,
+                ScheduleContract.Sessions.SESSION_URL,
+                ScheduleContract.Sessions.SESSION_YOUTUBE_URL,
+                ScheduleContract.Sessions.SESSION_PDF_URL,
+                ScheduleContract.Sessions.SESSION_NOTES_URL,
+                ScheduleContract.Sessions.SESSION_LIVESTREAM_URL,
+                ScheduleContract.Sessions.SESSION_MODERATOR_URL,
+                ScheduleContract.Sessions.ROOM_ID,
+                ScheduleContract.Rooms.ROOM_NAME,
+                ScheduleContract.Sessions.SESSION_COLOR,
+                ScheduleContract.Sessions.SESSION_PHOTO_URL,
+                ScheduleContract.Sessions.SESSION_RELATED_CONTENT,
+                ScheduleContract.Sessions.SESSION_TAGS,
+                ScheduleContract.Sessions.SESSION_SPEAKER_NAMES
+        };
+
+        int START = 0;
+        int END = 1;
+        int LEVEL = 2;
+        int TITLE = 3;
+        int ABSTRACT = 4;
+        int REQUIREMENTS = 5;
+        int IN_MY_SCHEDULE = 6;
+        int HASHTAG = 7;
+        int URL = 8;
+        int YOUTUBE_URL = 9;
+        int PDF_URL = 10;
+        int NOTES_URL = 11;
+        int LIVESTREAM_URL = 12;
+        int MODERATOR_URL = 13;
+        int ROOM_ID = 14;
+        int ROOM_NAME = 15;
+        int COLOR = 16;
+        int PHOTO_URL = 17;
+        int RELATED_CONTENT = 18;
+        int TAGS = 19;
+        int SPEAKER_NAMES = 20;
+
+        int[] LINKS_INDICES = {
+                YOUTUBE_URL,
+                MODERATOR_URL,
+                PDF_URL,
+                NOTES_URL,
+        };
+
+        int[] LINKS_TITLES = {
+                R.string.session_link_youtube,
+                R.string.session_link_moderator,
+                R.string.session_link_pdf,
+                R.string.session_link_notes,
+        };
+    }
+
+    private interface SpeakersQuery {
+        int _TOKEN = 0x3;
+
+        String[] PROJECTION = {
+                ScheduleContract.Speakers.SPEAKER_NAME,
+                ScheduleContract.Speakers.SPEAKER_IMAGE_URL,
+                ScheduleContract.Speakers.SPEAKER_COMPANY,
+                ScheduleContract.Speakers.SPEAKER_ABSTRACT,
+                ScheduleContract.Speakers.SPEAKER_URL,
+        };
+
+        int SPEAKER_NAME = 0;
+        int SPEAKER_IMAGE_URL = 1;
+        int SPEAKER_COMPANY = 2;
+        int SPEAKER_ABSTRACT = 3;
+        int SPEAKER_URL = 4;
+    }
+
+    private interface FeedbackQuery {
+        int _TOKEN = 0x4;
+
+        String[] PROJECTION = {
+                ScheduleContract.Feedback.SESSION_ID
+        };
+    }
+
+    private static final int TAG_METADATA_TOKEN = 0x5;
+
+    @Override
+    public Loader<Cursor> onCreateLoader(int id, Bundle data) {
+        CursorLoader loader = null;
+        if (id == SessionsQuery._TOKEN){
+            loader = new CursorLoader(this, mSessionUri, SessionsQuery.PROJECTION, null,
+                    null, null);
+        } else if (id == SpeakersQuery._TOKEN  && mSessionUri != null){
+            Uri speakersUri = ScheduleContract.Sessions.buildSpeakersDirUri(mSessionId);
+            loader = new CursorLoader(this, speakersUri, SpeakersQuery.PROJECTION, null,
+                    null, ScheduleContract.Speakers.DEFAULT_SORT);
+        } else if (id == FeedbackQuery._TOKEN) {
+            Uri feedbackUri = ScheduleContract.Feedback.buildFeedbackUri(mSessionId);
+            loader = new CursorLoader(this, feedbackUri, FeedbackQuery.PROJECTION, null,
+                    null, null);
+        } else if (id == TAG_METADATA_TOKEN) {
+            loader = TagMetadata.createCursorLoader(this);
+        }
+        return loader;
+    }
+
+    @Override
+    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
+        if (loader.getId() == SessionsQuery._TOKEN) {
+            onSessionQueryComplete(cursor);
+        } else if (loader.getId() == SpeakersQuery._TOKEN) {
+            onSpeakersQueryComplete(cursor);
+        } else if (loader.getId() == FeedbackQuery._TOKEN) {
+            onFeedbackQueryComplete(cursor);
+        } else if (loader.getId() == TAG_METADATA_TOKEN) {
+            mTagMetadata = new TagMetadata(cursor);
+            cursor.close();
+            tryRenderTags();
+        } else {
+            cursor.close();
+        }
+    }
+
+    @Override
+    public void onLoaderReset(Loader<Cursor> loader) {}
 }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailFragment.java
deleted file mode 100644
index b824bba..0000000
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailFragment.java
+++ /dev/null
@@ -1,1306 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * 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.google.samples.apps.iosched.ui;
-
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.*;
-import android.database.Cursor;
-import android.graphics.Paint;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.OvalShape;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.TextUtils;
-import android.util.Pair;
-import android.view.*;
-import android.view.View.OnClickListener;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.google.android.gms.plus.PlusOneButton;
-import com.google.android.youtube.player.YouTubeIntents;
-import com.google.samples.apps.iosched.Config;
-import com.google.samples.apps.iosched.R;
-import com.google.samples.apps.iosched.model.TagMetadata;
-import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.service.SessionAlarmService;
-import com.google.samples.apps.iosched.service.SessionCalendarService;
-import com.google.samples.apps.iosched.ui.widget.CheckableFrameLayout;
-import com.google.samples.apps.iosched.ui.widget.MessageCardView;
-import com.google.samples.apps.iosched.ui.widget.ObservableScrollView;
-import com.google.samples.apps.iosched.util.*;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-
-import com.bumptech.glide.request.bitmap.RequestListener;
-import com.bumptech.glide.request.target.Target;
-
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
-import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-
-/**
- * A fragment that shows detail information for a session, including session title, abstract,
- * time information, speaker photos and bios, etc.
- */
-public class SessionDetailFragment extends Fragment implements
-        LoaderManager.LoaderCallbacks<Cursor>,
-        ObservableScrollView.Callbacks {
-
-    private static final String TAG = makeLogTag(SessionDetailFragment.class);
-
-    private static final int[] SECTION_HEADER_RES_IDS = {
-            R.id.session_links_header,
-            R.id.session_speakers_header,
-            R.id.session_requirements_header,
-            R.id.related_videos_header,
-    };
-    private static final float PHOTO_ASPECT_RATIO = 1.7777777f;
-
-    public static final String VIEW_NAME_PHOTO = "photo";
-
-    private Handler mHandler = new Handler();
-    private static final int TIME_HINT_UPDATE_INTERVAL = 10000; // 10 sec
-
-    private TagMetadata mTagMetadata;
-
-    private String mSessionId;
-    private Uri mSessionUri;
-
-    private long mSessionStart;
-    private long mSessionEnd;
-    private String mTitleString;
-    private String mHashTag;
-    private String mUrl;
-    private String mRoomId;
-    private String mRoomName;
-    private String mTagsString;
-
-    // A comma-separated list of speakers to be passed to Android Wear
-    private String mSpeakers;
-
-    private boolean mStarred;
-    private boolean mInitStarred;
-    private boolean mDismissedWatchLivestreamCard = false;
-    private boolean mHasLivestream = false;
-    private MenuItem mSocialStreamMenuItem;
-    private MenuItem mShareMenuItem;
-
-    private ViewGroup mRootView;
-    private View mScrollViewChild;
-    private TextView mTitle;
-    private TextView mSubtitle;
-    private PlusOneButton mPlusOneButton;
-
-    private ObservableScrollView mScrollView;
-    private CheckableFrameLayout mAddScheduleButton;
-
-    private TextView mAbstract;
-    private LinearLayout mTags;
-    private ViewGroup mTagsContainer;
-    private TextView mRequirements;
-    private View mHeaderBox;
-    private View mHeaderContentBox;
-    private View mHeaderBackgroundBox;
-    private View mHeaderShadow;
-    private View mDetailsContainer;
-
-    private boolean mSessionCursor = false;
-    private boolean mSpeakersCursor = false;
-    private boolean mHasSummaryContent = false;
-
-    private ImageLoader mSpeakersImageLoader, mNoPlaceholderImageLoader;
-    private List<Runnable> mDeferredUiOperations = new ArrayList<Runnable>();
-
-    private StringBuilder mBuffer = new StringBuilder();
-
-    private int mHeaderTopClearance;
-    private int mPhotoHeightPixels;
-    private int mHeaderHeightPixels;
-    private int mAddScheduleButtonHeightPixels;
-
-    private boolean mHasPhoto;
-    private View mPhotoViewContainer;
-    private ImageView mPhotoView;
-    boolean mGapFillShown;
-    private int mSessionColor;
-    private String mLivestreamUrl;
-
-    private static final float GAP_FILL_DISTANCE_MULTIPLIER = 1.5f;
-
-    private Runnable mTimeHintUpdaterRunnable = null;
-
-    private boolean mAlreadyGaveFeedback = false;
-    private boolean mIsKeynote = false;
-
-    // this set stores the session IDs for which the user has dismissed the
-    // "give feedback" card. This information is kept for the duration of the app's execution
-    // so that if they say "No, thanks", we don't show the card again for that session while
-    // the app is still executing.
-    private static HashSet<String> sDismissedFeedbackCard = new HashSet<String>();
-
-    private TextView mSubmitFeedbackView;
-    private float mMaxHeaderElevation;
-    private float mFABElevation;
-
-    private int mTagColorDotSize;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final Intent intent = BaseActivity.fragmentArgumentsToIntent(getArguments());
-        mSessionUri = intent.getData();
-
-        if (mSessionUri == null) {
-            return;
-        }
-
-        mSessionId = ScheduleContract.Sessions.getSessionId(mSessionUri);
-
-        setHasOptionsMenu(true);
-
-        mFABElevation = getResources().getDimensionPixelSize(R.dimen.fab_elevation);
-        mMaxHeaderElevation = getResources().getDimensionPixelSize(
-                R.dimen.session_detail_max_header_elevation);
-
-        mTagColorDotSize = getResources().getDimensionPixelSize(R.dimen.tag_color_dot_size);
-
-        mHandler = new Handler();
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-
-        mRootView = (ViewGroup) inflater.inflate(R.layout.fragment_session_detail, container, false);
-        mScrollViewChild = mRootView.findViewById(R.id.scroll_view_child);
-        mScrollViewChild.setVisibility(View.INVISIBLE);
-
-        mDetailsContainer = mRootView.findViewById(R.id.details_container);
-        mHeaderBox = mRootView.findViewById(R.id.header_session);
-        mHeaderContentBox = mRootView.findViewById(R.id.header_session_contents);
-        mHeaderBackgroundBox = mRootView.findViewById(R.id.header_background);
-        mHeaderShadow = mRootView.findViewById(R.id.header_shadow);
-        mTitle = (TextView) mRootView.findViewById(R.id.session_title);
-        mSubtitle = (TextView) mRootView.findViewById(R.id.session_subtitle);
-        mPhotoViewContainer = mRootView.findViewById(R.id.session_photo_container);
-        mPhotoView = (ImageView) mRootView.findViewById(R.id.session_photo);
-
-        mPlusOneButton = (PlusOneButton) mRootView.findViewById(R.id.plus_one_button);
-        mAbstract = (TextView) mRootView.findViewById(R.id.session_abstract);
-        mRequirements = (TextView) mRootView.findViewById(R.id.session_requirements);
-        mTags = (LinearLayout) mRootView.findViewById(R.id.session_tags);
-        mTagsContainer = (ViewGroup) mRootView.findViewById(R.id.session_tags_container);
-
-        mAddScheduleButton = (CheckableFrameLayout)
-                mRootView.findViewById(R.id.add_schedule_button);
-        mAddScheduleButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                boolean starred = !mStarred;
-                SessionsHelper helper = new SessionsHelper(getActivity());
-                showStarred(starred, true);
-                helper.setSessionStarred(mSessionUri, starred, mTitleString);
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-                    mRootView.announceForAccessibility(starred ?
-                            getString(R.string.session_details_a11y_session_added) :
-                            getString(R.string.session_details_a11y_session_removed));
-                }
-
-                /* [ANALYTICS:EVENT]
-                 * TRIGGER:   Add or remove a session from My Schedule.
-                 * CATEGORY:  'Session'
-                 * ACTION:    'Starred' or 'Unstarred'
-                 * LABEL:     Session title/subtitle.
-                 * [/ANALYTICS]
-                 */
-                AnalyticsManager.sendEvent(
-                        "Session", starred ? "Starred" : "Unstarred", mTitleString, 0L);
-            }
-        });
-
-        ((BaseActivity) getActivity()).getLPreviewUtils().setViewName(mPhotoView, VIEW_NAME_PHOTO);
-
-        setupCustomScrolling(mRootView);
-        return mRootView;
-    }
-
-    private void recomputePhotoAndScrollingMetrics() {
-        final int actionBarSize = UIUtils.calculateActionBarSize(getActivity());
-        mHeaderTopClearance = actionBarSize - mHeaderContentBox.getPaddingTop();
-        mHeaderHeightPixels = mHeaderContentBox.getHeight();
-
-        mPhotoHeightPixels = mHeaderTopClearance;
-        if (mHasPhoto) {
-            mPhotoHeightPixels = (int) (mPhotoView.getWidth() / PHOTO_ASPECT_RATIO);
-            mPhotoHeightPixels = Math.min(mPhotoHeightPixels, mRootView.getHeight() * 2 / 3);
-        }
-
-        ViewGroup.LayoutParams lp;
-        lp = mPhotoViewContainer.getLayoutParams();
-        if (lp.height != mPhotoHeightPixels) {
-            lp.height = mPhotoHeightPixels;
-            mPhotoViewContainer.setLayoutParams(lp);
-        }
-
-        lp = mHeaderBackgroundBox.getLayoutParams();
-        if (lp.height != mHeaderHeightPixels) {
-            lp.height = mHeaderHeightPixels;
-            mHeaderBackgroundBox.setLayoutParams(lp);
-        }
-
-        ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
-                mDetailsContainer.getLayoutParams();
-        if (mlp.topMargin != mHeaderHeightPixels + mPhotoHeightPixels) {
-            mlp.topMargin = mHeaderHeightPixels + mPhotoHeightPixels;
-            mDetailsContainer.setLayoutParams(mlp);
-        }
-
-        onScrollChanged(0, 0); // trigger scroll handling
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        if (mSpeakersImageLoader == null) {
-            mSpeakersImageLoader = new ImageLoader(this.getActivity(), R.drawable.person_image_empty);
-        }
-        if (mNoPlaceholderImageLoader == null) {
-            mNoPlaceholderImageLoader = new ImageLoader(this.getActivity());
-        }
-    }
-
-    private void setupCustomScrolling(View rootView) {
-        mScrollView = (ObservableScrollView) rootView.findViewById(R.id.scroll_view);
-        mScrollView.addCallbacks(this);
-        ViewTreeObserver vto = mScrollView.getViewTreeObserver();
-        if (vto.isAlive()) {
-            vto.addOnGlobalLayoutListener(mGlobalLayoutListener);
-        }
-    }
-
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-        if (mScrollView == null) {
-            return;
-        }
-
-        ViewTreeObserver vto = mScrollView.getViewTreeObserver();
-        if (vto.isAlive()) {
-            vto.removeGlobalOnLayoutListener(mGlobalLayoutListener);
-        }
-    }
-
-    private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener
-            = new ViewTreeObserver.OnGlobalLayoutListener() {
-        @Override
-        public void onGlobalLayout() {
-            mAddScheduleButtonHeightPixels = mAddScheduleButton.getHeight();
-            recomputePhotoAndScrollingMetrics();
-        }
-    };
-
-    @Override
-    public void onScrollChanged(int deltaX, int deltaY) {
-        final BaseActivity activity = (BaseActivity) getActivity();
-        if (activity == null) {
-            return;
-        }
-
-        // Reposition the header bar -- it's normally anchored to the top of the content,
-        // but locks to the top of the screen on scroll
-        int scrollY = mScrollView.getScrollY();
-
-        float newTop = Math.max(mPhotoHeightPixels, scrollY + mHeaderTopClearance);
-        mHeaderBox.setTranslationY(newTop);
-        mAddScheduleButton.setTranslationY(newTop + mHeaderHeightPixels
-                - mAddScheduleButtonHeightPixels / 2);
-
-        mHeaderBackgroundBox.setPivotY(mHeaderHeightPixels);
-        int gapFillDistance = (int) (mHeaderTopClearance * GAP_FILL_DISTANCE_MULTIPLIER);
-        boolean showGapFill = !mHasPhoto || (scrollY > (mPhotoHeightPixels - gapFillDistance));
-        float desiredHeaderScaleY = showGapFill ?
-                ((mHeaderHeightPixels + gapFillDistance + 1) * 1f / mHeaderHeightPixels)
-                : 1f;
-        if (!mHasPhoto) {
-            mHeaderBackgroundBox.setScaleY(desiredHeaderScaleY);
-        } else if (mGapFillShown != showGapFill) {
-            mHeaderBackgroundBox.animate()
-                    .scaleY(desiredHeaderScaleY)
-                    .setInterpolator(new DecelerateInterpolator(2f))
-                    .setDuration(250)
-                    .start();
-        }
-        mGapFillShown = showGapFill;
-
-        LPreviewUtilsBase lpu = activity.getLPreviewUtils();
-
-        mHeaderShadow.setVisibility(lpu.hasLPreviewAPIs() ? View.GONE : View.VISIBLE);
-
-        if (mHeaderTopClearance != 0) {
-            // Fill the gap between status bar and header bar with color
-            float gapFillProgress = Math.min(Math.max(UIUtils.getProgress(scrollY,
-                    mPhotoHeightPixels - mHeaderTopClearance * 2,
-                    mPhotoHeightPixels - mHeaderTopClearance), 0), 1);
-            lpu.setViewElevation(mHeaderBackgroundBox, gapFillProgress * mMaxHeaderElevation);
-            lpu.setViewElevation(mHeaderContentBox, gapFillProgress * mMaxHeaderElevation + 0.1f);
-            lpu.setViewElevation(mAddScheduleButton, gapFillProgress * mMaxHeaderElevation
-                    + mFABElevation);
-            if (!lpu.hasLPreviewAPIs()) {
-                mHeaderShadow.setAlpha(gapFillProgress);
-            }
-        }
-
-        // Move background photo (parallax effect)
-        mPhotoViewContainer.setTranslationY(scrollY * 0.5f);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        updatePlusOneButton();
-        if (mTimeHintUpdaterRunnable != null) {
-            mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
-        }
-
-        // Refresh whether or not feedback has been submitted
-        getLoaderManager().restartLoader(FeedbackQuery._TOKEN, null, this);
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        if (mInitStarred != mStarred) {
-            if (UIUtils.getCurrentTime(getActivity()) < mSessionStart) {
-                // Update Calendar event through the Calendar API on Android 4.0 or new versions.
-                Intent intent = null;
-                if (mStarred) {
-                    // Set up intent to add session to Calendar, if it doesn't exist already.
-                    intent = new Intent(SessionCalendarService.ACTION_ADD_SESSION_CALENDAR,
-                            mSessionUri);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
-                            mSessionStart);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
-                            mSessionEnd);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_ROOM, mRoomName);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
-                } else {
-                    // Set up intent to remove session from Calendar, if exists.
-                    intent = new Intent(SessionCalendarService.ACTION_REMOVE_SESSION_CALENDAR,
-                            mSessionUri);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
-                            mSessionStart);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
-                            mSessionEnd);
-                    intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
-                }
-                intent.setClass(getActivity(), SessionCalendarService.class);
-                getActivity().startService(intent);
-
-                if (mStarred) {
-                    setupNotification();
-                }
-            }
-        }
-    }
-
-    private void setupNotification() {
-        Intent scheduleIntent;
-        final Context context = getActivity();
-
-        // Schedule session notification
-        if (UIUtils.getCurrentTime(context) < mSessionStart) {
-            LOGD(TAG, "Scheduling notification about session start.");
-            scheduleIntent = new Intent(
-                    SessionAlarmService.ACTION_SCHEDULE_STARRED_BLOCK,
-                    null, context, SessionAlarmService.class);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
-            context.startService(scheduleIntent);
-        } else {
-            LOGD(TAG, "Not scheduling notification about session start, too late.");
-        }
-
-        // Schedule feedback notification
-        if (UIUtils.getCurrentTime(context) < mSessionEnd) {
-            LOGD(TAG, "Scheduling notification about session feedback.");
-            scheduleIntent = new Intent(
-                    SessionAlarmService.ACTION_SCHEDULE_FEEDBACK_NOTIFICATION,
-                    null, context, SessionAlarmService.class);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ID, mSessionId);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_TITLE, mTitleString);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ROOM, mRoomName);
-            scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_SPEAKERS, mSpeakers);
-            context.startService(scheduleIntent);
-        } else {
-            LOGD(TAG, "Not scheduling feedback notification, too late.");
-        }
-    }
-
-    private void updateTimeBasedUi() {
-        final Context context = mRootView.getContext();
-        long currentTimeMillis = UIUtils.getCurrentTime(context);
-        boolean canShowLivestream = mHasLivestream;
-
-        if (canShowLivestream && !mDismissedWatchLivestreamCard
-                && currentTimeMillis > mSessionStart
-                && currentTimeMillis <= mSessionEnd) {
-            // show the "watch now" card
-            showWatchNowCard();
-        } else if (!mAlreadyGaveFeedback && mInitStarred && currentTimeMillis >= (mSessionEnd -
-                Config.FEEDBACK_MILLIS_BEFORE_SESSION_END)
-                && !sDismissedFeedbackCard.contains(mSessionId)) {
-            // show the "give feedback" card
-            showGiveFeedbackCard();
-        }
-
-        String timeHint = "";
-        long countdownMillis = mSessionStart - currentTimeMillis;
-
-        if (TimeUtils.hasConferenceEnded(context)) {
-            // no time hint to display
-            timeHint = "";
-        } else if (currentTimeMillis >= mSessionEnd) {
-            timeHint = context.getString(R.string.time_hint_session_ended);
-        } else if (currentTimeMillis >= mSessionStart) {
-            long minutesAgo = (currentTimeMillis - mSessionStart) / 60000;
-            if (minutesAgo > 1) {
-                timeHint = context.getString(R.string.time_hint_started_min, minutesAgo);
-            } else {
-                timeHint = context.getString(R.string.time_hint_started_just);
-            }
-        } else if (countdownMillis > 0 && countdownMillis < Config.HINT_TIME_BEFORE_SESSION) {
-            long millisUntil = mSessionStart - currentTimeMillis;
-            long minutesUntil = millisUntil / 60000 + (millisUntil % 1000 > 0 ? 1 : 0);
-            if (minutesUntil > 1) {
-                timeHint = context.getString(R.string.time_hint_about_to_start_min, minutesUntil);
-            } else {
-                timeHint = context.getString(R.string.time_hint_about_to_start_shortly, minutesUntil);
-            }
-        }
-
-        final TextView timeHintView = (TextView) mRootView.findViewById(R.id.time_hint);
-
-        if (!TextUtils.isEmpty(timeHint)) {
-            timeHintView.setVisibility(View.VISIBLE);
-            timeHintView.setText(timeHint);
-        } else {
-            timeHintView.setVisibility(View.GONE);
-        }
-    }
-
-    private void setTextSelectable(TextView tv) {
-        if (tv != null && !tv.isTextSelectable()) {
-            tv.setTextIsSelectable(true);
-        }
-    }
-
-    private void onFeedbackQueryComplete(Cursor cursor) {
-        // Views have not been set up yet -- continue loading the rest of data
-        if (mSubmitFeedbackView == null) {
-            LoaderManager manager = getLoaderManager();
-            manager.restartLoader(SessionsQuery._TOKEN, null, this);
-            manager.restartLoader(SpeakersQuery._TOKEN, null, this);
-            manager.restartLoader(TAG_METADATA_TOKEN, null, this);
-        }
-
-        // Is there existing feedback for this session?
-        mAlreadyGaveFeedback = cursor.getCount() > 0;
-
-        if (mAlreadyGaveFeedback) {
-            final MessageCardView giveFeedbackCardView = (MessageCardView) mRootView.findViewById(
-                    R.id.give_feedback_card);
-            if (giveFeedbackCardView != null) {
-                giveFeedbackCardView.setVisibility(View.GONE);
-            }
-            if (mSubmitFeedbackView != null) {
-                mSubmitFeedbackView.setVisibility(View.GONE);
-            }
-        }
-        LOGD(TAG, "User " + (mAlreadyGaveFeedback ? "already gave" : "has not given") + " feedback for session.");
-        cursor.close();
-    }
-
-    /**
-     * Handle {@link SessionsQuery} {@link Cursor}.
-     */
-    private void onSessionQueryComplete(Cursor cursor) {
-        mSessionCursor = true;
-        if (!cursor.moveToFirst()) {
-            if (isAdded()) {
-                // TODO: Remove this in favor of a callbacks interface that the activity
-                // can implement.
-                getActivity().finish();
-            }
-            return;
-        }
-
-        mTitleString = cursor.getString(SessionsQuery.TITLE);
-        mSessionColor = cursor.getInt(SessionsQuery.COLOR);
-
-        if (mSessionColor == 0) {
-            // no color -- use default
-            mSessionColor = getResources().getColor(R.color.default_session_color);
-        } else {
-            // make sure it's opaque
-            mSessionColor = UIUtils.setColorAlpha(mSessionColor, 255);
-        }
-
-        mHeaderBackgroundBox.setBackgroundColor(mSessionColor);
-        ((BaseActivity) getActivity()).getLPreviewUtils().setStatusBarColor(
-                UIUtils.scaleColor(mSessionColor, 0.8f, false));
-
-        mLivestreamUrl = cursor.getString(SessionsQuery.LIVESTREAM_URL);
-        mHasLivestream = !TextUtils.isEmpty(mLivestreamUrl);
-
-        // Format the time this session occupies
-        mSessionStart = cursor.getLong(SessionsQuery.START);
-        mSessionEnd = cursor.getLong(SessionsQuery.END);
-        mRoomName = cursor.getString(SessionsQuery.ROOM_NAME);
-        mSpeakers = cursor.getString(SessionsQuery.SPEAKER_NAMES);
-        String subtitle = UIUtils.formatSessionSubtitle(
-                mSessionStart, mSessionEnd, mRoomName, mBuffer, getActivity());
-        if (mHasLivestream) {
-            subtitle += " " + UIUtils.getLiveBadgeText(getActivity(), mSessionStart, mSessionEnd);
-        }
-
-        mTitle.setText(mTitleString);
-        mSubtitle.setText(subtitle);
-
-        for (int resId : SECTION_HEADER_RES_IDS) {
-            ((TextView) mRootView.findViewById(resId)).setTextColor(mSessionColor);
-        }
-
-        mPhotoViewContainer.setBackgroundColor(UIUtils.scaleSessionColorToDefaultBG(mSessionColor));
-
-        String photo = cursor.getString(SessionsQuery.PHOTO_URL);
-        if (!TextUtils.isEmpty(photo)) {
-            mHasPhoto = true;
-            mNoPlaceholderImageLoader.loadImage(photo, mPhotoView, new RequestListener<String>() {
-                @Override
-                public void onException(Exception e, String url, Target target) {
-                    mHasPhoto = false;
-                    recomputePhotoAndScrollingMetrics();
-                }
-
-                @Override
-                public void onImageReady(String url, Target target, boolean b, boolean b2) {
-                    // Trigger image transition
-                    recomputePhotoAndScrollingMetrics();
-                }
-            });
-            recomputePhotoAndScrollingMetrics();
-        } else {
-            mHasPhoto = false;
-            recomputePhotoAndScrollingMetrics();
-        }
-
-        mUrl = cursor.getString(SessionsQuery.URL);
-        if (TextUtils.isEmpty(mUrl)) {
-            mUrl = "";
-        }
-
-        mHashTag = cursor.getString(SessionsQuery.HASHTAG);
-        if (!TextUtils.isEmpty(mHashTag)) {
-            enableSocialStreamMenuItemDeferred();
-        }
-
-        mRoomId = cursor.getString(SessionsQuery.ROOM_ID);
-
-        final boolean inMySchedule = cursor.getInt(SessionsQuery.IN_MY_SCHEDULE) != 0;
-
-        setupShareMenuItemDeferred();
-
-        // Handle Keynote as a special case, where the user cannot remove it
-        // from the schedule (it is auto added to schedule on sync)
-        mTagsString = cursor.getString(SessionsQuery.TAGS);
-        mIsKeynote = mTagsString.contains(Config.Tags.SPECIAL_KEYNOTE);
-        mAddScheduleButton.setVisibility(
-                (AccountUtils.hasActiveAccount(getActivity()) && !mIsKeynote)
-                        ? View.VISIBLE : View.INVISIBLE);
-
-        tryRenderTags();
-
-        if (!mIsKeynote) {
-            showStarredDeferred(mInitStarred = inMySchedule, false);
-        }
-
-        final String sessionAbstract = cursor.getString(SessionsQuery.ABSTRACT);
-        if (!TextUtils.isEmpty(sessionAbstract)) {
-            UIUtils.setTextMaybeHtml(mAbstract, sessionAbstract);
-            mAbstract.setVisibility(View.VISIBLE);
-            mHasSummaryContent = true;
-        } else {
-            mAbstract.setVisibility(View.GONE);
-        }
-
-        updatePlusOneButton();
-
-        // Build requirements section
-        final View requirementsBlock = mRootView.findViewById(R.id.session_requirements_block);
-        final String sessionRequirements = cursor.getString(SessionsQuery.REQUIREMENTS);
-        if (!TextUtils.isEmpty(sessionRequirements)) {
-            UIUtils.setTextMaybeHtml(mRequirements, sessionRequirements);
-            requirementsBlock.setVisibility(View.VISIBLE);
-            mHasSummaryContent = true;
-        } else {
-            requirementsBlock.setVisibility(View.GONE);
-        }
-
-        // Build related videos section
-        final ViewGroup relatedVideosBlock = (ViewGroup) mRootView.findViewById(R.id.related_videos_block);
-        relatedVideosBlock.setVisibility(View.GONE);
-
-
-        // Build links section
-        buildLinksSection(cursor);
-
-        // Show empty message when all data is loaded, and nothing to show
-        if (mSpeakersCursor && !mHasSummaryContent) {
-            mRootView.findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
-        }
-
-        updateTimeBasedUi();
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                onScrollChanged(0, 0); // trigger scroll handling
-                mScrollViewChild.setVisibility(View.VISIBLE);
-                //mAbstract.setTextIsSelectable(true);
-            }
-        });
-
-        mTimeHintUpdaterRunnable = new Runnable() {
-            @Override
-            public void run() {
-                if (isAdded()) {
-                    updateTimeBasedUi();
-                    mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
-                }
-            }
-        };
-        mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
-    }
-
-    private void tryRenderTags() {
-        if (mTagMetadata == null || mTagsString == null || !isAdded()) {
-            return;
-        }
-
-        if (TextUtils.isEmpty(mTagsString)) {
-            mTagsContainer.setVisibility(View.GONE);
-        } else {
-            mTagsContainer.setVisibility(View.VISIBLE);
-            mTags.removeAllViews();
-            LayoutInflater inflater = LayoutInflater.from(getActivity());
-            String[] tagIds = mTagsString.split(",");
-
-            List<TagMetadata.Tag> tags = new ArrayList<TagMetadata.Tag>();
-            for (String tagId : tagIds) {
-                if (Config.Tags.SESSIONS.equals(tagId) ||
-                        Config.Tags.SPECIAL_KEYNOTE.equals(tagId)) {
-                    continue;
-                }
-
-                TagMetadata.Tag tag = mTagMetadata.getTag(tagId);
-                if (tag == null) {
-                    continue;
-                }
-
-                tags.add(tag);
-            }
-
-            if (tags.size() == 0) {
-                mTagsContainer.setVisibility(View.GONE);
-                return;
-            }
-
-            Collections.sort(tags, TagMetadata.TAG_DISPLAY_ORDER_COMPARATOR);
-
-            for (final TagMetadata.Tag tag : tags) {
-                TextView chipView = (TextView) inflater.inflate(
-                        R.layout.include_session_tag_chip, mTags, false);
-                chipView.setText(tag.getName());
-
-                if (Config.Tags.CATEGORY_TOPIC.equals(tag.getCategory())) {
-                    ShapeDrawable colorDrawable = new ShapeDrawable(new OvalShape());
-                    colorDrawable.setIntrinsicWidth(mTagColorDotSize);
-                    colorDrawable.setIntrinsicHeight(mTagColorDotSize);
-                    colorDrawable.getPaint().setStyle(Paint.Style.FILL);
-                    chipView.setCompoundDrawablesWithIntrinsicBounds(colorDrawable,
-                            null, null, null);
-                    colorDrawable.getPaint().setColor(tag.getColor());
-                }
-
-                chipView.setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View view) {
-                        getActivity().finish(); // TODO: better encapsulation
-                        Intent intent = new Intent(getActivity(), BrowseSessionsActivity.class)
-                                .putExtra(BrowseSessionsActivity.EXTRA_FILTER_TAG, tag.getId())
-                                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-                        startActivity(intent);
-                    }
-                });
-
-                mTags.addView(chipView);
-            }
-        }
-    }
-
-    private void buildLinksSection(Cursor cursor) {
-        final Context context = mRootView.getContext();
-
-        // Compile list of links (I/O live link, submit feedback, and normal links)
-        ViewGroup linkContainer = (ViewGroup) mRootView.findViewById(R.id.links_container);
-        linkContainer.removeAllViews();
-
-
-        // Build links section
-        // the Object can be either a string URL or an Intent
-        List<Pair<Integer, Object>> links = new ArrayList<Pair<Integer, Object>>();
-
-        long currentTimeMillis = UIUtils.getCurrentTime(context);
-        if (mHasLivestream
-                && currentTimeMillis > mSessionStart
-                && currentTimeMillis <= mSessionEnd) {
-            links.add(new Pair<Integer, Object>(
-                    R.string.session_link_livestream,
-                    getWatchLiveIntent(context)));
-        }
-
-        // Add session feedback link, if appropriate
-        if (!mAlreadyGaveFeedback && currentTimeMillis > mSessionEnd
-                - Config.FEEDBACK_MILLIS_BEFORE_SESSION_END) {
-            links.add(new Pair<Integer, Object>(
-                    R.string.session_feedback_submitlink,
-                    getFeedbackIntent()
-            ));
-        }
-
-        for (int i = 0; i < SessionsQuery.LINKS_INDICES.length; i++) {
-            final String linkUrl = cursor.getString(SessionsQuery.LINKS_INDICES[i]);
-            if (TextUtils.isEmpty(linkUrl)) {
-                continue;
-            }
-
-            links.add(new Pair<Integer, Object>(
-                    SessionsQuery.LINKS_TITLES[i],
-                    new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl))
-                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
-            ));
-        }
-
-        // Render links
-        if (links.size() > 0) {
-            LayoutInflater inflater = LayoutInflater.from(context);
-            int columns = context.getResources().getInteger(R.integer.links_columns);
-
-            LinearLayout currentLinkRowView = null;
-            for (int i = 0; i < links.size(); i++) {
-                final Pair<Integer, Object> link = links.get(i);
-
-                // Create link view
-                TextView linkView = (TextView) inflater.inflate(R.layout.list_item_session_link,
-                        linkContainer, false);
-                if (link.first == R.string.session_feedback_submitlink) {
-                    mSubmitFeedbackView = linkView;
-                }
-                linkView.setText(getString(link.first));
-                linkView.setOnClickListener(new View.OnClickListener() {
-                    @Override
-                    public void onClick(View view) {
-                        fireLinkEvent(link.first);
-                        Intent intent=null;
-                        if (link.second instanceof Intent) {
-                            intent = (Intent) link.second;
-                        } else if (link.second instanceof String) {
-                            intent = new Intent(Intent.ACTION_VIEW, Uri.parse((String) link.second))
-                                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-                        }
-                        try {
-                            startActivity(intent);
-                        } catch (ActivityNotFoundException ignored) {
-                        }
-                    }
-                });
-
-                // Place it inside a container
-                if (columns == 1) {
-                    linkContainer.addView(linkView);
-                } else {
-                    // create a new link row
-                    if (i % columns == 0) {
-                        currentLinkRowView = (LinearLayout) inflater.inflate(
-                                R.layout.include_link_row, linkContainer, false);
-                        currentLinkRowView.setWeightSum(columns);
-                        linkContainer.addView(currentLinkRowView);
-                    }
-
-                    ((LinearLayout.LayoutParams) linkView.getLayoutParams()).width = 0;
-                    ((LinearLayout.LayoutParams) linkView.getLayoutParams()).weight = 1;
-                    currentLinkRowView.addView(linkView);
-                }
-            }
-
-            mRootView.findViewById(R.id.session_links_header).setVisibility(View.VISIBLE);
-            mRootView.findViewById(R.id.links_container).setVisibility(View.VISIBLE);
-
-        } else {
-            mRootView.findViewById(R.id.session_links_header).setVisibility(View.GONE);
-            mRootView.findViewById(R.id.links_container).setVisibility(View.GONE);
-        }
-
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        if (mTimeHintUpdaterRunnable != null) {
-            mHandler.removeCallbacks(mTimeHintUpdaterRunnable);
-        }
-    }
-
-    private Intent getWatchLiveIntent(Context context) {
-        LPreviewUtilsBase lpu = ((BaseActivity) getActivity()).getLPreviewUtils();
-        if (lpu.hasLPreviewAPIs() && YouTubeIntents.canResolvePlayVideoIntent(context)) {
-            String youtubeVideoId = SessionLivestreamActivity.getVideoIdFromUrl(mLivestreamUrl);
-            return YouTubeIntents.createPlayVideoIntentWithOptions(
-                    context, youtubeVideoId, true, false);
-        }
-        return new Intent(Intent.ACTION_VIEW, mSessionUri).setClass(context,
-                SessionLivestreamActivity.class);
-    }
-
-    private void updatePlusOneButton() {
-        if (mPlusOneButton == null) {
-            return;
-        }
-
-        if (!TextUtils.isEmpty(mUrl) && !mIsKeynote) {
-            mPlusOneButton.initialize(mUrl, 0);
-            mPlusOneButton.setVisibility(View.VISIBLE);
-        } else {
-            mPlusOneButton.setVisibility(View.GONE);
-        }
-    }
-
-    private void showWatchNowCard() {
-        final MessageCardView messageCardView = (MessageCardView) mRootView.findViewById(
-                R.id.live_now_card);
-        messageCardView.show();
-        messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
-            @Override
-            public void onMessageCardButtonClicked(String tag) {
-                if ("WATCH_NOW".equals(tag)) {
-                    Intent intent = getWatchLiveIntent(getActivity());
-                    startActivity(intent);
-                } else {
-                    mDismissedWatchLivestreamCard = true;
-                    messageCardView.dismiss();
-                }
-            }
-        });
-    }
-
-    private void showGiveFeedbackCard() {
-        final MessageCardView messageCardView = (MessageCardView) mRootView.findViewById(
-                R.id.give_feedback_card);
-        messageCardView.show();
-        messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
-            @Override
-            public void onMessageCardButtonClicked(String tag) {
-                if ("GIVE_FEEDBACK".equals(tag)) {
-                    /* [ANALYTICS:EVENT]
-                     * TRIGGER:   Click on the Send Feedback action on the Session Details page.
-                     * CATEGORY:  'Session'
-                     * ACTION:    'Feedback'
-                     * LABEL:     session title/subtitle
-                     * [/ANALYTICS]
-                     */
-                    AnalyticsManager.sendEvent("Session", "Feedback", mTitleString, 0L);
-                    Intent intent = getFeedbackIntent();
-                    startActivity(intent);
-                } else {
-                    sDismissedFeedbackCard.add(mSessionId);
-                    messageCardView.dismiss();
-                }
-            }
-        });
-    }
-
-    private Intent getFeedbackIntent() {
-        return new Intent(Intent.ACTION_VIEW, mSessionUri, getActivity(),
-                SessionFeedbackActivity.class);
-    }
-
-    private void enableSocialStreamMenuItemDeferred() {
-        mDeferredUiOperations.add(new Runnable() {
-            @Override
-            public void run() {
-                mSocialStreamMenuItem.setVisible(true);
-            }
-        });
-        tryExecuteDeferredUiOperations();
-    }
-
-    private void showStarredDeferred(final boolean starred, final boolean allowAnimate) {
-        mDeferredUiOperations.add(new Runnable() {
-            @Override
-            public void run() {
-                showStarred(starred, allowAnimate);
-            }
-        });
-        tryExecuteDeferredUiOperations();
-    }
-
-    private void showStarred(boolean starred, boolean allowAnimate) {
-        mStarred = starred;
-
-        mAddScheduleButton.setChecked(mStarred, allowAnimate);
-
-        ImageView iconView = (ImageView) mAddScheduleButton.findViewById(R.id.add_schedule_icon);
-        ((BaseActivity) getActivity()).getLPreviewUtils().setOrAnimatePlusCheckIcon(
-                iconView, starred, allowAnimate);
-        mAddScheduleButton.setContentDescription(getString(starred
-                ? R.string.remove_from_schedule_desc
-                : R.string.add_to_schedule_desc));
-    }
-
-    private void setupShareMenuItemDeferred() {
-        mDeferredUiOperations.add(new Runnable() {
-            @Override
-            public void run() {
-                new SessionsHelper(getActivity()).tryConfigureShareMenuItem(mShareMenuItem,
-                        R.string.share_template, mTitleString, mHashTag, mUrl);
-            }
-        });
-        tryExecuteDeferredUiOperations();
-    }
-
-    private void tryExecuteDeferredUiOperations() {
-        if (mSocialStreamMenuItem != null) {
-            for (Runnable r : mDeferredUiOperations) {
-                r.run();
-            }
-            mDeferredUiOperations.clear();
-        }
-    }
-
-    private void onSpeakersQueryComplete(Cursor cursor) {
-        mSpeakersCursor = true;
-        final ViewGroup speakersGroup = (ViewGroup)
-                mRootView.findViewById(R.id.session_speakers_block);
-
-        // Remove all existing speakers (everything but first child, which is the header)
-        for (int i = speakersGroup.getChildCount() - 1; i >= 1; i--) {
-            speakersGroup.removeViewAt(i);
-        }
-
-        final LayoutInflater inflater = getActivity().getLayoutInflater();
-
-        boolean hasSpeakers = false;
-
-        while (cursor.moveToNext()) {
-            final String speakerName = cursor.getString(SpeakersQuery.SPEAKER_NAME);
-            if (TextUtils.isEmpty(speakerName)) {
-                continue;
-            }
-
-            final String speakerImageUrl = cursor.getString(SpeakersQuery.SPEAKER_IMAGE_URL);
-            final String speakerCompany = cursor.getString(SpeakersQuery.SPEAKER_COMPANY);
-            final String speakerUrl = cursor.getString(SpeakersQuery.SPEAKER_URL);
-            final String speakerAbstract = cursor.getString(SpeakersQuery.SPEAKER_ABSTRACT);
-
-            String speakerHeader = speakerName;
-            if (!TextUtils.isEmpty(speakerCompany)) {
-                speakerHeader += ", " + speakerCompany;
-            }
-
-            final View speakerView = inflater
-                    .inflate(R.layout.speaker_detail, speakersGroup, false);
-            final TextView speakerHeaderView = (TextView) speakerView
-                    .findViewById(R.id.speaker_header);
-            final ImageView speakerImageView = (ImageView) speakerView
-                    .findViewById(R.id.speaker_image);
-            final TextView speakerAbstractView = (TextView) speakerView
-                    .findViewById(R.id.speaker_abstract);
-
-            if (!TextUtils.isEmpty(speakerImageUrl) && mSpeakersImageLoader != null) {
-                mSpeakersImageLoader.loadImage(speakerImageUrl, speakerImageView);
-            }
-
-            speakerHeaderView.setText(speakerHeader);
-            speakerImageView.setContentDescription(
-                    getString(R.string.speaker_googleplus_profile, speakerHeader));
-            UIUtils.setTextMaybeHtml(speakerAbstractView, speakerAbstract);
-
-            if (!TextUtils.isEmpty(speakerUrl)) {
-                speakerImageView.setEnabled(true);
-                speakerImageView.setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View view) {
-                        Intent speakerProfileIntent = new Intent(Intent.ACTION_VIEW,
-                                Uri.parse(speakerUrl));
-                        speakerProfileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-                        UIUtils.preferPackageForIntent(getActivity(), speakerProfileIntent,
-                                UIUtils.GOOGLE_PLUS_PACKAGE_NAME);
-                        startActivity(speakerProfileIntent);
-                    }
-                });
-            } else {
-                speakerImageView.setEnabled(false);
-                speakerImageView.setOnClickListener(null);
-            }
-
-            speakersGroup.addView(speakerView);
-            hasSpeakers = true;
-            mHasSummaryContent = true;
-        }
-
-        speakersGroup.setVisibility(hasSpeakers ? View.VISIBLE : View.GONE);
-
-        // Show empty message when all data is loaded, and nothing to show
-        if (mSessionCursor && !mHasSummaryContent) {
-            mRootView.findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
-        }
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.session_detail, menu);
-        mSocialStreamMenuItem = menu.findItem(R.id.menu_social_stream);
-        mShareMenuItem = menu.findItem(R.id.menu_share);
-        tryExecuteDeferredUiOperations();
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        SessionsHelper helper = new SessionsHelper(getActivity());
-        switch (item.getItemId()) {
-            case R.id.menu_map_room:
-                /* [ANALYTICS:EVENT]
-                 * TRIGGER:   Click on the Map action on the Session Details page.
-                 * CATEGORY:  'Session'
-                 * ACTION:    'Map'
-                 * LABEL:     session title/subtitle
-                 * [/ANALYTICS]
-                 */
-                AnalyticsManager.sendEvent("Session", "Map", mTitleString, 0L);
-                helper.startMapActivity(mRoomId);
-                return true;
-
-            case R.id.menu_share:
-                // On ICS+ devices, we normally won't reach this as ShareActionProvider will handle
-                // sharing.
-                helper.shareSession(getActivity(), R.string.share_template, mTitleString,
-                        mHashTag, mUrl);
-                return true;
-
-            case R.id.menu_social_stream:
-                if (!TextUtils.isEmpty(mHashTag)) {
-                    /* [ANALYTICS:EVENT]
-                     * TRIGGER:   Click on the Social Stream action on the Session Details page.
-                     * CATEGORY:  'Session'
-                     * ACTION:    'Stream'
-                     * LABEL:     session title/subtitle
-                     * [/ANALYTICS]
-                     */
-                    AnalyticsManager.sendEvent("Session", "Stream", mTitleString, 0L);
-                    UIUtils.showHashtagStream(getActivity(), mHashTag);
-                }
-                return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-    }
-
-    @Override
-    public void onDestroyOptionsMenu() {
-    }
-
-    /*
-     * Event structure:
-     * Category -> "Session Details"
-     * Action -> Link Text
-     * Label -> Session's Title
-     * Value -> 0.
-     */
-    void fireLinkEvent(int actionId) {
-        /* [ANALYTICS:EVENT]
-         * TRIGGER:   Click on a link on the Session Details page.
-         * CATEGORY:  'Session'
-         * ACTION:    The link's name ("Watch Live", "Follow us on Google+", etc)
-         * LABEL:     The session's title/subtitle.
-         * [/ANALYTICS]
-         */
-        AnalyticsManager.sendEvent("Session", getString(actionId), mTitleString, 0L);
-    }
-
-    /**
-     * {@link com.google.samples.apps.iosched.provider.ScheduleContract.Sessions} query parameters.
-     */
-    private interface SessionsQuery {
-        int _TOKEN = 0x1;
-
-        String[] PROJECTION = {
-                ScheduleContract.Sessions.SESSION_START,
-                ScheduleContract.Sessions.SESSION_END,
-                ScheduleContract.Sessions.SESSION_LEVEL,
-                ScheduleContract.Sessions.SESSION_TITLE,
-                ScheduleContract.Sessions.SESSION_ABSTRACT,
-                ScheduleContract.Sessions.SESSION_REQUIREMENTS,
-                ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
-                ScheduleContract.Sessions.SESSION_HASHTAG,
-                ScheduleContract.Sessions.SESSION_URL,
-                ScheduleContract.Sessions.SESSION_YOUTUBE_URL,
-                ScheduleContract.Sessions.SESSION_PDF_URL,
-                ScheduleContract.Sessions.SESSION_NOTES_URL,
-                ScheduleContract.Sessions.SESSION_LIVESTREAM_URL,
-                ScheduleContract.Sessions.SESSION_MODERATOR_URL,
-                ScheduleContract.Sessions.ROOM_ID,
-                ScheduleContract.Rooms.ROOM_NAME,
-                ScheduleContract.Sessions.SESSION_COLOR,
-                ScheduleContract.Sessions.SESSION_PHOTO_URL,
-                ScheduleContract.Sessions.SESSION_RELATED_CONTENT,
-                ScheduleContract.Sessions.SESSION_TAGS,
-                ScheduleContract.Sessions.SESSION_SPEAKER_NAMES
-        };
-
-        int START = 0;
-        int END = 1;
-        int LEVEL = 2;
-        int TITLE = 3;
-        int ABSTRACT = 4;
-        int REQUIREMENTS = 5;
-        int IN_MY_SCHEDULE = 6;
-        int HASHTAG = 7;
-        int URL = 8;
-        int YOUTUBE_URL = 9;
-        int PDF_URL = 10;
-        int NOTES_URL = 11;
-        int LIVESTREAM_URL = 12;
-        int MODERATOR_URL = 13;
-        int ROOM_ID = 14;
-        int ROOM_NAME = 15;
-        int COLOR = 16;
-        int PHOTO_URL = 17;
-        int RELATED_CONTENT = 18;
-        int TAGS = 19;
-        int SPEAKER_NAMES = 20;
-
-        int[] LINKS_INDICES = {
-                YOUTUBE_URL,
-                MODERATOR_URL,
-                PDF_URL,
-                NOTES_URL,
-        };
-
-        int[] LINKS_TITLES = {
-                R.string.session_link_youtube,
-                R.string.session_link_moderator,
-                R.string.session_link_pdf,
-                R.string.session_link_notes,
-        };
-    }
-
-    private interface SpeakersQuery {
-        int _TOKEN = 0x3;
-
-        String[] PROJECTION = {
-                ScheduleContract.Speakers.SPEAKER_NAME,
-                ScheduleContract.Speakers.SPEAKER_IMAGE_URL,
-                ScheduleContract.Speakers.SPEAKER_COMPANY,
-                ScheduleContract.Speakers.SPEAKER_ABSTRACT,
-                ScheduleContract.Speakers.SPEAKER_URL,
-        };
-
-        int SPEAKER_NAME = 0;
-        int SPEAKER_IMAGE_URL = 1;
-        int SPEAKER_COMPANY = 2;
-        int SPEAKER_ABSTRACT = 3;
-        int SPEAKER_URL = 4;
-    }
-
-    private interface FeedbackQuery {
-        int _TOKEN = 0x4;
-
-        String[] PROJECTION = {
-                ScheduleContract.Feedback.SESSION_ID
-        };
-    }
-
-    private static final int TAG_METADATA_TOKEN = 0x5;
-
-	@Override
-	public Loader<Cursor> onCreateLoader(int id, Bundle data) {
-		CursorLoader loader = null;
-		if (id == SessionsQuery._TOKEN){
-			loader = new CursorLoader(getActivity(), mSessionUri, SessionsQuery.PROJECTION, null,
-					null, null);
-		} else if (id == SpeakersQuery._TOKEN  && mSessionUri != null){
-			Uri speakersUri = ScheduleContract.Sessions.buildSpeakersDirUri(mSessionId);
-			loader = new CursorLoader(getActivity(), speakersUri, SpeakersQuery.PROJECTION, null,
-                    null, ScheduleContract.Speakers.DEFAULT_SORT);
-        } else if (id == FeedbackQuery._TOKEN) {
-            Uri feedbackUri = ScheduleContract.Feedback.buildFeedbackUri(mSessionId);
-            loader = new CursorLoader(getActivity(), feedbackUri, FeedbackQuery.PROJECTION, null,
-                    null, null);
-        } else if (id == TAG_METADATA_TOKEN) {
-            loader = TagMetadata.createCursorLoader(getActivity());
-        }
-        return loader;
-	}
-
-	@Override
-	public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
-        if (!isAdded()) {
-            return;
-        }
-
-        if (loader.getId() == SessionsQuery._TOKEN) {
-            onSessionQueryComplete(cursor);
-        } else if (loader.getId() == SpeakersQuery._TOKEN) {
-            onSpeakersQueryComplete(cursor);
-        } else if (loader.getId() == FeedbackQuery._TOKEN) {
-            onFeedbackQueryComplete(cursor);
-        } else if (loader.getId() == TAG_METADATA_TOKEN) {
-            mTagMetadata = new TagMetadata(cursor);
-            cursor.close();
-            tryRenderTags();
-        } else {
-            cursor.close();
-        }
-	}
-
-    @Override
-	public void onLoaderReset(Loader<Cursor> loader) {}
-}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java
index e4a9f3a..d2bf0fb 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java
@@ -16,10 +16,12 @@
 
 package com.google.samples.apps.iosched.ui;
 
+import android.app.Fragment;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
-import android.app.Fragment;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.provider.ScheduleContract;
@@ -39,11 +41,23 @@
         }
 
         mSessionId = ScheduleContract.Sessions.getSessionId(getIntent().getData());
+
+        Toolbar toolbar = getActionBarToolbar();
+        toolbar.setTitle(R.string.title_session_feedback);
+        toolbar.setNavigationIcon(R.drawable.ic_up);
+        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                navigateUpToFromChild(SessionFeedbackActivity.this,
+                        new Intent(Intent.ACTION_VIEW,
+                                ScheduleContract.Sessions.buildSessionUri(mSessionId)));
+            }
+        });
     }
 
     @Override
     protected int getContentViewResId() {
-        return R.layout.activity_letterboxed_when_large;
+        return R.layout.activity_feedback;
     }
 
     @Override
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java
index 0f59861..e5e0d92 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java
@@ -18,7 +18,6 @@
 
 import android.app.Fragment;
 import android.app.LoaderManager;
-import android.content.ContentValues;
 import android.content.CursorLoader;
 import android.content.Intent;
 import android.content.Loader;
@@ -30,7 +29,6 @@
 import android.view.ViewGroup;
 import android.widget.EditText;
 import android.widget.RatingBar;
-import android.widget.SeekBar;
 import android.widget.TextView;
 
 import com.google.android.gms.common.ConnectionResult;
@@ -54,7 +52,7 @@
         GooglePlayServicesClient.ConnectionCallbacks,
         GooglePlayServicesClient.OnConnectionFailedListener {
 
-    private static final String TAG = makeLogTag(SessionDetailFragment.class);
+    private static final String TAG = makeLogTag(SessionDetailActivity.class);
 
     // Set this boolean extra to true to show a variable height header
     public static final String EXTRA_VARIABLE_HEIGHT_HEADER =
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java
index 73cc886..eec9202 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java
@@ -765,7 +765,7 @@
     }
 
     private int getActionBarHeightPx() {
-        int[] attrs = new int[] { android.R.attr.actionBarSize };
+        int[] attrs = new int[] { R.attr.actionBarSize };
         return (int) getTheme().obtainStyledAttributes(attrs).getDimension(0, 0f);
     }
 
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java
index 5c0793c..6427cd4 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java
@@ -20,8 +20,14 @@
 import android.app.Fragment;
 import android.app.ListFragment;
 import android.app.LoaderManager;
-import android.content.*;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.SharedPreferences;
 import android.database.Cursor;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -41,6 +47,8 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.bumptech.glide.GenericRequestBuilder;
+import com.bumptech.glide.ListPreloader;
 import com.google.samples.apps.iosched.Config;
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.model.TagMetadata;
@@ -48,7 +56,12 @@
 import com.google.samples.apps.iosched.ui.widget.CollectionView;
 import com.google.samples.apps.iosched.ui.widget.CollectionViewCallbacks;
 import com.google.samples.apps.iosched.ui.widget.MessageCardView;
-import com.google.samples.apps.iosched.util.*;
+import com.google.samples.apps.iosched.util.ImageLoader;
+import com.google.samples.apps.iosched.util.PrefUtils;
+import com.google.samples.apps.iosched.util.ThrottledContentObserver;
+import com.google.samples.apps.iosched.util.TimeUtils;
+import com.google.samples.apps.iosched.util.UIUtils;
+import com.google.samples.apps.iosched.util.WiFiUtils;
 
 import java.text.DateFormat;
 import java.util.ArrayList;
@@ -56,10 +69,11 @@
 import java.util.List;
 import java.util.TimeZone;
 
-import com.bumptech.glide.GenericRequestBuilder;
-import com.bumptech.glide.ListPreloader;
-
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGV;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 import static com.google.samples.apps.iosched.util.UIUtils.buildStyledSnippet;
 
 /**
@@ -72,6 +86,10 @@
 
     private static final String TAG = makeLogTag(SessionsFragment.class);
 
+    // Disable track branding
+    public static final String EXTRA_NO_TRACK_BRANDING =
+            "com.google.android.iosched.extra.NO_TRACK_BRANDING";
+
     private static final String STATE_SESSION_QUERY_TOKEN = "session_query_token";
     private static final String STATE_ARGUMENTS = "arguments";
 
@@ -92,6 +110,7 @@
     private Uri mCurrentUri = ScheduleContract.Sessions.CONTENT_URI;
     private Cursor mCursor;
     private boolean mIsSearchCursor;
+    private boolean mNoTrackBranding;
 
     // this variable is relevant when we start the sessions loader, and indicates the desired
     // behavior when load finishes: if true, this is a full reload (for example, because filters
@@ -231,6 +250,7 @@
             mArguments = savedInstanceState.getParcelable(STATE_ARGUMENTS);
             if (mArguments != null) {
                 mCurrentUri = mArguments.getParcelable("_uri");
+                mNoTrackBranding = mArguments.getBoolean(EXTRA_NO_TRACK_BRANDING);
             }
 
             if (mSessionQueryToken > 0) {
@@ -292,6 +312,8 @@
             mCurrentUri = ScheduleContract.Sessions.CONTENT_URI;
         }
 
+        mNoTrackBranding = mArguments.getBoolean(EXTRA_NO_TRACK_BRANDING);
+
         if (ScheduleContract.Sessions.isSearchUri(mCurrentUri)) {
             mSessionQueryToken = SessionsQuery.SEARCH_TOKEN;
         } else {
@@ -694,6 +716,7 @@
         int sessionColor = mCursor.getInt(SessionsQuery.COLOR);
         sessionColor = sessionColor == 0 ? getResources().getColor(R.color.default_session_color)
                 : sessionColor;
+        int darkSessionColor = 0;
         final String snippet = mIsSearchCursor ? mCursor.getString(SessionsQuery.SNIPPET) : null;
         final Spannable styledSnippet = mIsSearchCursor ? buildStyledSnippet(snippet) : null;
         final boolean starred = mCursor.getInt(SessionsQuery.IN_MY_SCHEDULE) != 0;
@@ -717,14 +740,18 @@
         final TextView snippetView = (TextView) view.findViewById(R.id.session_snippet);
         final TextView abstractView = (TextView) view.findViewById(R.id.session_abstract);
         final TextView categoryView = (TextView) view.findViewById(R.id.session_category);
-        final View boxView = view.findViewById(R.id.info_box);
         final View sessionTargetView = view.findViewById(R.id.session_target);
 
         if (sessionColor == 0) {
             // use default
             sessionColor = mDefaultSessionColor;
         }
-        sessionColor = UIUtils.scaleSessionColorToDefaultBG(sessionColor);
+
+        if (mNoTrackBranding) {
+            sessionColor = getResources().getColor(R.color.no_track_branding_session_color);
+        }
+
+        darkSessionColor = UIUtils.scaleSessionColorToDefaultBG(sessionColor);
 
         ImageView photoView = (ImageView) view.findViewById(R.id.session_photo_colored);
         if (photoView != null) {
@@ -738,23 +765,23 @@
                 });
             }
             // colored
-            photoView.setColorFilter(UIUtils.setColorAlpha(sessionColor,
-                    UIUtils.SESSION_PHOTO_SCRIM_ALPHA));
+            photoView.setColorFilter(mNoTrackBranding
+                    ? new PorterDuffColorFilter(
+                    getResources().getColor(R.color.no_track_branding_session_tile_overlay),
+                    PorterDuff.Mode.SRC_ATOP)
+                    : UIUtils.makeSessionImageScrimColorFilter(darkSessionColor));
         } else {
             photoView = (ImageView) view.findViewById(R.id.session_photo);
         }
-        ((BaseActivity) getActivity()).getLPreviewUtils().setViewName(photoView,
-                "photo_" + sessionId);
-
-
+        ViewCompat.setTransitionName(photoView, "photo_" + sessionId);
 
         // when we load a photo, it will fade in from transparent so the
         // background of the container must be the session color to avoid a white flash
         ViewParent parent = photoView.getParent();
         if (parent != null && parent instanceof View) {
-            ((View) parent).setBackgroundColor(sessionColor);
+            ((View) parent).setBackgroundColor(darkSessionColor);
         } else {
-            photoView.setBackgroundColor(sessionColor);
+            photoView.setBackgroundColor(darkSessionColor);
         }
 
         String photo = mCursor.getString(SessionsQuery.PHOTO_URL);
@@ -818,11 +845,6 @@
             abstractView.setText(mBuffer.toString());
         }
 
-        // in expanded mode, the box background color follows the session color
-        if (useExpandedMode()) {
-            boxView.setBackgroundColor(sessionColor);
-        }
-
         // show or hide the "in my schedule" indicator
         view.findViewById(R.id.indicator_in_schedule).setVisibility(starred ? View.VISIBLE
                 : View.INVISIBLE);
@@ -840,7 +862,7 @@
             if (cardContainer != null && abstractContainer != null) {
                 cardContainer.setVisibility(cardShown ? View.VISIBLE : View.GONE);
                 abstractContainer.setVisibility(cardShown ? View.GONE : View.VISIBLE);
-                abstractContainer.setBackgroundColor(sessionColor);
+                abstractContainer.setBackgroundColor(darkSessionColor);
             }
         }
 
@@ -891,7 +913,6 @@
     }
 
     private void setupLocalOrRemoteCard(final MessageCardView card) {
-        card.overrideBackground(R.drawable.card_bg);
         card.setText(getString(R.string.question_local_or_remote));
         card.setButton(0, getString(R.string.attending_remotely), CARD_ANSWER_ATTENDING_REMOTELY,
                 false, 0);
@@ -924,7 +945,6 @@
     }
 
     private void setupWifiOfferCard(final MessageCardView card) {
-        card.overrideBackground(R.drawable.card_bg);
         card.setText(getString(TimeUtils.hasConferenceStarted(getActivity()) ?
                 R.string.question_setup_wifi_after_i_o_start :
                 R.string.question_setup_wifi_before_i_o_start));
@@ -955,13 +975,11 @@
     }
 
     private void setupIOExtendedCard(final MessageCardView card) {
-        card.overrideBackground(R.drawable.card_bg);
         card.setText(getString(R.string.question_i_o_extended));
         card.setButton(0, getString(R.string.no_thanks), CARD_ANSWER_NO,
                 false, 0);
         card.setButton(1, getString(R.string.browse_events), CARD_ANSWER_YES,
                 true, 0);
-        final Context context = getActivity().getApplicationContext();
         card.setListener(new MessageCardView.OnMessageCardButtonClicked() {
             @Override
             public void onMessageCardButtonClicked(final String tag) {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java
index 1e2e1a7..4e138c8 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java
@@ -16,12 +16,14 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import android.annotation.TargetApi;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.os.Build;
 import android.os.Bundle;
-import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.support.v4.content.IntentCompat;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.service.SessionCalendarService;
@@ -30,50 +32,71 @@
 /**
  * Activity for customizing app settings.
  */
-public class SettingsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
+public class SettingsActivity extends BaseActivity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        getActionBar().setDisplayHomeAsUpEnabled(true);
-    }
+        setContentView(R.layout.activity_settings);
 
-    @Override
-    protected void onPostCreate(Bundle savedInstanceState) {
-        super.onPostCreate(savedInstanceState);
-        setupSimplePreferencesScreen();
-        PrefUtils.registerOnSharedPreferenceChangeListener(this, this);
-    }
+        Toolbar toolbar = getActionBarToolbar();
+        toolbar.setTitle(R.string.title_settings);
+        toolbar.setNavigationIcon(R.drawable.ic_up);
+        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                navigateUpToFromChild(SettingsActivity.this,
+                        IntentCompat.makeMainActivity(new ComponentName(SettingsActivity.this,
+                                BrowseSessionsActivity.class)));
+            }
+        });
 
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        PrefUtils.unrgisterOnSharedPreferenceChangeListener(this, this);
-    }
-
-    private void setupSimplePreferencesScreen() {
-        // Add 'general' preferences.
-        addPreferencesFromResource(R.xml.preferences);
-        if (PrefUtils.hasEnabledBle(this)) {
-            addPreferencesFromResource(R.xml.ble_preferences);
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction()
+                    .add(R.id.container, new SettingsFragment())
+                    .commit();
         }
     }
 
-    @Override
-    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-        if (PrefUtils.PREF_SYNC_CALENDAR.equals(key)) {
-            boolean shouldSyncCalendar = PrefUtils.shouldSyncCalendar(this);
+    public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
+        public SettingsFragment() {
+        }
 
-            Intent intent;
-            if (PrefUtils.shouldSyncCalendar(this)) {
-                // Add all calendar entries
-                intent = new Intent(SessionCalendarService.ACTION_UPDATE_ALL_SESSIONS_CALENDAR);
-            } else {
-                // Remove all calendar entries
-                intent = new Intent(SessionCalendarService.ACTION_CLEAR_ALL_SESSIONS_CALENDAR);
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setupSimplePreferencesScreen();
+            PrefUtils.registerOnSharedPreferenceChangeListener(getActivity(), this);
+        }
+
+        @Override
+        public void onDestroy() {
+            super.onDestroy();
+            PrefUtils.unregisterOnSharedPreferenceChangeListener(getActivity(), this);
+        }
+
+        private void setupSimplePreferencesScreen() {
+            // Add 'general' preferences.
+            addPreferencesFromResource(R.xml.preferences);
+            if (PrefUtils.hasEnabledBle(getActivity())) {
+                addPreferencesFromResource(R.xml.ble_preferences);
             }
+        }
 
-            intent.setClass(this, SessionCalendarService.class);
-            startService(intent);
+        @Override
+        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+            if (PrefUtils.PREF_SYNC_CALENDAR.equals(key)) {
+                Intent intent;
+                if (PrefUtils.shouldSyncCalendar(getActivity())) {
+                    // Add all calendar entries
+                    intent = new Intent(SessionCalendarService.ACTION_UPDATE_ALL_SESSIONS_CALENDAR);
+                } else {
+                    // Remove all calendar entries
+                    intent = new Intent(SessionCalendarService.ACTION_CLEAR_ALL_SESSIONS_CALENDAR);
+                }
+
+                intent.setClass(getActivity(), SessionCalendarService.class);
+                getActivity().startService(intent);
+            }
         }
     }
 }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java
index 6acb8da..ce43a3e 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java
@@ -17,7 +17,6 @@
 package com.google.samples.apps.iosched.ui;
 
 import android.os.Bundle;
-import android.app.ActionBar;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.util.AnalyticsManager;
@@ -38,7 +37,7 @@
         }
 
         setContentView(R.layout.activity_social);
-        getLPreviewUtils().trySetActionBar();
+
         if (null == savedInstanceState) {
             getFragmentManager().beginTransaction()
                     .replace(R.id.container, HashtagsFragment.newInstance())
@@ -56,21 +55,6 @@
         overridePendingTransition(0, 0);
     }
 
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ActionBar ab = getActionBar();
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
-        }
-    }
-
-    @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
     @Override
     protected int getSelfNavDrawerItem() {
         return NAVDRAWER_ITEM_SOCIAL;
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java
index 3f764a8..8b1c28c 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java
@@ -16,7 +16,6 @@
 
 package com.google.samples.apps.iosched.ui;
 
-import android.app.ActionBar;
 import android.app.Fragment;
 import android.os.Bundle;
 import android.text.TextUtils;
@@ -35,7 +34,9 @@
 import java.util.Collections;
 import java.util.Comparator;
 
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
 public class VideoLibraryActivity extends BaseActivity implements VideoLibraryFragment.Callbacks {
     private static final String TAG = makeLogTag(VideoLibraryActivity.class);
@@ -64,7 +65,7 @@
         }
 
         setContentView(R.layout.activity_video_library);
-        getLPreviewUtils().trySetActionBar();
+
         mDrawShadowFrameLayout = (DrawShadowFrameLayout) findViewById(R.id.main_content);
 
         /* [ANALYTICS:SCREEN]
@@ -87,7 +88,7 @@
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
-        enableActionBarAutoHide((CollectionView)findViewById(R.id.videos_collection_view));
+        enableActionBarAutoHide((CollectionView) findViewById(R.id.videos_collection_view));
     }
 
     @Override
@@ -119,27 +120,12 @@
         }
     }
 
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ActionBar ab = getActionBar();
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
-        }
-    }
-
     @Override
     protected void onActionBarAutoShowOrHide(boolean shown) {
         super.onActionBarAutoShowOrHide(shown);
         mDrawShadowFrameLayout.setShadowVisible(shown, shown);
     }
 
-    @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
     private void onYearSelected(int year) {
         if (mSelectedYear == year) {
             return;
@@ -292,7 +278,7 @@
     private void populateSpinner(Spinner spinner, ArrayList<String> items) {
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.explore_spinner_item,
                 android.R.id.text1, items);
-        adapter.setDropDownViewResource(R.layout.explore_spinner_item_dropdown);
+        adapter.setDropDownViewResource(R.layout.video_library_spinner_item_dropdown);
         spinner.setAdapter(adapter);
     }
 }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java b/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java
index b23dde8..271c677 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java
@@ -26,7 +26,7 @@
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.ui.MapFragment;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
 import com.google.samples.apps.iosched.ui.debug.DebugAction;
 import com.google.samples.apps.iosched.util.UIUtils;
 
@@ -46,7 +46,7 @@
                 UIUtils.getMapActivityClass(context));
         mapIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK |
                 Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-        mapIntent.putExtra(MapFragment.EXTRA_ROOM, "keynote");
+        mapIntent.putExtra(BaseMapActivity.EXTRA_ROOM, "keynote");
         PendingIntent piMap = TaskStackBuilder
                 .create(context)
                 .addNextIntent(mapIntent)
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java
index 094b07e..d9b8fc3 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java
@@ -16,18 +16,16 @@
 
 package com.google.samples.apps.iosched.ui.phone;
 
-import android.app.ActionBar;
-import android.app.Fragment;
 import android.app.FragmentManager;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
+import android.graphics.Rect;
 import android.os.Bundle;
-import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
 
 import com.google.samples.apps.iosched.R;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
 import com.google.samples.apps.iosched.ui.MapFragment;
-import com.google.samples.apps.iosched.ui.NearbyActivity;
 import com.google.samples.apps.iosched.ui.NearbyFragment;
 import com.google.samples.apps.iosched.ui.PartnersFragment;
 import com.google.samples.apps.iosched.util.AnalyticsManager;
@@ -35,19 +33,16 @@
 import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
 import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
-public class MapActivity extends NearbyActivity implements MapFragment.Callbacks {
+public class MapActivity extends BaseMapActivity implements MapFragment.Callbacks {
 
     private static final String TAG = makeLogTag(MapActivity.class);
-    public static final String EXTRA_DETACHED_MODE
-            = "com.google.samples.apps.iosched.EXTRA_DETACHED_MODE";
 
     private static final String SCREEN_LABEL = "Map";
     private static final String PARTNERS_FRAGMENT_TAG = "partners";
 
-    private int mActionBarOnColor;
-    private int mActionBarOffColor;
-    private ColorDrawable mActionBarBgDrawable;
     private boolean mPopupVisible = false; // Nearby or Partners
+    private boolean mFirstPopupAnimate = true;
+    private View mPopupContainerView;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -58,16 +53,7 @@
         }
 
         setContentView(R.layout.activity_map);
-        getLPreviewUtils().trySetActionBar();
-
-        if (null == savedInstanceState) {
-            // Pass arguments to MapFragment
-            MapFragment fragment = MapFragment.newInstance();
-            fragment.setArguments(intentToFragmentArguments(getIntent()));
-            getFragmentManager().beginTransaction()
-                    .replace(R.id.main_content, fragment)
-                    .commit();
-        }
+        mPopupContainerView = findViewById(R.id.fragment_container_popup);
 
         /* [ANALYTICS:SCREEN]
          * TRIGGER:   View the Map screen on a phone.
@@ -79,72 +65,55 @@
 
         overridePendingTransition(0, 0);
 
-        final Resources res = getResources();
-        mActionBarOffColor = res.getColor(R.color.translucent_actionbar_background);
-        mActionBarOnColor = res.getColor(R.color.theme_primary);
-
-        // Initialise and set background drawable here explicitly to ensure the background
-        // is drawn  when the background color is changed on JellyBean
-        mActionBarBgDrawable = new ColorDrawable(mActionBarOffColor);
-        getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
-
         getFragmentManager().addOnBackStackChangedListener(
                 new FragmentManager.OnBackStackChangedListener() {
                     @Override
                     public void onBackStackChanged() {
                         mPopupVisible = (getFragmentManager().getBackStackEntryCount() == 1);
-                        updateActionBarNavigation();
+                        updatePopup();
                     }
                 }
         );
 
-        updateActionBarNavigation();
+        updatePopup();
     }
 
-    @Override
-    protected void onPostCreate(Bundle savedInstanceState) {
-        super.onPostCreate(savedInstanceState);
-        Fragment nearbyFragment = getFragmentManager().findFragmentByTag(NEARBY_FRAGMENT_TAG);
-        Fragment partnersFragment = getFragmentManager().findFragmentByTag(PARTNERS_FRAGMENT_TAG);
-        mPopupVisible = nearbyFragment != null || partnersFragment != null;
-        updateActionBarNavigation();
-    }
-
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        ActionBar ab = getActionBar();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
+    private void updatePopup() {
+        View mapContainerView = findViewById(R.id.fragment_container_map);
+        if (mFirstPopupAnimate) {
+            if (mPopupVisible) {
+                mPopupContainerView.setTranslationY(mapContainerView.getHeight());
+                mPopupContainerView.setVisibility(View.VISIBLE);
+                mFirstPopupAnimate = false;
+            } else {
+                return;
+            }
         }
+        mPopupContainerView.animate()
+                .translationY(mPopupVisible ? 0 : mapContainerView.getHeight())
+                .setInterpolator(new DecelerateInterpolator())
+                .setDuration(250);
+    }
 
-        if (mPopupVisible) {
-            ab.hide();
-        } else {
-            ab.show();
+    @Override
+    public void onInsetsChanged(Rect insets) {
+        super.onInsetsChanged(insets);
+        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
+                mPopupContainerView.getLayoutParams();
+        lp.topMargin= insets.top;
+        mPopupContainerView.setLayoutParams(lp);
+    }
+
+    @Override
+    public void onBackPressed() {
+        // Force checking the native fragment manager for a backstack rather than
+        // the support lib fragment manager.
+        if (!getFragmentManager().popBackStackImmediate()) {
+            super.onBackPressed();
         }
     }
 
     @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
-    @Override
-    protected void onNavDrawerSlide(float offset) {
-        super.onNavDrawerSlide(offset);
-        // Make Action Bar gradually fade into the theme color
-        mActionBarBgDrawable.setColor(Color.argb(
-                Color.alpha(mActionBarOffColor) + (int) (offset * (Color.alpha(mActionBarOnColor) - Color.alpha(mActionBarOffColor))),
-                Color.red(mActionBarOffColor) + (int) (offset * (Color.red(mActionBarOnColor) - Color.red(mActionBarOffColor))),
-                Color.green(mActionBarOffColor) + (int) (offset * (Color.green(mActionBarOnColor) - Color.green(mActionBarOffColor))),
-                Color.blue(mActionBarOffColor) + (int) (offset * (Color.blue(mActionBarOnColor) - Color.blue(mActionBarOffColor)))
-        ));
-        getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
-    }
-
-    @Override
     public void onSessionRoomSelected(String roomId, String roomTitle) {
         // we no longer have a screen that shows sessions on a given room
     }
@@ -152,36 +121,17 @@
     @Override
     public void onShowPartners() {
         getFragmentManager().beginTransaction()
-                .replace(R.id.main_content, PartnersFragment.newInstance(true),
+                .add(R.id.fragment_container_popup, PartnersFragment.newInstance(true),
                         PARTNERS_FRAGMENT_TAG)
                 .addToBackStack(null)
                 .commit();
     }
 
-    @Override
-    protected int getSelfNavDrawerItem() {
-        if (getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false)) {
-            // in detached mode, we don't have a nav drawer
-            return NAVDRAWER_ITEM_INVALID;
-        } else {
-            return NAVDRAWER_ITEM_MAP;
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false)
-                && item.getItemId() == android.R.id.home) {
-            finish();
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
     // Show whichever Fragment has been provided by NearbyActivity.
     @Override
     protected void showNearbyFragment(String tag) {
         getFragmentManager().beginTransaction()
-                .replace(R.id.main_content, NearbyFragment.newInstance(true), tag)
+                .add(R.id.fragment_container_popup, NearbyFragment.newInstance(true), tag)
                 .addToBackStack(null)
                 .commit();
     }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java
index 259ec84..fe132e5 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java
@@ -16,19 +16,12 @@
 
 package com.google.samples.apps.iosched.ui.tablet;
 
-import android.app.ActionBar;
-import android.app.Fragment;
 import android.app.FragmentBreadCrumbs;
 import android.app.FragmentManager;
 import android.content.Intent;
 import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
 import android.os.Bundle;
 import android.view.Gravity;
-import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
@@ -36,8 +29,12 @@
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.model.TagMetadata;
 import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.ui.*;
-import com.google.samples.apps.iosched.ui.phone.MapActivity;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
+import com.google.samples.apps.iosched.ui.MapFragment;
+import com.google.samples.apps.iosched.ui.NearbyFragment;
+import com.google.samples.apps.iosched.ui.PartnersFragment;
+import com.google.samples.apps.iosched.ui.SessionDetailActivity;
+import com.google.samples.apps.iosched.ui.SessionsFragment;
 import com.google.samples.apps.iosched.util.AnalyticsManager;
 import com.google.samples.apps.iosched.util.UIUtils;
 
@@ -45,11 +42,10 @@
 
 /**
  * A multi-pane activity, where the primary navigation pane is a
- * {@link MapFragment}, that shows {@link SessionsFragment},
- * {@link SessionDetailFragment} as popups. This activity requires API level 11
- * or greater because of its use of {@link FragmentBreadCrumbs}.
+ * {@link MapFragment}, that shows {@link NearbyFragment},
+ * {@link PartnersFragment} as popups.
  */
-public class MapMultiPaneActivity extends NearbyActivity implements
+public class MapMultiPaneActivity extends BaseMapActivity implements
         FragmentManager.OnBackStackChangedListener,
         MapFragment.Callbacks,
         SessionsFragment.Callbacks {
@@ -61,17 +57,10 @@
     private FragmentBreadCrumbs mFragmentBreadCrumbs;
     private String mSelectedRoomName;
 
-    private MapFragment mMapFragment;
-
-    private int mActionBarOnColor;
-    private int mActionBarOffColor;
-    private ColorDrawable mActionBarBgDrawable;
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_map);
-        getLPreviewUtils().trySetActionBar();
 
         FragmentManager fm = getFragmentManager();
         fm.addOnBackStackChangedListener(this);
@@ -79,16 +68,6 @@
         mFragmentBreadCrumbs = (FragmentBreadCrumbs) findViewById(R.id.breadcrumbs);
         mFragmentBreadCrumbs.setActivity(this);
 
-        mMapFragment = (MapFragment) fm.findFragmentByTag("map");
-        if (mMapFragment == null) {
-            mMapFragment = MapFragment.newInstance();
-            mMapFragment.setArguments(intentToFragmentArguments(getIntent()));
-
-            fm.beginTransaction()
-                    .add(R.id.fragment_container_map, mMapFragment, "map")
-                    .commit();
-        }
-
         findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() {
             public void onClick(View view) {
                 clearBackStack(false);
@@ -107,53 +86,6 @@
         LOGD("Tracker", SCREEN_LABEL);
 
         overridePendingTransition(0, 0);
-
-        final Resources res = getResources();
-        mActionBarOffColor = res.getColor(R.color.translucent_actionbar_background);
-        mActionBarOnColor = res.getColor(R.color.theme_primary);
-
-        // Initialise and set background drawable here explicitly to ensure the background
-        // is drawn  when the background color is changed on JellyBean
-        mActionBarBgDrawable = new ColorDrawable(mActionBarOffColor);
-        getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
-    }
-
-    private void updateActionBarNavigation() {
-        boolean show = !isNavDrawerOpen();
-        if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
-            ActionBar ab = getActionBar();
-            ab.setDisplayShowTitleEnabled(show);
-            ab.setDisplayUseLogoEnabled(!show);
-        }
-    }
-
-    @Override
-    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
-        super.onNavDrawerStateChanged(isOpen, isAnimating);
-        updateActionBarNavigation();
-    }
-
-    @Override
-    protected void onNavDrawerSlide(float offset) {
-        super.onNavDrawerSlide(offset);
-        // Make Action Bar gradually fade into the theme color
-        mActionBarBgDrawable.setColor(Color.argb(
-                Color.alpha(mActionBarOffColor) + (int) (offset * (Color.alpha(mActionBarOnColor) - Color.alpha(mActionBarOffColor))),
-                Color.red(mActionBarOffColor) + (int) (offset * (Color.red(mActionBarOnColor) - Color.red(mActionBarOffColor))),
-                Color.green(mActionBarOffColor) + (int) (offset * (Color.green(mActionBarOnColor) - Color.green(mActionBarOffColor))),
-                Color.blue(mActionBarOffColor) + (int) (offset * (Color.blue(mActionBarOnColor) - Color.blue(mActionBarOffColor)))
-        ));
-        getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
-    }
-
-    @Override
-    protected int getSelfNavDrawerItem() {
-        if (getIntent().getBooleanExtra(MapActivity.EXTRA_DETACHED_MODE, false)) {
-            // in detached mode, we don't have a nav drawer
-            return NAVDRAWER_ITEM_INVALID;
-        } else {
-            return NAVDRAWER_ITEM_MAP;
-        }
     }
 
     @Override
@@ -222,10 +154,11 @@
         boolean landscape = getResources().getConfiguration().orientation
                 == Configuration.ORIENTATION_LANDSCAPE;
         boolean detailShown = findViewById(R.id.map_detail_spacer).getVisibility() == View.VISIBLE;
-
-        mMapFragment.setCenterPadding(
-                landscape ? (detailShown ? 0.25f : 0f) : 0,
-                landscape ? 0 : (detailShown ? 0.25f : 0));
+        if (mMapFragment != null) {
+            mMapFragment.setCenterPadding(
+                    landscape ? (detailShown ? 0.25f : 0f) : 0,
+                    landscape ? 0 : (detailShown ? 0.25f : 0));
+        }
     }
 
     void updateBreadCrumbs() {
@@ -260,46 +193,17 @@
          * [/ANALYTICS]
          */
         AnalyticsManager.sendEvent(SCREEN_LABEL, "selectsession", sessionId);
-        getLPreviewUtils().startActivityWithTransition(
+        getLUtils().startActivityWithTransition(
                 new Intent(Intent.ACTION_VIEW,
                         ScheduleContract.Sessions.buildSessionUri(sessionId)),
                 clickedView,
-                SessionDetailFragment.VIEW_NAME_PHOTO
+                SessionDetailActivity.TRANSITION_NAME_PHOTO
         );
     }
 
     @Override
     public void onTagMetadataLoaded(TagMetadata metadata) {}
 
-    private void showList(Fragment fragment, Uri uri){
-        // Show the sessions in the room
-        clearBackStack(true);
-        showDetailPane(true);
-        fragment.setArguments(BaseActivity.intentToFragmentArguments(
-                new Intent(Intent.ACTION_VIEW,
-                        uri
-                )));
-        getFragmentManager().beginTransaction()
-                .replace(R.id.fragment_container_detail, fragment)
-                .addToBackStack(null)
-                .commit();
-        updateBreadCrumbs();
-    }
-
-    private void showDetails(Fragment fragment, Uri uri){
-        // Show the session details
-        showDetailPane(true);
-        Intent intent = new Intent(Intent.ACTION_VIEW,uri);
-        //intent.putExtra(SessionDetailFragment.EXTRA_VARIABLE_HEIGHT_HEADER, true);
-        fragment.setArguments(BaseActivity.intentToFragmentArguments(intent));
-        getFragmentManager().beginTransaction()
-                .replace(R.id.fragment_container_detail, fragment)
-                .addToBackStack(null)
-                .commit();
-        updateBreadCrumbs();
-    }
-
-
     // TODO: This should also update the breadcrumbs, which will likely involve a major
     // refactoring of the way breadcrumbs are handled. Perhaps we can store breadcrumb titles in
     // every back stack entry...
@@ -313,13 +217,4 @@
                 .addToBackStack(null)
                 .commit();
     }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (getIntent().getBooleanExtra(MapActivity.EXTRA_DETACHED_MODE, false)
-                && item.getItemId() == android.R.id.home) {
-            finish();
-        }
-        return super.onOptionsItemSelected(item);
-    }
 }
diff --git a/android/src/lpreview/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
similarity index 82%
rename from android/src/lpreview/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
rename to android/src/main/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
index 88b8a45..3087376 100644
--- a/android/src/lpreview/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
@@ -18,7 +18,6 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Color;
@@ -30,10 +29,11 @@
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
 
 import com.google.samples.apps.iosched.R;
 
-@TargetApi(Build.VERSION_CODES.L)
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class AddToScheduleFABFrameLayout extends CheckableFrameLayout {
     private View mRevealView;
     private float mHotSpotX, mHotSpotY;
@@ -72,9 +72,13 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        Outline outline = new Outline();
-        outline.setOval(0, 0, w, h);
-        setOutline(outline);
+        ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setOval(0, 0, view.getWidth(), view.getHeight());
+            }
+        };
+        setOutlineProvider(viewOutlineProvider);
         setClipToOutline(true);
     }
 
@@ -82,9 +86,11 @@
     public void setChecked(boolean checked, boolean allowAnimate) {
         super.setChecked(checked, allowAnimate);
         if (allowAnimate) {
-            ValueAnimator animator = ViewAnimationUtils.createCircularReveal(
+            // TODO: switch to mHotSpotX/mHotSpotY/getWidth if/when nested reveals can be clipped
+            // by parents. was possible in LPV79 but no longer as of this writing.
+            Animator animator = ViewAnimationUtils.createCircularReveal(
                     mRevealView,
-                    (int) mHotSpotX, (int) mHotSpotY, 0, getWidth());
+                    (int) getWidth() / 2, (int) getHeight() / 2, 0, getWidth() / 2);
             animator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/CaptureInsetsFrameLayout.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/CaptureInsetsFrameLayout.java
deleted file mode 100644
index 3c37aaa..0000000
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/CaptureInsetsFrameLayout.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * 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.google.samples.apps.iosched.ui.widget;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-/**
- * A layout that captures the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above
- * UI chrome (status and navigation bars, overlay action bars).
- */
-public class CaptureInsetsFrameLayout extends FrameLayout {
-    private OnInsetsCallback mOnInsetsCallback;
-
-    public CaptureInsetsFrameLayout(Context context) {
-        super(context);
-    }
-
-    public CaptureInsetsFrameLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CaptureInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected boolean fitSystemWindows(Rect insets) {
-        if (mOnInsetsCallback != null) {
-            mOnInsetsCallback.onInsetsChanged(insets);
-        }
-        return false; // don't actually consume the insets
-    }
-
-    /**
-     * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
-     * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
-     * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
-     * clipToPadding to false.
-     */
-    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
-        mOnInsetsCallback = onInsetsCallback;
-    }
-
-    public static interface OnInsetsCallback {
-        public void onInsetsChanged(Rect insets);
-    }
-}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java
index 0cac141..5e7fff0 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java
@@ -16,27 +16,23 @@
 
 package com.google.samples.apps.iosched.ui.widget;
 
-import android.animation.Animator;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Typeface;
+import android.support.v7.widget.CardView;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
-import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import com.google.samples.apps.iosched.R;
-import com.google.samples.apps.iosched.util.UIUtils;
 
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
 import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
 import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
-public class MessageCardView extends FrameLayout implements View.OnClickListener {
+public class MessageCardView extends CardView implements View.OnClickListener {
     private static final String TAG = makeLogTag("MessageCardView");
     private TextView mTitleView;
     private TextView mMessageView;
@@ -50,16 +46,22 @@
         public void onMessageCardButtonClicked(String tag);
     }
 
-    public MessageCardView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
+    public MessageCardView(Context context) {
+        super(context, null, 0);
+        initialize(context, null, 0);
     }
 
-    public MessageCardView(Context context) {
-        this(context, null, 0);
+    public MessageCardView(Context context, AttributeSet attrs) {
+        super(context, attrs, 0);
+        initialize(context, attrs, 0);
     }
 
     public MessageCardView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        initialize(context, attrs, defStyle);
+    }
+
+    private void initialize(Context context, AttributeSet attrs, int defStyle) {
         LayoutInflater inflater = (LayoutInflater) context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
         mRoot = inflater.inflate(R.layout.message_card, this, true);
@@ -76,7 +78,7 @@
             button.setOnClickListener(this);
         }
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MessageCard, 0, 0);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MessageCard, defStyle, 0);
         String title = a.getString(R.styleable.MessageCard_messageTitle);
         setTitle(title);
         String text = a.getString(R.styleable.MessageCard_messageText);
@@ -98,6 +100,10 @@
         if (button2text != null) {
             setButton(1, button2text, button2tag, button2emphasis, emphasisColor);
         }
+
+        setRadius(getResources().getDimensionPixelSize(R.dimen.card_corner_radius));
+        setCardElevation(getResources().getDimensionPixelSize(R.dimen.card_elevation));
+        setPreventCornerOverlap(false);
     }
 
     public void setListener(OnMessageCardButtonClicked listener) {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
new file mode 100644
index 0000000..fc59e53
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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.google.samples.apps.iosched.ui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import com.google.samples.apps.iosched.R;
+
+/**
+ * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
+ * (status and navigation bars, overlay action bars).
+ */
+public class ScrimInsetsFrameLayout extends FrameLayout {
+    private Drawable mInsetForeground;
+
+    private Rect mInsets;
+    private Rect mTempRect = new Rect();
+    private OnInsetsCallback mOnInsetsCallback;
+
+    public ScrimInsetsFrameLayout(Context context) {
+        super(context);
+        init(context, null, 0);
+    }
+
+    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context, attrs, 0);
+    }
+
+    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context, attrs, defStyle);
+    }
+
+    private void init(Context context, AttributeSet attrs, int defStyle) {
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.ScrimInsetsView, defStyle, 0);
+        if (a == null) {
+            return;
+        }
+        mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
+        a.recycle();
+
+        setWillNotDraw(true);
+    }
+
+    @Override
+    protected boolean fitSystemWindows(Rect insets) {
+        mInsets = new Rect(insets);
+        setWillNotDraw(mInsetForeground == null);
+        postInvalidateOnAnimation();
+        if (mOnInsetsCallback != null) {
+            mOnInsetsCallback.onInsetsChanged(insets);
+        }
+        return true; // consume insets
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        int width = getWidth();
+        int height = getHeight();
+        if (mInsets != null && mInsetForeground != null) {
+            int sc = canvas.save();
+            canvas.translate(getScrollX(), getScrollY());
+
+            // Top
+            mTempRect.set(0, 0, width, mInsets.top);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            // Bottom
+            mTempRect.set(0, height - mInsets.bottom, width, height);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            // Left
+            mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            // Right
+            mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            canvas.restoreToCount(sc);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (mInsetForeground != null) {
+            mInsetForeground.setCallback(this);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mInsetForeground != null) {
+            mInsetForeground.setCallback(null);
+        }
+    }
+
+    /**
+     * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
+     * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
+     * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
+     * clipToPadding to false.
+     */
+    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
+        mOnInsetsCallback = onInsetsCallback;
+    }
+
+    public static interface OnInsetsCallback {
+        public void onInsetsChanged(Rect insets);
+    }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsScrollView.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsScrollView.java
new file mode 100644
index 0000000..9c83922
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsScrollView.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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.google.samples.apps.iosched.ui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.ScrollView;
+
+import com.google.samples.apps.iosched.R;
+
+/**
+ * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
+ * (status and navigation bars, overlay action bars).
+ */
+public class ScrimInsetsScrollView extends ScrollView {
+    private Drawable mInsetForeground;
+
+    private Rect mInsets;
+    private Rect mTempRect = new Rect();
+    private OnInsetsCallback mOnInsetsCallback;
+
+    public ScrimInsetsScrollView(Context context) {
+        super(context);
+        init(context, null, 0);
+    }
+
+    public ScrimInsetsScrollView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context, attrs, 0);
+    }
+
+    public ScrimInsetsScrollView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context, attrs, defStyle);
+    }
+
+    private void init(Context context, AttributeSet attrs, int defStyle) {
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.ScrimInsetsView, defStyle, 0);
+        if (a == null) {
+            return;
+        }
+        mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
+        a.recycle();
+
+        setWillNotDraw(true);
+    }
+
+    @Override
+    protected boolean fitSystemWindows(Rect insets) {
+        mInsets = new Rect(insets);
+        setWillNotDraw(mInsetForeground == null);
+        postInvalidateOnAnimation();
+        if (mOnInsetsCallback != null) {
+            mOnInsetsCallback.onInsetsChanged(insets);
+        }
+        return true; // consume insets
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        int width = getWidth();
+        int height = getHeight();
+        if (mInsets != null && mInsetForeground != null) {
+            int sc = canvas.save();
+            canvas.translate(getScrollX(), getScrollY());
+
+            // Top
+            mTempRect.set(0, 0, width, mInsets.top);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            // Bottom
+            mTempRect.set(0, height - mInsets.bottom, width, height);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            // Left
+            mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            // Right
+            mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
+            mInsetForeground.setBounds(mTempRect);
+            mInsetForeground.draw(canvas);
+
+            canvas.restoreToCount(sc);
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (mInsetForeground != null) {
+            mInsetForeground.setCallback(this);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mInsetForeground != null) {
+            mInsetForeground.setCallback(null);
+        }
+    }
+
+    /**
+     * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
+     * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
+     * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
+     * clipToPadding to false.
+     */
+    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
+        mOnInsetsCallback = onInsetsCallback;
+    }
+
+    public static interface OnInsetsCallback {
+        public void onInsetsChanged(Rect insets);
+    }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java
index 153ff6e..ef1256f 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java
@@ -182,6 +182,12 @@
                 PREFIX_PREF_PLUS_IMAGE_URL), null) : null;
     }
 
+    public static String getPlusImageUrl(final Context context, final String accountName) {
+        SharedPreferences sp = getSharedPreferences(context);
+        return hasActiveAccount(context) ? sp.getString(makeAccountSpecificPrefKey(accountName,
+                PREFIX_PREF_PLUS_IMAGE_URL), null) : null;
+    }
+
     public static void refreshAuthToken(Context mContext) {
         invalidateAuthToken(mContext);
         tryAuthenticateWithErrorNotification(mContext, ScheduleContract.CONTENT_AUTHORITY);
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java
index aff85ac..13a4c93 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java
@@ -22,6 +22,7 @@
 import android.net.Uri;
 
 import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.service.FeedbackListenerService;
 import com.google.samples.apps.iosched.service.SessionAlarmService;
 
 import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
@@ -72,7 +73,8 @@
      * should result in removal of the corresponding notifications on both ends.
      */
     public static void dismissFeedbackNotification(Context context, String sessionId) {
-        Intent dismissalIntent = new Intent(SessionAlarmService.ACTION_NOTIFICATION_DISMISSAL);
+        Intent dismissalIntent = new Intent(context, FeedbackListenerService.class);
+        dismissalIntent.setAction(SessionAlarmService.ACTION_NOTIFICATION_DISMISSAL);
         dismissalIntent.putExtra(SessionAlarmService.KEY_SESSION_ID, sessionId);
         context.startService(dismissalIntent);
     }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java b/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java
index b264867..2285f79 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java
@@ -26,7 +26,7 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import com.bumptech.glide.DrawableRequestBuilder;
+import com.bumptech.glide.BitmapRequestBuilder;
 import com.bumptech.glide.Glide;
 import com.bumptech.glide.ModelRequest;
 import com.bumptech.glide.load.Transformation;
@@ -103,7 +103,7 @@
      */
     public void loadImage(String url, ImageView imageView, RequestListener<String> requestListener,
                 Drawable placeholderOverride, boolean crop) {
-        DrawableRequestBuilder<String> request = beginImageLoad(url, requestListener, crop)
+        BitmapRequestBuilder request = beginImageLoad(url, requestListener, crop)
                 .animate(R.anim.image_fade_in);
         if (placeholderOverride != null) {
             request.placeholder(placeholderOverride);
@@ -113,11 +113,12 @@
         request.into(imageView);
     }
 
-    public DrawableRequestBuilder<String> beginImageLoad(String url,
+    public BitmapRequestBuilder beginImageLoad(String url,
             RequestListener<String> requestListener, boolean crop) {
         return mGlideModelRequest.load(url)
+                .asBitmap() // don't allow animated GIFs
                 .listener(requestListener)
-                .bitmapTransform(crop ? mCenterCrop : mNone);
+                .transform(crop ? mCenterCrop : mNone);
     }
 
     /**
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/LPreviewUtilsBase.java b/android/src/main/java/com/google/samples/apps/iosched/util/LPreviewUtilsBase.java
deleted file mode 100644
index e4fa0ae..0000000
--- a/android/src/main/java/com/google/samples/apps/iosched/util/LPreviewUtilsBase.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * 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.google.samples.apps.iosched.util;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.graphics.Typeface;
-import android.os.Handler;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.widget.DrawerLayout;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.google.samples.apps.iosched.R;
-
-public class LPreviewUtilsBase {
-    protected Activity mActivity;
-    private ActionBarDrawerToggle mDrawerToggle;
-    private ActionBarDrawerToggleWrapper mDrawerToggleWrapper;
-    private Handler mHandler = new Handler();
-
-    LPreviewUtilsBase(Activity activity) {
-        mActivity = activity;
-    }
-
-    public ActionBarDrawerToggleWrapper setupDrawerToggle(DrawerLayout drawerLayout,
-            final DrawerLayout.DrawerListener drawerListener) {
-        mDrawerToggle = new ActionBarDrawerToggle(mActivity, drawerLayout,
-                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
-            @Override
-            public void onDrawerClosed(View drawerView) {
-                super.onDrawerClosed(drawerView);
-                drawerListener.onDrawerClosed(drawerView);
-            }
-
-            @Override
-            public void onDrawerOpened(View drawerView) {
-                super.onDrawerOpened(drawerView);
-                drawerListener.onDrawerOpened(drawerView);
-            }
-
-            @Override
-            public void onDrawerStateChanged(int newState) {
-                super.onDrawerStateChanged(newState);
-                drawerListener.onDrawerStateChanged(newState);
-            }
-
-            @Override
-            public void onDrawerSlide(View drawerView, float slideOffset) {
-                super.onDrawerSlide(drawerView, slideOffset);
-                drawerListener.onDrawerSlide(drawerView, slideOffset);
-            }
-        };
-        drawerLayout.setDrawerListener(mDrawerToggle);
-        mDrawerToggleWrapper = new ActionBarDrawerToggleWrapper();
-        return mDrawerToggleWrapper;
-    }
-
-    public void trySetActionBar() {
-        // Do nothing pre-L
-    }
-
-    public boolean hasLPreviewAPIs() {
-        return false;
-    }
-
-    public boolean shouldChangeActionBarForDrawer() {
-        return true;
-    }
-
-    public void showHideActionBarIfPartOfDecor(boolean show) {
-        // pre-L, action bar is always part of the window decor
-        if (show) {
-            mActivity.getActionBar().show();
-        } else {
-            mActivity.getActionBar().hide();
-        }
-    }
-
-    public void setMediumTypeface(TextView textView) {
-        textView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
-    }
-
-    public class ActionBarDrawerToggleWrapper {
-        public void syncState() {
-            if (mDrawerToggle != null) {
-                mDrawerToggle.syncState();
-            }
-        }
-
-        public void onConfigurationChanged(Configuration newConfig) {
-            if (mDrawerToggle != null) {
-                mDrawerToggle.onConfigurationChanged(newConfig);
-            }
-        }
-
-        public boolean onOptionsItemSelected(MenuItem item) {
-            if (mDrawerToggle != null) {
-                return mDrawerToggle.onOptionsItemSelected(item);
-            }
-            return false;
-        }
-    }
-
-    public void startActivityWithTransition(Intent intent, View clickedView,
-            String sharedElementName) {
-        mActivity.startActivity(intent);
-    }
-
-    public void setViewName(View v, String viewName) {
-        // Can't do this pre-L
-    }
-
-    public void postponeEnterTransition() {
-        // Can't do this pre-L
-    }
-
-    public void startPostponedEnterTransition() {
-        // Can't do this pre-L
-    }
-
-    public int getStatusBarColor() {
-        // On pre-L devices, you can have any status bar color so long as it's black.
-        return Color.BLACK;
-    }
-
-    public void setStatusBarColor(int color) {
-        // Only black.
-    }
-
-    public void setViewElevation(View v, float elevation) {
-        // Can't do this pre-L
-    }
-
-    public void setOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
-            boolean allowAnimate) {
-        final int imageResId = isCheck
-                ? R.drawable.add_schedule_button_icon_checked
-                : R.drawable.add_schedule_button_icon_unchecked;
-
-        if (imageView.getTag() != null) {
-            if (imageView.getTag() instanceof Animator) {
-                Animator anim = (Animator) imageView.getTag();
-                anim.end();
-                imageView.setAlpha(1f);
-            }
-        }
-
-        if (allowAnimate && isCheck) {
-            int duration = mActivity.getResources().getInteger(
-                    android.R.integer.config_shortAnimTime);
-
-            Animator outAnimator = ObjectAnimator.ofFloat(imageView, View.ALPHA, 0f);
-            outAnimator.setDuration(duration / 2);
-            outAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    imageView.setImageResource(imageResId);
-                }
-            });
-
-            AnimatorSet inAnimator = new AnimatorSet();
-            outAnimator.setDuration(duration);
-            inAnimator.playTogether(
-                    ObjectAnimator.ofFloat(imageView, View.ALPHA, 1f),
-                    ObjectAnimator.ofFloat(imageView, View.SCALE_X, 0f, 1f),
-                    ObjectAnimator.ofFloat(imageView, View.SCALE_Y, 0f, 1f)
-            );
-
-            AnimatorSet set = new AnimatorSet();
-            set.playSequentially(outAnimator, inAnimator);
-            set.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    imageView.setTag(null);
-                }
-            });
-            imageView.setTag(set);
-            set.start();
-        } else {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    imageView.setImageResource(imageResId);
-                }
-            });
-        }
-    }
-}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/LUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/LUtils.java
new file mode 100644
index 0000000..f34fcff
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/LUtils.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * 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.google.samples.apps.iosched.util;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.graphics.drawable.AnimatedStateListDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Handler;
+import android.support.v7.app.ActionBarActivity;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.google.samples.apps.iosched.R;
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class LUtils {
+    private static final int[] STATE_CHECKED = new int[]{android.R.attr.state_checked};
+    private static final int[] STATE_UNCHECKED = new int[]{};
+
+    private static Typeface sMediumTypeface;
+
+    protected ActionBarActivity mActivity;
+    private Handler mHandler = new Handler();
+
+    private LUtils(ActionBarActivity activity) {
+        mActivity = activity;
+    }
+
+    public static LUtils getInstance(ActionBarActivity activity) {
+        return new LUtils(activity);
+    }
+
+    private static boolean hasL() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+    }
+
+    public void startActivityWithTransition(Intent intent, final View clickedView,
+                                            final String transitionName) {
+        ActivityOptions options = null;
+        if (hasL() && clickedView != null && !TextUtils.isEmpty(transitionName)) {
+//            options = ActivityOptions.makeSceneTransitionAnimation(
+//                    mActivity, clickedView, transitionName);
+        }
+
+        mActivity.startActivity(intent, (options != null) ? options.toBundle() : null);
+    }
+
+    public void setMediumTypeface(TextView textView) {
+        if (hasL()) {
+            if (sMediumTypeface == null) {
+                sMediumTypeface = Typeface.create("sans-serif-medium", Typeface.NORMAL);
+            }
+
+            textView.setTypeface(sMediumTypeface);
+        } else {
+            textView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
+        }
+    }
+
+    public int getStatusBarColor() {
+        if (!hasL()) {
+            // On pre-L devices, you can have any status bar color so long as it's black.
+            return Color.BLACK;
+        }
+
+        return mActivity.getWindow().getStatusBarColor();
+    }
+
+    public void setStatusBarColor(int color) {
+        if (!hasL()) {
+            return;
+        }
+
+        mActivity.getWindow().setStatusBarColor(color);
+    }
+
+    public void setOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
+                                          boolean allowAnimate) {
+        if (!hasL()) {
+            compatSetOrAnimatePlusCheckIcon(imageView, isCheck, allowAnimate);
+            return;
+        }
+
+        Drawable drawable = imageView.getDrawable();
+        if (!(drawable instanceof AnimatedStateListDrawable)) {
+            drawable = mActivity.getResources().getDrawable(R.drawable.add_schedule_fab_icon_anim);
+            imageView.setImageDrawable(drawable);
+        }
+        imageView.setColorFilter(isCheck ?
+                mActivity.getResources().getColor(R.color.theme_accent_1) : Color.WHITE);
+        if (allowAnimate) {
+            imageView.setImageState(isCheck ? STATE_UNCHECKED : STATE_CHECKED, false);
+            drawable.jumpToCurrentState();
+            imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
+        } else {
+            imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
+            drawable.jumpToCurrentState();
+        }
+    }
+
+    public void compatSetOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
+                                                boolean allowAnimate) {
+
+        final int imageResId = isCheck
+                ? R.drawable.add_schedule_button_icon_checked
+                : R.drawable.add_schedule_button_icon_unchecked;
+
+        if (imageView.getTag() != null) {
+            if (imageView.getTag() instanceof Animator) {
+                Animator anim = (Animator) imageView.getTag();
+                anim.end();
+                imageView.setAlpha(1f);
+            }
+        }
+
+        if (allowAnimate && isCheck) {
+            int duration = mActivity.getResources().getInteger(
+                    android.R.integer.config_shortAnimTime);
+
+            Animator outAnimator = ObjectAnimator.ofFloat(imageView, View.ALPHA, 0f);
+            outAnimator.setDuration(duration / 2);
+            outAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    imageView.setImageResource(imageResId);
+                }
+            });
+
+            AnimatorSet inAnimator = new AnimatorSet();
+            outAnimator.setDuration(duration);
+            inAnimator.playTogether(
+                    ObjectAnimator.ofFloat(imageView, View.ALPHA, 1f),
+                    ObjectAnimator.ofFloat(imageView, View.SCALE_X, 0f, 1f),
+                    ObjectAnimator.ofFloat(imageView, View.SCALE_Y, 0f, 1f)
+            );
+
+            AnimatorSet set = new AnimatorSet();
+            set.playSequentially(outAnimator, inAnimator);
+            set.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    imageView.setTag(null);
+                }
+            });
+            imageView.setTag(set);
+            set.start();
+        } else {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    imageView.setImageResource(imageResId);
+                }
+            });
+        }
+    }
+}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java b/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java
index 094010e..7426b11 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
 
@@ -43,7 +44,10 @@
 import java.io.IOException;
 import java.lang.ref.WeakReference;
 
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
 
 /**
  * This helper handles the UI flow for signing in and authenticating an account. It handles
@@ -303,8 +307,13 @@
                 // Record profile ID, image URL and name
                 LOGD(TAG, "Saving plus profile ID: " + currentUser.getId());
                 AccountUtils.setPlusProfileId(mAppContext, mAccountName, currentUser.getId());
-                LOGD(TAG, "Saving plus image URL: " + currentUser.getImage().getUrl());
-                AccountUtils.setPlusImageUrl(mAppContext, mAccountName, currentUser.getImage().getUrl());
+                String imageUrl = currentUser.getImage().getUrl();
+                if (imageUrl != null) {
+                    imageUrl = Uri.parse(imageUrl)
+                            .buildUpon().appendQueryParameter("sz", "256").build().toString();
+                }
+                LOGD(TAG, "Saving plus image URL: " + imageUrl);
+                AccountUtils.setPlusImageUrl(mAppContext, mAccountName, imageUrl);
                 LOGD(TAG, "Saving plus display name: " + currentUser.getDisplayName());
                 AccountUtils.setPlusName(mAppContext, mAccountName, currentUser.getDisplayName());
                 Person.Cover cover = currentUser.getCover();
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java
index 87725fa..750240a 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java
@@ -161,7 +161,7 @@
 
     public static void markUserRefusedSignIn(final Context context, final boolean refused) {
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
-        sp.edit().putBoolean(PREF_USER_REFUSED_SIGN_IN, refused).apply();
+        sp.edit().putBoolean(PREF_USER_REFUSED_SIGN_IN, refused).commit();
     }
 
     public static boolean hasUserRefusedSignIn(final Context context) {
@@ -313,8 +313,8 @@
         sp.registerOnSharedPreferenceChangeListener(listener);
     }
 
-    public static void unrgisterOnSharedPreferenceChangeListener(final Context context,
-            SharedPreferences.OnSharedPreferenceChangeListener listener) {
+    public static void unregisterOnSharedPreferenceChangeListener(final Context context,
+                                                                  SharedPreferences.OnSharedPreferenceChangeListener listener) {
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
         sp.unregisterOnSharedPreferenceChangeListener(listener);
     }
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/RecentTasksStyler.java b/android/src/main/java/com/google/samples/apps/iosched/util/RecentTasksStyler.java
new file mode 100644
index 0000000..c16779f
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/RecentTasksStyler.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * 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.google.samples.apps.iosched.util;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Build;
+
+import com.google.samples.apps.iosched.R;
+
+/**
+ * Helper class that applies the proper icon, title and background color to recent tasks list.
+ */
+public class RecentTasksStyler {
+    private static Bitmap sIcon = null;
+
+    private RecentTasksStyler() {
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public static void styleRecentTasksEntry(Activity activity) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+            return;
+        }
+
+        Resources resources = activity.getResources();
+        String label = resources.getString(activity.getApplicationInfo().labelRes);
+        int colorPrimary = resources.getColor(R.color.theme_primary);
+
+        if (sIcon == null) {
+            // Cache to avoid decoding the same bitmap on every Activity change
+            sIcon = BitmapFactory.decodeResource(resources, R.drawable.ic_stat_notification);
+        }
+
+        activity.setTaskDescription(new ActivityManager.TaskDescription(label, sIcon, colorPrimary));
+    }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java b/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java
index 8d70429..aa98f11 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java
@@ -16,25 +16,20 @@
 
 package com.google.samples.apps.iosched.util;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.AsyncQueryHandler;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
-import android.os.Build;
 import android.support.v4.app.ShareCompat;
 import android.view.MenuItem;
 
 import com.google.samples.apps.iosched.R;
 import com.google.samples.apps.iosched.appwidget.ScheduleWidgetProvider;
-import com.google.samples.apps.iosched.gcm.ServerUtilities;
 import com.google.samples.apps.iosched.provider.ScheduleContract;
 import com.google.samples.apps.iosched.sync.SyncHelper;
-import com.google.samples.apps.iosched.sync.TriggerSyncReceiver;
-import com.google.samples.apps.iosched.ui.MapFragment;
-import com.google.samples.apps.iosched.ui.phone.MapActivity;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
 
 import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
 import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
@@ -55,8 +50,8 @@
     public void startMapActivity(String roomId) {
         Intent intent = new Intent(mActivity.getApplicationContext(),
                 UIUtils.getMapActivityClass(mActivity));
-        intent.putExtra(MapFragment.EXTRA_ROOM, roomId);
-        intent.putExtra(MapActivity.EXTRA_DETACHED_MODE, true);
+        intent.putExtra(BaseMapActivity.EXTRA_ROOM, roomId);
+        intent.putExtra(BaseMapActivity.EXTRA_DETACHED_MODE, true);
         mActivity.startActivity(intent);
     }
 
@@ -71,27 +66,7 @@
 
     public void tryConfigureShareMenuItem(MenuItem menuItem, int messageTemplateResId,
             final String title, String hashtags, String url) {
-        // Intentionally removed by Roman
-//        if (UIUtils.hasICS()) {
-//            ActionProvider itemProvider = menuItem.getActionProvider();
-//            ShareActionProvider provider;
-//            if (!(itemProvider instanceof ShareActionProvider)) {
-//                provider = new ShareActionProvider(mActivity);
-//            } else {
-//                provider = (ShareActionProvider) itemProvider;
-//            }
-//            provider.setShareIntent(createShareIntent(messageTemplateResId, title, hashtags, url));
-//            provider.setOnShareTargetSelectedListener(
-//                    new ShareActionProvider.OnShareTargetSelectedListener() {
-//                        @Override
-//                        public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
-//                            AnalyticsManager.sendEvent("Session", "Shared", title, 0L);
-//                            return false;
-//                        }
-//                    });
-//
-//            menuItem.setActionProvider(provider);
-//        }
+        // TODO: remove
     }
 
     public void shareSession(Context context, int messageTemplateResId, String title,
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java
index 2cafde5..6440085 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java
@@ -26,11 +26,12 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.*;
-import android.graphics.drawable.Drawable;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Typeface;
 import android.net.Uri;
 import android.os.Build;
 import android.preference.PreferenceManager;
@@ -74,9 +75,10 @@
      * Factor applied to session color to derive the background color on panels and when
      * a session photo could not be downloaded (or while it is being downloaded)
      */
-    public static final float SESSION_BG_COLOR_SCALE_FACTOR = 0.65f;
-    public static final float SESSION_PHOTO_SCRIM_ALPHA = 0.75f;
+    public static final float SESSION_BG_COLOR_SCALE_FACTOR = 0.75f;
 
+    private static final float SESSION_PHOTO_SCRIM_ALPHA = 0.25f; // 0=invisible, 1=visible image
+    private static final float SESSION_PHOTO_SCRIM_SATURATION = 0.2f; // 0=gray, 1=color image
 
     public static final String TARGET_FORM_FACTOR_ACTIVITY_METADATA =
             "com.google.samples.apps.iosched.meta.TARGET_FORM_FACTOR";
@@ -294,9 +296,7 @@
     }
 
     public static boolean isTablet(Context context) {
-        return (context.getResources().getConfiguration().screenLayout
-                & Configuration.SCREENLAYOUT_SIZE_MASK)
-                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
+        return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
     }
 
     // Whether a feedback notification was fired for a particular session. In the event that a
@@ -429,7 +429,7 @@
         }
     }
 
-    private static final int[] RES_IDS_ACTION_BAR_SIZE = { android.R.attr.actionBarSize };
+    private static final int[] RES_IDS_ACTION_BAR_SIZE = { R.attr.actionBarSize };
 
     /** Calculates the Action Bar height in pixels. */
     public static int calculateActionBarSize(Context context) {
@@ -467,10 +467,6 @@
         return scaleColor(color, SESSION_BG_COLOR_SCALE_FACTOR, false);
     }
 
-    public static boolean hasActionBar(Activity activity) {
-        return activity.getActionBar() != null;
-    }
-
     public static void showHashtagStream(final Context context, String hashTag) {
         final String hashTagsString = getSessionHashtagsString(hashTag);
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(
@@ -537,4 +533,16 @@
 
         return (value - min) / (float) (max - min);
     }
+
+    // Desaturates and color-scrims the image
+    public static ColorFilter makeSessionImageScrimColorFilter(int sessionColor) {
+        float a = SESSION_PHOTO_SCRIM_ALPHA;
+        float sat = SESSION_PHOTO_SCRIM_SATURATION; // saturation (0=gray, 1=color)
+        return new ColorMatrixColorFilter(new float[]{
+                ((1 - 0.213f) * sat + 0.213f) * a, ((0 - 0.715f) * sat + 0.715f) * a, ((0 - 0.072f) * sat + 0.072f) * a, 0, Color.red(sessionColor) * (1 - a),
+                ((0 - 0.213f) * sat + 0.213f) * a, ((1 - 0.715f) * sat + 0.715f) * a, ((0 - 0.072f) * sat + 0.072f) * a, 0, Color.green(sessionColor) * (1 - a),
+                ((0 - 0.213f) * sat + 0.213f) * a, ((0 - 0.715f) * sat + 0.715f) * a, ((1 - 0.072f) * sat + 0.072f) * a, 0, Color.blue(sessionColor) * (1 - a),
+                0, 0, 0, 0, 255
+        });
+    }
 }
diff --git a/android/src/main/res/anim-v21/add_schedule_fab_state_list_anim.xml b/android/src/main/res/anim-v21/add_schedule_fab_state_list_anim.xml
new file mode 100644
index 0000000..2c6e6dc
--- /dev/null
+++ b/android/src/main/res/anim-v21/add_schedule_fab_state_list_anim.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+   Copyright 2014 Google Inc. All rights reserved.
+
+   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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_enabled="true"
+        android:state_pressed="true">
+        <set>
+            <objectAnimator
+                android:duration="@android:integer/config_shortAnimTime"
+                android:propertyName="translationZ"
+                android:valueTo="@dimen/fab_press_translation_z"
+                android:valueType="floatType" />
+        </set>
+    </item>
+    <item>
+        <set>
+            <objectAnimator
+                android:duration="@android:integer/config_shortAnimTime"
+                android:propertyName="translationZ"
+                android:valueTo="0"
+                android:valueType="floatType" />
+        </set>
+    </item>
+</selector>
diff --git a/android/src/main/res/drawable-hdpi/ic_launcher.png b/android/src/main/res/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index 633e56f..0000000
--- a/android/src/main/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/drawable-mdpi/ic_launcher.png b/android/src/main/res/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 786a92f..0000000
--- a/android/src/main/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-v21/add_schedule_fab_icon_anim.xml b/android/src/main/res/drawable-v21/add_schedule_fab_icon_anim.xml
similarity index 70%
rename from android/src/lpreview/res/drawable-v21/add_schedule_fab_icon_anim.xml
rename to android/src/main/res/drawable-v21/add_schedule_fab_icon_anim.xml
index 809878e..b161902 100644
--- a/android/src/lpreview/res/drawable-v21/add_schedule_fab_icon_anim.xml
+++ b/android/src/main/res/drawable-v21/add_schedule_fab_icon_anim.xml
@@ -15,267 +15,209 @@
   -->
 
 <animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:id="@+id/state_on">
-        <bitmap android:src="@drawable/ic_done_anim_030"
-            android:tint="@color/theme_accent_1" />
+    <item
+        android:id="@+id/state_on"
+        android:state_checked="true">
+        <bitmap android:src="@drawable/ic_done_anim_030" />
     </item>
     <item android:id="@+id/state_off">
-        <bitmap android:src="@drawable/ic_plus_anim_030"
-            android:tint="#fff" />
+        <bitmap android:src="@drawable/ic_plus_anim_030" />
     </item>
-    <transition android:fromId="@+id/state_on" android:toId="@+id/state_off">
+    <transition
+        android:fromId="@+id/state_on"
+        android:toId="@+id/state_off">
         <animation-list>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_000"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_000" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_001"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_001" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_002"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_002" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_003"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_003" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_004"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_004" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_005"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_005" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_006"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_006" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_007"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_007" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_008"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_008" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_009"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_009" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_010"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_010" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_011"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_011" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_012"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_012" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_013"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_013" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_014"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_014" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_015"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_015" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_016"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_016" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_017"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_017" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_018"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_018" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_019"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_019" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_020"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_020" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_021"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_021" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_022"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_022" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_023"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_023" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_024"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_024" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_025"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_025" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_026"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_026" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_027"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_027" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_028"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_028" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_029"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_029" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_plus_anim_030"
-                    android:tint="#fff" />
+                <bitmap android:src="@drawable/ic_plus_anim_030" />
             </item>
         </animation-list>
     </transition>
-    <transition android:fromId="@+id/state_off" android:toId="@+id/state_on">
+    <transition
+        android:fromId="@+id/state_off"
+        android:toId="@+id/state_on">
         <animation-list>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_000"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_000" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_001"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_001" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_002"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_002" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_003"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_003" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_004"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_004" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_005"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_005" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_006"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_006" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_007"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_007" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_008"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_008" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_009"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_009" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_010"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_010" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_011"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_011" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_012"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_012" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_013"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_013" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_014"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_014" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_015"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_015" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_016"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_016" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_017"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_017" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_018"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_018" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_019"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_019" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_020"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_020" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_021"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_021" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_022"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_022" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_023"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_023" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_024"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_024" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_025"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_025" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_026"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_026" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_027"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_027" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_028"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_028" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_029"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_029" />
             </item>
             <item android:duration="16">
-                <bitmap android:src="@drawable/ic_done_anim_030"
-                    android:tint="@color/theme_accent_1" />
+                <bitmap android:src="@drawable/ic_done_anim_030" />
             </item>
         </animation-list>
     </transition>
diff --git a/android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_off.xml b/android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_off.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_off.xml
rename to android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_off.xml
diff --git a/android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_on.xml b/android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
similarity index 96%
rename from android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
rename to android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
index 3b2dcad..2a4d1fe 100644
--- a/android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
+++ b/android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
@@ -15,7 +15,7 @@
    limitations under the License.
 -->
 
-<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#f1f1f1">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#ccc">
     <item>
         <shape>
             <solid android:color="#fff" />
diff --git a/android/src/lpreview/res/drawable-v21/photo_item_foreground.xml b/android/src/main/res/drawable-v21/photo_item_foreground.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/photo_item_foreground.xml
rename to android/src/main/res/drawable-v21/photo_item_foreground.xml
diff --git a/android/src/lpreview/res/values-v21/dimens.xml b/android/src/main/res/drawable-v21/photo_item_foreground_borderless.xml
similarity index 86%
rename from android/src/lpreview/res/values-v21/dimens.xml
rename to android/src/main/res/drawable-v21/photo_item_foreground_borderless.xml
index 6e4a762..7926e0a 100644
--- a/android/src/lpreview/res/values-v21/dimens.xml
+++ b/android/src/main/res/drawable-v21/photo_item_foreground_borderless.xml
@@ -14,6 +14,4 @@
   limitations under the License.
   -->
 
-<resources>
-    <dimen name="spinner_left_padding">16dp</dimen>
-</resources>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#2fff" />
diff --git a/android/src/lpreview/res/drawable-v21/popup_item_background.xml b/android/src/main/res/drawable-v21/popup_item_background.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/popup_item_background.xml
rename to android/src/main/res/drawable-v21/popup_item_background.xml
diff --git a/android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay.xml b/android/src/main/res/drawable-v21/schedule_item_touchoverlay.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay.xml
rename to android/src/main/res/drawable-v21/schedule_item_touchoverlay.xml
diff --git a/android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay_dark.xml b/android/src/main/res/drawable-v21/schedule_item_touchoverlay_dark.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay_dark.xml
rename to android/src/main/res/drawable-v21/schedule_item_touchoverlay_dark.xml
diff --git a/android/src/main/res/drawable-xhdpi/ic_launcher.png b/android/src/main/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index a9f7abb..0000000
--- a/android/src/main/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_000.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_000.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_000.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_000.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_001.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_001.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_001.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_001.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_002.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_002.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_002.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_002.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_003.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_003.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_003.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_003.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_004.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_004.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_004.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_004.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_005.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_005.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_005.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_005.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_006.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_006.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_006.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_006.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_007.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_007.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_007.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_007.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_008.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_008.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_008.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_008.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_009.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_009.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_009.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_009.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_010.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_010.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_010.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_010.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_011.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_011.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_011.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_011.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_012.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_012.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_012.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_012.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_013.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_013.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_013.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_013.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_014.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_014.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_014.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_014.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_015.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_015.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_015.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_015.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_016.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_016.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_016.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_016.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_017.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_017.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_017.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_017.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_018.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_018.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_018.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_018.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_019.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_019.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_019.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_019.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_020.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_020.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_020.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_020.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_021.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_021.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_021.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_021.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_022.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_022.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_022.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_022.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_023.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_023.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_023.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_023.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_024.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_024.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_024.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_024.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_025.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_025.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_025.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_025.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_026.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_026.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_026.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_026.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_027.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_027.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_027.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_027.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_028.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_028.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_028.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_028.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_029.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_029.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_029.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_029.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_030.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_030.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_030.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_030.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_000.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_000.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_000.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_000.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_001.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_001.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_001.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_001.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_002.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_002.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_002.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_002.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_003.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_003.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_003.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_003.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_004.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_004.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_004.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_004.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_005.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_005.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_005.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_005.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_006.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_006.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_006.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_006.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_007.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_007.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_007.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_007.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_008.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_008.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_008.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_008.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_009.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_009.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_009.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_009.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_010.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_010.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_010.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_010.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_011.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_011.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_011.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_011.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_012.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_012.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_012.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_012.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_013.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_013.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_013.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_013.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_014.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_014.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_014.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_014.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_015.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_015.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_015.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_015.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_016.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_016.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_016.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_016.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_017.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_017.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_017.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_017.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_018.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_018.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_018.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_018.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_019.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_019.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_019.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_019.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_020.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_020.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_020.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_020.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_021.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_021.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_021.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_021.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_022.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_022.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_022.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_022.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_023.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_023.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_023.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_023.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_024.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_024.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_024.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_024.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_025.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_025.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_025.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_025.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_026.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_026.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_026.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_026.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_027.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_027.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_027.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_027.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_028.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_028.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_028.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_028.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_029.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_029.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_029.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_029.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_030.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_030.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_030.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_030.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_ab_close.png b/android/src/main/res/drawable-xxhdpi/ic_ab_close.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_ab_close.png
rename to android/src/main/res/drawable-xxhdpi/ic_ab_close.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_share.png b/android/src/main/res/drawable-xxhdpi/ic_action_share.png
index ea53bb6..343dea6 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_action_share.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_action_share.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png b/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png
index 41f1e04..5334780 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer.png b/android/src/main/res/drawable-xxhdpi/ic_drawer.png
index 26420e5..19bae3e 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png
index 71358dc..877de76 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png
index 254eebb..2dad32e 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_feedback.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_feedback.png
deleted file mode 100644
index 71b5219..0000000
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_feedback.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png
index 7695310..f602193 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png
index 7932aa1..541c615 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/src/main/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100755
index 9680dc4..0000000
--- a/android/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_up.png b/android/src/main/res/drawable-xxhdpi/ic_up.png
index dc2da0b..3396894 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_up.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_up.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxxhdpi/ic_launcher.png b/android/src/main/res/drawable-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 3864db3..0000000
--- a/android/src/main/res/drawable-xxxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/layout-sw600dp/activity_map.xml b/android/src/main/res/layout-sw600dp/activity_map.xml
index 2e7ff8a..427032e 100644
--- a/android/src/main/res/layout-sw600dp/activity_map.xml
+++ b/android/src/main/res/layout-sw600dp/activity_map.xml
@@ -16,14 +16,20 @@
 
 <android.support.v4.widget.DrawerLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.phone.MapActivity">
 
-    <FrameLayout android:layout_width="match_parent"
-        android:layout_height="match_parent">
+    <com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/capture_insets_frame_layout"
+        app:insetForeground="@color/translucent_statusbar_background"
+        android:fitsSystemWindows="true">
 
         <FrameLayout
             android:id="@+id/fragment_container_map"
@@ -34,9 +40,9 @@
         <View android:layout_width="fill_parent"
             android:layout_height="fill_parent" />
 
-        <include layout="@layout/toolbar_actionbar_with_translucent_background" />
+        <include layout="@layout/toolbar_actionbar_translucent" />
 
-    </FrameLayout>
+    </com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout>
 
     <LinearLayout android:id="@+id/map_detail_spacer"
         android:visibility="gone"
@@ -46,46 +52,58 @@
         android:orientation="horizontal"
         android:weightSum="2"
         android:gravity="end"
-        android:baselineAligned="false">
+        android:baselineAligned="false"
+        android:clipToPadding="false">
 
-        <RelativeLayout android:id="@+id/map_detail_popup"
+        <android.support.v7.widget.CardView android:id="@+id/map_detail_popup"
             android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="1"
             android:layout_marginLeft="@dimen/multipane_half_padding"
             android:layout_marginBottom="@dimen/multipane_half_padding"
             android:layout_marginRight="@dimen/map_multipane_right_padding"
-            android:background="@drawable/card_bg">
+            app:cardBackgroundColor="#fff"
+            app:cardCornerRadius="@dimen/card_corner_radius"
+            app:cardElevation="@dimen/card_elevation"
+            app:cardPreventCornerOverlap="false">
 
-            <ImageButton android:id="@+id/close_button"
-                android:layout_alignParentTop="true"
-                android:layout_alignParentRight="true"
-                android:src="@drawable/ic_pane_close"
-                android:background="?selectableItemBackgroundBorderless"
-                android:layout_width="48dp"
-                android:layout_height="@dimen/detail_breadcrumb_height"
-                android:contentDescription="@string/close_detail_pane" />
-
-            <android.app.FragmentBreadCrumbs android:id="@+id/breadcrumbs"
-                android:layout_alignParentTop="true"
-                android:layout_alignParentLeft="true"
-                android:layout_toLeftOf="@id/close_button"
-                android:paddingLeft="8dp"
-                android:layout_height="@dimen/detail_breadcrumb_height"
+            <RelativeLayout
                 android:layout_width="match_parent"
-                android:gravity="center_vertical|left" />
+                android:layout_height="match_parent">
 
-            <FrameLayout android:id="@+id/fragment_container_detail"
-                android:layout_alignParentBottom="true"
-                android:layout_alignParentLeft="true"
-                android:layout_alignParentRight="true"
-                android:layout_below="@id/breadcrumbs"
-                android:layout_width="match_parent"
-                android:layout_height="0dp" />
-        </RelativeLayout>
+                <ImageButton
+                    android:id="@+id/close_button"
+                    android:layout_width="48dp"
+                    android:layout_height="@dimen/detail_breadcrumb_height"
+                    android:layout_alignParentRight="true"
+                    android:layout_alignParentTop="true"
+                    android:background="?selectableItemBackgroundBorderless"
+                    android:contentDescription="@string/close_detail_pane"
+                    android:src="@drawable/ic_pane_close" />
+
+                <android.app.FragmentBreadCrumbs
+                    android:id="@+id/breadcrumbs"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/detail_breadcrumb_height"
+                    android:layout_alignParentLeft="true"
+                    android:layout_alignParentTop="true"
+                    android:layout_toLeftOf="@id/close_button"
+                    android:gravity="center_vertical|left"
+                    android:paddingLeft="8dp" />
+
+                <FrameLayout
+                    android:id="@+id/fragment_container_detail"
+                    android:layout_width="match_parent"
+                    android:layout_height="0dp"
+                    android:layout_alignParentBottom="true"
+                    android:layout_alignParentLeft="true"
+                    android:layout_alignParentRight="true"
+                    android:layout_below="@id/breadcrumbs" />
+            </RelativeLayout>
+        </android.support.v7.widget.CardView>
     </LinearLayout>
 
     <!-- Nav drawer -->
-    <include layout="@layout/navdrawer_for_ab_overlay" />
+    <include layout="@layout/navdrawer" />
 
 </android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout-sw600dp/activity_welcome.xml b/android/src/main/res/layout-sw600dp/activity_welcome.xml
index 9c314fe..d2e234b 100644
--- a/android/src/main/res/layout-sw600dp/activity_welcome.xml
+++ b/android/src/main/res/layout-sw600dp/activity_welcome.xml
@@ -15,6 +15,7 @@
   -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:orientation="vertical"
     android:layout_width="match_parent"
@@ -30,92 +31,98 @@
         android:tint="#7000"
         android:layout_gravity="center|top" />
 
-    <LinearLayout
+    <android.support.v7.widget.CardView
         android:layout_width="500dp"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:background="@drawable/card_bg"
-        android:layout_gravity="center">
+        android:layout_gravity="center"
+        iosched:cardBackgroundColor="#fff"
+        iosched:cardCornerRadius="@dimen/card_corner_radius"
+        iosched:cardElevation="@dimen/card_elevation"
+        iosched:cardPreventCornerOverlap="false">
 
-        <ScrollView
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
+            android:layout_height="match_parent"
+            android:orientation="vertical">
 
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1">
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:paddingBottom="48dp"
+                    android:paddingLeft="72dp"
+                    android:paddingRight="72dp"
+                    android:paddingTop="48dp">
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:fontFamily="@string/font_fontFamily_medium"
+                        android:text="@string/welcome_to_google_i_o_app"
+                        android:textColor="@color/theme_primary"
+                        android:textSize="@dimen/text_size_xlarge"
+                        android:textStyle="@integer/font_textStyle_medium" />
+
+                    <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="16dp"
+                        android:autoLink="web"
+                        android:text="@string/welcome_text"
+                        android:textColor="@color/body_text_2"
+                        android:textSize="@dimen/text_size_medium" />
+
+                    <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="16dp"
+                        android:autoLink="web"
+                        android:text="@string/eula_legal_text"
+                        android:textColor="@color/body_text_2"
+                        android:textSize="@dimen/text_size_medium" />
+
+                </LinearLayout>
+            </ScrollView>
+
+            <!-- Button bar -->
             <LinearLayout
                 android:layout_width="match_parent"
-                android:paddingLeft="72dp"
-                android:paddingRight="72dp"
-                android:paddingTop="48dp"
-                android:paddingBottom="48dp"
-                android:orientation="vertical"
-                android:layout_height="wrap_content">
+                android:layout_height="48dp"
+                android:layout_gravity="bottom"
+                android:background="@color/theme_primary">
 
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:textSize="@dimen/text_size_xlarge"
-                    android:textColor="@color/theme_primary"
-                    android:textStyle="@integer/font_textStyle_medium"
+                <Button
+                    android:id="@+id/button_decline"
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="?photoItemForeground"
                     android:fontFamily="@string/font_fontFamily_medium"
-                    android:text="@string/welcome_to_google_i_o_app" />
-
-                <TextView
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="16dp"
-                    android:layout_width="match_parent"
-                    android:textColor="@color/body_text_2"
-                    android:autoLink="web"
+                    android:text="@string/decline"
+                    android:textAllCaps="true"
+                    android:textColor="#8fff"
                     android:textSize="@dimen/text_size_medium"
-                    android:text="@string/welcome_text" />
+                    android:textStyle="@integer/font_textStyle_medium" />
 
-                <TextView
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="16dp"
-                    android:layout_width="match_parent"
-                    android:textColor="@color/body_text_2"
+                <Button
+                    android:id="@+id/button_accept"
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="?photoItemForeground"
+                    android:fontFamily="@string/font_fontFamily_medium"
+                    android:text="@string/accept"
+                    android:textAllCaps="true"
+                    android:textColor="#fff"
                     android:textSize="@dimen/text_size_medium"
-                    android:autoLink="web"
-                    android:text="@string/eula_legal_text" />
+                    android:textStyle="@integer/font_textStyle_medium" />
 
             </LinearLayout>
-        </ScrollView>
-
-        <!-- Button bar -->
-        <LinearLayout
-            android:layout_height="48dp"
-            android:background="@color/theme_primary"
-            android:layout_gravity="bottom"
-            android:layout_width="match_parent">
-
-            <Button
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                android:layout_height="match_parent"
-                android:background="?photoItemForeground"
-                android:text="@string/decline"
-                android:textColor="#8fff"
-                android:textSize="@dimen/text_size_medium"
-                android:textStyle="@integer/font_textStyle_medium"
-                android:fontFamily="@string/font_fontFamily_medium"
-                android:textAllCaps="true"
-                android:id="@+id/button_decline" />
-
-            <Button
-                android:id="@+id/button_accept"
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                android:layout_height="match_parent"
-                android:background="?photoItemForeground"
-                android:text="@string/accept"
-                android:textSize="@dimen/text_size_medium"
-                android:textStyle="@integer/font_textStyle_medium"
-                android:fontFamily="@string/font_fontFamily_medium"
-                android:textAllCaps="true"
-                android:textColor="#fff" />
-
         </LinearLayout>
-
-    </LinearLayout>
-
+    </android.support.v7.widget.CardView>
 </FrameLayout>
diff --git a/android/src/lpreview/res/layout-v21/include_add_schedule_fab.xml b/android/src/main/res/layout-v21/include_add_schedule_fab.xml
similarity index 100%
rename from android/src/lpreview/res/layout-v21/include_add_schedule_fab.xml
rename to android/src/main/res/layout-v21/include_add_schedule_fab.xml
diff --git a/android/src/main/res/layout/activity_browse_sessions.xml b/android/src/main/res/layout/activity_browse_sessions.xml
index c5f3e62..6d2089a 100644
--- a/android/src/main/res/layout/activity_browse_sessions.xml
+++ b/android/src/main/res/layout/activity_browse_sessions.xml
@@ -20,6 +20,7 @@
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.BrowseSessionsActivity">
 
     <!-- Main layout -->
@@ -56,11 +57,9 @@
             <LinearLayout
                 android:id="@+id/filters_box"
                 android:visibility="gone"
-                android:layout_marginTop="?actionBarOverlayTopOffset"
                 android:paddingLeft="?spinnerBarInsetStart"
                 android:layout_width="match_parent"
                 android:layout_height="@dimen/filterbar_height"
-                android:background="@color/theme_primary"
                 android:orientation="horizontal">
 
                 <Spinner style="@style/Widget.IOSched.HeaderBar.Spinner"
@@ -82,12 +81,12 @@
         <FrameLayout android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
-            android:layout_marginTop="?android:actionBarSize">
+            android:layout_marginTop="?actionBarSize">
             <include layout="@layout/include_butter_bar" />
         </FrameLayout>
     </com.google.samples.apps.iosched.ui.widget.DrawShadowFrameLayout>
 
     <!-- Nav drawer -->
-    <include layout="@layout/navdrawer_for_ab_overlay" />
+    <include layout="@layout/navdrawer" />
 
 </android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_experts_directory.xml b/android/src/main/res/layout/activity_experts_directory.xml
index ffef6a7..6095f23 100644
--- a/android/src/main/res/layout/activity_experts_directory.xml
+++ b/android/src/main/res/layout/activity_experts_directory.xml
@@ -20,6 +20,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.ExpertsDirectoryActivity"
     android:layout_height="match_parent">
 
@@ -49,11 +50,9 @@
             <!-- Spinners for additional filters -->
             <LinearLayout
                 android:id="@+id/filters_box"
-                android:layout_marginTop="?actionBarOverlayTopOffset"
                 android:paddingLeft="?spinnerBarInsetStart"
                 android:layout_width="match_parent"
                 android:layout_height="@dimen/filterbar_height"
-                android:background="@color/theme_primary"
                 android:orientation="horizontal">
 
                 <Spinner style="@style/Widget.IOSched.HeaderBar.Spinner"
@@ -73,6 +72,6 @@
     </com.google.samples.apps.iosched.ui.widget.DrawShadowFrameLayout>
 
     <!-- Nav drawer -->
-    <include layout="@layout/navdrawer_for_ab_overlay" />
+    <include layout="@layout/navdrawer" />
 
 </android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_feedback.xml b/android/src/main/res/layout/activity_feedback.xml
new file mode 100644
index 0000000..a19e57e
--- /dev/null
+++ b/android/src/main/res/layout/activity_feedback.xml
@@ -0,0 +1,30 @@
+<!--
+  Copyright 2014 Google Inc. All rights reserved.
+
+  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=".ui.SessionFeedbackActivity">
+
+    <include layout="@layout/toolbar_actionbar_with_headerbar" />
+
+    <FrameLayout
+        android:id="@+id/root_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+</LinearLayout>
\ No newline at end of file
diff --git a/android/src/main/res/layout/activity_map.xml b/android/src/main/res/layout/activity_map.xml
index 4c63eb7..6312b32 100644
--- a/android/src/main/res/layout/activity_map.xml
+++ b/android/src/main/res/layout/activity_map.xml
@@ -15,30 +15,39 @@
   -->
 <android.support.v4.widget.DrawerLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.phone.MapActivity">
 
-    <FrameLayout android:layout_width="match_parent"
-        android:layout_height="match_parent">
+    <com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/capture_insets_frame_layout"
+        app:insetForeground="@color/translucent_statusbar_background"
+        android:fitsSystemWindows="true">
 
         <!-- Main layout -->
         <FrameLayout
-            android:id="@+id/main_content"
+            android:id="@+id/fragment_container_map"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
 
-        <!-- Empty view on top of map to avoid rendering issues with navigation drawer pre-JB -->
-        <View android:layout_width="match_parent"
+        <include layout="@layout/toolbar_actionbar_translucent" />
+
+        <android.support.v7.widget.CardView
+            android:id="@+id/fragment_container_popup"
+            android:visibility="gone"
+            android:clickable="true"
+            android:layout_width="match_parent"
             android:layout_height="match_parent" />
 
-        <include layout="@layout/toolbar_actionbar_with_translucent_background" />
-
-    </FrameLayout>
+    </com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout>
 
     <!-- Nav drawer -->
-    <include layout="@layout/navdrawer_for_ab_overlay" />
+    <include layout="@layout/navdrawer" />
 
 </android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_my_schedule_narrow.xml b/android/src/main/res/layout/activity_my_schedule_narrow.xml
index 428bd36..31734cf 100644
--- a/android/src/main/res/layout/activity_my_schedule_narrow.xml
+++ b/android/src/main/res/layout/activity_my_schedule_narrow.xml
@@ -20,6 +20,7 @@
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.MyScheduleActivity">
 
     <!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_my_schedule_wide.xml b/android/src/main/res/layout/activity_my_schedule_wide.xml
index 35442e2..c8d4c92 100644
--- a/android/src/main/res/layout/activity_my_schedule_wide.xml
+++ b/android/src/main/res/layout/activity_my_schedule_wide.xml
@@ -20,6 +20,7 @@
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.MyScheduleActivity">
 
     <!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_nearby_eula.xml b/android/src/main/res/layout/activity_nearby_eula.xml
index eb52681..e63ed99 100644
--- a/android/src/main/res/layout/activity_nearby_eula.xml
+++ b/android/src/main/res/layout/activity_nearby_eula.xml
@@ -15,6 +15,7 @@
   -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:orientation="vertical"
     android:layout_width="match_parent"
@@ -42,37 +43,46 @@
             <FrameLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:paddingTop="100dp"
                 android:paddingBottom="16dp"
                 android:paddingLeft="16dp"
-                android:paddingRight="16dp">
+                android:paddingRight="16dp"
+                android:paddingTop="100dp"
+                android:clipToPadding="false">
 
-                <LinearLayout
+                <android.support.v7.widget.CardView
                     android:layout_width="match_parent"
-                    android:padding="24dp"
-                    android:orientation="vertical"
-                    android:background="@drawable/card_bg"
-                    android:layout_height="wrap_content">
+                    android:layout_height="wrap_content"
+                    iosched:cardBackgroundColor="#fff"
+                    iosched:cardCornerRadius="@dimen/card_corner_radius"
+                    iosched:cardElevation="@dimen/card_elevation"
+                    iosched:cardPreventCornerOverlap="false">
 
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:textSize="@dimen/text_size_xlarge"
-                        android:textColor="@color/theme_primary"
-                        android:textStyle="@integer/font_textStyle_medium"
-                        android:fontFamily="@string/font_fontFamily_medium"
-                        android:text="@string/physicalweb_intro_title" />
-
-                    <TextView
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
+                    <LinearLayout
                         android:layout_width="match_parent"
-                        android:textColor="@color/body_text_2"
-                        android:textSize="@dimen/text_size_medium"
-                        android:autoLink="web"
-                        android:text="@string/physicalweb_intro_text" />
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical"
+                        android:padding="24dp">
 
-                </LinearLayout>
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:fontFamily="@string/font_fontFamily_medium"
+                            android:text="@string/physicalweb_intro_title"
+                            android:textColor="@color/theme_primary"
+                            android:textSize="@dimen/text_size_xlarge"
+                            android:textStyle="@integer/font_textStyle_medium" />
+
+                        <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="16dp"
+                            android:autoLink="web"
+                            android:text="@string/physicalweb_intro_text"
+                            android:textColor="@color/body_text_2"
+                            android:textSize="@dimen/text_size_medium" />
+
+                    </LinearLayout>
+                </android.support.v7.widget.CardView>
             </FrameLayout>
         </ScrollView>
 
diff --git a/android/src/main/res/layout/activity_people_ive_met.xml b/android/src/main/res/layout/activity_people_ive_met.xml
index 04bb368..ad8c28a 100644
--- a/android/src/main/res/layout/activity_people_ive_met.xml
+++ b/android/src/main/res/layout/activity_people_ive_met.xml
@@ -22,6 +22,7 @@
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     tools:context=".ui.PeopleIveMetActivity"
+    android:fitsSystemWindows="true"
     android:layout_height="match_parent">
 
     <!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_search.xml b/android/src/main/res/layout/activity_search.xml
index 5275ef4..f46faea 100644
--- a/android/src/main/res/layout/activity_search.xml
+++ b/android/src/main/res/layout/activity_search.xml
@@ -14,9 +14,18 @@
   limitations under the License.
   -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/fragment_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context=".ui.SearchActivity"/>
+    android:orientation="vertical">
+
+    <include layout="@layout/toolbar_actionbar_with_headerbar" />
+
+    <FrameLayout
+        android:id="@+id/fragment_container"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        tools:context=".ui.SearchActivity" />
+</LinearLayout>
\ No newline at end of file
diff --git a/android/src/main/res/layout/fragment_session_detail.xml b/android/src/main/res/layout/activity_session_detail.xml
similarity index 79%
rename from android/src/main/res/layout/fragment_session_detail.xml
rename to android/src/main/res/layout/activity_session_detail.xml
index c4c0764..e1a8207 100644
--- a/android/src/main/res/layout/fragment_session_detail.xml
+++ b/android/src/main/res/layout/activity_session_detail.xml
@@ -13,6 +13,7 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
+
 <com.google.samples.apps.iosched.ui.widget.ObservableScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:iosched="http://schemas.android.com/apk/res-auto"
@@ -33,8 +34,7 @@
         <!-- Background photo -->
         <FrameLayout android:id="@+id/session_photo_container"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:foreground="@drawable/photo_banner_scrim">
+            android:layout_height="wrap_content">
 
             <ImageView
                 android:id="@+id/session_photo"
@@ -63,6 +63,7 @@
                 iosched:button2tag="WATCH_NOW"
                 iosched:button2emphasis="true"
                 iosched:emphasisColor="@color/theme_accent_2"
+                iosched:cardBackgroundColor="#fff"
                 android:layout_marginLeft="@dimen/keyline_2_session_detail"
                 android:layout_marginBottom="16dp"
                 android:visibility="gone"
@@ -77,6 +78,7 @@
                 iosched:button2text="@string/give_feedback"
                 iosched:button2tag="GIVE_FEEDBACK"
                 iosched:button2emphasis="true"
+                iosched:cardBackgroundColor="#fff"
                 android:layout_marginLeft="@dimen/keyline_2_session_detail"
                 android:layout_marginBottom="16dp"
                 android:visibility="gone"
@@ -191,9 +193,6 @@
 
             <LinearLayout android:orientation="vertical"
                 android:id="@+id/links_container"
-                android:divider="?android:dividerHorizontal"
-                android:showDividers="middle"
-                android:dividerPadding="16dp"
                 android:layout_marginLeft="@dimen/keyline_2_session_detail"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
@@ -212,63 +211,48 @@
         </LinearLayout>
 
         <!-- Title/subtitle bar (floating; position determined at run time as the content view scrolls) -->
-        <FrameLayout android:layout_width="match_parent"
+        <LinearLayout
+            android:id="@+id/header_session"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:clipChildren="false"
             android:clipToPadding="false"
-            android:id="@+id/header_session">
+            android:orientation="vertical"
+            android:paddingBottom="16dp">
 
-            <!-- height assigned dynamically -->
-            <View android:id="@+id/header_background"
+            <include layout="@layout/toolbar_actionbar" />
+
+            <!-- Session title -->
+            <TextView android:layout_height="wrap_content"
                 android:layout_width="match_parent"
-                android:layout_height="0dp" />
+                android:layout_marginBottom="0dp"
+                android:layout_marginLeft="@dimen/keyline_2_session_detail"
+                android:layout_marginRight="@dimen/keyline_1"
+                android:text="@string/placeholder_session_title"
+                android:id="@+id/session_title"
+                android:maxLines="4"
+                android:ellipsize="end"
+                android:textSize="@dimen/text_size_large"
+                android:lineSpacingMultiplier="1.1"
+                android:textStyle="@integer/font_textStyle_medium"
+                android:fontFamily="@string/font_fontFamily_medium"
+                android:textColor="@color/body_text_1_inverse"
+                android:textAlignment="viewStart" />
 
-            <LinearLayout
-                android:id="@+id/header_session_contents"
+            <!-- Session subtitle -->
+            <TextView android:layout_height="wrap_content"
                 android:layout_width="match_parent"
-                android:orientation="vertical"
-                android:paddingLeft="@dimen/keyline_2_session_detail"
-                android:paddingTop="16dp"
-                android:paddingRight="@dimen/keyline_1"
-                android:paddingBottom="16dp"
-                android:layout_height="wrap_content">
+                android:layout_marginLeft="@dimen/keyline_2_session_detail"
+                android:layout_marginRight="@dimen/keyline_1"
+                android:text="@string/placeholder_session_subtitle"
+                android:id="@+id/session_subtitle"
+                android:maxLines="2"
+                android:ellipsize="end"
+                android:textSize="16sp"
+                android:textColor="@color/body_text_2_inverse"
+                android:textAlignment="viewStart" />
 
-                <!-- Session title -->
-                <TextView android:layout_height="wrap_content"
-                    android:layout_width="match_parent"
-                    android:layout_marginBottom="0dp"
-                    android:text="@string/placeholder_session_title"
-                    android:id="@+id/session_title"
-                    android:maxLines="4"
-                    android:ellipsize="end"
-                    android:textSize="@dimen/text_size_large"
-                    android:lineSpacingMultiplier="1.1"
-                    android:textStyle="@integer/font_textStyle_medium"
-                    android:fontFamily="@string/font_fontFamily_medium"
-                    android:textColor="@color/body_text_1_inverse"
-                    android:textAlignment="viewStart" />
-
-                <!-- Session subtitle -->
-                <TextView android:layout_height="wrap_content"
-                    android:layout_width="match_parent"
-                    android:text="@string/placeholder_session_subtitle"
-                    android:id="@+id/session_subtitle"
-                    android:maxLines="2"
-                    android:ellipsize="end"
-                    android:textSize="16sp"
-                    android:textColor="@color/body_text_2_inverse"
-                    android:textAlignment="viewStart" />
-
-            </LinearLayout>
-
-            <View android:id="@+id/header_shadow"
-                android:layout_width="match_parent"
-                android:layout_height="6dp"
-                android:layout_gravity="bottom"
-                android:layout_marginBottom="-6dp"
-                android:background="@drawable/bottom_shadow" />
-
-        </FrameLayout>
+        </LinearLayout>
 
         <!-- FAB -->
         <include layout="@layout/include_add_schedule_fab" />
diff --git a/android/src/main/res/layout/activity_settings.xml b/android/src/main/res/layout/activity_settings.xml
new file mode 100644
index 0000000..26be77d
--- /dev/null
+++ b/android/src/main/res/layout/activity_settings.xml
@@ -0,0 +1,31 @@
+<!--
+  Copyright 2014 Google Inc. All rights reserved.
+
+  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=".ui.SettingsActivity">
+
+    <include layout="@layout/toolbar_actionbar_with_headerbar" />
+
+    <FrameLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+</LinearLayout>
diff --git a/android/src/main/res/layout/activity_social.xml b/android/src/main/res/layout/activity_social.xml
index 53f4141..3cb29b0 100644
--- a/android/src/main/res/layout/activity_social.xml
+++ b/android/src/main/res/layout/activity_social.xml
@@ -20,6 +20,7 @@
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.SocialActivity">
 
     <!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_video_library.xml b/android/src/main/res/layout/activity_video_library.xml
index 3f424d8..7e58d24 100644
--- a/android/src/main/res/layout/activity_video_library.xml
+++ b/android/src/main/res/layout/activity_video_library.xml
@@ -20,6 +20,7 @@
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
     tools:context=".ui.VideoLibraryActivity">
 
     <!-- Main layout -->
@@ -49,11 +50,9 @@
             <!-- Spinners for additional filters -->
             <LinearLayout
                 android:id="@+id/filters_box"
-                android:layout_marginTop="?actionBarOverlayTopOffset"
                 android:paddingLeft="?spinnerBarInsetStart"
                 android:layout_width="match_parent"
                 android:layout_height="@dimen/filterbar_height"
-                android:background="@color/theme_primary"
                 android:orientation="horizontal">
 
                 <Spinner style="@style/Widget.IOSched.HeaderBar.Spinner"
@@ -73,6 +72,6 @@
     </com.google.samples.apps.iosched.ui.widget.DrawShadowFrameLayout>
 
     <!-- Nav drawer -->
-    <include layout="@layout/navdrawer_for_ab_overlay" />
+    <include layout="@layout/navdrawer" />
 
 </android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_welcome.xml b/android/src/main/res/layout/activity_welcome.xml
index 582c29e..0edeeea 100644
--- a/android/src/main/res/layout/activity_welcome.xml
+++ b/android/src/main/res/layout/activity_welcome.xml
@@ -15,6 +15,7 @@
   -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:orientation="vertical"
     android:layout_width="match_parent"
@@ -42,46 +43,55 @@
             <FrameLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:paddingTop="100dp"
                 android:paddingBottom="16dp"
                 android:paddingLeft="16dp"
-                android:paddingRight="16dp">
+                android:paddingRight="16dp"
+                android:paddingTop="100dp"
+                android:clipToPadding="false">
 
-                <LinearLayout
+                <android.support.v7.widget.CardView
                     android:layout_width="match_parent"
-                    android:padding="24dp"
-                    android:orientation="vertical"
-                    android:background="@drawable/card_bg"
-                    android:layout_height="wrap_content">
+                    android:layout_height="wrap_content"
+                    iosched:cardBackgroundColor="#fff"
+                    iosched:cardCornerRadius="@dimen/card_corner_radius"
+                    iosched:cardElevation="@dimen/card_elevation"
+                    iosched:cardPreventCornerOverlap="false">
 
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:textSize="@dimen/text_size_xlarge"
-                        android:textColor="@color/theme_primary"
-                        android:textStyle="@integer/font_textStyle_medium"
-                        android:fontFamily="@string/font_fontFamily_medium"
-                        android:text="@string/welcome_to_google_i_o_app" />
-
-                    <TextView
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
+                    <LinearLayout
                         android:layout_width="match_parent"
-                        android:textColor="@color/body_text_2"
-                        android:autoLink="web"
-                        android:textSize="@dimen/text_size_medium"
-                        android:text="@string/welcome_text" />
+                        android:layout_height="match_parent"
+                        android:orientation="vertical"
+                        android:padding="24dp">
 
-                    <TextView
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
-                        android:layout_width="match_parent"
-                        android:textColor="@color/body_text_2"
-                        android:textSize="@dimen/text_size_medium"
-                        android:autoLink="web"
-                        android:text="@string/eula_legal_text" />
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:fontFamily="@string/font_fontFamily_medium"
+                            android:text="@string/welcome_to_google_i_o_app"
+                            android:textColor="@color/theme_primary"
+                            android:textSize="@dimen/text_size_xlarge"
+                            android:textStyle="@integer/font_textStyle_medium" />
 
-                </LinearLayout>
+                        <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="16dp"
+                            android:autoLink="web"
+                            android:text="@string/welcome_text"
+                            android:textColor="@color/body_text_2"
+                            android:textSize="@dimen/text_size_medium" />
+
+                        <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="16dp"
+                            android:autoLink="web"
+                            android:text="@string/eula_legal_text"
+                            android:textColor="@color/body_text_2"
+                            android:textSize="@dimen/text_size_medium" />
+
+                    </LinearLayout>
+                </android.support.v7.widget.CardView>
             </FrameLayout>
         </ScrollView>
 
diff --git a/android/src/main/res/layout/dialog_about.xml b/android/src/main/res/layout/dialog_about.xml
index c030704..d502ca2 100644
--- a/android/src/main/res/layout/dialog_about.xml
+++ b/android/src/main/res/layout/dialog_about.xml
@@ -18,7 +18,5 @@
     android:id="@android:id/text1"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:padding="16dp"
-    android:textSize="@dimen/text_size_medium"
-    android:background="@android:color/white"
-    android:textColor="@android:color/black" />
+    android:padding="24dp"
+    android:textSize="@dimen/text_size_medium" />
diff --git a/android/src/main/res/layout/explore_spinner_item_dropdown.xml b/android/src/main/res/layout/explore_spinner_item_dropdown.xml
index f11c1c8..d81bc6b 100644
--- a/android/src/main/res/layout/explore_spinner_item_dropdown.xml
+++ b/android/src/main/res/layout/explore_spinner_item_dropdown.xml
@@ -39,7 +39,7 @@
         android:textColor="@color/body_text_3" />
 
     <TextView
-        android:id="@+id/normal_text"
+        android:id="@android:id/text1"
         android:layout_height="@dimen/explore_dropdown_item_height"
         android:layout_width="match_parent"
         android:paddingLeft="16dp"
diff --git a/android/src/main/res/layout/fragment_experts_directory.xml b/android/src/main/res/layout/fragment_experts_directory.xml
index 5d1efc2..63846e9 100644
--- a/android/src/main/res/layout/fragment_experts_directory.xml
+++ b/android/src/main/res/layout/fragment_experts_directory.xml
@@ -20,7 +20,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     xmlns:iosched="http://schemas.android.com/apk/res-auto"
-    android:padding="@dimen/half_explore_grid_padding"
+    android:padding="@dimen/explore_grid_padding_half"
     android:clipToPadding="false"
     android:scrollbarStyle="outsideOverlay"
     iosched:internalPadding="@dimen/explore_grid_padding" />
diff --git a/android/src/main/res/layout/fragment_hashtags.xml b/android/src/main/res/layout/fragment_hashtags.xml
index 939e4f9..e482470 100644
--- a/android/src/main/res/layout/fragment_hashtags.xml
+++ b/android/src/main/res/layout/fragment_hashtags.xml
@@ -23,9 +23,11 @@
     android:id="@+id/social_collection_vew"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:padding="@dimen/social_grid_padding"
+    android:paddingTop="@dimen/explore_grid_padding"
+    android:paddingLeft="@dimen/explore_grid_padding_half"
+    android:paddingRight="@dimen/explore_grid_padding_half"
+    iosched:internalPadding="@dimen/explore_grid_padding"
     android:layout_marginStart="@dimen/social_hz_margin"
     android:layout_marginEnd="@dimen/social_hz_margin"
     android:clipToPadding="false"
-    iosched:internalPadding="@dimen/social_grid_padding"
     tools:context="com.google.samples.apps.iosched.ui.HashtagsFragment" />
diff --git a/android/src/main/res/layout/fragment_map.xml b/android/src/main/res/layout/fragment_map.xml
index 6580e3f..b7deaea 100644
--- a/android/src/main/res/layout/fragment_map.xml
+++ b/android/src/main/res/layout/fragment_map.xml
@@ -17,6 +17,4 @@
     android:id="@+id/map_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/theme_primary" >
-
-</FrameLayout>
+    android:background="@color/theme_primary" />
\ No newline at end of file
diff --git a/android/src/main/res/layout/fragment_nearby.xml b/android/src/main/res/layout/fragment_nearby.xml
index c40e7db..d5b257b 100644
--- a/android/src/main/res/layout/fragment_nearby.xml
+++ b/android/src/main/res/layout/fragment_nearby.xml
@@ -20,28 +20,28 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <LinearLayout android:id="@+id/headerbar"
+    <FrameLayout android:id="@+id/headerbar"
         android:layout_width="match_parent"
-        android:layout_height="?android:actionBarSize"
-        android:orientation="horizontal"
+        android:layout_height="?actionBarSize"
+        android:elevation="@dimen/headerbar_elevation"
         android:background="#e5e5e5">
 
         <ImageButton android:id="@+id/close_button"
-            android:layout_width="48dp"
+            android:layout_width="56dp"
             android:layout_height="match_parent"
             android:background="?selectableItemBackgroundBorderless"
             android:src="@drawable/ic_pane_close"
             android:contentDescription="@string/close_detail_pane" />
 
-        <TextView android:layout_width="wrap_content"
+        <TextView android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_marginLeft="4dp"
+            android:layout_marginLeft="@dimen/keyline_2"
             android:textSize="@dimen/text_size_large"
             android:textColor="@color/body_text_1"
             android:gravity="center_vertical"
             android:text="@string/map_nearby_button" />
 
-    </LinearLayout>
+    </FrameLayout>
 
     <FrameLayout android:id="@+id/list_container"
         android:layout_width="match_parent"
diff --git a/android/src/main/res/layout/fragment_partners.xml b/android/src/main/res/layout/fragment_partners.xml
index 0b70e32..1eef654 100644
--- a/android/src/main/res/layout/fragment_partners.xml
+++ b/android/src/main/res/layout/fragment_partners.xml
@@ -21,14 +21,15 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <LinearLayout android:id="@+id/headerbar"
+    <FrameLayout android:id="@+id/headerbar"
         android:layout_width="match_parent"
-        android:layout_height="?android:actionBarSize"
+        android:layout_height="?actionBarSize"
+        android:elevation="@dimen/headerbar_elevation"
         android:orientation="horizontal"
         android:background="#e5e5e5">
 
         <ImageButton android:id="@+id/close_button"
-            android:layout_width="48dp"
+            android:layout_width="56dp"
             android:layout_height="match_parent"
             android:background="?selectableItemBackgroundBorderless"
             android:src="@drawable/ic_pane_close"
@@ -36,13 +37,13 @@
 
         <TextView android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_marginLeft="4dp"
+            android:layout_marginLeft="@dimen/keyline_2"
             android:textSize="@dimen/text_size_large"
             android:textColor="@color/body_text_1"
             android:gravity="center_vertical"
             android:text="@string/partners" />
 
-    </LinearLayout>
+    </FrameLayout>
 
     <FrameLayout android:layout_width="match_parent"
         android:layout_height="0dp"
@@ -53,8 +54,8 @@
             android:id="@+id/collection_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:paddingLeft="@dimen/half_explore_grid_padding"
-            android:paddingRight="@dimen/half_explore_grid_padding"
+            android:paddingLeft="@dimen/explore_grid_padding_half"
+            android:paddingRight="@dimen/explore_grid_padding_half"
             android:paddingTop="@dimen/explore_grid_padding"
             android:clipToPadding="false"
             android:scrollbarStyle="outsideOverlay"
diff --git a/android/src/main/res/layout/fragment_session_feedback.xml b/android/src/main/res/layout/fragment_session_feedback.xml
index 13642d7..8177731 100644
--- a/android/src/main/res/layout/fragment_session_feedback.xml
+++ b/android/src/main/res/layout/fragment_session_feedback.xml
@@ -19,7 +19,8 @@
     android:id="@+id/scroll_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:fillViewport="true">
 
     <LinearLayout
         android:orientation="vertical"
diff --git a/android/src/main/res/layout/fragment_sessions.xml b/android/src/main/res/layout/fragment_sessions.xml
index 84507fc..ffb781c 100644
--- a/android/src/main/res/layout/fragment_sessions.xml
+++ b/android/src/main/res/layout/fragment_sessions.xml
@@ -22,7 +22,7 @@
         android:id="@+id/sessions_collection_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:padding="@dimen/half_explore_grid_padding"
+        android:padding="@dimen/explore_grid_padding_half"
         android:clipToPadding="false"
         android:scrollbarStyle="outsideOverlay"
         iosched:internalPadding="@dimen/explore_grid_padding" />
@@ -30,7 +30,7 @@
     <ProgressBar
         android:id="@+id/loading"
         android:visibility="gone"
-        android:paddingTop="?android:actionBarSize"
+        android:paddingTop="?actionBarSize"
         android:layout_gravity="center"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -39,7 +39,7 @@
     <TextView
         android:id="@+id/empty_text"
         android:visibility="gone"
-        android:paddingTop="?android:actionBarSize"
+        android:paddingTop="?actionBarSize"
         android:layout_gravity="center"
         android:gravity="center"
         android:layout_width="match_parent"
diff --git a/android/src/main/res/layout/fragment_video_library.xml b/android/src/main/res/layout/fragment_video_library.xml
index a596f1c..95e8a9f 100644
--- a/android/src/main/res/layout/fragment_video_library.xml
+++ b/android/src/main/res/layout/fragment_video_library.xml
@@ -25,9 +25,9 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:clipToPadding="false"
-        android:paddingLeft="@dimen/explore_grid_padding"
-        android:paddingRight="@dimen/explore_grid_padding"
-        android:paddingBottom="@dimen/explore_grid_padding"
+        android:paddingTop="@dimen/explore_grid_padding"
+        android:paddingLeft="@dimen/explore_grid_padding_half"
+        android:paddingRight="@dimen/explore_grid_padding_half"
         iosched:internalPadding="@dimen/explore_grid_padding" />
 
     <!-- Empty view -->
@@ -40,7 +40,7 @@
         android:textSize="@dimen/text_size_medium"
         android:textColor="@color/body_text_2"
         android:text="@string/no_matching_videos"
-        android:paddingTop="?android:actionBarSize" />
+        android:paddingTop="?actionBarSize" />
 
 </FrameLayout>
 
diff --git a/android/src/main/res/layout/header_experts_directory.xml b/android/src/main/res/layout/header_experts_directory.xml
index f655a68..56bbea9 100644
--- a/android/src/main/res/layout/header_experts_directory.xml
+++ b/android/src/main/res/layout/header_experts_directory.xml
@@ -33,5 +33,6 @@
         iosched:messageTitle="@string/experts_directory_header_title"
         iosched:messageText="@string/experts_directory_header_body"
         iosched:button1text="@string/experts_directory_header_dismiss"
-        iosched:button1emphasis="true" />
+        iosched:button1emphasis="true"
+        iosched:cardBackgroundColor="#fff" />
 </FrameLayout>
diff --git a/android/src/main/res/layout/include_link_row.xml b/android/src/main/res/layout/include_link_row.xml
index 19c837e..4c4255d 100644
--- a/android/src/main/res/layout/include_link_row.xml
+++ b/android/src/main/res/layout/include_link_row.xml
@@ -17,7 +17,4 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="horizontal"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:showDividers="middle"
-    android:divider="?android:dividerVertical"
-    android:dividerPadding="8dp" />
+    android:layout_height="wrap_content" />
diff --git a/android/src/main/res/layout/list_item_session.xml b/android/src/main/res/layout/list_item_session.xml
index ad10d4f..19b5d30 100644
--- a/android/src/main/res/layout/list_item_session.xml
+++ b/android/src/main/res/layout/list_item_session.xml
@@ -17,71 +17,53 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="300dp"
-    android:id="@+id/session_target"
-    android:foreground="?photoItemForeground">
+    android:foreground="?photoItemForeground"
+    android:id="@+id/session_target">
 
-    <!-- Session info -->
-    <LinearLayout
-        android:orientation="vertical"
+    <!-- Session image -->
+    <ImageView android:id="@+id/session_photo_colored"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent" />
 
-        <!-- Session image -->
-        <FrameLayout android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
+    <!-- Session category/group if non-default (e.g. "Workshop") -->
+    <TextView android:id="@+id/session_category"
+        style="@style/ExploreItem.Category"
+        android:padding="16dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
 
-            <ImageView android:id="@+id/session_photo"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop" />
+    <!-- Info box -->
+    <LinearLayout
+        android:id="@+id/info_box"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:padding="16dp"
+        android:orientation="vertical">
 
-            <!-- Live Now indicator -->
-            <include layout="@layout/include_live_now_badge" />
-
-            <!-- Session category/group if non-default (e.g. "Workshop") -->
-            <TextView android:id="@+id/session_category"
-                style="@style/ExploreItem.Category"
-                android:padding="16dp"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content" />
-
-        </FrameLayout>
-
-        <!-- Info box -->
-        <LinearLayout
-            android:id="@+id/info_box"
+        <!-- Session title -->
+        <TextView android:id="@+id/session_title"
+            style="@style/ExploreItem.Title"
             android:layout_width="match_parent"
-            android:layout_height="120dp"
-            android:gravity="center"
-            android:padding="16dp"
-            android:orientation="vertical"
-            android:background="@color/theme_primary">
+            android:layout_height="wrap_content"
+            android:text="@string/placeholder_session_title" />
 
-            <!-- Session title -->
-            <TextView android:id="@+id/session_title"
-                style="@style/ExploreItem.Title"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/placeholder_session_title" />
+        <!-- Subtitle -->
+        <TextView android:id="@+id/session_subtitle_short"
+            style="@style/ExploreItem.Subtitle"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="8dp"
+            android:text="@string/placeholder_session_subtitle" />
 
-            <!-- Subtitle -->
-            <TextView android:id="@+id/session_subtitle"
-                style="@style/ExploreItem.Subtitle"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:paddingBottom="8dp"
-                android:text="@string/placeholder_session_subtitle" />
+        <!-- Abstract snippet -->
+        <TextView android:id="@+id/session_snippet"
+            style="@style/ExploreItem.Snippet"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:maxLines="5"
+            android:text="@string/placeholder_lorem_ipsum" />
 
-            <!-- Abstract snippet -->
-            <TextView android:id="@+id/session_snippet"
-                style="@style/ExploreItem.Snippet"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:maxLines="3"
-                android:text="@string/placeholder_lorem_ipsum" />
-
-        </LinearLayout>
     </LinearLayout>
 
     <!-- "In schedule" indicator -->
@@ -92,4 +74,6 @@
         android:src="@drawable/indicator_in_schedule"
         android:contentDescription="@null" />
 
+    <!-- Live Now indicator -->
+    <include layout="@layout/include_live_now_badge" />
 </FrameLayout>
diff --git a/android/src/main/res/layout/list_item_session_hero_narrow.xml b/android/src/main/res/layout/list_item_session_hero_narrow.xml
index c5b9cff..2912c96 100644
--- a/android/src/main/res/layout/list_item_session_hero_narrow.xml
+++ b/android/src/main/res/layout/list_item_session_hero_narrow.xml
@@ -23,6 +23,7 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:animateLayoutChanges="true"
@@ -99,6 +100,7 @@
         android:layout_marginBottom="8dp"
         android:layout_marginLeft="4dp"
         android:layout_marginRight="4dp"
+        iosched:cardBackgroundColor="#fff"
         android:visibility="visible"
         android:layout_height="wrap_content"
         />
diff --git a/android/src/main/res/layout/list_item_session_hero_wide.xml b/android/src/main/res/layout/list_item_session_hero_wide.xml
index cbd2a4d..be1d337 100644
--- a/android/src/main/res/layout/list_item_session_hero_wide.xml
+++ b/android/src/main/res/layout/list_item_session_hero_wide.xml
@@ -21,6 +21,7 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:animateLayoutChanges="true"
@@ -110,6 +111,7 @@
                 android:layout_height="wrap_content"
                 android:clickable="true"
                 android:focusable="true"
+                iosched:cardBackgroundColor="#fff"
                 />
         </FrameLayout>
     </FrameLayout>
diff --git a/android/src/main/res/layout/message_card.xml b/android/src/main/res/layout/message_card.xml
index 9a494c1..c7f70a1 100644
--- a/android/src/main/res/layout/message_card.xml
+++ b/android/src/main/res/layout/message_card.xml
@@ -19,8 +19,7 @@
     android:id="@+id/card_root"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/card_bg">
+    android:layout_height="match_parent">
 
     <TextView
         android:id="@+id/title"
@@ -91,4 +90,4 @@
     </LinearLayout>
 
 
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/android/src/main/res/layout/my_schedule_item.xml b/android/src/main/res/layout/my_schedule_item.xml
index b09d0d1..c39991d 100644
--- a/android/src/main/res/layout/my_schedule_item.xml
+++ b/android/src/main/res/layout/my_schedule_item.xml
@@ -115,6 +115,5 @@
             android:scaleType="center"
             android:src="@drawable/ic_schedule_feedback"
             android:background="?photoItemForeground" />
-
-    </FrameLayout>
+        </FrameLayout>
 </LinearLayout>
diff --git a/android/src/main/res/layout/navdrawer.xml b/android/src/main/res/layout/navdrawer.xml
index 0d7027b..f05fe26 100644
--- a/android/src/main/res/layout/navdrawer.xml
+++ b/android/src/main/res/layout/navdrawer.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
    Copyright 2014 Google Inc. All rights reserved.
 
@@ -15,19 +14,114 @@
    limitations under the License.
 -->
 
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.google.samples.apps.iosched.ui.widget.ScrimInsetsScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/navdrawer_width"
     android:layout_height="match_parent"
-    android:id="@+id/navdrawer"
     android:layout_gravity="start"
-    android:background="@color/navdrawer_background">
+    android:id="@+id/navdrawer"
+    android:background="@color/navdrawer_background"
+    android:fitsSystemWindows="true"
+    app:insetForeground="#4000">
 
     <LinearLayout android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical">
 
-        <include layout="@layout/navdrawer_content" />
+        <FrameLayout
+            android:id="@+id/chosen_account_view"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/navdrawer_chosen_account_height"
+            android:foreground="?photoItemForeground">
 
+            <ImageView android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:scaleType="centerCrop"
+                android:src="@drawable/default_cover"
+                android:tint="@color/session_photo_scrim"
+                android:id="@+id/profile_cover_image" />
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingLeft="@dimen/keyline_1"
+                android:paddingRight="@dimen/keyline_1"
+                android:paddingTop="@dimen/keyline_1"
+                android:id="@+id/chosen_account_content_view">
+
+                <com.google.samples.apps.iosched.ui.widget.BezelImageView
+                    android:id="@+id/profile_image"
+                    android:layout_width="@dimen/navdrawer_profile_image_size"
+                    android:layout_height="@dimen/navdrawer_profile_image_size"
+                    android:src="@drawable/person_image_empty"
+                    android:scaleType="centerCrop"
+                    app:maskDrawable="@drawable/circle_mask" />
+
+                <ImageView
+                    android:id="@+id/expand_account_box_indicator"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:visibility="gone"
+                    android:layout_marginLeft="16dp"
+                    android:paddingBottom="16dp"
+                    android:layout_alignParentEnd="true"
+                    android:layout_alignParentBottom="true"
+                    android:scaleType="center"
+                    android:src="@drawable/ic_drawer_accounts_expand" />
+
+                <TextView
+                    android:id="@+id/profile_email_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_alignLeft="@id/profile_image"
+                    android:layout_toLeftOf="@id/expand_account_box_indicator"
+                    android:layout_alignParentBottom="true"
+                    android:paddingBottom="16dp"
+                    android:textSize="@dimen/text_size_medium"
+                    android:textColor="@color/body_text_2_inverse"
+                    android:maxLines="1"
+                    android:singleLine="true"
+                    android:ellipsize="end" />
+
+                <TextView
+                    android:id="@+id/profile_name_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_above="@id/profile_email_text"
+                    android:layout_alignLeft="@id/profile_image"
+                    android:layout_toLeftOf="@id/expand_account_box_indicator"
+                    android:textSize="@dimen/text_size_large"
+                    android:textColor="@color/body_text_1_inverse"
+                    android:maxLines="1"
+                    android:singleLine="true"
+                    android:ellipsize="end" />
+
+            </RelativeLayout>
+
+        </FrameLayout>
+
+        <FrameLayout android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <!-- Account items -->
+            <LinearLayout
+                android:id="@+id/account_list"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:orientation="vertical"
+                android:visibility="invisible" />
+
+            <!-- Drawer items -->
+            <LinearLayout
+                android:id="@+id/navdrawer_items_list"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginBottom="8dp"
+                android:orientation="vertical" />
+        </FrameLayout>
     </LinearLayout>
 
-</ScrollView>
+</com.google.samples.apps.iosched.ui.widget.ScrimInsetsScrollView>
\ No newline at end of file
diff --git a/android/src/main/res/layout/navdrawer_content.xml b/android/src/main/res/layout/navdrawer_content.xml
deleted file mode 100644
index ddba93d..0000000
--- a/android/src/main/res/layout/navdrawer_content.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<!--
-  Copyright 2014 Google Inc. All rights reserved.
-
-  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.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:iosched="http://schemas.android.com/apk/res-auto">
-
-    <FrameLayout
-        android:id="@+id/chosen_account_view"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/navdrawer_chosen_account_height"
-        android:foreground="?photoItemForeground">
-
-        <ImageView android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:scaleType="centerCrop"
-            android:src="@drawable/default_cover"
-            android:tint="@color/session_photo_scrim"
-            android:id="@+id/profile_cover_image" />
-
-        <RelativeLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingLeft="@dimen/keyline_1"
-            android:paddingRight="@dimen/keyline_1"
-            android:paddingTop="@dimen/keyline_1">
-
-            <com.google.samples.apps.iosched.ui.widget.BezelImageView
-                android:id="@+id/profile_image"
-                android:layout_width="@dimen/navdrawer_profile_image_size"
-                android:layout_height="@dimen/navdrawer_profile_image_size"
-                android:src="@drawable/person_image_empty"
-                android:scaleType="centerCrop"
-                iosched:maskDrawable="@drawable/circle_mask" />
-
-            <ImageView
-                android:id="@+id/expand_account_box_indicator"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:visibility="gone"
-                android:layout_marginLeft="16dp"
-                android:paddingBottom="16dp"
-                android:layout_alignParentEnd="true"
-                android:layout_alignParentBottom="true"
-                android:scaleType="center"
-                android:src="@drawable/ic_drawer_accounts_expand" />
-
-            <TextView
-                android:id="@+id/profile_email_text"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignLeft="@id/profile_image"
-                android:layout_toLeftOf="@id/expand_account_box_indicator"
-                android:layout_alignParentBottom="true"
-                android:paddingBottom="16dp"
-                android:textSize="@dimen/text_size_medium"
-                android:textColor="@color/body_text_1_inverse"
-                android:maxLines="1"
-                android:singleLine="true"
-                android:ellipsize="end" />
-
-            <TextView
-                android:id="@+id/profile_name_text"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_above="@id/profile_email_text"
-                android:layout_alignLeft="@id/profile_image"
-                android:layout_toLeftOf="@id/expand_account_box_indicator"
-                android:textSize="@dimen/text_size_large"
-                android:textStyle="bold"
-                android:textColor="@color/body_text_1_inverse"
-                android:maxLines="1"
-                android:singleLine="true"
-                android:ellipsize="end" />
-
-        </RelativeLayout>
-
-    </FrameLayout>
-
-    <FrameLayout android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <!-- Account items -->
-        <LinearLayout
-            android:id="@+id/account_list"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:orientation="vertical"
-            android:visibility="invisible" />
-
-        <!-- Drawer items -->
-        <LinearLayout
-            android:id="@+id/navdrawer_items_list"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:layout_marginBottom="8dp"
-            android:orientation="vertical" />
-    </FrameLayout>
-</merge>
diff --git a/android/src/main/res/layout/navdrawer_for_ab_overlay.xml b/android/src/main/res/layout/navdrawer_for_ab_overlay.xml
deleted file mode 100644
index 1b7a090..0000000
--- a/android/src/main/res/layout/navdrawer_for_ab_overlay.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Copyright 2014 Google Inc. All rights reserved.
-
-   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 xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/navdrawer_width"
-    android:layout_height="match_parent"
-    android:id="@+id/navdrawer"
-    android:layout_gravity="start"
-    android:background="@color/navdrawer_background"
-    android:paddingTop="?actionBarOverlayTopOffset"
-    android:clipToPadding="false">
-
-    <LinearLayout android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <include layout="@layout/navdrawer_content" />
-
-    </LinearLayout>
-
-</ScrollView>
diff --git a/android/src/main/res/layout/navdrawer_item.xml b/android/src/main/res/layout/navdrawer_item.xml
index a734953..bda2962 100644
--- a/android/src/main/res/layout/navdrawer_item.xml
+++ b/android/src/main/res/layout/navdrawer_item.xml
@@ -33,11 +33,11 @@
         android:id="@+id/title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:gravity="start|center_vertical"
         android:layout_gravity="start|center_vertical"
+        android:gravity="start|center_vertical"
+        android:fontFamily="@string/font_fontFamily_medium"
+        android:textStyle="@integer/font_textStyle_medium"
         android:textSize="14sp"
-        android:textStyle="@integer/font_textStyle_drawer_item"
-        android:fontFamily="@string/font_fontFamily_drawer_item"
         android:text="@string/placeholder_lorem_ipsum" />
 
 </LinearLayout>
diff --git a/android/src/main/res/layout/nearby_button.xml b/android/src/main/res/layout/nearby_button.xml
index 20baf93..4965c5b 100644
--- a/android/src/main/res/layout/nearby_button.xml
+++ b/android/src/main/res/layout/nearby_button.xml
@@ -32,6 +32,7 @@
         android:textStyle="@integer/font_textStyle_medium"
         android:fontFamily="@string/font_fontFamily_medium"
         android:textAllCaps="true"
+        android:stateListAnimator="@null"
         android:background="@drawable/nearby_button_background"
         android:textColor="@color/body_text_1_inverse"/>
 
diff --git a/android/src/main/res/layout/toolbar_actionbar.xml b/android/src/main/res/layout/toolbar_actionbar.xml
index 57d3173..7717e34 100644
--- a/android/src/main/res/layout/toolbar_actionbar.xml
+++ b/android/src/main/res/layout/toolbar_actionbar.xml
@@ -14,6 +14,13 @@
   limitations under the License.
   -->
 
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="0dp"
-    android:layout_height="0dp" />
+<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
+    iosched:theme="@style/ActionBarThemeOverlay"
+    iosched:popupTheme="@style/ActionBarPopupThemeOverlay"
+    android:id="@+id/toolbar_actionbar"
+    android:background="@null"
+    iosched:titleTextAppearance="@style/ActionBar.TitleText"
+    iosched:contentInsetStart="?actionBarInsetStart"
+    android:layout_width="match_parent"
+    android:layout_height="?actionBarSize" />
diff --git a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_translucent_background.xml b/android/src/main/res/layout/toolbar_actionbar_translucent.xml
similarity index 63%
rename from android/src/lpreview/res/layout-v21/toolbar_actionbar_with_translucent_background.xml
rename to android/src/main/res/layout/toolbar_actionbar_translucent.xml
index aca3d8e..5861831 100644
--- a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_translucent_background.xml
+++ b/android/src/main/res/layout/toolbar_actionbar_translucent.xml
@@ -14,9 +14,13 @@
   limitations under the License.
   -->
 
-<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
-    android:theme="@style/ActionBarThemeOverlay"
-    android:background="@color/translucent_actionbar_background"
+<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
+    iosched:theme="@style/ActionBarThemeOverlay"
+    iosched:popupTheme="@style/ActionBarPopupThemeOverlay"
     android:id="@+id/toolbar_actionbar"
+    android:background="@color/translucent_actionbar_background"
+    iosched:titleTextAppearance="@style/ActionBar.TitleText"
+    iosched:contentInsetStart="?actionBarInsetStart"
     android:layout_width="match_parent"
-    android:layout_height="?android:actionBarSize" />
+    android:layout_height="?actionBarSize" />
diff --git a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_headerbar.xml b/android/src/main/res/layout/toolbar_actionbar_with_headerbar.xml
similarity index 62%
rename from android/src/lpreview/res/layout-v21/toolbar_actionbar_with_headerbar.xml
rename to android/src/main/res/layout/toolbar_actionbar_with_headerbar.xml
index 47c3296..578aea0 100644
--- a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_headerbar.xml
+++ b/android/src/main/res/layout/toolbar_actionbar_with_headerbar.xml
@@ -14,9 +14,13 @@
   limitations under the License.
   -->
 
-<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto"
     style="@style/HeaderBar"
-    android:theme="@style/ActionBarThemeOverlay"
+    iosched:theme="@style/ActionBarThemeOverlay"
+    iosched:popupTheme="@style/ActionBarPopupThemeOverlay"
     android:id="@+id/toolbar_actionbar"
+    iosched:titleTextAppearance="@style/ActionBar.TitleText"
+    iosched:contentInsetStart="?actionBarInsetStart"
     android:layout_width="match_parent"
-    android:layout_height="?android:actionBarSize" />
+    android:layout_height="?actionBarSize" />
diff --git a/android/src/main/res/layout/video_library_spinner_item_dropdown.xml b/android/src/main/res/layout/video_library_spinner_item_dropdown.xml
new file mode 100644
index 0000000..d1b38d0
--- /dev/null
+++ b/android/src/main/res/layout/video_library_spinner_item_dropdown.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2014 Google Inc. All rights reserved.
+
+  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="wrap_content">
+
+    <TextView
+        android:id="@android:id/text1"
+        android:layout_height="@dimen/explore_dropdown_item_height"
+        android:layout_width="match_parent"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
+        android:drawablePadding="8dp"
+        android:gravity="center_vertical|start"
+        android:textSize="16sp"
+        android:textColor="@color/list_dropdown_foreground_color" />
+</LinearLayout>
diff --git a/android/src/main/res/menu/browse_sessions.xml b/android/src/main/res/menu/browse_sessions.xml
index 5185805..82b0f70 100644
--- a/android/src/main/res/menu/browse_sessions.xml
+++ b/android/src/main/res/menu/browse_sessions.xml
@@ -13,50 +13,51 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
 
     <item android:id="@+id/menu_search"
         android:icon="@drawable/ic_action_search"
-        android:title="@string/description_search"
         android:orderInCategory="1"
-        android:showAsAction="always" />
+        android:title="@string/description_search"
+        iosched:showAsAction="always" />
 
     <item android:id="@+id/menu_refresh"
-        android:title="@string/description_refresh"
         android:orderInCategory="1"
-        android:showAsAction="never" />
+        android:title="@string/description_refresh"
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_wifi"
-        android:title="@string/description_configure_wifi"
         android:orderInCategory="98"
-        android:showAsAction="never" />
+        android:title="@string/description_configure_wifi"
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_i_o_hunt"
-          android:title="@string/description_i_o_hunt"
           android:orderInCategory="99"
-          android:showAsAction="never" />
+          android:title="@string/description_i_o_hunt"
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_io_extended"
-        android:visible="false"
-        android:title="@string/description_i_o_extended"
         android:orderInCategory="99"
-        android:showAsAction="never" />
+        android:title="@string/description_i_o_extended"
+        android:visible="false"
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_map"
-        android:visible="false"
-        android:title="@string/description_map"
         android:orderInCategory="100"
-        android:showAsAction="never" />
+        android:title="@string/description_map"
+        android:visible="false"
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_debug"
-        android:visible="false"
-        android:title="@string/description_debug"
         android:orderInCategory="101"
-        android:showAsAction="never" />
+        android:title="@string/description_debug"
+        android:visible="false"
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_about"
-        android:title="@string/description_about"
         android:orderInCategory="99"
-        android:showAsAction="never" />
+        android:title="@string/description_about"
+        iosched:showAsAction="never" />
 
 </menu>
diff --git a/android/src/main/res/menu/my_schedule.xml b/android/src/main/res/menu/my_schedule.xml
index 23707a0..0f9463a 100644
--- a/android/src/main/res/menu/my_schedule.xml
+++ b/android/src/main/res/menu/my_schedule.xml
@@ -13,49 +13,50 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
 
     <item android:id="@+id/menu_search"
         android:icon="@drawable/ic_action_search"
         android:title="@string/description_search"
         android:orderInCategory="1"
-        android:showAsAction="always" />
+        iosched:showAsAction="always" />
 
     <item android:id="@+id/menu_refresh"
         android:title="@string/description_refresh"
         android:orderInCategory="1"
-        android:showAsAction="never" />
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_wifi"
         android:title="@string/description_configure_wifi"
         android:orderInCategory="98"
-        android:showAsAction="never" />
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_i_o_hunt"
           android:title="@string/description_i_o_hunt"
           android:orderInCategory="99"
-          android:showAsAction="never" />
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_io_extended"
         android:visible="false"
         android:title="@string/description_i_o_extended"
         android:orderInCategory="99"
-        android:showAsAction="never" />
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_map"
         android:visible="false"
         android:title="@string/description_map"
         android:orderInCategory="100"
-        android:showAsAction="never" />
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_debug"
         android:visible="false"
         android:title="@string/description_debug"
         android:orderInCategory="101"
-        android:showAsAction="never" />
+        iosched:showAsAction="never" />
 
     <item android:id="@+id/menu_about"
         android:title="@string/description_about"
         android:orderInCategory="99"
-        android:showAsAction="never" />
+        iosched:showAsAction="never" />
 </menu>
diff --git a/android/src/main/res/menu/nearby.xml b/android/src/main/res/menu/nearby.xml
index 256d9d7..247e692 100644
--- a/android/src/main/res/menu/nearby.xml
+++ b/android/src/main/res/menu/nearby.xml
@@ -1,5 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-
 <!--
   Copyright 2014 Google Inc. All rights reserved.
 
@@ -16,10 +14,11 @@
   limitations under the License.
   -->
 
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/menu_nearby"
         android:title="@string/map_nearby_button"
         android:orderInCategory="1"
-        android:showAsAction="ifRoom"
-        android:actionLayout="@layout/nearby_button" />
+        iosched:showAsAction="ifRoom"
+        iosched:actionLayout="@layout/nearby_button" />
 </menu>
diff --git a/android/src/main/res/menu/search.xml b/android/src/main/res/menu/search.xml
index e473f9a..6b41dbe 100644
--- a/android/src/main/res/menu/search.xml
+++ b/android/src/main/res/menu/search.xml
@@ -13,11 +13,12 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/menu_search"
         android:icon="@drawable/ic_action_search"
         android:title="@string/description_search"
         android:orderInCategory="0"
-        android:actionViewClass="android.widget.SearchView"
-        android:showAsAction="always" />
+        iosched:actionViewClass="android.support.v7.widget.SearchView"
+        iosched:showAsAction="always" />
 </menu>
diff --git a/android/src/main/res/menu/session_detail.xml b/android/src/main/res/menu/session_detail.xml
index 224f894..8cef605 100644
--- a/android/src/main/res/menu/session_detail.xml
+++ b/android/src/main/res/menu/session_detail.xml
@@ -13,21 +13,22 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/menu_map_room"
         android:icon="@drawable/ic_action_map"
         android:title="@string/description_map"
         android:orderInCategory="1"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
     <item android:id="@+id/menu_share"
         android:icon="@drawable/ic_action_share"
         android:title="@string/description_share"
         android:orderInCategory="1"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
     <item android:id="@+id/menu_social_stream"
         android:icon="@drawable/ic_action_social_stream"
         android:title="@string/description_social_stream"
         android:orderInCategory="1"
         android:visible="false"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
 </menu>
diff --git a/android/src/main/res/menu/session_livestream.xml b/android/src/main/res/menu/session_livestream.xml
index 4ea44ed..9bf002e 100644
--- a/android/src/main/res/menu/session_livestream.xml
+++ b/android/src/main/res/menu/session_livestream.xml
@@ -13,26 +13,27 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
 
     <item android:id="@+id/menu_presentation"
           android:icon="@drawable/ic_media_route_off_holo_light"
           android:title="@string/description_presentation"
           android:orderInCategory="1"
           android:visible="false"
-          android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
 
     <item android:id="@+id/menu_captions"
           android:icon="@drawable/ic_action_captions"
           android:title="@string/description_captions"
           android:orderInCategory="1"
           android:visible="false"
-          android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
 
     <item android:id="@+id/menu_share"
         android:icon="@drawable/ic_action_share"
         android:title="@string/description_share"
         android:orderInCategory="1"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
 
 </menu>
diff --git a/android/src/main/res/menu/sessions_context.xml b/android/src/main/res/menu/sessions_context.xml
index 53ea059..88da537 100644
--- a/android/src/main/res/menu/sessions_context.xml
+++ b/android/src/main/res/menu/sessions_context.xml
@@ -13,25 +13,26 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:iosched="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/menu_star"
         android:icon="@drawable/ic_action_add_schedule"
         android:title="@string/description_add_schedule"
         android:orderInCategory="1"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
     <item android:id="@+id/menu_map_room"
         android:icon="@drawable/ic_action_map"
         android:title="@string/description_map"
         android:orderInCategory="2"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
     <item android:id="@+id/menu_share"
         android:icon="@drawable/ic_action_share"
         android:title="@string/description_share"
         android:orderInCategory="3"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
     <item android:id="@+id/menu_social_stream"
         android:icon="@drawable/ic_action_social_stream"
         android:title="@string/description_social_stream"
         android:orderInCategory="3"
-        android:showAsAction="ifRoom" />
+        iosched:showAsAction="ifRoom" />
 </menu>
diff --git a/android/src/main/res/mipmap-hdpi/ic_launcher.png b/android/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..494089c
--- /dev/null
+++ b/android/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-mdpi/ic_launcher.png b/android/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..09a8ae6
--- /dev/null
+++ b/android/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..8f2bd09
--- /dev/null
+++ b/android/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ec08ac7
--- /dev/null
+++ b/android/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6d13883
--- /dev/null
+++ b/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/lpreview/res/transition-v21/shared_element.xml b/android/src/main/res/transition-v21/shared_element.xml
similarity index 100%
rename from android/src/lpreview/res/transition-v21/shared_element.xml
rename to android/src/main/res/transition-v21/shared_element.xml
diff --git a/android/src/lpreview/res/transition-v21/window_enter_exit.xml b/android/src/main/res/transition-v21/window_enter_exit.xml
similarity index 100%
rename from android/src/lpreview/res/transition-v21/window_enter_exit.xml
rename to android/src/main/res/transition-v21/window_enter_exit.xml
diff --git a/android/src/main/res/values-sw360dp/dimens.xml b/android/src/main/res/values-sw360dp/dimens.xml
index 9cb8340..880cdef 100644
--- a/android/src/main/res/values-sw360dp/dimens.xml
+++ b/android/src/main/res/values-sw360dp/dimens.xml
@@ -18,4 +18,8 @@
     <!-- Live Stream -->
     <dimen name="livestream_spinner_width">240dp</dimen>
 
+    <dimen name="navdrawer_chosen_account_height">164dp</dimen>
+    <dimen name="navdrawer_width">304dp</dimen>
+    <dimen name="navdrawer_profile_image_size">64dp</dimen>
+
 </resources>
diff --git a/android/src/lpreview/res/values-v21/fonts.xml b/android/src/main/res/values-sw600dp-v21/styles.xml
similarity index 67%
copy from android/src/lpreview/res/values-v21/fonts.xml
copy to android/src/main/res/values-sw600dp-v21/styles.xml
index 2680a08..934a527 100644
--- a/android/src/lpreview/res/values-v21/fonts.xml
+++ b/android/src/main/res/values-sw600dp-v21/styles.xml
@@ -15,9 +15,12 @@
   -->
 
 <resources>
-    <integer name="font_textStyle_medium">0</integer> <!-- normal -->
-    <string name="font_fontFamily_medium">sans-serif-medium</string>
 
-    <integer name="font_textStyle_drawer_item">0</integer> <!-- normal -->
-    <string name="font_fontFamily_drawer_item">sans-serif-medium</string>
+    <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
+        <item name="android:windowBackground">@android:color/white</item>
+        <item name="android:windowFullscreen">true</item>
+
+        <item name="android:windowElevation">16dp</item>
+    </style>
+
 </resources>
diff --git a/android/src/main/res/values-sw600dp/dimens.xml b/android/src/main/res/values-sw600dp/dimens.xml
index f2b9883..25434d0 100644
--- a/android/src/main/res/values-sw600dp/dimens.xml
+++ b/android/src/main/res/values-sw600dp/dimens.xml
@@ -21,8 +21,6 @@
     <dimen name="add_to_schedule_button_height">72dp</dimen> <!-- including padding -->
     <dimen name="add_to_schedule_button_height_no_padding">56dp</dimen>
 
-    <dimen name="navdrawer_chosen_account_height">140dp</dimen>
-
     <dimen name="filter_spinner_width">200dp</dimen>
     <integer name="filter_spinner_weight">0</integer>
 
diff --git a/android/src/main/res/values-sw600dp/styles.xml b/android/src/main/res/values-sw600dp/styles.xml
index 4966da1..d5a4d6d 100644
--- a/android/src/main/res/values-sw600dp/styles.xml
+++ b/android/src/main/res/values-sw600dp/styles.xml
@@ -28,4 +28,6 @@
         <item name="android:colorBackgroundCacheHint">@null</item>
     </style>
 
+    <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base" />
+
 </resources>
diff --git a/android/src/main/res/values-v17/styles.xml b/android/src/main/res/values-v17/styles.xml
index fe3e0e3..d6e7971 100644
--- a/android/src/main/res/values-v17/styles.xml
+++ b/android/src/main/res/values-v17/styles.xml
@@ -18,7 +18,7 @@
 
     <!-- Enable RTL support on newer devices -->
     <!-- Prevents crash on certain devices to namespace conflict -->
-    <style name="FrameworkRoot.Theme" parent="android:Theme.Holo.Light.DarkActionBar">
+    <style name="FrameworkRoot.Theme" parent="Theme.AppCompat.Light">
         <item name="android:paddingStart">?android:attr/paddingLeft</item>
         <item name="android:paddingEnd">?android:attr/paddingRight</item>
         <item name="android:layout_marginStart">?android:attr/layout_marginLeft</item>
diff --git a/android/src/lpreview/res/values-v21/fonts.xml b/android/src/main/res/values-v21/fonts.xml
similarity index 83%
rename from android/src/lpreview/res/values-v21/fonts.xml
rename to android/src/main/res/values-v21/fonts.xml
index 2680a08..9b6c194 100644
--- a/android/src/lpreview/res/values-v21/fonts.xml
+++ b/android/src/main/res/values-v21/fonts.xml
@@ -17,7 +17,4 @@
 <resources>
     <integer name="font_textStyle_medium">0</integer> <!-- normal -->
     <string name="font_fontFamily_medium">sans-serif-medium</string>
-
-    <integer name="font_textStyle_drawer_item">0</integer> <!-- normal -->
-    <string name="font_fontFamily_drawer_item">sans-serif-medium</string>
 </resources>
diff --git a/android/src/lpreview/res/values-v21/refs.xml b/android/src/main/res/values-v21/refs.xml
similarity index 100%
rename from android/src/lpreview/res/values-v21/refs.xml
rename to android/src/main/res/values-v21/refs.xml
diff --git a/android/src/main/res/values-v21/styles.xml b/android/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..361f4dd
--- /dev/null
+++ b/android/src/main/res/values-v21/styles.xml
@@ -0,0 +1,49 @@
+<!--
+  Copyright 2014 Google Inc. All rights reserved.
+
+  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="Theme" parent="FrameworkRoot.Theme" /> <!-- doesn't contain the pre-L code from the values/styles.xml -->
+
+    <style name="Theme.IOSched" parent="Theme.IOSched.Base">
+        <item name="popupItemBackground">@drawable/popup_item_background</item>
+        <item name="photoItemForeground">@drawable/photo_item_foreground</item>
+        <item name="photoItemForegroundBorderless">@drawable/photo_item_foreground_borderless</item>
+
+        <item name="android:navigationBarColor">#000</item>
+        <item name="android:statusBarColor">?colorPrimaryDark</item>
+
+        <item name="android:alertDialogTheme">@style/Theme.IOSched.AlertDialog</item>
+    </style>
+
+    <style name="Theme.IOSched.WithNavDrawer" parent="Theme.IOSched">
+        <item name="android:statusBarColor">@android:color/transparent</item>
+    </style>
+
+    <style name="Theme.IOSched.AlertDialog" parent="android:Theme.Material.Light.Dialog.Alert">
+        <item name="android:colorPrimary">@color/theme_primary</item>
+        <item name="android:colorPrimaryDark">@color/theme_primary_dark</item>
+        <item name="android:colorAccent">@color/theme_accent_2</item>
+    </style>
+
+    <style name="Widget.IOSched.HeaderBar.Spinner" parent="Widget.IOSched.HeaderBar.Spinner.Base">
+        <item name="android:theme">@style/ActionBarThemeOverlay</item>
+    </style>
+
+    <style name="TabIndicator">
+        <item name="android:theme">@style/ActionBarThemeOverlay</item>
+    </style>
+</resources>
diff --git a/android/src/main/res/values/attrs.xml b/android/src/main/res/values/attrs.xml
index 73eb02c..dde6599 100644
--- a/android/src/main/res/values/attrs.xml
+++ b/android/src/main/res/values/attrs.xml
@@ -16,12 +16,12 @@
 <resources>
 
     <declare-styleable name="BaseTheme">
-        <attr name="actionBarOverlayTopOffset" format="dimension" />
+        <attr name="actionBarIconColor" format="color" />
         <attr name="actionBarInsetStart" format="dimension" />
         <attr name="spinnerBarInsetStart" format="dimension" />
-        <attr name="selectableItemBackgroundBorderless" format="dimension" />
-        <attr name="popupItemBackground" format="dimension" />
-        <attr name="photoItemForeground" format="dimension" />
+        <attr name="popupItemBackground" format="reference" />
+        <attr name="photoItemForeground" format="reference" />
+        <attr name="photoItemForegroundBorderless" format="reference" />
     </declare-styleable>
 
     <declare-styleable name="MultiSwipeRefreshLayout">
@@ -33,6 +33,10 @@
         <attr name="shadowVisible" format="boolean" />
     </declare-styleable>
 
+    <declare-styleable name="ScrimInsetsView">
+        <attr name="insetForeground" format="reference|color" />
+    </declare-styleable>
+
     <declare-styleable name="BezelImageView">
         <attr name="maskDrawable" format="reference" />
         <attr name="borderDrawable" format="reference" />
diff --git a/android/src/main/res/values/colors.xml b/android/src/main/res/values/colors.xml
index fd57b75..cc9a095 100644
--- a/android/src/main/res/values/colors.xml
+++ b/android/src/main/res/values/colors.xml
@@ -50,7 +50,7 @@
     <color name="navdrawer_background">#ffffffff</color>
     <color name="navdrawer_text_color">@color/body_text_1</color>
     <color name="navdrawer_text_color_selected">@color/theme_primary</color>
-    <color name="navdrawer_icon_tint">#808080</color>
+    <color name="navdrawer_icon_tint">#888</color>
     <color name="navdrawer_icon_tint_selected">@color/theme_primary</color>
 
     <color name="refresh_progress_1">@color/theme_accent_2</color>
@@ -66,6 +66,8 @@
     <color name="session_photo_scrim">#6000</color>
 
     <color name="default_session_color">@color/theme_primary</color>
+    <color name="no_track_branding_session_tile_overlay">#8333</color>
+    <color name="no_track_branding_session_color">#333</color>
 
     <color name="nearby_header_color">#00c</color>
     <color name="nearby_url_color">#0a0</color>
@@ -76,6 +78,7 @@
     <color name="butter_bar_light">#eee0e0e0</color>
 
     <color name="translucent_actionbar_background">#cc3f51b5</color>
+    <color name="translucent_statusbar_background">#cc3f51b5</color>
 
     <color name="tab_background">@color/theme_primary</color>
     <color name="tab_selected_strip">@color/theme_accent_1</color>
diff --git a/android/src/main/res/values/dimens.xml b/android/src/main/res/values/dimens.xml
index 6933048..91dd3c1 100644
--- a/android/src/main/res/values/dimens.xml
+++ b/android/src/main/res/values/dimens.xml
@@ -51,7 +51,7 @@
     <dimen name="list_item_action_height">90dp</dimen>
     <dimen name="list_item_action_margin">2dp</dimen>
     <dimen name="action_button_padding">10dp</dimen>
-    <dimen name="spinner_left_padding">4dp</dimen>
+    <dimen name="spinner_left_padding">16dp</dimen>
 
     <!-- body content -->
     <dimen name="element_spacing_normal">8dp</dimen>
@@ -71,7 +71,7 @@
     <dimen name="map_content_padding">8dp</dimen>
     <dimen name="map_infowindow_width">260dp</dimen>
 
-    <dimen name="navdrawer_chosen_account_height">120dp</dimen>
+    <dimen name="navdrawer_chosen_account_height">140dp</dimen>
     <dimen name="navdrawer_width">260dp</dimen>
     <dimen name="navdrawer_profile_image_size">40dp</dimen>
 
@@ -89,7 +89,8 @@
     <dimen name="explore_dropdown_item_height">48dp</dimen>
     <dimen name="explore_spinner_width">200dp</dimen>
     <dimen name="explore_grid_padding">4dp</dimen>
-    <dimen name="half_explore_grid_padding">2dp</dimen>
+    <dimen name="explore_grid_padding_half">2dp</dimen>
+
     <dimen name="explore_hero_item_height">240dp</dimen>
 
     <dimen name="filter_spinner_width">0dp</dimen>
@@ -113,17 +114,19 @@
     <dimen name="keyline_2_session_detail">@dimen/keyline_2</dimen>
 
     <dimen name="session_detail_speaker_left_offset">@dimen/keyline_1</dimen>
-    <dimen name="fab_elevation">2dp</dimen>
-    <dimen name="fab_press_translation_z">2dp</dimen>
 
-    <dimen name="session_detail_max_header_elevation">2dp</dimen>
-    <dimen name="headerbar_elevation">2dp</dimen>
+    <dimen name="fab_elevation">8dp</dimen>
+    <dimen name="fab_press_translation_z">6dp</dimen>
+    <dimen name="headerbar_elevation">4dp</dimen>
+    <dimen name="session_detail_max_header_elevation">@dimen/headerbar_elevation</dimen>
+    <dimen name="card_elevation">2dp</dimen>
+
+    <dimen name="card_corner_radius">2dp</dimen>
 
     <!-- Social -->
     <dimen name="hashtag_line_height">1dp</dimen>
     <dimen name="hashtag_height">120dp</dimen>
     <dimen name="hashtag_desc_size">40dp</dimen>
-    <dimen name="social_grid_padding">4dp</dimen>
     <dimen name="social_hz_margin">0dp</dimen>
     <dimen name="hashtag_text_size">14sp</dimen>
     <dimen name="hashtag_hero_text_size">45sp</dimen>
diff --git a/android/src/main/res/values/fonts.xml b/android/src/main/res/values/fonts.xml
index dd12fd4..9e33312 100644
--- a/android/src/main/res/values/fonts.xml
+++ b/android/src/main/res/values/fonts.xml
@@ -17,7 +17,4 @@
 <resources>
     <integer name="font_textStyle_medium">1</integer> <!-- bold -->
     <string name="font_fontFamily_medium">sans-serif</string>
-
-    <integer name="font_textStyle_drawer_item">0</integer> <!-- normal -->
-    <string name="font_fontFamily_drawer_item">sans-serif</string>
 </resources>
diff --git a/android/src/main/res/values/refs.xml b/android/src/main/res/values/refs.xml
index 5269692..a627782 100644
--- a/android/src/main/res/values/refs.xml
+++ b/android/src/main/res/values/refs.xml
@@ -15,8 +15,6 @@
   -->
 
 <resources>
-    <item name="toolbar_actionbar_with_headerbar" type="layout">@layout/toolbar_actionbar</item>
-    <item name="toolbar_actionbar_with_translucent_background" type="layout">@layout/toolbar_actionbar</item>
     <item name="schedule_item_touchoverlay_dark" type="drawable">@drawable/schedule_item_touchoverlay</item>
     <item name="header_shadow" type="drawable">@drawable/bottom_shadow</item>
 </resources>
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index 4a8438d..6f11514 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -32,6 +32,12 @@
         <item quantity="other">%d sessions are about to start.</item>
     </plurals>
 
+    <!-- Indicates a certain number of sessions. -->
+    <plurals name="session_plurals">
+        <item quantity="one">1 session</item>
+        <item quantity="other">%1$d sessions</item>
+    </plurals>
+
     <!-- Title for the notification that alerts the user that some of their sessions are about to begin. -->
     <plurals name="session_notification_title">
         <item quantity="one">1 session is starting in <xliff:g id="remaining_time">%1$d</xliff:g> min.</item>
diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml
index ffd2b15..e33f9ba 100644
--- a/android/src/main/res/values/styles.xml
+++ b/android/src/main/res/values/styles.xml
@@ -18,49 +18,50 @@
     <!-- Root styles that vary by API level -->
     <!-- Disable RTL support on older devices -->
     <!-- Prevents crash on certain devices to namespace conflict -->
-    <style name="FrameworkRoot.Theme" parent="android:Theme.Holo.Light.DarkActionBar" />
-    <style name="FrameworkRoot.ActionBar" parent="android:Widget.Holo.ActionBar" />
-    <style name="FrameworkRoot.ActionBar.TitleText" parent="android:TextAppearance.Holo.Widget.ActionBar.Title" />
-    <style name="FrameworkRoot.ActionBar.TabBar" parent="android:Widget.Holo.ActionBar.TabBar" />
-    <style name="FrameworkRoot.EditText" parent="android:Widget.Holo.Light.EditText" />
-    <style name="FrameworkRoot.Widget" parent="android:Theme.Holo" />
-    <style name="FrameworkRoot.Widget.ActionButton.Overflow" parent="android:Widget.Holo.ActionButton.Overflow" />
-    <style name="FrameworkRoot.Widget.Spinner" parent="android:Widget.Holo.Light.Spinner" />
-    <style name="FrameworkRoot.Widget.ListView.DropDown" parent="android:Widget.Holo.Light.ListView.DropDown" />
-    <style name="FrameworkRoot.Widget.PopupMenu" parent="android:Widget.Holo.Light.PopupMenu" />
-    <style name="FrameworkRoot.TextAppearance.Widget.PopupMenu.Large" parent="android:TextAppearance.Holo.Widget.PopupMenu.Large" />
+    <style name="FrameworkRoot.Theme" parent="Theme.AppCompat.Light" />
+    <style name="FrameworkRoot.Widget" parent="Theme.AppCompat" />
 
     <!-- Immediate parent theme to specify base values for custom attributes -->
     <style name="Theme" parent="FrameworkRoot.Theme">
         <!-- Only needed for pre-L -->
-        <item name="android:actionOverflowButtonStyle">@style/ActionButton.Overflow</item>
         <item name="android:editTextBackground">@drawable/edit_text</item>
         <item name="android:editTextStyle">@style/Widget.IOSched.EditText</item>
-        <item name="android:actionBarWidgetTheme">@style/Theme.IOSched.Widget</item>
-        <item name="android:actionDropDownStyle">@style/Widget.IOSched.HeaderBar.Spinner</item>
     </style>
 
     <style name="Theme.IOSched.Base" parent="Theme">
-        <item name="actionBarOverlayTopOffset">?android:actionBarSize</item>
-        <item name="actionBarInsetStart">?android:actionBarSize</item>
-        <item name="spinnerBarInsetStart">?android:actionBarSize</item>
-        <item name="selectableItemBackgroundBorderless">?android:selectableItemBackground</item>
+        <item name="actionBarIconColor">#fff</item>
+        <item name="actionBarInsetStart">@dimen/keyline_2</item>
+        <item name="homeAsUpIndicator">@drawable/ic_up</item>
+        <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
         <item name="popupItemBackground">?android:selectableItemBackground</item>
         <item name="photoItemForeground">?android:selectableItemBackground</item>
+        <item name="photoItemForegroundBorderless">?android:selectableItemBackground</item>
+
+        <item name="colorPrimary">@color/theme_primary</item>
+        <item name="colorPrimaryDark">@color/theme_primary_dark</item>
+        <item name="colorAccent">@color/theme_accent_2</item>
+
+        <item name="android:textColorLink">@color/theme_accent_2</item>
+
+        <item name="windowActionBar">false</item>
+        <item name="android:windowNoTitle">true</item>
 
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowBackground">@android:color/white</item>
-        <item name="android:actionBarStyle">@style/ActionBar</item>
         <item name="android:homeAsUpIndicator">@drawable/ic_up</item>
 
         <item name="android:popupMenuStyle">@style/Widget.IOSched.PopupMenu</item>
         <item name="android:listPopupWindowStyle">@style/Widget.IOSched.PopupMenu</item>
         <item name="android:dropDownListViewStyle">@style/Widget.IOSched.ListView.DropDown</item>
         <item name="android:textAppearanceLargePopupMenu">@style/TextAppearance.LargePopupMenu</item>
+
+        <item name="searchViewStyle">@style/Widget.IOSched.SearchView</item>
     </style>
 
     <style name="Theme.IOSched" parent="Theme.IOSched.Base" />
 
+    <style name="Theme.IOSched.WithNavDrawer" parent="Theme.IOSched" />
+
     <style name="Theme.IOSched.Widget" parent="FrameworkRoot.Widget">
         <item name="android:popupMenuStyle">@style/Widget.IOSched.PopupMenu</item>
         <item name="android:listPopupWindowStyle">@style/Widget.IOSched.PopupMenu</item>
@@ -68,55 +69,67 @@
         <item name="android:textAppearanceLargePopupMenu">@style/TextAppearance.LargePopupMenu</item>
     </style>
 
-    <style name="ActionButton.Overflow" parent="FrameworkRoot.Widget.ActionButton.Overflow">
-        <item name="android:src">@drawable/ic_action_overflow</item>
+    <style name="ActionBarThemeOverlay" parent="">
+        <item name="android:textColorPrimary">#fff</item>
+        <item name="colorControlNormal">?actionBarIconColor</item>
+        <item name="colorControlHighlight">#3fff</item>
     </style>
 
-    <style name="Theme.IOSched.Welcome" parent="Theme.IOSched">
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowNoTitle">true</item>
+    <style name="ActionBarPopupThemeOverlay" parent="ThemeOverlay.AppCompat.Light" />
+
+    <style name="ActionBar.TitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
+        <item name="android:textColor">#fff</item>
+        <item name="android:textSize">18sp</item>
     </style>
 
-    <style name="Theme.IOSched.Sessions.Base" parent="Theme.IOSched">
-        <item name="android:windowActionBarOverlay">true</item>
+    <style name="Theme.IOSched.Welcome" parent="Theme.IOSched" />
+
+    <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.WithNavDrawer">
+        <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
+        <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
         <item name="android:windowBackground">@color/gray_background</item>
     </style>
 
     <style name="Theme.IOSched.Search" parent="Theme.IOSched">
         <item name="android:windowBackground">@color/gray_background</item>
+        <item name="android:autoCompleteTextViewStyle">@style/Widget.IOSched.Search.AutoCompleteTextView</item>
+        <item name="colorControlActivated">@color/theme_accent_1</item>
     </style>
 
-    <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.Sessions.Base" />
-
-    <style name="Theme.IOSched.VideoLibrary" parent="Theme.IOSched">
-        <item name="android:windowActionBarOverlay">true</item>
+    <style name="Widget.IOSched.Search.AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
+        <item name="android:textColorHint">#5fff</item>
     </style>
 
-    <style name="Widget.IOSched.HeaderBar.Spinner.Base" parent="FrameworkRoot.Widget.Spinner">
+    <style name="Theme.IOSched.VideoLibrary" parent="Theme.IOSched.WithNavDrawer" />
+
+    <style name="Widget.IOSched.HeaderBar.Spinner.Base" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
         <item name="android:background">?android:selectableItemBackground</item>
         <item name="android:dropDownSelector">?android:selectableItemBackground</item>
         <item name="android:divider">@null</item>
         <item name="android:dividerHeight">0dp</item>
+        <item name="android:overlapAnchor">true</item>
     </style>
 
     <style name="Widget.IOSched.HeaderBar.Spinner" parent="Widget.IOSched.HeaderBar.Spinner.Base" />
 
-    <style name="Widget.IOSched.PopupMenu" parent="FrameworkRoot.Widget.PopupMenu">
+    <style name="Widget.IOSched.PopupMenu" parent="Widget.AppCompat.Light.PopupMenu">
         <item name="android:dropDownSelector">?popupItemBackground</item>
     </style>
 
-    <style name="Widget.IOSched.ListView.DropDown" parent="FrameworkRoot.Widget.ListView.DropDown">
+    <style name="Widget.IOSched.ListView.DropDown" parent="Widget.AppCompat.Light.ListView.DropDown">
         <item name="android:listSelector">?popupItemBackground</item>
         <item name="android:divider">@null</item>
         <item name="android:dividerHeight">0dp</item>
     </style>
 
-    <style name="TextAppearance.LargePopupMenu" parent="FrameworkRoot.TextAppearance.Widget.PopupMenu.Large">
+    <style name="TextAppearance.LargePopupMenu" parent="TextAppearance.AppCompat.Widget.PopupMenu.Large">
         <item name="android:textColor">@color/body_text_1</item>
     </style>
 
+    <style name="Widget.IOSched.SearchView" parent="Widget.AppCompat.SearchView" />
+
     <!-- My Schedule -->
-    <style name="Theme.IOSched.MySchedule" parent="Theme.IOSched" />
+    <style name="Theme.IOSched.MySchedule" parent="Theme.IOSched.WithNavDrawer" />
 
     <!-- Intermediary theme for SessionDetails (so we can override it on large screens) -->
     <style name="Theme.IOSched.SessionDetails.Base" parent="Theme.IOSched">
@@ -124,15 +137,11 @@
     </style>
 
     <!-- Session Details -->
-    <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
-        <item name="android:actionBarStyle">@style/TransparentActionBar</item>
-        <item name="android:windowActionBarOverlay">true</item>
-    </style>
+    <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base" />
 
     <!-- Social -->
-    <style name="Theme.IOSched.Social" parent="Theme.IOSched">
+    <style name="Theme.IOSched.Social" parent="Theme.IOSched.WithNavDrawer">
         <item name="android:windowBackground">@color/gray_background</item>
-        <item name="android:windowContentOverlay">@drawable/header_shadow</item>
     </style>
 
     <!-- Account chooser -->
@@ -140,55 +149,32 @@
         <item name="android:actionBarStyle">@style/ActionBar.Accounts</item>
     </style>
 
-    <style name="ActionBar.Accounts" parent="ActionBar">
+    <style name="ActionBar.Accounts" parent="">
         <item name="android:displayOptions">showHome|useLogo</item>
     </style>
 
     <!-- People I've Met -->
-    <style name="Theme.IOSched.PeopleIveMet" parent="Theme.IOSched">
-        <item name="android:windowContentOverlay">@drawable/header_shadow</item>
-    </style>
+    <style name="Theme.IOSched.PeopleIveMet" parent="Theme.IOSched.WithNavDrawer" />
 
     <!-- Experts -->
-    <style name="Theme.IOSched.ExpertsDirectory" parent="Theme.IOSched">
-        <item name="android:windowActionBarOverlay">true</item>
-    </style>
+    <style name="Theme.IOSched.ExpertsDirectory" parent="Theme.IOSched.WithNavDrawer" />
 
-    <!-- Action bar -->
-    <style name="ActionBar.Base" parent="FrameworkRoot.ActionBar">
-        <item name="android:background">@drawable/actionbar_background</item>
-        <item name="android:icon">@drawable/actionbar_icon</item>
-        <item name="android:displayOptions">showHome|showTitle</item>
-        <item name="android:titleTextStyle">@style/ActionBar.TitleText</item>
-        <item name="android:logo">@drawable/actionbar_logo</item>
-    </style>
-
-    <style name="ActionBar" parent="ActionBar.Base" />
-
-    <style name="ActionBar.TitleText" parent="FrameworkRoot.ActionBar.TitleText">
-        <item name="android:textColor">#fff</item>
-        <item name="android:textSize">18sp</item>
-    </style>
-
+    <!-- Misc -->
     <style name="TabIndicator" />
 
     <!-- Transparent Action Bar -->
-    <style name="TransparentActionBar" parent="ActionBar">
+    <style name="TransparentActionBar" parent="">
         <item name="android:background">@null</item>
     </style>
 
-    <style name="TranslucentActionBar" parent="ActionBar">
+    <style name="TranslucentActionBar" parent="">
         <item name="android:background">@color/translucent_actionbar_background</item>
     </style>
 
     <!-- Live stream -->
     <style name="Theme.IOSched.Livestream" parent="Theme.IOSched">
         <item name="android:windowBackground">@color/gray_background</item>
-    </style>
-
-    <!-- Etc. -->
-    <style name="Theme.IOSched.WithElevatedHeader" parent="Theme.IOSched">
-        <item name="android:windowContentOverlay">@drawable/header_shadow</item>
+        <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
     </style>
 
     <!-- Empty views -->
@@ -278,10 +264,7 @@
     </style>
 
     <!-- Map -->
-    <style name="Theme.IOSched.Map" parent="Theme.IOSched">
-        <item name="android:actionBarStyle">@style/TranslucentActionBar</item>
-        <item name="android:windowActionBarOverlay">true</item>
-    </style>
+    <style name="Theme.IOSched.Map" parent="Theme.IOSched.WithNavDrawer" />
 
     <style name="MapInfoText" parent="@style/TextHeaderSub">
         <item name="android:textColor">@color/map_info_1</item>
@@ -312,7 +295,7 @@
         <item name="android:shadowRadius">3</item>
     </style>
 
-    <style name="Widget.IOSched.EditText" parent="FrameworkRoot.EditText">
+    <style name="Widget.IOSched.EditText" parent="Widget.AppCompat.EditText">
         <item name="android:background">@drawable/edit_text</item>
     </style>
 
@@ -329,7 +312,10 @@
         <item name="android:textColor">@color/theme_primary</item>
     </style>
 
-    <style name="HeaderBar" />
+    <style name="HeaderBar">
+        <item name="android:background">?colorPrimary</item>
+        <item name="android:elevation">@dimen/headerbar_elevation</item>
+    </style>
 
     <!-- Session feedback -->
 
diff --git a/art/actionbar_action_icons.ai b/art/actionbar_action_icons.ai
index b1eac2c..316a7d4 100644
--- a/art/actionbar_action_icons.ai
+++ b/art/actionbar_action_icons.ai
Binary files differ
diff --git a/art/drawer_icons.ai b/art/drawer_icons.ai
index f0eee67..d68265e 100644
--- a/art/drawer_icons.ai
+++ b/art/drawer_icons.ai
Binary files differ
diff --git a/art/ic_launcher_material-xxxhdpi.psd b/art/ic_launcher_material-xxxhdpi.psd
new file mode 100644
index 0000000..ef8413c
--- /dev/null
+++ b/art/ic_launcher_material-xxxhdpi.psd
Binary files differ
diff --git a/art/ic_launcher_material.ai b/art/ic_launcher_material.ai
index 74bef3d..636f523 100644
--- a/art/ic_launcher_material.ai
+++ b/art/ic_launcher_material.ai
Binary files differ
diff --git a/binaries/iosched-lpreview.apk b/binaries/iosched-lpreview.apk
deleted file mode 100644
index 5c2afe9..0000000
--- a/binaries/iosched-lpreview.apk
+++ /dev/null
Binary files differ
diff --git a/doc/BUILDING.md b/doc/BUILDING.md
index 38bb756..3bbac7b 100644
--- a/doc/BUILDING.md
+++ b/doc/BUILDING.md
@@ -105,8 +105,7 @@
 
     ./gradlew -Plpreview installLpreviewDebug
 
-You will need a device flashed with the Android L preview system image, or
-you can use the emulator.
+You will need a device flashed with the Android L preview system image.
 
 # Server-side setup
 
diff --git a/doc/IMAGES.md b/doc/IMAGES.md
index 76feba6..2fc995c 100644
--- a/doc/IMAGES.md
+++ b/doc/IMAGES.md
@@ -77,7 +77,7 @@
 
 URL | Image size
 --- | ----------
-myserver.com/images/**__w-200-400-600-800-1000__**/session1.jpg | original
+myserver.com/images/**\_\_w-200-400-600-800-1000\_\_**/session1.jpg | original
 myserver.com/images/w200/session1.jpg | 200px wide
 myserver.com/images/w400/session1.jpg | 400px wide
 myserver.com/images/w600/session1.jpg | 600px wide
diff --git a/gcm-server/build.gradle b/gcm-server/build.gradle
index 3079d11..dc529e3 100644
--- a/gcm-server/build.gradle
+++ b/gcm-server/build.gradle
@@ -52,7 +52,6 @@
     downloadSdk = true
 
     appcfg {
-        email = 'mangini@google.com'
         passIn = true
         oauth2 = true