am 805cb8fa: Merge "Fix the host inttypes.h problem globally."

* commit '805cb8fa40f71b3e1f6566bf10ca169d4a2ff86f':
  Fix the host inttypes.h problem globally.
diff --git a/CleanSpec.mk b/CleanSpec.mk
index c912497..9582513 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -200,6 +200,12 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/SprintDM.apk)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/omadm)
 
+# GCC 4.8
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/lib/*.o)
+
 # KLP I mean KitKat now API 19.
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
@@ -208,6 +214,9 @@
 # 4.4.1
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
+# 4.4.2
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 2bcf0cf..8bf7565 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -20,7 +20,7 @@
 # src:dest pair is the first one to match the same dest"
 #$(1): the src:dest pair
 define check-product-copy-files
-$(if $(filter %.apk, $(1)),$(error \
+$(if $(filter %.apk, $(call word-colon, 2, $(1))),$(error \
     Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))
 endef
 # filter out the duplicate <source file>:<dest file> pairs.
@@ -385,6 +385,8 @@
   INSTALLED_KERNEL_TARGET :=
 endif
 
+VERITY_SIGNER_CMD := $(HOST_OUT_EXECUTABLES)/verity_signer
+
 # -----------------------------------------------------------------
 # the ramdisk
 INTERNAL_RAMDISK_FILES := $(filter $(TARGET_ROOT_OUT)/%, \
@@ -617,6 +619,10 @@
 endif
 INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
 
+ifeq (true, $(PRODUCT_SUPPORTS_VERITY))
+INTERNAL_USERIMAGES_DEPS += $(HOST_OUT_EXECUTABLES)/verity_signer
+endif
+
 SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts
 INTERNAL_USERIMAGES_DEPS += $(SELINUX_FC)
 
@@ -825,7 +831,12 @@
 define build-systemimage-target
   @echo "Target system fs image: $(1)"
   @mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt
-  $(call generate-userimage-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt, skip_fsck=true)
+  $(call generate-userimage-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt, \
+      skip_fsck=true \
+      verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY) \
+      verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_PARTITION) \
+      verity_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY) \
+      verity_signer_cmd=$(VERITY_SIGNER_CMD))
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
       $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1)
@@ -902,11 +913,6 @@
 .PHONY: stnod
 stnod: systemtarball-nodeps
 
-# For platform-java goal, add platform as well
-ifneq (,$(filter platform-java, $(MAKECMDGOALS)))
-PLATFORM_ZIP_ADD_JAVA := true
-endif
-
 #######
 ## platform.zip: system, plus other files to be used in PDK fusion build,
 ## in a zip file
@@ -923,7 +929,7 @@
 		$(TARGET_COPY_OUT_SYSTEM) \
 		$(patsubst $(PRODUCT_OUT)/%, %, $(TARGET_OUT_NOTICE_FILES)) \
 		$(addprefix symbols/,$(PDK_SYMBOL_FILES_LIST))
-ifeq (true,$(PLATFORM_ZIP_ADD_JAVA))
+ifneq ($(PDK_PLATFORM_JAVA_ZIP_CONTENTS),)
 	$(hide) cd $(OUT_DIR) && zip -qry $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS)
 endif
 ifneq ($(PDK_PLATFORM_ZIP_PRODUCT_BINARIES),)
@@ -1259,6 +1265,7 @@
 	@# build them.
 	$(hide) mkdir -p $(zip_root)/META
 	$(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
+	$(hide) if test -e $(tool_extensions)/releasetools.py; then $(ACP) $(tool_extensions)/releasetools.py $(zip_root)/META/; fi
 	$(hide)	echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
 	$(hide) echo "recovery_api_version=$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/misc_info.txt
 	$(hide) echo "fstab_version=$(PRIVATE_RECOVERY_FSTAB_VERSION)" >> $(zip_root)/META/misc_info.txt
@@ -1278,6 +1285,7 @@
 endif
 	$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "update_rename_support=1" >> $(zip_root)/META/misc_info.txt
 	$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
 	@# Zip everything up, preserving symlinks
@@ -1438,7 +1446,7 @@
 # the dependency will be set up later in build/core/main.mk.
 $(EMMA_META_ZIP) :
 	@echo "Collecting Emma coverage meta files."
-	$(hide) find $(TARGET_COMMON_OUT_ROOT) -name "coverage.em" | \
+	$(hide) find $(TARGET_COMMON_OUT_ROOT) $(HOST_COMMON_OUT_ROOT) -name "coverage.em" | \
 		zip -@ -q $@
 
 endif # EMMA_INSTRUMENT=true
@@ -1454,7 +1462,8 @@
 	@echo "Packaging Proguard obfuscation dictionary files."
 	$(hide) dict_files=`find $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS -name proguard_dictionary`; \
 		if [ -n "$$dict_files" ]; then \
-		  zip -q $@ $$dict_files; \
+		  unobfuscated_jars=$${dict_files//proguard_dictionary/classes.jar}; \
+		  zip -q $@ $$dict_files $$unobfuscated_jars; \
 		else \
 		  touch $(dir $@)/dummy; \
 		  (cd $(dir $@) && zip -q $(notdir $@) dummy); \
diff --git a/core/build_id.mk b/core/build_id.mk
index aaf4185..221a2f3 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -18,6 +18,6 @@
 # (like "CRB01").  It must be a single word, and is
 # capitalized by convention.
 
-BUILD_ID := OPENMASTER
+BUILD_ID := MASTER
 
 DISPLAY_BUILD_NUMBER := true
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 8863fe6..6e26106 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -141,6 +141,7 @@
 LOCAL_POST_INSTALL_CMD:=
 LOCAL_DIST_BUNDLED_BINARIES:=
 LOCAL_HAL_STATIC_LIBRARIES:=
+LOCAL_RMTYPEDEFS:=
 LOCAL_NO_SYNTAX_CHECK:=
 LOCAL_NO_STATIC_ANALYZER:=
 LOCAL_32BIT_ONLY:= # '',true
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index f6971c5..7e733d8 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -114,7 +114,7 @@
 # into no-op in some builds while mesg is defined earlier. So we explicitly
 # disable "-Wunused-but-set-variable" here.
 ifneq ($(filter 4.6 4.6.% 4.7 4.7.% 4.8, $($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)),)
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -Wno-unused-but-set-variable -fno-builtin-sin \
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -fno-builtin-sin \
 			-fno-strict-volatile-bitfields
 endif
 
diff --git a/core/combo/include/arch/darwin-x86/AndroidConfig.h b/core/combo/include/arch/darwin-x86/AndroidConfig.h
index 012f014..121bba3 100644
--- a/core/combo/include/arch/darwin-x86/AndroidConfig.h
+++ b/core/combo/include/arch/darwin-x86/AndroidConfig.h
@@ -56,13 +56,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-/* #define HAVE_OOM_ADJ */
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/freebsd-x86/AndroidConfig.h b/core/combo/include/arch/freebsd-x86/AndroidConfig.h
index 6f50918..120f484 100644
--- a/core/combo/include/arch/freebsd-x86/AndroidConfig.h
+++ b/core/combo/include/arch/freebsd-x86/AndroidConfig.h
@@ -61,13 +61,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-/* #define HAVE_OOM_ADJ */
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/linux-arm/AndroidConfig.h b/core/combo/include/arch/linux-arm/AndroidConfig.h
index 9257d3e..28d0d30 100644
--- a/core/combo/include/arch/linux-arm/AndroidConfig.h
+++ b/core/combo/include/arch/linux-arm/AndroidConfig.h
@@ -69,13 +69,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-#define HAVE_OOM_ADJ
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/linux-mips/AndroidConfig.h b/core/combo/include/arch/linux-mips/AndroidConfig.h
index e24f3ea..8bfbe9f 100644
--- a/core/combo/include/arch/linux-mips/AndroidConfig.h
+++ b/core/combo/include/arch/linux-mips/AndroidConfig.h
@@ -69,13 +69,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-#define HAVE_OOM_ADJ
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/linux-ppc/AndroidConfig.h b/core/combo/include/arch/linux-ppc/AndroidConfig.h
index a12ef47..24b0da5 100644
--- a/core/combo/include/arch/linux-ppc/AndroidConfig.h
+++ b/core/combo/include/arch/linux-ppc/AndroidConfig.h
@@ -56,13 +56,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-#define HAVE_OOM_ADJ
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/linux-x86/AndroidConfig.h b/core/combo/include/arch/linux-x86/AndroidConfig.h
index 2db66a2..359cfb9 100644
--- a/core/combo/include/arch/linux-x86/AndroidConfig.h
+++ b/core/combo/include/arch/linux-x86/AndroidConfig.h
@@ -56,13 +56,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-#define HAVE_OOM_ADJ
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/target_linux-x86/AndroidConfig.h b/core/combo/include/arch/target_linux-x86/AndroidConfig.h
index 25a1f5d..bbb36fc 100644
--- a/core/combo/include/arch/target_linux-x86/AndroidConfig.h
+++ b/core/combo/include/arch/target_linux-x86/AndroidConfig.h
@@ -55,13 +55,6 @@
 #define HAVE_FORKEXEC
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-#define HAVE_OOM_ADJ
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/combo/include/arch/windows/AndroidConfig.h b/core/combo/include/arch/windows/AndroidConfig.h
index 0a52674..204740d 100644
--- a/core/combo/include/arch/windows/AndroidConfig.h
+++ b/core/combo/include/arch/windows/AndroidConfig.h
@@ -83,13 +83,6 @@
 #endif
 
 /*
- * Process out-of-memory adjustment.  Set if running on Linux,
- * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
- * badness adjustment.
- */
-/* #define HAVE_OOM_ADJ */
-
-/*
  * IPC model.  Choose one:
  *
  * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
diff --git a/core/config.mk b/core/config.mk
index ee47772..1390281 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -331,6 +331,7 @@
 LLVM_RS_CC := $(HOST_OUT_EXECUTABLES)/llvm-rs-cc$(HOST_EXECUTABLE_SUFFIX)
 BCC_COMPAT := $(HOST_OUT_EXECUTABLES)/bcc_compat$(HOST_EXECUTABLE_SUFFIX)
 LINT := prebuilts/sdk/tools/lint
+RMTYPEDEFS := $(HOST_OUT_EXECUTABLES)/rmtypedefs
 
 # ACP is always for the build OS, not for the host OS
 ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX)
diff --git a/core/definitions.mk b/core/definitions.mk
index 7c29e30..852f42c 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1547,7 +1547,7 @@
 $(call unzip-jar-files,$(PRIVATE_STATIC_JAVA_LIBRARIES),$(PRIVATE_CLASS_INTERMEDIATES_DIR))
 $(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list)
 $(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
-	    find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list; \
+          find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list; \
 fi
 $(hide) tr ' ' '\n' < $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list \
     | sort -u > $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq
@@ -1576,8 +1576,13 @@
     $(foreach pkg, $(PRIVATE_JAR_PACKAGES), \
         -not -path $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))) \
     | xargs rm -rf)
-$(hide) jar $(if $(strip $(PRIVATE_JAR_MANIFEST)),-cfm,-cf) \
-    $@ $(PRIVATE_JAR_MANIFEST) -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .
+$(if $(PRIVATE_RMTYPEDEFS), $(hide) $(RMTYPEDEFS) -v $(PRIVATE_CLASS_INTERMEDIATES_DIR))
+$(if $(PRIVATE_JAR_MANIFEST), \
+    $(hide) sed -e 's/%BUILD_NUMBER%/$(BUILD_NUMBER)/' \
+            $(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf && \
+        jar -cfm $@ $(dir $@)/manifest.mf \
+            -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) ., \
+    $(hide) jar -cf $@ -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .)
 endef
 
 define transform-java-to-classes.jar
@@ -1627,8 +1632,13 @@
     $(foreach pkg, $(PRIVATE_JAR_PACKAGES), \
         -not -path $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))) \
     | xargs rm -rf)
-$(hide) jar $(if $(strip $(PRIVATE_JAR_MANIFEST)),-cfm,-cf) \
-    $@ $(PRIVATE_JAR_MANIFEST) -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .
+$(if $(PRIVATE_RMTYPEDEFS), $(hide) $(RMTYPEDEFS) -v $(PRIVATE_CLASS_INTERMEDIATES_DIR))
+$(if $(PRIVATE_JAR_MANIFEST), \
+    $(hide) sed -e 's/%BUILD_NUMBER%/$(BUILD_NUMBER)/' \
+            $(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf && \
+        jar -cfm $@ $(dir $@)/manifest.mf \
+            -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) ., \
+    $(hide) jar -cf $@ -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .)
 $(hide) mv $(PRIVATE_CLASS_INTERMEDIATES_DIR)/newstamp $(PRIVATE_CLASS_INTERMEDIATES_DIR)/stamp
 endef
 
@@ -1650,9 +1660,10 @@
 define transform-classes.jar-to-dex
 @echo "target Dex: $(PRIVATE_MODULE)"
 @mkdir -p $(dir $@)
+$(hide) rm -f $(dir $@)/classes*.dex
 $(hide) $(DX) \
     $(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx2048M) \
-    --dex --output=$@ \
+    --dex --output=$(dir $@) \
     $(incremental_dex) \
     $(if $(NO_OPTIMIZE_DX), \
         --no-optimize) \
@@ -1712,11 +1723,7 @@
 
 #TODO: update the manifest to point to the dex file
 define add-dex-to-package
-$(if $(filter classes.dex,$(notdir $(PRIVATE_DEX_FILE))),\
-$(hide) zip -qj $@ $(PRIVATE_DEX_FILE),\
-$(hide) _adtp_classes_dex=$(dir $(PRIVATE_DEX_FILE))classes.dex; \
-cp $(PRIVATE_DEX_FILE) $$_adtp_classes_dex && \
-zip -qj $@ $$_adtp_classes_dex && rm -f $$_adtp_classes_dex)
+$(hide) zip -qj $@ $(dir $(PRIVATE_DEX_FILE))/classes*.dex
 endef
 
 # Add java resources added by the current module.
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index f528ee0..d8e9251 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -52,12 +52,7 @@
 endif
 
 
-$(full_target): PRIVATE_BOOTCLASSPATH :=
-ifeq ($(BUILD_OS),linux)
-# You have to set bootclasspath for javadoc manually on linux since Java 6.
-host_jdk_rt_jar := $(dir $(HOST_JDK_TOOLS_JAR))../jre/lib/rt.jar
-$(full_target): PRIVATE_BOOTCLASSPATH := $(host_jdk_rt_jar)
-endif
+$(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core)
 
 ifneq ($(LOCAL_IS_HOST_MODULE),true)
 
@@ -202,6 +197,7 @@
                 -J-Xmx1024m \
                 $(PRIVATE_PROFILING_OPTIONS) \
                 $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
+                $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
                 -sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
                 -d $(PRIVATE_OUT_DIR) \
                 -quiet \
@@ -233,6 +229,8 @@
 	@mkdir -p $(dir $@)
 	$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_DOCS_DIR) && zip -rq $$F * )
 
+$(LOCAL_MODULE)-docs.zip : $(out_zip)
+
 $(call dist-for-goals,docs,$(out_zip))
 
 endif
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 4cb389b..b2122e9 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -207,6 +207,7 @@
 HOST_OUT_INTERMEDIATE_LIBRARIES := $(HOST_OUT_INTERMEDIATES)/lib
 HOST_OUT_NOTICE_FILES := $(HOST_OUT_INTERMEDIATES)/NOTICE_FILES
 HOST_OUT_COMMON_INTERMEDIATES := $(HOST_COMMON_OUT_ROOT)/obj
+HOST_OUT_FAKE := $(HOST_OUT)/fake_packages
 
 HOST_OUT_GEN := $(HOST_OUT)/gen
 HOST_OUT_COMMON_GEN := $(HOST_COMMON_OUT_ROOT)/gen
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index e5ebb11..2a8f18f 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -20,21 +20,64 @@
 
 #######################################
 include $(BUILD_SYSTEM)/host_java_library_common.mk
+#######################################
+
+# Enable emma instrumentation only if the module asks so.
+ifeq (true,$(LOCAL_EMMA_INSTRUMENT))
+ifneq (true,$(EMMA_INSTRUMENT))
+LOCAL_EMMA_INSTRUMENT :=
+endif
+endif
+
+full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
+emma_intermediates_dir := $(intermediates.COMMON)/emma_out
+# emma is hardcoded to use the leaf name of its input for the output file --
+# only the output directory can be changed
+full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(notdir $(full_classes_compiled_jar))
+
+LOCAL_INTERMEDIATE_TARGETS += \
+    $(full_classes_compiled_jar) \
+    $(full_classes_emma_jar)
+
+#######################################
 include $(BUILD_SYSTEM)/base_rules.mk
 #######################################
 
-$(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
+ifeq (true,$(LOCAL_EMMA_INSTRUMENT))
+$(full_classes_emma_jar): PRIVATE_EMMA_COVERAGE_FILE := $(intermediates.COMMON)/coverage.em
+$(full_classes_emma_jar): PRIVATE_EMMA_INTERMEDIATES_DIR := $(emma_intermediates_dir)
+ifdef LOCAL_EMMA_COVERAGE_FILTER
+$(full_classes_emma_jar): PRIVATE_EMMA_COVERAGE_FILTER := $(LOCAL_EMMA_COVERAGE_FILTER)
+else
+# by default, avoid applying emma instrumentation onto emma classes itself,
+# otherwise there will be exceptions thrown
+$(full_classes_emma_jar): PRIVATE_EMMA_COVERAGE_FILTER := *,-emma,-emmarun,-com.vladium.*
+endif
+# this rule will generate both $(PRIVATE_EMMA_COVERAGE_FILE) and
+# $(full_classes_emma_jar)
+$(full_classes_emma_jar) : $(full_classes_compiled_jar) | $(EMMA_JAR)
+	$(transform-classes.jar-to-emma)
 
-java_alternative_checked_module :=
+$(LOCAL_BUILT_MODULE) : $(full_classes_emma_jar)
+	@echo Copying: $@
+	$(hide) $(ACP) -fp $< $@
+
+else # LOCAL_EMMA_INSTRUMENT
+# Directly build into LOCAL_BUILT_MODULE.
+full_classes_compiled_jar := $(LOCAL_BUILT_MODULE)
+endif # LOCAL_EMMA_INSTRUMENT
+
+$(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
 
 # The layers file allows you to enforce a layering between java packages.
 # Run build/tools/java-layers.py for more details.
 layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
 
-$(LOCAL_BUILT_MODULE): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
-$(LOCAL_BUILT_MODULE): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
-$(LOCAL_BUILT_MODULE): PRIVATE_JAR_EXCLUDE_FILES :=
-$(LOCAL_BUILT_MODULE): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
-$(LOCAL_BUILT_MODULE): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) \
+$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
+$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
+$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
+$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES :=
+$(full_classes_compiled_jar): PRIVATE_RMTYPEDEFS :=
+$(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) \
 		$(jar_manifest_file) $(proto_java_sources_file_stamp) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-java-to-package)
diff --git a/core/java.mk b/core/java.mk
index 95ec8f5..fc30d3c 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -72,10 +72,10 @@
 # Choose leaf name for the compiled jar file.
 ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
 full_classes_compiled_jar_leaf := classes-no-debug-var.jar
-built_dex_intermediate_leaf := classes-no-local.dex
+built_dex_intermediate_leaf := no-local
 else
 full_classes_compiled_jar_leaf := classes-full-debug.jar
-built_dex_intermediate_leaf := classes-with-local.dex
+built_dex_intermediate_leaf := with-local
 endif
 
 ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
@@ -96,7 +96,7 @@
 # only the output directory can be changed
 full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(jarjar_leaf)
 full_classes_proguard_jar := $(intermediates.COMMON)/$(proguard_jar_leaf)
-built_dex_intermediate := $(intermediates.COMMON)/$(built_dex_intermediate_leaf)
+built_dex_intermediate := $(intermediates.COMMON)/$(built_dex_intermediate_leaf)/classes.dex
 full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
 
 ifeq ($(LOCAL_MODULE_CLASS)$(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),APPS)
@@ -321,6 +321,10 @@
 $(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
 $(full_classes_compiled_jar): PRIVATE_WARNINGS_ENABLE := $(LOCAL_WARNINGS_ENABLE)
 
+ifdef LOCAL_RMTYPEDEFS
+$(full_classes_compiled_jar): | $(RMTYPEDEFS)
+endif
+
 # Compile the java files to a .jar file.
 # This intentionally depends on java_sources, not all_java_sources.
 # Deps for generated source files must be handled separately,
@@ -328,6 +332,7 @@
 $(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
 $(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES := $(LOCAL_JAR_EXCLUDE_FILES)
 $(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES := $(LOCAL_JAR_PACKAGES)
+$(full_classes_compiled_jar): PRIVATE_RMTYPEDEFS := $(LOCAL_RMTYPEDEFS)
 $(full_classes_compiled_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
 $(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) \
         $(jar_manifest_file) $(layers_file) $(RenderScript_file_stamp) \
@@ -464,7 +469,9 @@
 	$(transform-classes.jar-to-dex)
 $(built_dex): $(built_dex_intermediate) | $(ACP)
 	@echo Copying: $@
-	$(hide) $(ACP) -fp $< $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) rm -f $(dir $@)/classes*.dex
+	$(hide) $(ACP) -fp $(dir $<)/classes*.dex $(dir $@)
 ifneq ($(GENERATE_DEX_DEBUG),)
 	$(install-dex-debug)
 endif
diff --git a/core/llvm_config.mk b/core/llvm_config.mk
index 33b1d06..5789f00 100644
--- a/core/llvm_config.mk
+++ b/core/llvm_config.mk
@@ -1,7 +1,17 @@
-CLANG := $(HOST_OUT_EXECUTABLES)/clang$(HOST_EXECUTABLE_SUFFIX)
-CLANG_CXX := $(HOST_OUT_EXECUTABLES)/clang++$(HOST_EXECUTABLE_SUFFIX)
-LLVM_AS := $(HOST_OUT_EXECUTABLES)/llvm-as$(HOST_EXECUTABLE_SUFFIX)
-LLVM_LINK := $(HOST_OUT_EXECUTABLES)/llvm-link$(HOST_EXECUTABLE_SUFFIX)
+ifeq (true,$(FORCE_BUILD_LLVM_COMPONENTS))
+LLVM_PREBUILTS_PATH := $(BUILD_OUT_EXECUTABLES)
+LLVM_PREBUILTS_HEADER_PATH := external/clang/lib/include
+else
+LLVM_PREBUILTS_PATH := prebuilts/clang/$(BUILD_OS)-x86/host/3.3/bin
+LLVM_PREBUILTS_HEADER_PATH := prebuilts/clang/$(BUILD_OS)-x86/host/3.3/lib/clang/3.3/include/
+endif
+
+CLANG := $(LLVM_PREBUILTS_PATH)/clang$(BUILD_EXECUTABLE_SUFFIX)
+CLANG_CXX := $(LLVM_PREBUILTS_PATH)/clang++$(BUILD_EXECUTABLE_SUFFIX)
+CLANG_TBLGEN := $(LLVM_PREBUILTS_PATH)/clang-tblgen$(BUILD_EXECUTABLE_SUFFIX)
+LLVM_AS := $(LLVM_PREBUILTS_PATH)/llvm-as$(BUILD_EXECUTABLE_SUFFIX)
+LLVM_LINK := $(LLVM_PREBUILTS_PATH)/llvm-link$(BUILD_EXECUTABLE_SUFFIX)
+TBLGEN := $(LLVM_PREBUILTS_PATH)/tblgen$(BUILD_EXECUTABLE_SUFFIX)
 
 # Clang flags for all host or target rules
 CLANG_CONFIG_EXTRA_ASFLAGS :=
@@ -129,8 +139,8 @@
 include $(BUILD_SYSTEM)/llvm_config_define_clang_flags.mk
 
 # Clang compiler-specific libc headers
-CLANG_CONFIG_EXTRA_HOST_C_INCLUDES := external/clang/lib/include
-CLANG_CONFIG_EXTRA_TARGET_C_INCLUDES := external/clang/lib/include $(TARGET_OUT_HEADERS)/clang
+CLANG_CONFIG_EXTRA_HOST_C_INCLUDES := $(LLVM_PREBUILTS_HEADER_PATH)
+CLANG_CONFIG_EXTRA_TARGET_C_INCLUDES := $(LLVM_PREBUILTS_HEADER_PATH) $(TARGET_OUT_HEADERS)/clang
 
 # Address sanitizer clang config
 ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS := -fsanitize=address
diff --git a/core/main.mk b/core/main.mk
index e2b93c2..7892782 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -149,20 +149,22 @@
 endif
 endif
 
+java_version_str := $(shell java -version 2>&1)
+javac_version_str := $(shell javac -version 2>&1)
+
+# Check for the current jdk
 ifeq ($(requires_openjdk), true)
-ifeq ($(shell java -version 2>&1 | grep -i openjdk),)
+# The user asked for java7 openjdk, so check that the host
+# java version is really openjdk
+ifeq ($(shell echo '$(java_version_str)' | grep -i openjdk),)
 $(info ************************************************************)
-$(info You are attempting to build with an unsupported JDK.)
-$(info $(space))
-$(info This build requires OpenJDK, but you are using:)
-$(info $(shell java -version 2>&1 | head -n 2).)
-$(info Please follow the machine setup instructions at)
-$(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
+$(info You asked for an OpenJDK 7 build but your version is)
+$(info $(java_version_str).)
 $(info ************************************************************)
 $(error stop)
 endif # java version is not OpenJdk
 else # if requires_openjdk
-ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
+ifneq ($(shell echo '$(java_version_str)' | grep -i openjdk),)
 $(info ************************************************************)
 $(info You are attempting to build with an unsupported JDK.)
 $(info $(space))
@@ -178,12 +180,14 @@
 # EXPERIMENTAL_USE_JAVA7 is set, 1.6 otherwise.
 ifneq ($(EXPERIMENTAL_USE_JAVA7),)
 required_version := "1.7.x"
-java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.7[\. "$$]')
-javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.7[\. "$$]')
+required_javac_version := "1.7"
+java_version := $(shell echo '$(java_version_str)' | grep '^java .*[ "]1\.7[\. "$$]')
+javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.7[\. "$$]')
 else # if EXPERIMENTAL_USE_JAVA7
 required_version := "1.6.x"
-java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')
-javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')
+required_javac_version := "1.6"
+java_version := $(shell echo '$(java_version_str)' | grep '^java .*[ "]1\.6[\. "$$]')
+javac_version := $(shell echo '$(javac_version_str)' | head -n 1 | grep '[ "]1\.6[\. "$$]')
 endif # if EXPERIMENTAL_USE_JAVA7
 
 ifeq ($(strip $(java_version)),)
@@ -191,7 +195,7 @@
 $(info You are attempting to build with the incorrect version)
 $(info of java.)
 $(info $(space))
-$(info Your version is: $(shell java -version 2>&1 | head -n 1).)
+$(info Your version is: $(java_version_str).)
 $(info The required version is: $(required_version))
 $(info $(space))
 $(info Please follow the machine setup instructions at)
@@ -206,8 +210,8 @@
 $(info You are attempting to build with the incorrect version)
 $(info of javac.)
 $(info $(space))
-$(info Your version is: $(shell javac -version 2>&1 | head -n 1).)
-$(info The required version is: $(required_java_version))
+$(info Your version is: $(javac_version_str).)
+$(info The required version is: $(required_javac_version))
 $(info $(space))
 $(info Please follow the machine setup instructions at)
 $(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
@@ -215,6 +219,7 @@
 $(error stop)
 endif
 
+
 ifndef BUILD_EMULATOR
 ifeq (darwin,$(HOST_OS))
 GCC_REALPATH = $(realpath $(shell which $(HOST_CC)))
@@ -889,6 +894,7 @@
   $(foreach f,$(INSTALLED_RADIOIMAGE_TARGET), \
     $(call dist-for-goals, droidcore, $(f)))
 
+  ifneq ($(ANDROID_BUILD_EMBEDDED),true)
   ifneq ($(TARGET_BUILD_PDK),true)
     $(call dist-for-goals, droidcore, \
       $(APPS_ZIP) \
@@ -896,6 +902,7 @@
       $(PACKAGE_STATS_FILE) \
     )
   endif
+  endif
 
   ifeq ($(EMMA_INSTRUMENT),true)
     $(EMMA_META_ZIP) : $(INSTALLED_SYSTEMIMAGE)
diff --git a/core/multi_prebuilt.mk b/core/multi_prebuilt.mk
index be60e2f..bc85cea 100644
--- a/core/multi_prebuilt.mk
+++ b/core/multi_prebuilt.mk
@@ -69,7 +69,11 @@
   $(if $(7), \
     $(eval LOCAL_BUILT_MODULE_STEM := $(7)) \
    , \
-    $(eval LOCAL_BUILT_MODULE_STEM := $(notdir $(LOCAL_SRC_FILES))) \
+    $(if $(word 2,$(tw)), \
+      $(eval LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)$(suffix $(LOCAL_SRC_FILES))) \
+     , \
+      $(eval LOCAL_BUILT_MODULE_STEM := $(notdir $(LOCAL_SRC_FILES))) \
+     ) \
    ) \
   $(eval LOCAL_MODULE_SUFFIX := $(suffix $(LOCAL_SRC_FILES))) \
   $(if $(filter user,$(TARGET_BUILD_VARIANT)), \
diff --git a/core/pathmap.mk b/core/pathmap.mk
index feecfbf..8e441c4 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -89,6 +89,7 @@
 	    telephony \
 	    wifi \
 	    keystore \
+	    rs \
 	 )
 
 #
@@ -108,19 +109,29 @@
         v7/gridlayout \
         v7/appcompat \
         v7/mediarouter \
+        v7/recyclerview \
         v8/renderscript \
         v13
 
 #
+# A list of all source roots under frameworks/support.
+#
+FRAMEWORKS_MULTIDEX_SUBDIRS := \
+        multidex \
+        multidex/instrumentation
+
+#
 # A version of FRAMEWORKS_SUPPORT_SUBDIRS that is expanded to full paths from
 # the root of the tree.
 #
 FRAMEWORKS_SUPPORT_JAVA_SRC_DIRS := \
-	$(addprefix frameworks/support/,$(FRAMEWORKS_SUPPORT_SUBDIRS))
+	$(addprefix frameworks/support/,$(FRAMEWORKS_SUPPORT_SUBDIRS)) \
+        $(addprefix frameworks/,$(FRAMEWORKS_MULTIDEX_SUBDIRS))
 
 #
 # A list of support library modules.
 #
 FRAMEWORKS_SUPPORT_JAVA_LIBRARIES := \
-    $(foreach dir,$(FRAMEWORKS_SUPPORT_SUBDIRS),android-support-$(subst /,-,$(dir)))
+    $(foreach dir,$(FRAMEWORKS_SUPPORT_SUBDIRS),android-support-$(subst /,-,$(dir))) \
+    $(foreach dir,$(FRAMEWORKS_MULTIDEX_SUBDIRS),android-support-$(subst /,-,$(dir)))
 
diff --git a/core/pdk_config.mk b/core/pdk_config.mk
index 9590d70..b0cccc9 100644
--- a/core/pdk_config.mk
+++ b/core/pdk_config.mk
@@ -37,11 +37,16 @@
 endif  # fusion
 endif  # pdk or fusion
 
+PDK_PLATFORM_JAVA_ZIP_JAVA_TARGET_LIB_DIR :=
+PDK_PLATFORM_JAVA_ZIP_JAVA_HOST_LIB_DIR := \
+	host/common/obj/JAVA_LIBRARIES/bouncycastle-host_intermediates
+PDK_PLATFORM_JAVA_ZIP_CONTENTS :=
+
 ifneq (,$(filter platform-java, $(MAKECMDGOALS))$(PDK_FUSION_PLATFORM_ZIP))
 # additional items to add to platform.zip for platform-java build
 # For these dirs, add classes.jar and javalib.jar from the dir to platform.zip
 # all paths under out dir
-PDK_PLATFORM_JAVA_ZIP_JAVA_LIB_DIR := \
+PDK_PLATFORM_JAVA_ZIP_JAVA_TARGET_LIB_DIR += \
 	target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates \
 	target/common/obj/JAVA_LIBRARIES/core_intermediates \
 	target/common/obj/JAVA_LIBRARIES/core-junit_intermediates \
@@ -52,14 +57,21 @@
 	target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates \
 	target/common/obj/JAVA_LIBRARIES/voip-common_intermediates \
 	target/common/obj/JAVA_LIBRARIES/mms-common_intermediates \
-	target/common/obj/JAVA_LIBRARIES/android-ex-camera2_intermediates
+	target/common/obj/JAVA_LIBRARIES/android-ex-camera2_intermediates \
+	target/common/obj/JAVA_LIBRARIES/android-common_intermediates \
+
 # not java libraries
-PDK_PLATFORM_JAVA_ZIP_CONTENTS := \
+PDK_PLATFORM_JAVA_ZIP_CONTENTS += \
 	target/common/obj/APPS/framework-res_intermediates/package-export.apk \
 	target/common/obj/APPS/framework-res_intermediates/src/R.stamp
+endif # platform-java or FUSION build
+
+PDK_PLATFORM_JAVA_ZIP_JAVA_LIB_DIR := \
+	$(PDK_PLATFORM_JAVA_ZIP_JAVA_TARGET_LIB_DIR) \
+	$(PDK_PLATFORM_JAVA_ZIP_JAVA_HOST_LIB_DIR)
+
 PDK_PLATFORM_JAVA_ZIP_CONTENTS += $(foreach lib_dir,$(PDK_PLATFORM_JAVA_ZIP_JAVA_LIB_DIR),\
     $(lib_dir)/classes.jar $(lib_dir)/javalib.jar)
-endif # platform-java or FUSION build
 
 # check and override java support level
 ifneq ($(TARGET_BUILD_PDK)$(PDK_FUSION_PLATFORM_ZIP),)
@@ -117,6 +129,11 @@
 	$(hide) rm -rf $@
 	$(hide) cp -fpPR $< $@
 
+# implicit rules for host java files
+$(HOST_COMMON_OUT_ROOT)/% : $(_pdk_fusion_intermediates)/host/common/% $(_pdk_fusion_stamp)
+	@mkdir -p $(dir $@)
+	$(hide) cp -fpPR $< $@
+
 ifeq (true,$(TARGET_BUILD_PDK_JAVA_PLATFORM))
 
 PDK_FUSION_OUT_DIR := $(OUT_DIR)
@@ -137,11 +154,11 @@
 target/common/obj/APPS/framework-res_intermediates/package-export.apk))
 
 # javalib.jar should pull classes.jar as classes.jar is not explicitly pulled.
-$(foreach lib_dir,$(PDK_PLATFORM_JAVA_ZIP_JAVA_LIB_DIR),\
+$(foreach lib_dir,$(PDK_PLATFORM_JAVA_ZIP_JAVA_TARGET_LIB_DIR),\
 $(eval $(call JAVA_dependency_template,$(lib_dir)/javalib.jar,\
 $(lib_dir)/classes.jar)))
 
-# implicit rules for all others
+# implicit rules for all other target files
 $(TARGET_COMMON_OUT_ROOT)/% : $(_pdk_fusion_intermediates)/target/common/% $(_pdk_fusion_stamp)
 	@mkdir -p $(dir $@)
 	$(hide) cp -fpPR $< $@
diff --git a/core/product.mk b/core/product.mk
index cf6fb9a..67f5fdf 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -99,6 +99,9 @@
     PRODUCT_RUNTIMES \
     PRODUCT_BOOT_JARS \
     PRODUCT_DEX_PREOPT_IMAGE_IN_DATA \
+    PRODUCT_SUPPORTS_VERITY \
+    PRODUCT_VERITY_PARTITION \
+    PRODUCT_VERITY_SIGNING_KEY
 
 define dump-product
 $(info ==== $(1) ====)\
diff --git a/core/product_config.mk b/core/product_config.mk
index 7a27426..1333ff8 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -267,7 +267,7 @@
 PRODUCT_RUNTIMES := $(product_runtimes)
 product_runtimes :=
 
-PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PROPERTY_OVERRIDES += persist.sys.dalvik.vm.lib=$(DALVIK_VM_LIB)
+PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PROPERTY_OVERRIDES += persist.sys.dalvik.vm.lib.1=$(DALVIK_VM_LIB)
 
 ifeq ($(words $(PRODUCT_RUNTIMES)),1)
   # If we only have one runtime, we can strip classes.dex by default during dex_preopt
@@ -317,8 +317,10 @@
 # Everyone gets nodpi assets which are density-independent.
 PRODUCT_AAPT_CONFIG += nodpi
 
+# Keep a copy of the space-separated config
+PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
+
 # Convert spaces to commas.
-comma := ,
 PRODUCT_AAPT_CONFIG := \
     $(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_CONFIG)))
 PRODUCT_AAPT_PREF_CONFIG := \
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index ed8c125..f991a9e 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -28,6 +28,8 @@
 VMTESTSTF_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,vm-tests-tf,HOST)
 VMTESTSTF_JAR := $(VMTESTSTF_INTERMEDIATES)/android.core.vm-tests-tf.jar
 
+# The list of test packages that core-tests (libcore/Android.mk)
+# is split into.
 CTS_CORE_CASE_LIST := \
 	android.core.tests.libcore.package.dalvik \
 	android.core.tests.libcore.package.com \
@@ -36,8 +38,26 @@
 	android.core.tests.libcore.package.tests \
 	android.core.tests.libcore.package.org \
 	android.core.tests.libcore.package.libcore \
+	android.core.tests.libcore.package.jsr166 \
+	android.core.tests.libcore.package.harmony_annotation \
+	android.core.tests.libcore.package.harmony_java_io \
+	android.core.tests.libcore.package.harmony_java_lang \
+	android.core.tests.libcore.package.harmony_java_math \
+	android.core.tests.libcore.package.harmony_java_net \
+	android.core.tests.libcore.package.harmony_java_nio \
+	android.core.tests.libcore.package.harmony_java_text \
+	android.core.tests.libcore.package.harmony_java_util \
+	android.core.tests.libcore.package.harmony_javax_security \
 	android.core.tests.runner
 
+# The list of test packages that apache-harmony-tests (external/apache-harmony/Android.mk)
+# is split into.
+CTS_CORE_CASE_LIST += \
+	android.core.tests.libcore.package.harmony_beans \
+	android.core.tests.libcore.package.harmony_logging \
+	android.core.tests.libcore.package.harmony_prefs \
+	android.core.tests.libcore.package.harmony_sql
+
 # Depend on the full package paths rather than the phony targets to avoid
 # rebuilding the packages every time.
 CTS_CORE_CASES := $(foreach pkg,$(CTS_CORE_CASE_LIST),$(call intermediates-dir-for,APPS,$(pkg))/package.apk)
@@ -85,12 +105,14 @@
 BOUNCYCASTLE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,bouncycastle,,COMMON)
 APACHEXML_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,apache-xml,,COMMON)
 OKHTTP_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp,,COMMON)
+APACHEHARMONY_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,apache-harmony-tests,,COMMON)
 SQLITEJDBC_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,sqlite-jdbc,,COMMON)
 JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
 CORETESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
+JSR166TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,jsr166-tests,,COMMON)
 CONSCRYPTTESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,conscrypt-tests,,COMMON)
 
-GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(CONSCRYPT_INTERMEDIATES)/classes.jar:$(BOUNCYCASTLE_INTERMEDIATES)/classes.jar:$(APACHEXML_INTERMEDIATES)/classes.jar:$(OKHTTP_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(SQLITEJDBC_INTERMEDIATES)/javalib.jar:$(CORETESTS_INTERMEDIATES)/javalib.jar:$(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(CONSCRYPT_INTERMEDIATES)/classes.jar:$(BOUNCYCASTLE_INTERMEDIATES)/classes.jar:$(APACHEXML_INTERMEDIATES)/classes.jar:$(APACHEHARMONY_INTERMEDIATES)/classes.jar:$(OKHTTP_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(SQLITEJDBC_INTERMEDIATES)/javalib.jar:$(CORETESTS_INTERMEDIATES)/javalib.jar:$(JSR166TESTS_INTERMEDIATES)/javalib.jar:$(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar
 
 CTS_CORE_XMLS := \
 	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik.xml \
@@ -99,7 +121,21 @@
 	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.sun.xml \
 	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tests.xml \
 	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.org.xml \
-	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore.xml
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.jsr166.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_annotation.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_io.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_lang.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_math.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_net.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_nio.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_text.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_util.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_javax_security.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_beans.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_logging.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_prefs.xml \
+	$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_sql.xml \
 
 $(CTS_CORE_XMLS): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 # Why does this depend on javalib.jar instead of classes.jar?  Because
@@ -107,7 +143,7 @@
 # build system requires that dependencies use javalib.jar.  If
 # javalib.jar is up-to-date, then classes.jar is as well.  Depending
 # on classes.jar will build the files incorrectly.
-CTS_CORE_XMLS_DEPS := $(CTS_CORE_CASES) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(HOST_OUT_JAVA_LIBRARIES)/junit.jar $(CORE_INTERMEDIATES)/javalib.jar $(BOUNCYCASTLE_INTERMEDIATES)/javalib.jar $(APACHEXML_INTERMEDIATES)/javalib.jar $(OKHTTP_INTERMEDIATES)/javalib.jar $(SQLITEJDBC_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(CORETESTS_INTERMEDIATES)/javalib.jar $(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar | $(ACP)
+CTS_CORE_XMLS_DEPS := $(CTS_CORE_CASES) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(HOST_OUT_JAVA_LIBRARIES)/junit.jar $(CORE_INTERMEDIATES)/javalib.jar $(BOUNCYCASTLE_INTERMEDIATES)/javalib.jar $(APACHEXML_INTERMEDIATES)/javalib.jar $(APACHEHARMONY_INTERMEDIATES)/javalib.jar $(OKHTTP_INTERMEDIATES)/javalib.jar $(SQLITEJDBC_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(CORETESTS_INTERMEDIATES)/javalib.jar $(JSR166TESTS_INTERMEDIATES)/javalib.jar $(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar build/core/tasks/cts.mk | $(ACP)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
@@ -158,6 +194,105 @@
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,libcore,\
 		libcore/expectations)
 
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.jsr166.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.jsr166,\
+		cts/tests/core/libcore/jsr166/AndroidManifest.xml,\
+		$(JSR166TESTS_INTERMEDIATES)/javalib.jar,jsr166,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_annotation.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_annotation,\
+		cts/tests/core/libcore/harmony_annotation/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.annotation.tests,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_io.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_io,\
+		cts/tests/core/libcore/harmony_java_io/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.io,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_lang.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_lang,\
+		cts/tests/core/libcore/harmony_java_lang/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.lang,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_math.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_math,\
+		cts/tests/core/libcore/harmony_java_math/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.math,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_net.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_net,\
+		cts/tests/core/libcore/harmony_java_net/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.net,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_nio.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_nio,\
+		cts/tests/core/libcore/harmony_java_nio/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.nio,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_text.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_text,\
+		cts/tests/core/libcore/harmony_java_text/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.text,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_util.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_util,\
+		cts/tests/core/libcore/harmony_java_util/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.util,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_javax_security.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_javax_security,\
+		cts/tests/core/libcore/harmony_javax_security/AndroidManifest.xml,\
+		$(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.javax.security,\
+		libcore/expectations)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_beans.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_beans,\
+		cts/tests/core/libcore/harmony_beans/AndroidManifest.xml,\
+		$(APACHEHARMONY_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.beans,\
+		libcore/expectations external/apache-harmony/Android.mk)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_logging.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_logging,\
+		cts/tests/core/libcore/harmony_logging/AndroidManifest.xml,\
+		$(APACHEHARMONY_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.logging,\
+		libcore/expectations external/apache-harmony/Android.mk)
+
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_prefs.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_prefs,\
+		cts/tests/core/libcore/harmony_prefs/AndroidManifest.xml,\
+		$(APACHEHARMONY_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.prefs,\
+		libcore/expectations external/apache-harmony/Android.mk)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_sql.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_sql,\
+		cts/tests/core/libcore/harmony_sql/AndroidManifest.xml,\
+		$(APACHEHARMONY_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.sql,\
+		libcore/expectations external/apache-harmony/Android.mk)
+
 # ----- Generate the test descriptions for the vm-tests-tf -----
 #
 CORE_VM_TEST_TF_DESC := $(CTS_TESTCASES_OUT)/android.core.vm-tests-tf.xml
diff --git a/core/tasks/vendor_module_check.mk b/core/tasks/vendor_module_check.mk
index c51a40c..80b05b3 100644
--- a/core/tasks/vendor_module_check.mk
+++ b/core/tasks/vendor_module_check.mk
@@ -22,6 +22,7 @@
         csr \
         elan \
         google \
+        htc \
         imgtec \
         invensense \
         lge \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 40248fc..99283b0 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -41,7 +41,7 @@
   # which is the version that we reveal to the end user.
   # Update this value when the platform version changes (rather
   # than overriding it somewhere else).  Can be an arbitrary string.
-  PLATFORM_VERSION := 4.4.3.2.1.000.000
+  PLATFORM_VERSION := 4.4.2
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 65adb0c..82c88d2 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -60,6 +60,5 @@
     $(LOCAL_DIR)/vbox_x86.mk \
     $(LOCAL_DIR)/sdk.mk \
     $(LOCAL_DIR)/sdk_x86.mk \
-    $(LOCAL_DIR)/sdk_mips.mk \
-    $(LOCAL_DIR)/large_emu_hw.mk
+    $(LOCAL_DIR)/sdk_mips.mk
 endif
diff --git a/target/product/base.mk b/target/product/base.mk
index 68e3ff3..657d88c 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -34,6 +34,7 @@
     framework2 \
     fsck_msdos \
     ime \
+    inputflinger \
     javax.obex \
     libandroid \
     libandroid_runtime \
@@ -47,6 +48,7 @@
     libeffectproxy \
     libeffects \
     libinput \
+    libinputflinger \
     libiprouteutil \
     libjni_latinime \
     libjnigraphics \
@@ -78,6 +80,7 @@
     libutils \
     libvisualizer \
     libvorbisidec \
+    libwifi-service \
     media \
     media_cmd \
     mediaserver \
diff --git a/target/product/core.mk b/target/product/core.mk
index c5ef2aa..71d2d6f 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -22,15 +22,31 @@
 PRODUCT_PACKAGES += \
     BasicDreams \
     Browser \
+    Calculator \
+    Calendar \
+    CalendarProvider \
+    CertInstaller \
     Contacts \
+    DeskClock \
     DocumentsUI \
     DownloadProviderUi \
+    Email \
+    Exchange2 \
     ExternalStorageProvider \
+    FusedLocation \
+    InputDevices \
     KeyChain \
+    Keyguard \
+    LatinIME \
+    Launcher2 \
     PicoTts \
     PacProcessor \
+    PrintSpooler \
     ProxyHandler \
+    QuickSearchBox \
+    Settings \
     SharedStorageBackup \
+    TeleService \
     VpnDialogs
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_base.mk)
diff --git a/target/product/core_base.mk b/target/product/core_base.mk
index 658e502..d7cf810 100644
--- a/target/product/core_base.mk
+++ b/target/product/core_base.mk
@@ -64,7 +64,8 @@
     requestsync \
     screenrecord \
     telephony-common \
-    voip-common
+    voip-common \
+    wifi-service
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core_minimal.mk)
 # Override the PRODUCT_BOOT_JARS set in core_minimal.mk. The order matters.
@@ -83,4 +84,5 @@
     android.policy \
     services \
     apache-xml \
-    webviewchromium
+    webviewchromium \
+    wifi-service
\ No newline at end of file
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index 79ba0d4..8f44f97 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -55,7 +55,8 @@
     make_ext4fs \
     screencap \
     sensorservice \
-    uiautomator
+    uiautomator \
+    uncrypt
 
 # The order of PRODUCT_BOOT_JARS matters.
 PRODUCT_BOOT_JARS := \
@@ -70,7 +71,8 @@
     android.policy \
     services \
     apache-xml \
-    webviewchromium
+    webviewchromium \
+    wifi-service
 
 PRODUCT_RUNTIMES := runtime_libart_default
 PRODUCT_RUNTIMES += runtime_libdvm
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
new file mode 100644
index 0000000..2707490
--- /dev/null
+++ b/target/product/core_tiny.mk
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Tiny configuration for small devices such as wearables. Includes base and embedded.
+# No telephony
+
+PRODUCT_PACKAGES := \
+    Bluetooth \
+    CertInstaller \
+    FusedLocation \
+    InputDevices \
+    bluetooth-health
+
+PRODUCT_PACKAGES += \
+    audio \
+    clatd \
+    clatd.conf \
+    dhcpcd.conf \
+    network \
+    pand \
+    pppd \
+    sdptool
+
+PRODUCT_PACKAGES += \
+    audio.primary.default \
+    audio_policy.default \
+    local_time.default \
+    power.default
+
+PRODUCT_PACKAGES += \
+    local_time.default
+
+PRODUCT_PACKAGES += \
+    BackupRestoreConfirmation \
+    DefaultContainerService \
+    SettingsProvider \
+    Shell \
+    bu \
+    com.android.location.provider \
+    com.android.location.provider.xml \
+    framework-res \
+    installd \
+    ip \
+    ip-up-vpn \
+    ip6tables \
+    iptables \
+    keystore \
+    keystore.default \
+    libOpenMAXAL \
+    libOpenSLES \
+    libdownmix \
+    libfilterfw \
+    libsqlite_jni \
+    libwilhelm \
+    make_ext4fs \
+    screencap \
+    sensorservice \
+    uiautomator \
+    uncrypt
+
+# The order matters
+PRODUCT_BOOT_JARS := \
+    core \
+    conscrypt \
+    okhttp \
+    core-junit \
+    bouncycastle \
+    ext \
+    framework \
+    framework2 \
+    android.policy \
+    services \
+    apache-xml
+
+PRODUCT_RUNTIMES := runtime_libdvm_default
+
+PRODUCT_PROPERTY_OVERRIDES += \
+    ro.carrier=unknown
+
+MINIMAL_FONT_FOOTPRINT := true
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/base.mk)
+$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
+
+# Overrides
+PRODUCT_BRAND := tiny
+PRODUCT_DEVICE := tiny
+PRODUCT_NAME := core_tiny
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index d370af9..b0a5396 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -20,6 +20,7 @@
 PRODUCT_PACKAGES += \
     adb \
     adbd \
+    atrace \
     bootanimation \
     debuggerd \
     dumpstate \
@@ -58,6 +59,7 @@
     libui \
     libutils \
     linker \
+    lmkd \
     logcat \
     logwrapper \
     mkshrc \
diff --git a/target/product/generic_no_telephony.mk b/target/product/generic_no_telephony.mk
index 963d56a..22589ca 100644
--- a/target/product/generic_no_telephony.mk
+++ b/target/product/generic_no_telephony.mk
@@ -17,33 +17,15 @@
 # This is a generic phone product that isn't specialized for a specific device.
 # It includes the base Android platform.
 
-PRODUCT_POLICY := android.policy_phone
-
 PRODUCT_PACKAGES := \
-    DeskClock \
     Bluetooth \
-    Calculator \
-    Calendar \
     Camera2 \
-    CertInstaller \
-    Email \
-    Exchange2 \
-    FusedLocation \
     Gallery2 \
-    InputDevices \
-    Keyguard \
-    LatinIME \
-    Launcher2 \
     Music \
     MusicFX \
     OneTimeInitializer \
-    PrintSpooler \
     Provision \
-    QuickSearchBox \
-    Settings \
     SystemUI \
-    TeleService \
-    CalendarProvider \
     bluetooth-health \
     WallpaperCropper
 
diff --git a/target/product/large_emu_hw.mk b/target/product/large_emu_hw.mk
deleted file mode 100644
index a918c1d..0000000
--- a/target/product/large_emu_hw.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This is a generic product for devices with large display but not specialized
-# for a specific device. It includes the base Android platform.
-
-PRODUCT_POLICY := android.policy_mid
-
-PRODUCT_PACKAGES := \
-    CarHome \
-    DeskClock \
-    Bluetooth \
-    Calculator \
-    Calendar \
-    CertInstaller \
-    Email \
-    Exchange2 \
-    Gallery2 \
-    LatinIME \
-    Launcher2 \
-    Music \
-    Provision \
-    QuickSearchBox \
-    Settings \
-    Sync \
-    Updater \
-    CalendarProvider \
-    SyncProvider \
-    bluetooth-health \
-    hostapd \
-    wpa_supplicant.conf
-
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
-
-# Overrides
-PRODUCT_BRAND := generic
-PRODUCT_DEVICE := generic
-PRODUCT_NAME := large_emu_hw
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index bc59782..dab9fbd 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -14,55 +14,39 @@
 # limitations under the License.
 #
 
-PRODUCT_POLICY := android.policy_phone
 PRODUCT_PROPERTY_OVERRIDES :=
 
 PRODUCT_PACKAGES := \
-	Calculator \
-	DeskClock \
-	Email \
-	Exchange2 \
-	FusedLocation \
-	Gallery \
-	Keyguard \
-	Music \
-	Mms \
-	OpenWnn \
-	PrintSpooler \
-	libWnnEngDic \
-	libWnnJpnDic \
-	libwnndict \
-	TeleService \
-	PinyinIME \
-	Protips \
-	SoftKeyboard \
-	SystemUI \
-	Launcher2 \
+	ApiDemos \
+	ConnectivityTest \
+	CubeLiveWallpapers \
+	CustomLocale \
 	Development \
 	DevelopmentSettings \
+	Dialer \
 	Fallback \
-	Settings \
-	SdkSetup \
-	CustomLocale \
-	sqlite3 \
-	InputDevices \
-	LatinIME \
-	CertInstaller \
-	LiveWallpapersPicker \
-	ApiDemos \
+	Gallery \
 	GestureBuilder \
-	CubeLiveWallpapers \
-	QuickSearchBox \
-	WidgetPreview \
-	librs_jni \
-	ConnectivityTest \
 	GpsLocationTest \
-	CalendarProvider \
-	Calendar \
+	LegacyCamera \
+	librs_jni \
+	libwnndict \
+	libWnnEngDic \
+	libWnnJpnDic \
+	LiveWallpapersPicker \
+	Mms \
+	Music \
+	OpenWnn \
+	PinyinIME \
+	Protips \
+	rild \
+	SdkSetup \
 	SmokeTest \
 	SmokeTestApp \
-	rild \
-	LegacyCamera
+	SoftKeyboard \
+	sqlite3 \
+	SystemUI \
+	WidgetPreview
 
 # Define the host tools and libs that are parts of the SDK.
 -include sdk/build/product_sdk.mk
@@ -96,14 +80,17 @@
 $(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
 
-# Overrides
-PRODUCT_BRAND := generic
-PRODUCT_NAME := sdk
-PRODUCT_DEVICE := generic
+# include available languages for TTS in the system image
+-include external/svox/pico/lang/PicoLangDeDeInSystem.mk
+-include external/svox/pico/lang/PicoLangEnGBInSystem.mk
+-include external/svox/pico/lang/PicoLangEnUsInSystem.mk
+-include external/svox/pico/lang/PicoLangEsEsInSystem.mk
+-include external/svox/pico/lang/PicoLangFrFrInSystem.mk
+-include external/svox/pico/lang/PicoLangItItInSystem.mk
 
 # locale + densities. en_US is both first and in alphabetical order to
 # ensure this is the default locale.
-PRODUCT_LOCALES = \
+PRODUCT_LOCALES := \
 	en_US \
 	ldpi \
 	hdpi \
@@ -167,10 +154,7 @@
 	zh_CN \
 	zh_TW
 
-# include available languages for TTS in the system image
--include external/svox/pico/lang/PicoLangDeDeInSystem.mk
--include external/svox/pico/lang/PicoLangEnGBInSystem.mk
--include external/svox/pico/lang/PicoLangEnUsInSystem.mk
--include external/svox/pico/lang/PicoLangEsEsInSystem.mk
--include external/svox/pico/lang/PicoLangFrFrInSystem.mk
--include external/svox/pico/lang/PicoLangItItInSystem.mk
+# Overrides
+PRODUCT_BRAND := generic
+PRODUCT_NAME := sdk
+PRODUCT_DEVICE := generic
diff --git a/target/product/sdk_x86.mk b/target/product/sdk_x86.mk
index 873d0c0..6c5e746 100644
--- a/target/product/sdk_x86.mk
+++ b/target/product/sdk_x86.mk
@@ -19,7 +19,7 @@
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
 
-include $(SRC_TARGET_DIR)/product/sdk.mk
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk.mk)
 
 # Overrides
 PRODUCT_BRAND := generic_x86
diff --git a/target/product/security/Android.mk b/target/product/security/Android.mk
new file mode 100644
index 0000000..5a40397
--- /dev/null
+++ b/target/product/security/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+
+#######################################
+# verity_key
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := verity_key
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_PREBUILT)
diff --git a/tools/droiddoc/templates-ds/jd_lists_unified.cs b/tools/droiddoc/templates-ds/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-ds/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-ds/package.cs b/tools/droiddoc/templates-ds/package.cs
index ea3e4f4..d67d5d9 100644
--- a/tools/droiddoc/templates-ds/package.cs
+++ b/tools/droiddoc/templates-ds/package.cs
@@ -45,6 +45,7 @@
   <?cs /if ?>
 <?cs /def ?>
 
+<?cs call:class_table("Annotations", package.annotations) ?>
 <?cs call:class_table("Interfaces", package.interfaces) ?>
 <?cs call:class_table("Classes", package.classes) ?>
 <?cs call:class_table("Enums", package.enums) ?>
diff --git a/tools/droiddoc/templates-pdk/head_tag.cs b/tools/droiddoc/templates-pdk/head_tag.cs
index 0ecda7b..a61cadb 100644
--- a/tools/droiddoc/templates-pdk/head_tag.cs
+++ b/tools/droiddoc/templates-pdk/head_tag.cs
@@ -27,6 +27,17 @@
 if:resources ?>
 <script src="<?cs var:toroot ?>resources/resources-data.js" type="text/javascript"></script><?cs 
 /if ?>
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-10664927-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
 <noscript>
   <style type="text/css">
     html,body{overflow:auto;}
@@ -37,4 +48,4 @@
     #resize-packages-nav{border-bottom:3px solid #666;}
   </style>
 </noscript>
-</head>
\ No newline at end of file
+</head>
diff --git a/tools/droiddoc/templates-pdk/jd_lists_unified.cs b/tools/droiddoc/templates-pdk/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-pdk/trailer.cs b/tools/droiddoc/templates-pdk/trailer.cs
index 155ba58..46c7bbc 100644
--- a/tools/droiddoc/templates-pdk/trailer.cs
+++ b/tools/droiddoc/templates-pdk/trailer.cs
@@ -1,11 +1,19 @@
 </div> <!-- end body-content --> <?cs # normally opened by header.cs ?>
-
 <script type="text/javascript">
 init(); /* initialize android-developer-docs.js */
-var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
-document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
 </script>
-<script type="text/javascript">
-var pageTracker = _gat._getTracker("UA-5831155-1");
-pageTracker._trackPageview();
-</script>
\ No newline at end of file
+<!--
+    Copyright 2013 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
diff --git a/tools/droiddoc/templates-sac/designpage.cs b/tools/droiddoc/templates-sac/designpage.cs
index c714a74..c5f03ff 100644
--- a/tools/droiddoc/templates-sac/designpage.cs
+++ b/tools/droiddoc/templates-sac/designpage.cs
@@ -86,14 +86,5 @@
 
       </div>
     </div>
-
-    <script type="text/javascript">
-    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
-    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
-    </script>
-    <script type="text/javascript">
-    var pageTracker = _gat._getTracker("UA-5831155-1");
-    pageTracker._trackPageview();
-    </script>
   </body>
 </html>
diff --git a/tools/droiddoc/templates-sac/head_tag.cs b/tools/droiddoc/templates-sac/head_tag.cs
index 2d64e4f..9fca488 100644
--- a/tools/droiddoc/templates-sac/head_tag.cs
+++ b/tools/droiddoc/templates-sac/head_tag.cs
@@ -48,7 +48,7 @@
 
 <script type="text/javascript">
   var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_setAccount', 'UA-45455297-1']);
   _gaq.push(['_trackPageview']);
 
   (function() {
@@ -57,4 +57,4 @@
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
   })();
 </script>
-</head>
\ No newline at end of file
+</head>
diff --git a/tools/droiddoc/templates-sac/jd_lists_unified.cs b/tools/droiddoc/templates-sac/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-sac/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-sac/package.cs b/tools/droiddoc/templates-sac/package.cs
index 99eaff2..abd49f1 100644
--- a/tools/droiddoc/templates-sac/package.cs
+++ b/tools/droiddoc/templates-sac/package.cs
@@ -45,6 +45,7 @@
   <?cs /if ?>
 <?cs /def ?>
 
+<?cs call:class_table("Annotations", package.annotations) ?>
 <?cs call:class_table("Interfaces", package.interfaces) ?>
 <?cs call:class_table("Classes", package.classes) ?>
 <?cs call:class_table("Enums", package.enums) ?>
diff --git a/tools/droiddoc/templates-sdk/assets/css/default.css b/tools/droiddoc/templates-sdk/assets/css/default.css
index c4b81d2..69418df 100644
--- a/tools/droiddoc/templates-sdk/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk/assets/css/default.css
@@ -428,6 +428,10 @@
   border-bottom:0;
   padding:0;
 }
+.content-header > div:first-child {
+  height:55px; /* set fixed height for the header div to ensure the
+                  next/prev links align with toc on training classes */
+}
 
 .content-footer {
   border-top: 1px solid #ccc;
@@ -524,6 +528,11 @@
     width:262px;
   }
 
+  .paging-links a.start-class-link {
+    width:100%;
+    text-align:right;
+  }
+
   /* list of classes on course landing page */
   ol.class-list {
     list-style:none;
@@ -1824,7 +1833,7 @@
 }
 
 #tb-wrapper {
-  margin:-27px 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
+  margin:-29px 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
 }
 
 #tb,
@@ -1897,6 +1906,10 @@
   font-size:inherit;
 }
 
+.sidebox > *:last-child {
+  margin-bottom:0;
+}
+
 #tb ol,
 #tb ul,
 #qv ul {
@@ -2259,12 +2272,16 @@
 
 
 /* nav tree */
-#side-nav, #devdoc-nav, #swapper,
+#side-nav, #swapper,
 #nav-tree, #tree-list {
   overflow:hidden;
   margin-left:0;
 }
 
+#devdoc-nav {
+  overflow:visible !important; /* To keep the "to top" button visible */
+}
+
 #nav-tree ul {
   list-style:none;
   padding:0;
@@ -2497,7 +2514,7 @@
 }
 
 /* --------------------------------------------------------------------------
-Styles for samples project trees and code browsing in resources tab 
+Styles for samples browser
 */
 
 #codesample-wrapper {
@@ -2543,6 +2560,30 @@
   display:inline-block;
 }
 
+/*
+Styles for displaying image or video resources in samples browser.
+Resources are marked as no-display if they exceed the size limit.
+*/
+div#codesample-resource img, div#codesample-resource video {
+  border: 1px solid #ececec;
+}
+
+div#codesample-resource.noDisplay div {
+  border: 1px solid #ececec;
+  width:120px;
+  margin-bottom:4px;
+  padding:20px;
+}
+
+div#codesample-resource .noDisplay-message:after {
+  font-style:italic;
+  font-size:12px;
+  content: 'This resource is not available for browsing. To view it, please download the project.';
+}
+
+/*
+Styles for project structure (treeview) page
+*/
 .structure-dir {
 background-image:url(../../assets/images/folder.png);
 background-repeat:no-repeat;
@@ -4791,25 +4832,32 @@
 
 .landing-banner,
 .landing-docs {
-  margin:20px 0 0;
+  margin:20px 0;
 }
-.landing-banner div:first-child,
-.landing-docs div:first-child,
-.landing-docs .col-12 {
+.landing-banner > div:first-child,
+.landing-docs > div:first-child,
+.landing-docs > .col-12 {
   margin-left:0;
   min-height:280px;
 }
-.landing-banner div:last-child,
-.landing-docs div:last-child,
-.landing-docs .col-12 {
+.landing-banner.short > div {
+  min-height:50px;
+}
+.landing-banner > div:last-child,
+.landing-docs > div:last-child,
+.landing-docs > .col-12 {
   margin-right:0;
 }
 
+.landing-banner > div > *:last-child {
+  margin-bottom:0;
+}
 .landing-banner h1 {
   margin-top:0;
 }
-.landing-docs {
-  clear:left;
+.landing-docs,
+.landing-banner {
+  clear:both;
   overflow:hidden;
 }
 .landing-docs h3 {
@@ -4839,6 +4887,32 @@
 
 
 
+.next-docs {
+  border-top:1px solid #ccc;
+  margin:40px 0 0;
+  padding:5px 0 0;
+  clear:left;
+  overflow:hidden;
+}
+.next-docs div:first-child {
+  margin-left:0;
+}
+.next-docs div:last-child {
+  margin-right:0;
+}
+
+.next-docs h2 {
+  font-size:14px;
+  line-height:21px;
+  color:#555;
+  text-transform:uppercase;
+  border-bottom:none;
+  margin:0 0 1em;
+  padding:5px 0 0;
+}
+
+
+
 /************* HOME/LANDING PAGE *****************/
 
 .slideshow-home {
diff --git a/tools/droiddoc/templates-sdk/assets/css/resourcecards.css b/tools/droiddoc/templates-sdk/assets/css/resourcecards.css
new file mode 100644
index 0000000..1222b04
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/css/resourcecards.css
@@ -0,0 +1,371 @@
+/* content layout */
+.resource-widget.resource-flow-layout {
+  display: inline-block;
+  margin-right: -20px;
+  /* clearfix idiom */ }
+  .resource-widget.resource-flow-layout.col-1 {
+    width: 60px; }
+  .resource-widget.resource-flow-layout.col-2 {
+    width: 120px; }
+  .resource-widget.resource-flow-layout.col-3 {
+    width: 180px; }
+  .resource-widget.resource-flow-layout.col-4 {
+    width: 240px; }
+  .resource-widget.resource-flow-layout.col-5 {
+    width: 300px; }
+  .resource-widget.resource-flow-layout.col-6 {
+    width: 360px; }
+  .resource-widget.resource-flow-layout.col-7 {
+    width: 420px; }
+  .resource-widget.resource-flow-layout.col-8 {
+    width: 480px; }
+  .resource-widget.resource-flow-layout.col-9 {
+    width: 540px; }
+  .resource-widget.resource-flow-layout.col-10 {
+    width: 600px; }
+  .resource-widget.resource-flow-layout.col-11 {
+    width: 660px; }
+  .resource-widget.resource-flow-layout.col-12 {
+    width: 720px; }
+  .resource-widget.resource-flow-layout.col-13 {
+    width: 780px; }
+  .resource-widget.resource-flow-layout.col-14 {
+    width: 840px; }
+  .resource-widget.resource-flow-layout.col-15 {
+    width: 900px; }
+  .resource-widget.resource-flow-layout.col-16 {
+    width: 960px; }
+  .resource-widget.resource-flow-layout:after {
+    content: ".";
+    display: block;
+    height: 0;
+    clear: both;
+    visibility: hidden; }
+  * html .resource-widget.resource-flow-layout {
+    height: 1px; }
+
+.resource-card {
+  /* stuff that applies to all cards */
+  display: -webkit-flex;
+  -webkit-transform: translateZ(0);
+  float: left;
+  position: relative;
+  margin-right: 20px;
+  margin-bottom: 20px;
+  background-color: #fff;
+  border-radius: 2px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
+  opacity: 0.8;
+  overflow: hidden;
+  transition: 0.4s box-shadow ease, 0.4s opacity ease;
+  /* card templates */
+  /* specific cards and customizations */ }
+  .resource-card .photo {
+    position: relative;
+    background-color: #eee;
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: 50% 50%; }
+  .resource-card.nophoto .photo:after {
+    content: '';
+    display: block;
+    position: absolute;
+    left: 20px;
+    top: 20px;
+    right: 20px;
+    bottom: 20px;
+    opacity: 0.2;
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: contain; }
+  .resource-card .icon {
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: contain;
+    opacity: 0;
+    transition: 0.4s ease; }
+  .resource-card:hover .icon {
+    opacity: 0.2; }
+  .resource-card:hover {
+    opacity: 1;
+    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.5); }
+  .resource-card.resource-card-youtube.nophoto .photo:after, .resource-card.resource-card-youtube .icon {
+    background-image: url(../images/card_video.png); }
+  .resource-card.resource-card-samples.nophoto .photo:after, .resource-card.resource-card-samples .icon {
+    background-image: url(../images/card_sample.png); }
+  .resource-card.resource-card-blog.nophoto .photo:after, .resource-card.resource-card-blog .icon {
+    background-image: url(../images/card_post.png); }
+  .resource-card.resource-card-training.nophoto .photo:after, .resource-card.resource-card-training .icon {
+    background-image: url(../images/card_training.png); }
+  .resource-card .resource-card-text {
+    color: #333333; }
+  .resource-card .title {
+    /*font-weight: 700;*/
+    font-family: 'Roboto Condensed'; }
+  .resource-card .subtitle {
+    font-family: 'Roboto Condensed';
+    text-transform: uppercase;
+    opacity: 0.3; }
+  .resource-card .abstract {
+    font-weight: 300;
+    font-family: 'Roboto'; }
+  .resource-card.resource-card-12x7 {
+    width: 700px;
+    height: 400px;
+    -webkit-flex-direction: column; }
+    .resource-card.resource-card-12x7 .photo {
+      -webkit-flex: 1 1 auto;
+      border-bottom: 1px solid #ddd; }
+    .resource-card.resource-card-12x7 .resource-card-text {
+      margin: 20px;
+      padding-right: 88px; }
+    .resource-card.resource-card-12x7 .icon {
+      position: absolute;
+      right: 20px;
+      bottom: 20px;
+      width: 48px;
+      height: 48px; }
+    .resource-card.resource-card-12x7 .title {
+      font-size: 36px;
+      line-height: 35px;
+      max-height: 70px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical; }
+    .resource-card.resource-card-12x7 .subtitle {
+      font-size: 18px;
+      line-height: 20px;
+      max-height: 20px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 1;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      margin-top: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-12x7:hover .subtitle {
+      margin-top: 10px;
+      max-height: 20px; }
+    .resource-card.resource-card-12x7 .abstract {
+      font-size: 18px;
+      margin-top: 0;
+      line-height: 25px;
+      max-height: 75px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 3;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-12x7:hover .abstract {
+      margin-top: 20px;
+      max-height: 75px; }
+  .resource-card.resource-card-8x6 {
+    width: 460px;
+    height: 340px;
+    -webkit-flex-direction: column; }
+    .resource-card.resource-card-8x6 .photo {
+      -webkit-flex: 1 1 auto;
+      border-bottom: 1px solid #ddd; }
+    .resource-card.resource-card-8x6 .resource-card-text {
+      margin: 20px;
+      padding-right: 88px; }
+    .resource-card.resource-card-8x6 .icon {
+      position: absolute;
+      right: 20px;
+      bottom: 20px;
+      width: 48px;
+      height: 48px; }
+    .resource-card.resource-card-8x6 .title {
+      font-size: 36px;
+      line-height: 35px;
+      max-height: 70px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical; }
+    .resource-card.resource-card-8x6 .subtitle {
+      font-size: 18px;
+      line-height: 20px;
+      max-height: 20px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 1;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      margin-top: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-8x6:hover .subtitle {
+      margin-top: 10px;
+      max-height: 20px; }
+    .resource-card.resource-card-8x6 .abstract {
+      font-size: 18px;
+      margin-top: 0;
+      line-height: 25px;
+      max-height: 75px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 3;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-8x6:hover .abstract {
+      margin-top: 20px;
+      max-height: 75px; }
+    .resource-card.resource-card-8x6 .icon {
+      width: 32px;
+      height: 32px; }
+    .resource-card.resource-card-8x6 .title {
+      font-size: 24px;
+      line-height: 25px;
+      max-height: 50px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical; }
+    .resource-card.resource-card-8x6 .abstract {
+      font-size: 16px;
+      margin-top: 10px;
+      line-height: 20px;
+      max-height: 60px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 3;
+      -webkit-box-orient: vertical; }
+    .resource-card.resource-card-8x6 .subtitle {
+      font-size: 16px;
+      line-height: 20px;
+      max-height: 20px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 1;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      margin-top: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-8x6:hover .subtitle {
+      margin-top: 10px;
+      max-height: 20px; }
+    .resource-card.resource-card-8x6 .abstract {
+      font-size: 16px;
+      margin-top: 0;
+      line-height: 20px;
+      max-height: 60px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 3;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-8x6:hover .abstract {
+      margin-top: 10px;
+      max-height: 60px; }
+  .resource-card.resource-card-6x4 {
+    width: 340px;
+    height: 220px;
+    -webkit-flex-direction: column; }
+    .resource-card.resource-card-6x4 .photo {
+      -webkit-flex: 1 1 auto;
+      border-bottom: 1px solid #ddd; }
+    .resource-card.resource-card-6x4 .resource-card-text {
+      margin: 10px;
+      padding-right: 26px; }
+    .resource-card.resource-card-6x4 .icon {
+      position: absolute;
+      right: 10px;
+      bottom: 10px;
+      width: 16px;
+      height: 16px; }
+    .resource-card.resource-card-6x4 .title {
+      font-size: 16px;
+      line-height: 20px;
+      max-height: 40px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical; }
+    .resource-card.resource-card-6x4 .subtitle {
+      font-size: 13px;
+      line-height: 15px;
+      max-height: 30px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      margin-top: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-6x4:hover .subtitle {
+      max-height: 30px; }
+    .resource-card.resource-card-6x4 .abstract {
+      display: none; }
+    .resource-card.resource-card-6x4 .abstract {
+      font-size: 13px;
+      margin-top: 0;
+      line-height: 15px;
+      max-height: 30px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      display: block;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-6x4:hover .abstract {
+      margin-top: 10px;
+      max-height: 30px; }
+  .resource-card.resource-card-4x3 {
+    width: 220px;
+    height: 160px;
+    -webkit-flex-direction: column; }
+    .resource-card.resource-card-4x3 .photo {
+      -webkit-flex: 1 1 auto;
+      border-bottom: 1px solid #ddd; }
+    .resource-card.resource-card-4x3 .resource-card-text {
+      margin: 10px;
+      padding-right: 26px; }
+    .resource-card.resource-card-4x3 .icon {
+      position: absolute;
+      right: 10px;
+      bottom: 10px;
+      width: 16px;
+      height: 16px; }
+    .resource-card.resource-card-4x3 .title {
+      font-size: 16px;
+      line-height: 20px;
+      max-height: 40px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical; }
+    .resource-card.resource-card-4x3 .subtitle {
+      font-size: 13px;
+      line-height: 15px;
+      max-height: 30px;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      overflow: hidden;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+      max-height: 0;
+      margin-top: 0;
+      transition: 0.4s ease; }
+    .resource-card.resource-card-4x3:hover .subtitle {
+      max-height: 30px; }
+    .resource-card.resource-card-4x3 .abstract {
+      display: none; }
diff --git a/tools/droiddoc/templates-sdk/assets/images/card_post.png b/tools/droiddoc/templates-sdk/assets/images/card_post.png
new file mode 100644
index 0000000..e061ee9
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/card_post.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/card_sample.png b/tools/droiddoc/templates-sdk/assets/images/card_sample.png
new file mode 100644
index 0000000..3dc36e0
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/card_sample.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/card_training.png b/tools/droiddoc/templates-sdk/assets/images/card_training.png
new file mode 100644
index 0000000..5bb7c81
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/card_training.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/card_video.png b/tools/droiddoc/templates-sdk/assets/images/card_video.png
new file mode 100644
index 0000000..807c0af
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/card_video.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/js/docs.js b/tools/droiddoc/templates-sdk/assets/js/docs.js
index 1996dac..6630bf9 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -23,7 +23,7 @@
 $(document).ready(function() {
 
   // load json file for JD doc search suggestions
-  $.getScript(toRoot + 'reference/jd_lists.js');
+  $.getScript(toRoot + 'jd_lists_unified.js');
   // load json file for Android API search suggestions
   $.getScript(toRoot + 'reference/lists.js');
   // load json files for Google services API suggestions
@@ -1539,6 +1539,13 @@
     $link.attr('href',toroot + match.link);
 }
 
+function set_item_values_jd(toroot, $li, match)
+{
+    var $link = $('a',$li);
+    $link.html(match.title);
+    $link.attr('href',toroot + match.url);
+}
+
 function new_suggestion($list) {
     var $li = $("<li class='jd-autocomplete'></li>");
     $list.append($li);
@@ -1615,6 +1622,9 @@
         $(".search_filtered_wrapper.docs li").remove();
 
         // determine google results to show
+        // NOTE: The order of the conditions below for the sugg.type MUST BE SPECIFIC:
+        // The order must match the reverse order that each section appears as a card in
+        // the suggestion UI... this may be only for the "develop" grouped items though.
         gDocsListLength = gDocsMatches.length < ROW_COUNT_DOCS ? gDocsMatches.length : ROW_COUNT_DOCS;
         for (i=0; i<gDocsListLength; i++) {
             var sugg = gDocsMatches[i];
@@ -1625,16 +1635,19 @@
             if (sugg.type == "distribute") {
                 $li = new_suggestion($(".suggest-card.distribute ul"));
             } else
+            if (sugg.type == "samples") {
+                $li = new_suggestion($(".suggest-card.develop .child-card.samples"));
+            } else
             if (sugg.type == "training") {
                 $li = new_suggestion($(".suggest-card.develop .child-card.training"));
             } else
-            if (sugg.type == "guide"||"google") {
+            if (sugg.type == "about"||"guide"||"tools"||"google") {
                 $li = new_suggestion($(".suggest-card.develop .child-card.guides"));
             } else {
               continue;
             }
 
-            set_item_values(toroot, $li, sugg);
+            set_item_values_jd(toroot, $li, sugg);
             set_item_selected($li, i == gSelectedIndex);
         }
 
@@ -1659,6 +1672,10 @@
           $(".child-card.training").prepend("<li class='header'>Training:</li>");
           $(".child-card.training li").appendTo(".suggest-card.develop ul");
         }
+        if ($(".child-card.samples li").length > 0) {
+          $(".child-card.samples").prepend("<li class='header'>Samples:</li>");
+          $(".child-card.samples li").appendTo(".suggest-card.develop ul");
+        }
 
         if ($(".suggest-card.develop li").length > 0) {
           $(".suggest-card.develop").show(300);
@@ -1681,6 +1698,7 @@
   */
 function search_changed(e, kd, toroot)
 {
+    var currentLang = getLangPref();
     var search = document.getElementById("search_autocomplete");
     var text = search.value.replace(/(^ +)|( +$)/g, '');
     // get the ul hosting the currently selected item
@@ -1794,8 +1812,8 @@
       }
     }
 
-    // if key-up event and not arrow down/up,
-    // read the search query and add suggestsions to gMatches
+    // if key-up event and not arrow down/up/left/right,
+    // read the search query and add suggestions to gMatches
     else if (!kd && (e.keyCode != 40)
                  && (e.keyCode != 38)
                  && (e.keyCode != 37)
@@ -1841,31 +1859,35 @@
 
 
 
-        // Search for JD docs
+        // Search for matching JD docs
         if (text.length >= 3) {
-          for (var i=0; i<JD_DATA.length; i++) {
-            // Regex to match only the beginning of a word
-            var textRegex = new RegExp("\\b" + text.toLowerCase(), "g");
+          // Regex to match only the beginning of a word
+          var textRegex = new RegExp("\\b" + text.toLowerCase(), "g");
+
+
+          // Search for Training classes
+          for (var i=0; i<TRAINING_RESOURCES.length; i++) {
             // current search comparison, with counters for tag and title,
             // used later to improve ranking
-            var s = JD_DATA[i];
+            var s = TRAINING_RESOURCES[i];
             s.matched_tag = 0;
             s.matched_title = 0;
             var matched = false;
 
             // Check if query matches any tags; work backwards toward 1 to assist ranking
-            for (var j = s.tags.length - 1; j >= 0; j--) {
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
               // it matches a tag
-              if (s.tags[j].toLowerCase().match(textRegex)) {
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
                 matched = true;
                 s.matched_tag = j + 1; // add 1 to index position
               }
             }
-            // Don't consider doc title for lessons (only for class landing pages)
-            // ...it is not a training lesson (or is but has matched a tag)
-            if (!(s.type == "training" && s.link.indexOf("index.html") == -1) || matched) {
+            // Don't consider doc title for lessons (only for class landing pages),
+            // unless the lesson has a tag that already matches
+            if ((s.lang == currentLang) &&
+                  (!(s.type == "training" && s.url.indexOf("index.html") == -1) || matched)) {
               // it matches the doc title
-              if (s.label.toLowerCase().match(textRegex)) {
+              if (s.title.toLowerCase().match(textRegex)) {
                 matched = true;
                 s.matched_title = 1;
               }
@@ -1875,6 +1897,231 @@
               matchedCountDocs++;
             }
           }
+
+
+          // Search for API Guides
+          for (var i=0; i<GUIDE_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = GUIDE_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+
+          // Search for Tools Guides
+          for (var i=0; i<TOOLS_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = TOOLS_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+
+          // Search for About docs
+          for (var i=0; i<ABOUT_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = ABOUT_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+
+          // Search for Design guides
+          for (var i=0; i<DESIGN_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = DESIGN_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+
+          // Search for Distribute guides
+          for (var i=0; i<DISTRIBUTE_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = DISTRIBUTE_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+
+          // Search for Google guides
+          for (var i=0; i<GOOGLE_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = GOOGLE_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+
+          // Search for Samples
+          for (var i=0; i<SAMPLES_RESOURCES.length; i++) {
+            // current search comparison, with counters for tag and title,
+            // used later to improve ranking
+            var s = SAMPLES_RESOURCES[i];
+            s.matched_tag = 0;
+            s.matched_title = 0;
+            var matched = false;
+            // Check if query matches any tags; work backwards toward 1 to assist ranking
+            for (var j = s.keywords.length - 1; j >= 0; j--) {
+              // it matches a tag
+              if (s.keywords[j].toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_tag = j + 1; // add 1 to index position
+              }
+            }
+            // Check if query matches the doc title, but only for current language
+            if (s.lang == currentLang) {
+              // if query matches the doc title.t
+              if (s.title.toLowerCase().match(textRegex)) {
+                matched = true;
+                s.matched_title = 1;
+              }
+            }
+            if (matched) {
+              gDocsMatches[matchedCountDocs] = s;
+              matchedCountDocs++;
+            }
+          }
+
+          // Rank/sort all the matched pages
           rank_autocomplete_doc_results(text, gDocsMatches);
         }
 
diff --git a/tools/droiddoc/templates-sdk/assets/js/jd_tag_helpers.js b/tools/droiddoc/templates-sdk/assets/js/jd_tag_helpers.js
new file mode 100644
index 0000000..d179cbc
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/js/jd_tag_helpers.js
@@ -0,0 +1,106 @@
+function mergeArrays() {
+  var arr = arguments[0] || [];
+  for (var i = 1; i < arguments.length; i++) {
+    arr = arr.concat(arguments[i]);
+  }
+  return arr;
+}
+
+var ALL_RESOURCES = mergeArrays(
+  DESIGN_RESOURCES,
+  DISTRIBUTE_RESOURCES,
+  GOOGLE_RESOURCES,
+  GUIDE_RESOURCES,
+  SAMPLES_RESOURCES,
+  TOOLS_RESOURCES,
+  TRAINING_RESOURCES,
+  YOUTUBE_RESOURCES,
+  BLOGGER_RESOURCES
+);
+
+for (var i = 0; i < ALL_RESOURCES.length; i++) {
+  ALL_RESOURCES[i].index = i;
+}
+
+function mergeMaps() {
+  var allRes = {};
+  var offset = 0;
+
+  for (var i = 0; i < arguments.length; i++) {
+    var r = arguments[i];
+    for (var tag in r.map) {
+      allRes[tag] = allRes[tag] || [];
+      allRes[tag] = allRes[tag].concat(r.map[tag].map(function(i){ return ALL_RESOURCES[i + offset]; }));
+    }
+    offset += r.arr.length;
+  }
+
+  return allRes;
+}
+
+function setFromArray(arr) {
+  arr = arr || [];
+  var set = {};
+  for (var i = 0; i < arr.length; i++) {
+    set[arr[i]] = true;
+  }
+  return set;
+}
+
+function buildResourceLookupMap(resourceDict) {
+  var map = {};
+  for (var key in resourceDict) {
+    var dictForKey = {};
+    var srcArr = resourceDict[key];
+    for (var i = 0; i < srcArr.length; i++) {
+      dictForKey[srcArr[i].index] = true;
+    }
+    map[key] = dictForKey;
+  }
+  return map;
+}
+
+// Type lookups
+
+var ALL_RESOURCES_BY_TYPE = {
+  'design': DESIGN_RESOURCES,
+  'distribute': DISTRIBUTE_RESOURCES,
+  'google': GOOGLE_RESOURCES,
+  'guide': GUIDE_RESOURCES,
+  'samples': SAMPLES_RESOURCES,
+  'tools': TOOLS_RESOURCES,
+  'training': TRAINING_RESOURCES,
+  'youtube': YOUTUBE_RESOURCES,
+  'blog': BLOGGER_RESOURCES
+};
+var IS_RESOURCE_OF_TYPE = buildResourceLookupMap(ALL_RESOURCES_BY_TYPE);
+
+// Tag lookups
+
+var ALL_RESOURCES_BY_TAG = mergeMaps(
+  {map:DESIGN_BY_TAG,arr:DESIGN_RESOURCES},
+  {map:DISTRIBUTE_BY_TAG,arr:DISTRIBUTE_RESOURCES},
+  {map:GOOGLE_BY_TAG,arr:GOOGLE_RESOURCES},
+  {map:GUIDE_BY_TAG,arr:GUIDE_RESOURCES},
+  {map:SAMPLES_BY_TAG,arr:SAMPLES_RESOURCES},
+  {map:TOOLS_BY_TAG,arr:TOOLS_RESOURCES},
+  {map:TRAINING_BY_TAG,arr:TRAINING_RESOURCES},
+  {map:YOUTUBE_BY_TAG,arr:YOUTUBE_RESOURCES},
+  {map:BLOGGER_BY_TAG,arr:BLOGGER_RESOURCES}
+);
+var IS_RESOURCE_TAGGED = buildResourceLookupMap(ALL_RESOURCES_BY_TAG);
+
+// Language lookups
+
+var ALL_RESOURCES_BY_LANG = {};
+for (var i = 0; i < ALL_RESOURCES.length; i++) {
+  var res = ALL_RESOURCES[i];
+  var lang = res.lang;
+  if (!lang) {
+    continue;
+  }
+
+  ALL_RESOURCES_BY_LANG[lang] = ALL_RESOURCES_BY_LANG[lang] || [];
+  ALL_RESOURCES_BY_LANG[lang].push(res);
+}
+var IS_RESOURCE_IN_LANG = buildResourceLookupMap(ALL_RESOURCES_BY_LANG);
\ No newline at end of file
diff --git a/tools/droiddoc/templates-sdk/assets/js/resourcecards.js b/tools/droiddoc/templates-sdk/assets/js/resourcecards.js
new file mode 100644
index 0000000..fbba201
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/js/resourcecards.js
@@ -0,0 +1,244 @@
+// Requires jd_tag_helpers.js and the data JS to be loaded.
+
+$(document).ready(function() {
+  $('.resource-widget').each(function() {
+    initResourceWidget(this);
+  });
+});
+
+
+function initResourceWidget(widget) {
+  var $widget = $(widget);
+  var isFlow, isCarousel;
+  isFlow = $widget.hasClass('resource-flow-layout');
+  if (!isFlow) {
+    isCarousel = $widget.hasClass('resource-carousel-layout');
+  }
+
+  // find size of widget by pulling out its class name
+  var sizeCols = 1;
+  var m = $widget.get(0).className.match(/\bcol-(\d+)\b/);
+  if (m) {
+    sizeCols = parseInt(m[1], 10);
+  }
+
+  var opts = {
+    source: $widget.data('source'),
+    cardSizes: ($widget.data('cardsizes') || '').split(','),
+    maxResults: parseInt($widget.data('maxresults') || '100'),
+    itemsPerPage: $widget.data('itemsperpage'),
+    sortOrder: $widget.data('sortorder'),
+    query: $widget.data('query'),
+    collectionId: $widget.data('collectionid'),
+    sizeCols: sizeCols
+  };
+
+  // run the search for the set of resources to show
+  var resources = buildResourceList(opts);
+
+  if (isFlow) {
+    drawResourcesFlowWidget($widget, opts, resources);
+  }
+}
+
+
+function drawResourcesFlowWidget($widget, opts, resources) {
+  $widget.empty();
+  var cardSizes = opts.cardSizes || ['4x3'];
+
+  for (var i = 0; i < resources.length; i++) {
+    var resource = resources[i];
+
+    var cardSize = i >= cardSizes.length ? cardSizes[cardSizes.length - 1] : cardSizes[i];
+    cardSize = cardSize.replace(/^\s+|\s+$/,'');
+
+    var $card = $('<a>')
+        .addClass('resource-card resource-card-' + cardSize + ' resource-card-' + resource.type)
+        .attr('href', resource.url);
+
+    $('<img>')
+        .addClass('photo')
+        .attr('src', resource.image || '')
+        .appendTo($card);
+
+    var subtitle = resource.type;
+    if (resource.timestamp) {
+      var d = new Date(resource.timestamp);
+      // TODO: localize, humanize
+      subtitle = (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear() + ' on ' + subtitle;
+    }
+
+    $('<div>')
+        .addClass('resource-card-text')
+        .append($('<div>').addClass('icon'))
+        .append($('<div>').addClass('title').text(resource.title))
+        .append($('<div>').addClass('subtitle').text(subtitle))
+        .append($('<div>').addClass('abstract').text(resource.summary))
+        .appendTo($card);
+
+    $card.appendTo($widget);
+  }
+
+  $widget.find('.resource-card .photo').each(function() {
+    var src = $(this).attr('src');
+    if (!src) {
+      $(this).parents('.resource-card').addClass('nophoto');
+      $(this).replaceWith($('<div>')
+          .addClass('photo'));
+    } else {
+      $(this).replaceWith($('<div>')
+          .addClass('photo')
+          .css('background-image', 'url(' + $(this).attr('src') + ')'));
+    }
+  });
+}
+
+
+function buildResourceList(opts) {
+  var maxResults = opts.maxResults || 100;
+
+  switch (opts.source) {
+    case 'query':
+      var query = opts.query || '';
+      var expressions = parseResourceQuery(query);
+      var alreadyAddedResources = {};
+      var allResources = [];
+      for (var i = 0; i < expressions.length; i++) {
+        var clauses = expressions[i];
+
+        // build initial set of resources from first clause
+        var firstClause = clauses[0];
+        var resources = [];
+        switch (firstClause.attr) {
+          case 'type':
+            resources = ALL_RESOURCES_BY_TYPE[firstClause.value];
+            break;
+          case 'lang':
+            resources = ALL_RESOURCES_BY_LANG[firstClause.value];
+            break;
+          case 'tag':
+            resources = ALL_RESOURCES_BY_TAG[firstClause.value];
+            break;
+        }
+        resources = resources || [];
+
+        // use additional clauses to filter corpus
+        if (clauses.length > 1) {
+          var otherClauses = clauses.slice(1);
+          resources = resources.filter(getResourceMatchesClausesFilter(otherClauses));
+        }
+
+        // filter out resources already added
+        if (i > 1) {
+          resources = resources.filter(getResourceNotAlreadyAddedFilter(alreadyAddedResources));
+        }
+
+        allResources = allResources.concat(resources);
+        if (allResources.length > maxResults) {
+          break;
+        }
+      }
+      if (opts.sortOrder) {
+        var attr = opts.sortOrder;
+        var desc = attr.charAt(0) == '-';
+        if (desc) {
+          attr = attr.substring(1);
+        }
+        allResources = allResources.sort(function(x,y) {
+          return (desc ? -1 : 1) * (parseInt(x[attr], 10) - parseInt(y[attr], 10));
+        });
+      }
+      return allResources.slice(0, maxResults);
+
+    case 'related':
+      // TODO
+      break;
+
+    case 'collection':
+      // TODO
+      break;
+  }
+}
+
+
+function getResourceNotAlreadyAddedFilter(addedResources) {
+  return function(x) {
+    return !!addedResources[x];
+  };
+}
+
+
+function getResourceMatchesClausesFilter(clauses) {
+  return function(x) {
+    return doesResourceMatchClauses(x, clauses);
+  };
+}
+
+
+function doesResourceMatchClauses(resource, clauses) {
+  for (var i = 0; i < clauses.length; i++) {
+    var map;
+    switch (clauses[i].attr) {
+      case 'type':
+        map = IS_RESOURCE_OF_TYPE[clauses[i].value];
+        break;
+      case 'lang':
+        map = IS_RESOURCE_IN_LANG[clauses[i].value];
+        break;
+      case 'tag':
+        map = IS_RESOURCE_TAGGED[clauses[i].value];
+        break;
+    }
+
+    if (!map || (!!clauses[i].negative ? map[resource.index] : !map[resource.index])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+function parseResourceQuery(query) {
+  // Parse query into array of expressions (expression e.g. 'tag:foo + type:video')
+  var expressions = [];
+  var expressionStrs = query.split(',') || [];
+  for (var i = 0; i < expressionStrs.length; i++) {
+    var expr = expressionStrs[i] || '';
+
+    // Break expression into clauses (clause e.g. 'tag:foo')
+    var clauses = [];
+    var clauseStrs = expr.split(/(?=[\+\-])/);
+    for (var j = 0; j < clauseStrs.length; j++) {
+      var clauseStr = clauseStrs[j] || '';
+
+      // Get attribute and value from clause (e.g. attribute='tag', value='foo')
+      var parts = clauseStr.split(':');
+      var clause = {};
+
+      clause.attr = parts[0].replace(/\s+/g,'');
+      if (clause.attr) {
+        if (clause.attr.charAt(0) == '+') {
+          clause.attr = clause.attr.substring(1);
+        } else if (clause.attr.charAt(0) == '-') {
+          clause.negative = true;
+          clause.attr = clause.attr.substring(1);
+        }
+      }
+
+      if (parts.length > 1) {
+        clause.value = parts[1].replace(/\s+/g,'');
+      }
+
+      clauses.push(clause);
+    }
+
+    if (!clauses.length) {
+      continue;
+    }
+
+    expressions.push(clauses);
+  }
+
+  return expressions;
+}
+
diff --git a/tools/droiddoc/templates-sdk/components/masthead.cs b/tools/droiddoc/templates-sdk/components/masthead.cs
index f3eb401..47639bb 100644
--- a/tools/droiddoc/templates-sdk/components/masthead.cs
+++ b/tools/droiddoc/templates-sdk/components/masthead.cs
@@ -122,6 +122,8 @@
       </div>
       <div class="child-card training no-display">
       </div>
+      <div class="child-card samples no-display">
+      </div>
     </div>
     <div class="suggest-card design no-display">
       <ul class="search_filtered">
@@ -160,7 +162,7 @@
                           ja-lang="トレーニング"
                           es-lang="Capacitación"               
                           >Training</a></li>
-                        <li><a href="<?cs var:toroot ?>guide/components/index.html"
+                        <li><a href="<?cs var:toroot ?>guide/index.html"
                           zh-tw-lang="API 指南"
                           zh-cn-lang="API 指南"
                           ru-lang="Руководства по API"
@@ -231,7 +233,7 @@
                   ja-lang="トレーニング"
                   es-lang="Capacitación"               
                   >Training</a></li>
-                <li class="guide"><a href="<?cs var:toroot ?>guide/components/index.html"
+                <li class="guide"><a href="<?cs var:toroot ?>guide/index.html"
                   zh-tw-lang="API 指南"
                   zh-cn-lang="API 指南"
                   ru-lang="Руководства по API"
diff --git a/tools/droiddoc/templates-sdk/customizations.cs b/tools/droiddoc/templates-sdk/customizations.cs
index d54d371..52b7224 100644
--- a/tools/droiddoc/templates-sdk/customizations.cs
+++ b/tools/droiddoc/templates-sdk/customizations.cs
@@ -144,12 +144,8 @@
 <?cs
         include:"../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
 
-
       </div>
-      <script type="text/javascript">
-       showSamplesRefTree();
 
-      </script>
     </div> <!-- end side-nav -->
     <script>
       $(document).ready(function() {
@@ -251,6 +247,7 @@
 <?cs 
             if:subcount(class.package) ?>
             <ul>
+              <?cs call:list("Annotations", class.package.annotations) ?>
               <?cs call:list("Interfaces", class.package.interfaces) ?>
               <?cs call:list("Classes", class.package.classes) ?>
               <?cs call:list("Enums", class.package.enums) ?>
@@ -259,6 +256,7 @@
             </ul><?cs 
             elif:subcount(package) ?>
             <ul>
+              <?cs call:class_link_list("Annotations", package.annotations) ?>
               <?cs call:class_link_list("Interfaces", package.interfaces) ?>
               <?cs call:class_link_list("Classes", package.classes) ?>
               <?cs call:class_link_list("Enums", package.enums) ?>
diff --git a/tools/droiddoc/templates-sdk/designpage.cs b/tools/droiddoc/templates-sdk/designpage.cs
index c714a74..2be179d 100644
--- a/tools/droiddoc/templates-sdk/designpage.cs
+++ b/tools/droiddoc/templates-sdk/designpage.cs
@@ -95,5 +95,16 @@
     var pageTracker = _gat._getTracker("UA-5831155-1");
     pageTracker._trackPageview();
     </script>
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
   </body>
 </html>
diff --git a/tools/droiddoc/templates-sdk/docpage.cs b/tools/droiddoc/templates-sdk/docpage.cs
index 6faac04..ea462c9 100644
--- a/tools/droiddoc/templates-sdk/docpage.cs
+++ b/tools/droiddoc/templates-sdk/docpage.cs
@@ -13,7 +13,7 @@
 
 <div <?cs if:fullpage
 ?>class="fullpage"<?cs elif:design||tools||about||sdk||distribute
-?>class="col-13" id="doc-col"<?cs else 
+?>class="col-13" id="doc-col"<?cs else
 ?>class="col-12" id="doc-col"<?cs /if ?> >
 
 <?cs if:(design||training||walkthru) && !page.trainingcourse && !page.article ?><?cs # header logic for docs that provide previous/next buttons ?>
@@ -33,7 +33,7 @@
             ru-lang="Предыдущий"
             ko-lang="이전"
             ja-lang="前へ"
-            es-lang="Anterior"               
+            es-lang="Anterior"
             >Previous</a>
         <a href="#" class="next-page-link hide"
             zh-tw-lang="下一堂課"
@@ -41,7 +41,7 @@
             ru-lang="Следующий"
             ko-lang="다음"
             ja-lang="次へ"
-            es-lang="Siguiente"               
+            es-lang="Siguiente"
             >Next</a>
         <a href="#" class="start-class-link hide"
             zh-tw-lang="開始上課"
@@ -49,7 +49,7 @@
             ru-lang="Начало работы"
             ko-lang="시작하기"
             ja-lang="開始する"
-            es-lang="Empezar"               
+            es-lang="Empezar"
             >Get started</a>
       </div>
     <?cs elif:!page.trainingcourse ?>
@@ -60,7 +60,7 @@
             ru-lang="Предыдущий"
             ko-lang="이전"
             ja-lang="前へ"
-            es-lang="Anterior"               
+            es-lang="Anterior"
             >Previous</a>
         <a href="#" class="next-page-link hide"
             zh-tw-lang="下一堂課"
@@ -68,17 +68,26 @@
             ru-lang="Следующий"
             ko-lang="다음"
             ja-lang="次へ"
-            es-lang="Siguiente"               
+            es-lang="Siguiente"
             >Next</a>
       </div>
     <?cs /if ?><?cs # end if training ?>
   </div>
   <?cs /if ?>
+<?cs elif:samplesProjectIndex ?>
+  <div id="api-info-block">
+  <div class="sum-details-links">
+  Overview
+  &#124; <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
+  &#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
+  </div><!-- end sum-details-links -->
+  </div><!-- end breadcurmb block -->
+  <h1 itemprop="name"><?cs var:projectDir ?></h1>
 <?cs else ?>
   <?cs if:(!fullpage && !header.hide) ?>
     <?cs if:page.landing ?><?cs # header logic for docs that are landing pages ?>
       <div class="landing-banner">
-        <?cs if:page.landing.image ?><?cs # use two-column layout only if there's an image ?>
+        <?cs if:page.landing.image ?><?cs # use two-column layout only if there is an image ?>
         <div class="col-6">
           <img src="<?cs var:toroot ?><?cs var:page.landing.image ?>" alt="" />
         </div>
@@ -86,7 +95,7 @@
         <?cs /if ?>
           <h1 itemprop="name" style="margin-bottom:0;"><?cs var:page.title ?></h1>
           <p itemprop="description"><?cs var:page.landing.intro ?></p>
-          
+
           <p><a class="next-page-link topic-start-link"></a></p>
         <?cs if:page.landing.image ?>
         </div>
@@ -115,14 +124,14 @@
     <div class="jd-descr" itemprop="articleBody">
     <?cs call:tag_list(root.descr) ?>
     </div>
-      
-      <div class="content-footer <?cs 
+
+      <div class="content-footer <?cs
                     if:fullpage ?>wrap<?cs
-                    else ?>layout-content-row<?cs /if ?>" 
+                    else ?>layout-content-row<?cs /if ?>"
                     itemscope itemtype="http://schema.org/SiteNavigationElement">
-        <div class="layout-content-col <?cs 
-                    if:fullpage ?>col-16<?cs 
-                    elif:training||guide ?>col-8<?cs 
+        <div class="layout-content-col <?cs
+                    if:fullpage ?>col-16<?cs
+                    elif:training||guide ?>col-8<?cs
                     else ?>col-9<?cs /if ?>" style="padding-top:4px">
           <?cs if:!page.noplus ?><?cs if:fullpage ?><style>#___plusone_0 {float:right !important;}</style><?cs /if ?>
             <div class="g-plusone" data-size="medium"></div>
@@ -137,7 +146,7 @@
                 ru-lang="Предыдущий"
                 ko-lang="이전"
                 ja-lang="前へ"
-                es-lang="Anterior"               
+                es-lang="Anterior"
                 >Previous</a>
             <a href="#" class="next-page-link hide"
                 zh-tw-lang="下一堂課"
@@ -145,13 +154,21 @@
                 ru-lang="Следующий"
                 ko-lang="다음"
                 ja-lang="次へ"
-                es-lang="Siguiente"               
+                es-lang="Siguiente"
                 >Next</a>
+            <a href="#" class="start-class-link hide"
+                zh-tw-lang="開始上課"
+                zh-cn-lang="开始"
+                ru-lang="Начало работы"
+                ko-lang="시작하기"
+                ja-lang="開始する"
+                es-lang="Empezar"
+                >Get started</a>
           <?cs /if ?>
         </div>
         <?cs /if ?>
       </div>
-      
+
       <?cs # for training classes, provide a different kind of link when the next page is a different class ?>
       <?cs if:training && !page.article ?>
       <div class="layout-content-row content-footer next-class" style="display:none" itemscope itemtype="http://schema.org/SiteNavigationElement">
@@ -166,6 +183,16 @@
 
 <?cs include:"trailer.cs" ?>
 
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
 </body>
 </html>
 
diff --git a/tools/droiddoc/templates-sdk/head_tag.cs b/tools/droiddoc/templates-sdk/head_tag.cs
index 379829c..2d4664c 100644
--- a/tools/droiddoc/templates-sdk/head_tag.cs
+++ b/tools/droiddoc/templates-sdk/head_tag.cs
@@ -50,10 +50,18 @@
 /if ?>
 <script type="text/javascript">
   var toRoot = "<?cs var:toroot ?>";
+  var metaTags = [<?cs var:meta.tags ?>];
   var devsite = <?cs if:devsite ?>true<?cs else ?>false<?cs /if ?>;
 </script>
 <script src="<?cs var:toroot ?>assets/js/docs.js" type="text/javascript"></script>
 
+<!-- RESOURCES LIBRARY -->
+<script src="<?cs if:android.whichdoc != 'online' ?>http:<?cs /if ?>//androiddevdocs-staging.appspot.com/ytblogger_lists_unified.js" type="text/javascript"></script>
+<script src="<?cs var:toroot ?>jd_lists_unified.js" type="text/javascript"></script>
+<script src="<?cs var:toroot ?>assets/js/jd_tag_helpers.js" type="text/javascript"></script>
+<link href="<?cs var:toroot ?>assets/css/resourcecards.css"  rel="stylesheet" type="text/css" />
+<script src="<?cs var:toroot ?>assets/js/resourcecards.js" type="text/javascript"></script>
+
 <script type="text/javascript">
   var _gaq = _gaq || [];
   _gaq.push(['_setAccount', 'UA-5831155-1']);
diff --git a/tools/droiddoc/templates-sdk/jd_lists_unified.cs b/tools/droiddoc/templates-sdk/jd_lists_unified.cs
new file mode 100644
index 0000000..417a5c1
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/jd_lists_unified.cs
@@ -0,0 +1 @@
+<?cs var:reference_tree ?>
diff --git a/tools/droiddoc/templates-sdk/package.cs b/tools/droiddoc/templates-sdk/package.cs
index 99eaff2..abd49f1 100644
--- a/tools/droiddoc/templates-sdk/package.cs
+++ b/tools/droiddoc/templates-sdk/package.cs
@@ -45,6 +45,7 @@
   <?cs /if ?>
 <?cs /def ?>
 
+<?cs call:class_table("Annotations", package.annotations) ?>
 <?cs call:class_table("Interfaces", package.interfaces) ?>
 <?cs call:class_table("Classes", package.classes) ?>
 <?cs call:class_table("Enums", package.enums) ?>
diff --git a/tools/droiddoc/templates-sdk/sample.cs b/tools/droiddoc/templates-sdk/sample.cs
index 3fed799..c6f28f8 100644
--- a/tools/droiddoc/templates-sdk/sample.cs
+++ b/tools/droiddoc/templates-sdk/sample.cs
@@ -7,7 +7,7 @@
 
 <div <?cs if:fullpage
 ?>class="fullpage"<?cs elif:design||tools||about||sdk||distribute
-?>class="col-13" id="doc-col"<?cs else 
+?>class="col-13" id="doc-col"<?cs else
 ?>class="col-12" id="doc-col"<?cs /if ?> >
 
 <!-- start breadcrumb block -->
@@ -17,7 +17,9 @@
   <!-- related links -->
   <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/index.html">Overview</a>
   &#124; <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
-  &#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
+  &#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip"
+    onclick="_gaq.push(['_trackEvent', 'Samples', 'Download', <?cs var:projectDir ?>]);"
+    >Download</a>
 
 </div><!-- end sum-details-links -->
 
@@ -27,7 +29,7 @@
 
 <div id="pathCrumb">
 <?cs each:item = parentdirs ?>
-  <?cs if:pathCrumbLinks
+  <?cs if:LinkifyPathCrumb
     ?><a href="<?cs var:toroot ?><?cs var:item.Link ?>"><?cs var:item.Name ?></a> / 
   <?cs else
     ?><?cs var:item.Name ?> / <?cs /if ?>
@@ -50,18 +52,37 @@
 <?cs var:summary ?>
 
 <!-- begin file contents -->
-<div id="codesample-wrapper">
-<pre id="codesample-line-numbers" class="no-pretty-print hidden"></pre>
-<pre id="codesample-block"><?cs var:fileContents ?></pre>
-</div>
+
+<?cs # embed image/videos if below maxsize (show message otherwise), else display source code ?>
+<?cs if:resType == "img" ?>
+  <div id="codesample-resource"
+    <?cs if:noDisplay ?>
+      class="noDisplay"><div class="noDisplay-message"></div>
+    <?cs else ?>
+      ><img src="<?cs var:realFile ?>" title="<?cs var:page.title ?>">
+    <?cs /if ?>
+  </div>
+<?cs elif:resType == "video" ?>
+  <div id="codesample-resource"
+    <?cs if:noDisplay ?>
+      class="noDisplay"><div class="noDisplay-message"></div>
+    <?cs else ?>
+      ><video class="play-on-hover" controls style="border:1px solid #ececec;background-color:#f9f9f9;" poster="">
+        <source src="<?cs var:page.title ?>">
+      </video>
+    <?cs /if ?>
+  </div>
+<?cs else ?>
+  <div id="codesample-wrapper">
+    <pre id="codesample-line-numbers" class="no-pretty-print hidden"></pre>
+    <pre id="codesample-block"><?cs var:fileContents ?></pre>
+  </div>
+  <script type="text/javascript">
+  initCodeLineNumbers();
+  </script>
+<?cs /if ?>
 
 <!-- end file contents -->
-<script type="text/javascript">
-  initCodeLineNumbers();
-</script>
-
-
-
 
 <?cs else ?><?cs
   # else, this means it's offline docs,
@@ -69,6 +90,49 @@
 
 <?cs /if ?><?cs # end if/else online docs ?>
 
+      <div class="content-footer <?cs
+                    if:fullpage ?>wrap<?cs
+                    else ?>layout-content-row<?cs /if ?>"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col <?cs
+                    if:fullpage ?>col-16<?cs
+                    elif:training||guide ?>col-8<?cs
+                    else ?>col-9<?cs /if ?>" style="padding-top:4px">
+          <?cs if:!page.noplus ?><?cs if:fullpage ?><style>#___plusone_0 {float:right !important;}</style><?cs /if ?>
+            <div class="g-plusone" data-size="medium"></div>
+          <?cs /if ?>
+        </div>
+        <?cs if:!fullscreen ?>
+        <div class="paging-links layout-content-col col-4">
+          <?cs if:(design||training||walkthru) && !page.landing && !page.trainingcourse && !footer.hide ?>
+            <a href="#" class="prev-page-link hide"
+                zh-tw-lang="上一堂課"
+                zh-cn-lang="上一课"
+                ru-lang="Предыдущий"
+                ko-lang="이전"
+                ja-lang="前へ"
+                es-lang="Anterior"
+                >Previous</a>
+            <a href="#" class="next-page-link hide"
+                zh-tw-lang="下一堂課"
+                zh-cn-lang="下一课"
+                ru-lang="Следующий"
+                ko-lang="다음"
+                ja-lang="次へ"
+                es-lang="Siguiente"
+                >Next</a>
+          <?cs /if ?>
+        </div>
+        <?cs /if ?>
+      </div>
+
+      <?cs # for training classes, provide a different kind of link when the next page is a different class ?>
+      <?cs if:training && !page.article ?>
+      <div class="layout-content-row content-footer next-class" style="display:none" itemscope itemtype="http://schema.org/SiteNavigationElement">
+          <a href="#" class="next-class-link hide">Next class: </a>
+      </div>
+      <?cs /if ?>
+
   </div> <!-- end jd-content -->
 
 <?cs include:"footer.cs" ?>
diff --git a/tools/droiddoc/templates-sdk/sampleindex.cs b/tools/droiddoc/templates-sdk/sampleindex.cs
index 8db15c4..98767b1 100644
--- a/tools/droiddoc/templates-sdk/sampleindex.cs
+++ b/tools/droiddoc/templates-sdk/sampleindex.cs
@@ -20,7 +20,9 @@
 &#124; Project<?cs else ?>Overview
 &#124; <a href="<?cs var:toroot ?>samples/<?cs var:projectDir ?>/project.html">Project</a>
 <?cs /if ?>
-&#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip">Download</a>
+&#124; <a href="<?cs var:toroot ?>downloads/samples/<?cs var:projectDir ?>.zip"
+    onclick="_gaq.push(['_trackEvent', 'Samples', 'Download', <?cs var:projectDir ?>]);"
+    >Download</a>
 
 </div><!-- end sum-details-links -->
 
@@ -78,6 +80,48 @@
           so don't show src links (we dont have the pages!) ?>
 
 <?cs /if ?><?cs # end if/else online docs ?>
+      <div class="content-footer <?cs
+                    if:fullpage ?>wrap<?cs
+                    else ?>layout-content-row<?cs /if ?>"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col <?cs
+                    if:fullpage ?>col-16<?cs
+                    elif:training||guide ?>col-8<?cs
+                    else ?>col-9<?cs /if ?>" style="padding-top:4px">
+          <?cs if:!page.noplus ?><?cs if:fullpage ?><style>#___plusone_0 {float:right !important;}</style><?cs /if ?>
+            <div class="g-plusone" data-size="medium"></div>
+          <?cs /if ?>
+        </div>
+        <?cs if:!fullscreen ?>
+        <div class="paging-links layout-content-col col-4">
+          <?cs if:(design||training||walkthru) && !page.landing && !page.trainingcourse && !footer.hide ?>
+            <a href="#" class="prev-page-link hide"
+                zh-tw-lang="上一堂課"
+                zh-cn-lang="上一课"
+                ru-lang="Предыдущий"
+                ko-lang="이전"
+                ja-lang="前へ"
+                es-lang="Anterior"
+                >Previous</a>
+            <a href="#" class="next-page-link hide"
+                zh-tw-lang="下一堂課"
+                zh-cn-lang="下一课"
+                ru-lang="Следующий"
+                ko-lang="다음"
+                ja-lang="次へ"
+                es-lang="Siguiente"
+                >Next</a>
+          <?cs /if ?>
+        </div>
+        <?cs /if ?>
+      </div>
+
+      <?cs # for training classes, provide a different kind of link when the next page is a different class ?>
+      <?cs if:training && !page.article ?>
+      <div class="layout-content-row content-footer next-class" style="display:none" itemscope itemtype="http://schema.org/SiteNavigationElement">
+          <a href="#" class="next-class-link hide">Next class: </a>
+      </div>
+      <?cs /if ?>
 
   </div> <!-- end jd-content -->
 
diff --git a/tools/droiddoc/templates-sdk/sdkpage.cs b/tools/droiddoc/templates-sdk/sdkpage.cs
index ecc26f5..d98146a 100644
--- a/tools/droiddoc/templates-sdk/sdkpage.cs
+++ b/tools/droiddoc/templates-sdk/sdkpage.cs
@@ -83,7 +83,7 @@
       <th>MD5 Checksum</th>
   </tr>
   <tr>
-    <td rowspan="2" style="white-space:nowrap">Windows 32-bit</td>
+    <td>Windows 32-bit</td>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.win32_download ?>"><?cs var:ndk.win32_download ?></a>
@@ -91,33 +91,33 @@
     <td><?cs var:ndk.win32_bytes ?></td>
     <td><?cs var:ndk.win32_checksum ?></td>
   </tr>
-  <tr>
-    <td>
+ <!-- <tr>
+   <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.win32.legacy_download ?>"><?cs var:ndk.win32.legacy_download ?></a>
     </td>
     <td><?cs var:ndk.win32.legacy_bytes ?></td>
     <td><?cs var:ndk.win32.legacy_checksum ?></td>
-  </tr>
+  </tr> -->
   <tr>
-    <td rowspan="2" style="white-space:nowrap">Windows 64-bit</td>
+    <td>Windows 64-bit</td>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.win64_download ?>"><?cs var:ndk.win64_download ?></a>
     </td>
     <td><?cs var:ndk.win64_bytes ?></td>
     <td><?cs var:ndk.win64_checksum ?></td>
-  </tr>
-  <tr>
+  </tr> 
+ <!--  <tr>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.win64.legacy_download ?>"><?cs var:ndk.win64.legacy_download ?></a>
     </td>
     <td><?cs var:ndk.win64.legacy_bytes ?></td>
     <td><?cs var:ndk.win64.legacy_checksum ?></td>
-  </tr>
+  </tr> -->
   <tr>
-    <td rowspan="2" style="white-space:nowrap">Mac OS X 32-bit</td>
+    <td>Mac OS X 32-bit</td>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.mac32_download ?>"><?cs var:ndk.mac32_download ?></a>
@@ -125,16 +125,15 @@
     <td><?cs var:ndk.mac32_bytes ?></td>
     <td><?cs var:ndk.mac32_checksum ?></td>
   </tr>
-  <tr>
+ <!--  <tr>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.mac32.legacy_download ?>"><?cs var:ndk.mac32.legacy_download ?></a>
     </td>
     <td><?cs var:ndk.mac32.legacy_bytes ?></td>
     <td><?cs var:ndk.mac32.legacy_checksum ?></td>
-  </tr>
-  <tr>
-    <td rowspan="2"  style="white-space:nowrap">Mac OS X 64-bit</td>
+  </tr> -->
+    <td>Mac OS X 64-bit</td>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.mac64_download ?>"><?cs var:ndk.mac64_download ?></a>
@@ -142,17 +141,16 @@
     <td><?cs var:ndk.mac64_bytes ?></td>
     <td><?cs var:ndk.mac64_checksum ?></td>
   </tr>
-  <tr>
+ <!--  <tr>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.mac64.legacy_download ?>"><?cs var:ndk.mac64.legacy_download ?></a>
     </td>
     <td><?cs var:ndk.mac64.legacy_bytes ?></td>
     <td><?cs var:ndk.mac64.legacy_checksum ?></td>
-  </tr>
-
+  </tr> -->
   <tr>
-    <td rowspan="2" style="white-space:nowrap">Linux 32-bit (x86)</td>
+    <td>Linux 32-bit (x86)</td>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.linux32_download ?>"><?cs var:ndk.linux32_download ?></a>
@@ -160,16 +158,16 @@
     <td><?cs var:ndk.linux32_bytes ?></td>
     <td><?cs var:ndk.linux32_checksum ?></td>
   </tr>
-  <tr>
+ <!--  <tr>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.linux32.legacy_download ?>"><?cs var:ndk.linux32.legacy_download ?></a>
     </td>
     <td><?cs var:ndk.linux32.legacy_bytes ?></td>
     <td><?cs var:ndk.linux32.legacy_checksum ?></td>
-  </tr>
+  </tr> -->
   <tr>
-    <td rowspan="2" style="white-space:nowrap">Linux 64-bit (x86)</td>
+    <td>Linux 64-bit (x86)</td>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.linux64_download ?>"><?cs var:ndk.linux64_download ?></a>
@@ -177,13 +175,28 @@
     <td><?cs var:ndk.linux64_bytes ?></td>
     <td><?cs var:ndk.linux64_checksum ?></td>
   </tr>
-  <tr>
+  <!--  <tr>
     <td>
   <a onClick="return onDownload(this)"
      href="http://dl.google.com/android/ndk/<?cs var:ndk.linux64.legacy_download ?>"><?cs var:ndk.linux64.legacy_download ?></a>
     </td>
     <td><?cs var:ndk.linux64.legacy_bytes ?></td>
     <td><?cs var:ndk.linux64.legacy_checksum ?></td>
+  </tr> -->
+    <tr>
+      <th>Additional Download</th>
+      <th>Package</th>
+      <th style="white-space:nowrap">Size (Bytes)</th>
+      <th>MD5 Checksum</th>
+  </tr>
+  <tr>
+    <td>STL debug info</td>
+    <td>
+  <a onClick="return onDownload(this)"
+     href="http://dl.google.com/android/ndk/<?cs var:ndk.debug_info_download ?>"><?cs var:ndk.debug_info_download ?></a>
+    </td>
+    <td><?cs var:ndk.debug_info_bytes ?></td>
+    <td><?cs var:ndk.debug_info_checksum ?></td>
   </tr>
   </table>
   
@@ -491,6 +504,7 @@
       $("#sdk-terms-form,.sdk-terms-intro").fadeOut('slow');
       $("#next-steps").fadeIn('slow');
       $("h1#tos-header").text('Get Ready to Code!');
+      _gaq.push(['_trackEvent', 'SDK', 'ADT and Tools', $("#downloadForRealz").html()]);
       return true;
     } else {
       $("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#258AAF"}, 200,
@@ -560,6 +574,16 @@
 
 <?cs include:"trailer.cs" ?>
 
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
 </body>
 </html>
 
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index f8f2ada..ffda6cf 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -24,6 +24,8 @@
 import os.path
 import subprocess
 import sys
+import commands
+import shutil
 
 def RunCommand(cmd):
   """ Echo and run the given command
@@ -38,6 +40,170 @@
   p.communicate()
   return p.returncode
 
+def GetVerityTreeSize(partition_size):
+  cmd = "system/extras/verity/build_verity_tree.py -s %d"
+  cmd %= partition_size
+  status, output = commands.getstatusoutput(cmd)
+  if status:
+    print output
+    return False, 0
+  return True, int(output)
+
+def GetVerityMetadataSize(partition_size):
+  cmd = "system/extras/verity/build_verity_metadata.py -s %d"
+  cmd %= partition_size
+  status, output = commands.getstatusoutput(cmd)
+  if status:
+    print output
+    return False, 0
+  return True, int(output)
+
+def AdjustPartitionSizeForVerity(partition_size):
+  """Modifies the provided partition size to account for the verity metadata.
+
+  This information is used to size the created image appropriately.
+  Args:
+    partition_size: the size of the partition to be verified.
+  Returns:
+    The size of the partition adjusted for verity metadata.
+  """
+  success, verity_tree_size = GetVerityTreeSize(partition_size)
+  if not success:
+    return 0;
+  success, verity_metadata_size = GetVerityMetadataSize(partition_size)
+  if not success:
+    return 0
+  return partition_size - verity_tree_size - verity_metadata_size
+
+def BuildVerityTree(unsparse_image_path, verity_image_path, partition_size, prop_dict):
+  cmd = ("system/extras/verity/build_verity_tree.py %s %s %d" %
+            (unsparse_image_path, verity_image_path, partition_size))
+  print cmd
+  status, output = commands.getstatusoutput(cmd)
+  if status:
+    print "Could not build verity tree! Error: %s" % output
+    return False
+  root, salt = output.split()
+  prop_dict["verity_root_hash"] = root
+  prop_dict["verity_salt"] = salt
+  return True
+
+def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
+                        block_device, signer_path, key):
+  cmd = ("system/extras/verity/build_verity_metadata.py %s %s %s %s %s %s %s" %
+              (image_size,
+              verity_metadata_path,
+              root_hash,
+              salt,
+              block_device,
+              signer_path,
+              key))
+  print cmd
+  status, output = commands.getstatusoutput(cmd)
+  if status:
+    print "Could not build verity metadata! Error: %s" % output
+    return False
+  return True
+
+def Append2Simg(sparse_image_path, unsparse_image_path, error_message):
+  """Appends the unsparse image to the given sparse image.
+
+  Args:
+    sparse_image_path: the path to the (sparse) image
+    unsparse_image_path: the path to the (unsparse) image
+  Returns:
+    True on success, False on failure.
+  """
+  cmd = "append2simg %s %s"
+  cmd %= (sparse_image_path, unsparse_image_path)
+  print cmd
+  status, output = commands.getstatusoutput(cmd)
+  if status:
+    print "%s: %s" % (error_message, output)
+    return False
+  return True
+
+def BuildVerifiedImage(data_image_path, verity_image_path, verity_metadata_path):
+  if not Append2Simg(data_image_path, verity_metadata_path, "Could not append verity metadata!"):
+    return False
+  if not Append2Simg(data_image_path, verity_image_path, "Could not append verity tree!"):
+    return False
+  return True
+
+def UnsparseImage(sparse_image_path, replace=True):
+  img_dir = os.path.dirname(sparse_image_path)
+  unsparse_image_path = "unsparse_" + os.path.basename(sparse_image_path)
+  unsparse_image_path = os.path.join(img_dir, unsparse_image_path)
+  if os.path.exists(unsparse_image_path):
+    if replace:
+      os.unlink(unsparse_image_path)
+    else:
+      return True, unsparse_image_path
+  inflate_command = ["simg2img", sparse_image_path, unsparse_image_path]
+  exit_code = RunCommand(inflate_command)
+  if exit_code != 0:
+    os.remove(unsparse_image_path)
+    return False, None
+  return True, unsparse_image_path
+
+def MakeVerityEnabledImage(out_file, prop_dict):
+  """Creates an image that is verifiable using dm-verity.
+
+  Args:
+    out_file: the location to write the verifiable image at
+    prop_dict: a dictionary of properties required for image creation and verification
+  Returns:
+    True on success, False otherwise.
+  """
+  # get properties
+  image_size = prop_dict["partition_size"]
+  part_size = int(prop_dict["original_partition_size"])
+  block_dev = prop_dict["verity_block_device"]
+  signer_key = prop_dict["verity_key"]
+  signer_path = prop_dict["verity_signer_cmd"]
+
+  # make a tempdir
+  tempdir_name = os.path.join(os.path.dirname(out_file), "verity_images")
+  if os.path.exists(tempdir_name):
+    shutil.rmtree(tempdir_name)
+  os.mkdir(tempdir_name)
+
+  # get partial image paths
+  verity_image_path = os.path.join(tempdir_name, "verity.img")
+  verity_metadata_path = os.path.join(tempdir_name, "verity_metadata.img")
+  success, unsparse_image_path = UnsparseImage(out_file)
+  if not success:
+    shutil.rmtree(tempdir_name)
+    return False
+
+  # build the verity tree and get the root hash and salt
+  if not BuildVerityTree(unsparse_image_path, verity_image_path, part_size, prop_dict):
+    shutil.rmtree(tempdir_name)
+    return False
+
+  # build the metadata blocks
+  root_hash = prop_dict["verity_root_hash"]
+  salt = prop_dict["verity_salt"]
+  if not BuildVerityMetadata(image_size,
+                              verity_metadata_path,
+                              root_hash,
+                              salt,
+                              block_dev,
+                              signer_path,
+                              signer_key):
+    shutil.rmtree(tempdir_name)
+    return False
+
+  # build the full verified image
+  if not BuildVerifiedImage(out_file,
+                            verity_image_path,
+                            verity_metadata_path):
+    shutil.rmtree(tempdir_name)
+    return False
+
+  shutil.rmtree(tempdir_name)
+  return True
+
 def BuildImage(in_dir, prop_dict, out_file):
   """Build an image to out_file from in_dir with property prop_dict.
 
@@ -52,6 +218,16 @@
   build_command = []
   fs_type = prop_dict.get("fs_type", "")
   run_fsck = False
+
+  # adjust the partition size to make room for the hashes if this is to be verified
+  if prop_dict.get("verity") == "true":
+    partition_size = int(prop_dict.get("partition_size"))
+    adjusted_size = AdjustPartitionSizeForVerity(partition_size)
+    if not adjusted_size:
+      return False
+    prop_dict["partition_size"] = str(adjusted_size)
+    prop_dict["original_partition_size"] = str(partition_size)
+
   if fs_type.startswith("ext"):
     build_command = ["mkuserimg.sh"]
     if "extfs_sparse_flag" in prop_dict:
@@ -59,8 +235,9 @@
       run_fsck = True
     build_command.extend([in_dir, out_file, fs_type,
                           prop_dict["mount_point"]])
-    if "partition_size" in prop_dict:
-      build_command.append(prop_dict["partition_size"])
+    build_command.append(prop_dict["partition_size"])
+    if "timestamp" in prop_dict:
+      build_command.extend(["-T", str(prop_dict["timestamp"])])
     if "selinux_fc" in prop_dict:
       build_command.append(prop_dict["selinux_fc"])
   else:
@@ -77,14 +254,14 @@
   if exit_code != 0:
     return False
 
+  # create the verified image if this is to be verified
+  if prop_dict.get("verity") == "true":
+    if not MakeVerityEnabledImage(out_file, prop_dict):
+      return False
+
   if run_fsck and prop_dict.get("skip_fsck") != "true":
-    # Inflate the sparse image
-    unsparse_image = os.path.join(
-        os.path.dirname(out_file), "unsparse_" + os.path.basename(out_file))
-    inflate_command = ["simg2img", out_file, unsparse_image]
-    exit_code = RunCommand(inflate_command)
-    if exit_code != 0:
-      os.remove(unsparse_image)
+    success, unsparse_image = UnsparseImage(out_file, replace=False)
+    if not success:
       return False
 
     # Run e2fsck on the inflated image file
@@ -104,6 +281,10 @@
     mount_point: such as "system", "data" etc.
   """
   d = {}
+  if "build.prop" in glob_dict:
+    bp = glob_dict["build.prop"]
+    if "ro.build.date.utc" in bp:
+      d["timestamp"] = bp["ro.build.date.utc"]
 
   def copy_prop(src_p, dest_p):
     if src_p in glob_dict:
@@ -114,6 +295,10 @@
       "mkyaffs2_extra_flags",
       "selinux_fc",
       "skip_fsck",
+      "verity",
+      "verity_block_device",
+      "verity_key",
+      "verity_signer_cmd"
       )
   for p in common_props:
     copy_prop(p, p)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index f179717..d0d57a9 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -756,6 +756,7 @@
           if x == ".py":
             f = b
           info = imp.find_module(f, [d])
+        print "loaded device-specific extensions from", path
         self.module = imp.load_module("device_specific", *info)
       except ImportError:
         print "unable to load device-specific module; assuming none"
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 189672c..426b713 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -188,6 +188,15 @@
     """Moves a file from one location to another."""
     if self.info.get("update_rename_support", False):
       self.script.append('rename("%s", "%s");' % (srcfile, tgtfile))
+    else:
+      raise ValueError("Rename not supported by update binary")
+
+  def SkipNextActionIfTargetExists(self, tgtfile, tgtsha1):
+    """Prepend an action with an apply_patch_check in order to
+       skip the action if the file exists.  Used when a patch
+       is later renamed."""
+    cmd = ('sha1_check(read_file("%s"), %s) || ' % (tgtfile, tgtsha1))
+    self.script.append(self._WordWrap(cmd))
 
   def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
     """Apply binary patches (in *patchpairs) to the given srcfile to
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index b7e6613..1174075 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -52,6 +52,11 @@
   -a  (--aslr_mode)  <on|off>
       Specify whether to turn on ASLR for the package (on by default).
 
+  -2  (--two_step)
+      Generate a 'two-step' OTA package, where recovery is updated
+      first, so that any changes made to the system partition are done
+      using the new recovery (new kernel, etc.).
+
 """
 
 import sys
@@ -88,6 +93,7 @@
 OPTIONS.extra_script = None
 OPTIONS.aslr_mode = True
 OPTIONS.worker_threads = 3
+OPTIONS.two_step = False
 OPTIONS.no_signing = False
 
 def MostPopularKey(d, default):
@@ -430,6 +436,46 @@
 
   AppendAssertions(script, OPTIONS.info_dict)
   device_specific.FullOTA_Assertions()
+
+  # Two-step package strategy (in chronological order, which is *not*
+  # the order in which the generated script has things):
+  #
+  # if stage is not "2/3" or "3/3":
+  #    write recovery image to boot partition
+  #    set stage to "2/3"
+  #    reboot to boot partition and restart recovery
+  # else if stage is "2/3":
+  #    write recovery image to recovery partition
+  #    set stage to "3/3"
+  #    reboot to recovery partition and restart recovery
+  # else:
+  #    (stage must be "3/3")
+  #    set stage to ""
+  #    do normal full package installation:
+  #       wipe and install system, boot image, etc.
+  #       set up system to update recovery partition on first boot
+  #    complete script normally (allow recovery to mark itself finished and reboot)
+
+  recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
+                                         OPTIONS.input_tmp, "RECOVERY")
+  if OPTIONS.two_step:
+    if not OPTIONS.info_dict.get("multistage_support", None):
+      assert False, "two-step packages not supported by this build"
+    fs = OPTIONS.info_dict["fstab"]["/misc"]
+    assert fs.fs_type.upper() == "EMMC", \
+        "two-step packages only supported on devices with EMMC /misc partitions"
+    bcb_dev = {"bcb_dev": fs.device}
+    common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
+    script.AppendExtra("""
+if get_stage("%(bcb_dev)s", "stage") == "2/3" then
+""" % bcb_dev)
+    script.WriteRawImage("/recovery", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "3/3");
+reboot_now("%(bcb_dev)s", "recovery");
+else if get_stage("%(bcb_dev)s", "stage") == "3/3" then
+""" % bcb_dev)
+
   device_specific.FullOTA_InstallBegin()
 
   script.ShowProgress(0.5, 0)
@@ -450,8 +496,6 @@
 
   boot_img = common.GetBootableImage("boot.img", "boot.img",
                                      OPTIONS.input_tmp, "BOOT")
-  recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
-                                         OPTIONS.input_tmp, "RECOVERY")
   MakeRecoveryPatch(OPTIONS.input_tmp, output_zip, recovery_img, boot_img)
 
   Item.GetMetadata(input_zip)
@@ -471,6 +515,19 @@
     script.AppendExtra(OPTIONS.extra_script)
 
   script.UnmountAll()
+
+  if OPTIONS.two_step:
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "");
+""" % bcb_dev)
+    script.AppendExtra("else\n")
+    script.WriteRawImage("/boot", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "2/3");
+reboot_now("%(bcb_dev)s", "");
+endif;
+endif;
+""" % bcb_dev)
   script.AddToZip(input_zip, output_zip)
   WriteMetadata(metadata, output_zip)
 
@@ -505,6 +562,16 @@
   except KeyError:
     raise common.ExternalError("couldn't find %s in build.prop" % (property,))
 
+def AddToKnownPaths(filename, known_paths):
+  if filename[-1] == "/":
+    return
+  dirs = filename.split("/")[:-1]
+  while len(dirs) > 0:
+    path = "/".join(dirs)
+    if path in known_paths:
+      break;
+    known_paths.add(path)
+    dirs.pop()
 
 def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
   source_version = OPTIONS.source_info_dict["recovery_api_version"]
@@ -541,14 +608,16 @@
   patch_list = []
   diffs = []
   renames = {}
+  known_paths = set()
   largest_source_size = 0
 
   matching_file_cache = {}
-  for fn in source_data.keys():
-    sf = source_data[fn]
+  for fn, sf in source_data.items():
     assert fn == sf.name
     matching_file_cache["path:" + fn] = sf
-    # Only allow eligability for filename/sha matching
+    if fn in target_data.keys():
+      AddToKnownPaths(fn, known_paths)
+    # Only allow eligibility for filename/sha matching
     # if there isn't a perfect path match.
     if target_data.get(sf.name) is None:
       matching_file_cache["file:" + fn.split("/")[-1]] = sf
@@ -569,6 +638,8 @@
       print "send", fn, "verbatim"
       tf.AddToZip(output_zip)
       verbatim_targets.append((fn, tf.size))
+      if fn in target_data.keys():
+        AddToKnownPaths(fn, known_paths)
     elif tf.sha1 != sf.sha1:
       # File is different; consider sending as a patch
       diffs.append(common.Difference(tf, sf))
@@ -580,13 +651,20 @@
 
   for diff in diffs:
     tf, sf, d = diff.GetPatch()
-    if d is None or len(d) > tf.size * OPTIONS.patch_threshold:
+    path = "/".join(tf.name.split("/")[:-1])
+    if d is None or len(d) > tf.size * OPTIONS.patch_threshold or \
+        path not in known_paths:
       # patch is almost as big as the file; don't bother patching
+      # or a patch + rename cannot take place due to the target 
+      # directory not existing
       tf.AddToZip(output_zip)
       verbatim_targets.append((tf.name, tf.size))
+      if sf.name in renames:
+        del renames[sf.name]
+      AddToKnownPaths(tf.name, known_paths)
     else:
       common.ZipWriteStr(output_zip, "patch/" + sf.name + ".p", d)
-      patch_list.append((sf.name, tf, sf, tf.size, common.sha1(d).hexdigest()))
+      patch_list.append((tf, sf, tf.size, common.sha1(d).hexdigest()))
       largest_source_size = max(largest_source_size, sf.size)
 
   source_fp = GetBuildProp("ro.build.fingerprint", OPTIONS.source_info_dict)
@@ -602,7 +680,8 @@
       OPTIONS.source_info_dict)
   target_boot = common.GetBootableImage(
       "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT")
-  updating_boot = (source_boot.data != target_boot.data)
+  updating_boot = (not OPTIONS.two_step and
+                   (source_boot.data != target_boot.data))
 
   source_recovery = common.GetBootableImage(
       "/tmp/recovery.img", "recovery.img", OPTIONS.source_tmp, "RECOVERY",
@@ -620,18 +699,60 @@
   AppendAssertions(script, OPTIONS.target_info_dict)
   device_specific.IncrementalOTA_Assertions()
 
+  # Two-step incremental package strategy (in chronological order,
+  # which is *not* the order in which the generated script has
+  # things):
+  #
+  # if stage is not "2/3" or "3/3":
+  #    do verification on current system
+  #    write recovery image to boot partition
+  #    set stage to "2/3"
+  #    reboot to boot partition and restart recovery
+  # else if stage is "2/3":
+  #    write recovery image to recovery partition
+  #    set stage to "3/3"
+  #    reboot to recovery partition and restart recovery
+  # else:
+  #    (stage must be "3/3")
+  #    perform update:
+  #       patch system files, etc.
+  #       force full install of new boot image
+  #       set up system to update recovery partition on first boot
+  #    complete script normally (allow recovery to mark itself finished and reboot)
+
+  if OPTIONS.two_step:
+    if not OPTIONS.info_dict.get("multistage_support", None):
+      assert False, "two-step packages not supported by this build"
+    fs = OPTIONS.info_dict["fstab"]["/misc"]
+    assert fs.fs_type.upper() == "EMMC", \
+        "two-step packages only supported on devices with EMMC /misc partitions"
+    bcb_dev = {"bcb_dev": fs.device}
+    common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
+    script.AppendExtra("""
+if get_stage("%(bcb_dev)s", "stage") == "2/3" then
+""" % bcb_dev)
+    script.AppendExtra("sleep(20);\n");
+    script.WriteRawImage("/recovery", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "3/3");
+reboot_now("%(bcb_dev)s", "recovery");
+else if get_stage("%(bcb_dev)s", "stage") != "3/3" then
+""" % bcb_dev)
+
   script.Print("Verifying current system...")
 
   device_specific.IncrementalOTA_VerifyBegin()
 
   script.ShowProgress(0.1, 0)
-  total_verify_size = float(sum([i[2].size for i in patch_list]) + 1)
+  total_verify_size = float(sum([i[1].size for i in patch_list]) + 1)
   if updating_boot:
     total_verify_size += source_boot.size
   so_far = 0
 
-  for fn, tf, sf, size, patch_sha in patch_list:
-    script.PatchCheck("/"+fn, tf.sha1, sf.sha1)
+  for tf, sf, size, patch_sha in patch_list:
+    if tf.name != sf.name:
+      script.SkipNextActionIfTargetExists(tf.name, tf.sha1)
+    script.PatchCheck("/"+sf.name, tf.sha1, sf.sha1)
     so_far += sf.size
     script.SetProgress(so_far / total_verify_size)
 
@@ -657,10 +778,23 @@
 
   device_specific.IncrementalOTA_VerifyEnd()
 
+  if OPTIONS.two_step:
+    script.WriteRawImage("/boot", "recovery.img")
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "2/3");
+reboot_now("%(bcb_dev)s", "");
+else
+""" % bcb_dev)
+
   script.Comment("---- start making changes here ----")
 
   device_specific.IncrementalOTA_InstallBegin()
 
+  if OPTIONS.two_step:
+    common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
+    script.WriteRawImage("/boot", "boot.img")
+    print "writing full boot image (forced by two-step mode)"
+
   if OPTIONS.wipe_user_data:
     script.Print("Erasing user data...")
     script.FormatPartition("/data")
@@ -681,31 +815,34 @@
   script.Print("Patching system files...")
   deferred_patch_list = []
   for item in patch_list:
-    fn, tf, sf, size, _ = item
+    tf, sf, size, _ = item
     if tf.name == "system/build.prop":
       deferred_patch_list.append(item)
       continue
-    script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1, sf.sha1, "patch/"+fn+".p")
+    if (sf.name != tf.name):
+      script.SkipNextActionIfTargetExists(tf.name, tf.sha1)
+    script.ApplyPatch("/"+sf.name, "-", tf.size, tf.sha1, sf.sha1, "patch/"+sf.name+".p")
     so_far += tf.size
     script.SetProgress(so_far / total_patch_size)
 
-  if updating_boot:
-    # Produce the boot image by applying a patch to the current
-    # contents of the boot partition, and write it back to the
-    # partition.
-    script.Print("Patching boot image...")
-    script.ApplyPatch("%s:%s:%d:%s:%d:%s"
-                      % (boot_type, boot_device,
-                         source_boot.size, source_boot.sha1,
-                         target_boot.size, target_boot.sha1),
-                      "-",
-                      target_boot.size, target_boot.sha1,
-                      source_boot.sha1, "patch/boot.img.p")
-    so_far += target_boot.size
-    script.SetProgress(so_far / total_patch_size)
-    print "boot image changed; including."
-  else:
-    print "boot image unchanged; skipping."
+  if not OPTIONS.two_step:
+    if updating_boot:
+      # Produce the boot image by applying a patch to the current
+      # contents of the boot partition, and write it back to the
+      # partition.
+      script.Print("Patching boot image...")
+      script.ApplyPatch("%s:%s:%d:%s:%d:%s"
+                        % (boot_type, boot_device,
+                           source_boot.size, source_boot.sha1,
+                           target_boot.size, target_boot.sha1),
+                        "-",
+                        target_boot.size, target_boot.sha1,
+                        source_boot.sha1, "patch/boot.img.p")
+      so_far += target_boot.size
+      script.SetProgress(so_far / total_patch_size)
+      print "boot image changed; including."
+    else:
+      print "boot image unchanged; skipping."
 
   if updating_recovery:
     # Recovery is generated as a patch using both the boot image
@@ -793,10 +930,17 @@
   # get set the OTA package again to retry.
   script.Print("Patching remaining system files...")
   for item in deferred_patch_list:
-    fn, tf, sf, size, _ = item
-    script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1, sf.sha1, "patch/"+fn+".p")
+    tf, sf, size, _ = item
+    script.ApplyPatch("/"+sf.name, "-", tf.size, tf.sha1, sf.sha1, "patch/"+sf.name+".p")
   script.SetPermissions("/system/build.prop", 0, 0, 0644, None, None)
 
+  if OPTIONS.two_step:
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "");
+endif;
+endif;
+""" % bcb_dev)
+
   script.AddToZip(target_zip, output_zip)
   WriteMetadata(metadata, output_zip)
 
@@ -823,6 +967,8 @@
         OPTIONS.aslr_mode = False
     elif o in ("--worker_threads"):
       OPTIONS.worker_threads = int(a)
+    elif o in ("-2", "--two_step"):
+      OPTIONS.two_step = True
     elif o in ("--no_signing"):
       OPTIONS.no_signing = True
     else:
@@ -830,7 +976,7 @@
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:k:i:d:wne:a:",
+                             extra_opts="b:k:i:d:wne:a:2",
                              extra_long_opts=["board_config=",
                                               "package_key=",
                                               "incremental_from=",
@@ -839,6 +985,7 @@
                                               "extra_script=",
                                               "worker_threads=",
                                               "aslr_mode=",
+                                              "two_step",
                                               "no_signing",
                                               ],
                              extra_option_handler=option_handler)
@@ -868,11 +1015,23 @@
     print "--- target info ---"
     common.DumpInfoDict(OPTIONS.info_dict)
 
+  # If the caller explicitly specified the device-specific extensions
+  # path via -s/--device_specific, use that.  Otherwise, use
+  # META/releasetools.py if it is present in the target target_files.
+  # Otherwise, take the path of the file from 'tool_extensions' in the
+  # info dict and look for that in the local filesystem, relative to
+  # the current directory.
+
   if OPTIONS.device_specific is None:
-    OPTIONS.device_specific = OPTIONS.info_dict.get("tool_extensions", None)
+    from_input = os.path.join(OPTIONS.input_tmp, "META", "releasetools.py")
+    if os.path.exists(from_input):
+      print "(using device-specific extensions from target_files)"
+      OPTIONS.device_specific = from_input
+    else:
+      OPTIONS.device_specific = OPTIONS.info_dict.get("tool_extensions", None)
+
   if OPTIONS.device_specific is not None:
-    OPTIONS.device_specific = os.path.normpath(OPTIONS.device_specific)
-    print "using device-specific extensions in", OPTIONS.device_specific
+    OPTIONS.device_specific = os.path.abspath(OPTIONS.device_specific)
 
   if OPTIONS.no_signing:
     output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)