Merge "Signapk.java: hide the password"
diff --git a/.gitignore b/.gitignore
index 0d20b64..c9b568f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 *.pyc
+*.swp
diff --git a/CleanSpec.mk b/CleanSpec.mk
index dae2b35..5b18d44 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/*)
@@ -211,11 +217,34 @@
 # 4.4.2
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
+# "L" and beyond.
+# Make libart the default runtime
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+
 # Rename persist.sys.dalvik.vm.lib to allow new default
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
+# KKWT development
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# L development
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# L development
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
 # Add ro.product.cpu.abilist{32,64} to build.prop.
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+
+# Unset TARGET_PREFER_32_BIT_APPS for 64 bit targets.
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
 # Adding dalvik.vm.dex2oat-flags to eng builds
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
@@ -236,9 +265,70 @@
 # Switching to 32-bit-by-default host multilib build
 $(call add-clean-step, rm -rf $(HOST_OUT_INTERMEDIATES))
 
+# KKWT has become API 20
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# ims-common.jar added to BOOTCLASSPATH
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/ETC/init.environ.rc_intermediates)
+
 # Change ro.zygote for core_64_bit.mk from zygote32_64 to zygote64_32
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
+
+# Adding dalvik.vm.dex2oat-Xms, dalvik.vm.dex2oat-Xmx
+# dalvik.vm.image-dex2oat-Xms, and dalvik.vm.image-dex2oat-Xmx
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system)
+
+# Switch host builds to Clang by default
+$(call add-clean-step, rm -rf $(OUT_DIR)/host)
+
+# Adding dalvik.vm.dex2oat-filter
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
+
+# API 21?
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# API 21!
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# API 22!
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# Move to libc++ as the default STL.
+$(call add-clean-step, rm -rf $(OUT_DIR))
+
+# dex2oat instruction-set changes
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
+
+# Make GNU++11 the default standard version. This requires a cleanspec because
+# char16_t/char32_t will be real types now instead of typedefs, which means
+# an ABI change since the names will mangle differently.
+$(call add-clean-step, rm -rf $(OUT_DIR))
+
+# 5.1!
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# Remove ro.product.locale.language/country and add ro.product.locale
+# instead.
+$(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 853bd44..5fb366a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -22,7 +22,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.
@@ -109,7 +109,7 @@
 build_desc := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT) $(PLATFORM_VERSION) $(BUILD_ID) $(BUILD_NUMBER) $(BUILD_VERSION_TAGS)
 $(INSTALLED_BUILD_PROP_TARGET): PRIVATE_BUILD_DESC := $(build_desc)
 
-# The string used to uniquely identify this build;  used by the OTA server.
+# The string used to uniquely identify the combined build and product; used by the OTA server.
 ifeq (,$(strip $(BUILD_FINGERPRINT)))
   ifneq ($(filter eng.%,$(BUILD_NUMBER)),)
     # Trim down BUILD_FINGERPRINT: the default BUILD_NUMBER makes it easily exceed
@@ -124,6 +124,22 @@
   $(error BUILD_FINGERPRINT cannot contain spaces: "$(BUILD_FINGERPRINT)")
 endif
 
+# The string used to uniquely identify the system build; used by the OTA server.
+# This purposefully excludes any product-specific variables.
+ifeq (,$(strip $(BUILD_THUMBPRINT)))
+  BUILD_THUMBPRINT := $(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
+endif
+ifneq ($(words $(BUILD_THUMBPRINT)),1)
+  $(error BUILD_THUMBPRINT cannot contain spaces: "$(BUILD_THUMBPRINT)")
+endif
+
+KNOWN_OEM_THUMBPRINT_PROPERTIES := \
+    ro.product.brand \
+    ro.product.name \
+    ro.product.device
+OEM_THUMBPRINT_PROPERTIES := $(filter $(KNOWN_OEM_THUMBPRINT_PROPERTIES),\
+    $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES))
+
 # Display parameters shown under Settings -> About Phone
 ifeq ($(TARGET_BUILD_VARIANT),user)
   # User builds should show:
@@ -140,29 +156,12 @@
   BUILD_DISPLAY_ID := $(build_desc)
 endif
 
-# Whether there is default locale set in PRODUCT_PROPERTY_OVERRIDES
-product_property_override_locale_language := $(strip \
-    $(patsubst ro.product.locale.language=%,%,\
-    $(filter ro.product.locale.language=%,$(PRODUCT_PROPERTY_OVERRIDES))))
-product_property_overrides_locale_region := $(strip \
-    $(patsubst ro.product.locale.region=%,%,\
-    $(filter ro.product.locale.region=%,$(PRODUCT_PROPERTY_OVERRIDES))))
-
-# Selects the first locale in the list given as the argument,
-# and splits it into language and region, which each may be
-# empty.
-define default-locale
-$(subst _, , $(firstword $(1)))
-endef
-
-# Selects the first locale in the list given as the argument
-# and returns the language (or the region), if it's not set in PRODUCT_PROPERTY_OVERRIDES;
-# Return empty string if it's already set in PRODUCT_PROPERTY_OVERRIDES.
-define default-locale-language
-$(if $(product_property_override_locale_language),,$(word 1, $(call default-locale, $(1))))
-endef
-define default-locale-region
-$(if $(product_property_overrides_locale_region),,$(word 2, $(call default-locale, $(1))))
+# Accepts a whitespace separated list of product locales such as
+# (en_US en_AU en_GB...) and returns the first locale in the list with
+# underscores replaced with hyphens. In the example above, this will
+# return "en-US".
+define get-default-product-locale
+$(strip $(subst _,-, $(firstword $(1))))
 endef
 
 BUILDINFO_SH := build/tools/buildinfo.sh
@@ -172,16 +171,23 @@
 else
 system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
 endif
-
-$(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file)
+$(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET)
 	@echo Target buildinfo: $@
 	@mkdir -p $(dir $@)
+	$(hide) echo > $@
+ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES),)
+	$(hide) echo "#" >> $@; \
+	        echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
+	        echo "#" >> $@;
+	$(hide) $(foreach prop,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES), \
+		echo "import /oem/oem.prop $(prop)" >> $@;)
+endif
 	$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
+			TARGET_BUILD_FLAVOR="$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)" \
 			TARGET_DEVICE="$(TARGET_DEVICE)" \
 			PRODUCT_NAME="$(TARGET_PRODUCT)" \
 			PRODUCT_BRAND="$(PRODUCT_BRAND)" \
-			PRODUCT_DEFAULT_LANGUAGE="$(call default-locale-language,$(PRODUCT_LOCALES))" \
-			PRODUCT_DEFAULT_REGION="$(call default-locale-region,$(PRODUCT_LOCALES))" \
+			PRODUCT_DEFAULT_LOCALE="$(call get-default-product-locale,$(PRODUCT_LOCALES))" \
 			PRODUCT_DEFAULT_WIFI_CHANNELS="$(PRODUCT_DEFAULT_WIFI_CHANNELS)" \
 			PRODUCT_MODEL="$(PRODUCT_MODEL)" \
 			PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
@@ -192,9 +198,11 @@
 			PLATFORM_VERSION="$(PLATFORM_VERSION)" \
 			PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
 			PLATFORM_VERSION_CODENAME="$(PLATFORM_VERSION_CODENAME)" \
+			PLATFORM_VERSION_ALL_CODENAMES="$(PLATFORM_VERSION_ALL_CODENAMES)" \
 			BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
 			TARGET_BOOTLOADER_BOARD_NAME="$(TARGET_BOOTLOADER_BOARD_NAME)" \
 			BUILD_FINGERPRINT="$(BUILD_FINGERPRINT)" \
+			$(if $(OEM_THUMBPRINT_PROPERTIES),BUILD_THUMBPRINT="$(BUILD_THUMBPRINT)") \
 			TARGET_BOARD_PLATFORM="$(TARGET_BOARD_PLATFORM)" \
 			TARGET_CPU_ABI_LIST="$(TARGET_CPU_ABI_LIST)" \
 			TARGET_CPU_ABI_LIST_32_BIT="$(TARGET_CPU_ABI_LIST_32_BIT)" \
@@ -202,7 +210,7 @@
 			TARGET_CPU_ABI="$(TARGET_CPU_ABI)" \
 			TARGET_CPU_ABI2="$(TARGET_CPU_ABI2)" \
 			TARGET_AAPT_CHARACTERISTICS="$(TARGET_AAPT_CHARACTERISTICS)" \
-	        bash $(BUILDINFO_SH) > $@
+	        bash $(BUILDINFO_SH) >> $@
 	$(hide) $(foreach file,$(system_prop_file), \
 		if [ -f "$(file)" ]; then \
 			echo "#" >> $@; \
@@ -218,11 +226,43 @@
 		        echo "#" >> $@; )
 	$(hide) $(foreach line,$(ADDITIONAL_BUILD_PROPERTIES), \
 		echo "$(line)" >> $@;)
-	$(hide) build/tools/post_process_props.py $@
+	$(hide) cat $(INSTALLED_ANDROID_INFO_TXT_TARGET) | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >> $@
+	$(hide) build/tools/post_process_props.py $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_PROPERTY_BLACKLIST)
 
 build_desc :=
 
 # -----------------------------------------------------------------
+# vendor build.prop
+#
+# For verifying that the vendor build is what we thing it is
+ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
+INSTALLED_VENDOR_BUILD_PROP_TARGET := $(TARGET_OUT_VENDOR)/build.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_VENDOR_BUILD_PROP_TARGET)
+$(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(INSTALLED_BUILD_PROP_TARGET)
+	@echo Target vendor buildinfo: $@
+	@mkdir -p $(dir $@)
+	$(hide) echo > $@
+	$(hide) echo ro.vendor.build.date=`date`>>$@
+	$(hide) echo ro.vendor.build.date.utc=`date +%s`>>$@
+	$(hide) echo ro.vendor.build.fingerprint="$(BUILD_FINGERPRINT)">>$@
+endif
+
+# ----------------------------------------------------------------
+# boot.img build.prop
+# as with vendor build.prop above, for verifying that the bootimage
+# build is what we think it is
+
+INSTALLED_BOOTIMAGE_BUILD_PROP_TARGET := $(TARGET_ROOT_OUT)/build.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_BOOTIMAGE_BUILD_PROP_TARGET)
+$(INSTALLED_BOOTIMAGE_BUILD_PROP_TARGET): $(INSTALLED_BUILD_PROP_TARGET)
+	@echo Target bootimage buildinfo: $@
+	@mkdir -p $(dir $@)
+	$(hide) echo > $@
+	$(hide) echo ro.bootimage.build.date=`date`>>$@
+	$(hide) echo ro.bootimage.build.date.utc=`date +%s`>>$@
+	$(hide) echo ro.bootimage.build.fingerprint="$(BUILD_FINGERPRINT)">>$@
+
+# -----------------------------------------------------------------
 # sdk-build.prop
 #
 # There are certain things in build.prop that we don't want to
@@ -447,30 +487,34 @@
 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
 
 ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
-tmp_dir_for_image := $(call intermediates-dir-for,EXECUTABLES,boot_img)/bootimg
-INTERNAL_BOOTIMAGE_ARGS += --tmpdir $(tmp_dir_for_image)
-INTERNAL_BOOTIMAGE_ARGS += --genext2fs $(MKEXT2IMG)
-$(INSTALLED_BOOTIMAGE_TARGET): $(MKEXT2IMG) $(INTERNAL_BOOTIMAGE_FILES)
+$(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore)
+else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)) # TARGET_BOOTIMAGE_USE_EXT2 != true
+
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER)
 	$(call pretty,"Target boot image: $@")
-	$(hide) $(MKEXT2BOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
+	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
+	$(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $@
+	$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
 
 .PHONY: bootimage-nodeps
-bootimage-nodeps: $(MKEXT2IMG)
+bootimage-nodeps: $(MKBOOTIMG) $(BOOT_SIGNER)
 	@echo "make $@: ignoring dependencies"
-	$(hide) $(MKEXT2BOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
+	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
+	$(BOOT_SIGNER) /boot $(INSTALLED_BOOTIMAGE_TARGET) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(INSTALLED_BOOTIMAGE_TARGET)
+	$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
 
-else # TARGET_BOOTIMAGE_USE_EXT2 != true
+else # PRODUCT_SUPPORTS_VERITY != true
 
 $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)
 	$(call pretty,"Target boot image: $@")
 	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
-	$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
+	$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
 
 .PHONY: bootimage-nodeps
 bootimage-nodeps: $(MKBOOTIMG)
 	@echo "make $@: ignoring dependencies"
 	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
-	$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw)
+	$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
 
 endif # TARGET_BOOTIMAGE_USE_EXT2
 
@@ -618,17 +662,35 @@
 endif
 endif
 
+# These options tell the recovery updater/installer how to mount the partitions writebale.
+# <fstype>=<fstype_opts>[|<fstype_opts>]...
+# fstype_opts := <opt>[,<opt>]...
+#         opt := <name>[=<value>]
+# The following worked on Nexus devices with Kernel 3.1, 3.4, 3.10
+DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS := ext4=max_batch_time=0,commit=1,data=ordered,barrier=1,errors=panic,nodelalloc
+
 ifneq (true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED))
   INTERNAL_USERIMAGES_SPARSE_EXT_FLAG := -s
 endif
 
 ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
-INTERNAL_USERIMAGES_DEPS := $(MKEXTUSERIMG) $(MAKE_EXT4FS) $(SIMG2IMG) $(E2FSCK)
-else
-INTERNAL_USERIMAGES_DEPS := $(MKYAFFS2)
+INTERNAL_USERIMAGES_DEPS := $(SIMG2IMG)
+INTERNAL_USERIMAGES_DEPS += $(MKEXTUSERIMG) $(MAKE_EXT4FS) $(E2FSCK)
+ifeq ($(TARGET_USERIMAGES_USE_F2FS),true)
+INTERNAL_USERIMAGES_DEPS += $(MKF2FSUSERIMG) $(MAKE_F2FS)
 endif
+endif
+
+ifeq ($(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs)
+INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG)
+endif
+
 INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
 
+ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY))
+INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER)
+endif
+
 SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts
 INTERNAL_USERIMAGES_DEPS += $(SELINUX_FC)
 
@@ -637,14 +699,24 @@
 define generate-userimage-prop-dictionary
 $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
+$(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
+$(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
 $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
 $(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
 $(if $(BOARD_VENDORIMAGE_PARTITION_SIZE),$(hide) echo "vendor_size=$(BOARD_VENDORIMAGE_PARTITION_SIZE)" >> $(1))
+$(if $(BOARD_VENDORIMAGE_JOURNAL_SIZE),$(hide) echo "vendor_journal_size=$(BOARD_VENDORIMAGE_JOURNAL_SIZE)" >> $(1))
+$(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
+$(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
 $(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1))
-$(if $(mkyaffs2_extra_flags),$(hide) echo "mkyaffs2_extra_flags=$(mkyaffs2_extra_flags)" >> $(1))
 $(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_signer_cmd=$(VERITY_SIGNER)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1))
 $(if $(2),$(hide) $(foreach kv,$(2),echo "$(kv)" >> $(1);))
 endef
 
@@ -661,14 +733,31 @@
 recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system
 recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img
 recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET)
-recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery)/recovery
+recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery,,,$(TARGET_PREFER_32_BIT))/recovery
 recovery_resources_common := $(call include-path-for, recovery)/res
 
-# Select the 18x32 font on high-density devices; and the 12x22 font on
-# other devices.  Note that the font selected here can be overridden
-# for a particular device by putting a font.png in its private
-# recovery resources.
-ifneq (,$(filter xxhdpi xhdpi,$(subst $(comma),$(space),$(PRODUCT_AAPT_CONFIG))))
+# Set recovery_density to the density bucket of the device.
+recovery_density := unknown
+ifneq (,$(PRODUCT_AAPT_PREF_CONFIG))
+# If PRODUCT_AAPT_PREF_CONFIG includes a dpi bucket, then use that value.
+recovery_density := $(filter %dpi,$(PRODUCT_AAPT_PREF_CONFIG))
+else
+# Otherwise, use the default medium density.
+recovery_densities := mdpi
+endif
+
+ifneq (,$(wildcard $(recovery_resources_common)-$(recovery_density)))
+recovery_resources_common := $(recovery_resources_common)-$(recovery_density)
+else
+recovery_resources_common := $(recovery_resources_common)-xhdpi
+endif
+
+# Select the 18x32 font on high-density devices (xhdpi and up); and
+# the 12x22 font on other devices.  Note that the font selected here
+# can be overridden for a particular device by putting a font.png in
+# its private recovery resources.
+
+ifneq (,$(filter xxxhdpi xxhdpi xhdpi,$(recovery_density)))
 recovery_font := $(call include-path-for, recovery)/fonts/18x32.png
 else
 recovery_font := $(call include-path-for, recovery)/fonts/12x22.png
@@ -728,6 +817,40 @@
 	@mkdir -p $(dir $@)
 	java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) $(extra_keys) > $@
 
+# $(1): output file
+define build-recoveryimage-target
+  @echo ----- Making recovery image ------
+  $(hide) rm -rf $(TARGET_RECOVERY_OUT)
+  $(hide) mkdir -p $(TARGET_RECOVERY_OUT)
+  $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/tmp
+  @echo Copying baseline ramdisk...
+  $(hide) cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+  @echo Modifying ramdisk contents...
+  $(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
+  $(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
+  $(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
+  $(hide) cp -f $(recovery_sepolicy) $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
+  $(hide) -cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/
+  $(hide) cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/
+  $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/res
+  $(hide) rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res/*
+  $(hide) cp -rf $(recovery_resources_common)/* $(TARGET_RECOVERY_ROOT_OUT)/res
+  $(hide) cp -f $(recovery_font) $(TARGET_RECOVERY_ROOT_OUT)/res/images/font.png
+  $(hide) $(foreach item,$(recovery_resources_private), \
+    cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)
+  $(hide) $(foreach item,$(recovery_fstab), \
+    cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)
+  $(hide) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
+  $(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
+          > $(TARGET_RECOVERY_ROOT_OUT)/default.prop
+  $(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
+  $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)
+  $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)),\
+    $(BOOT_SIGNER) /recovery $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1))
+  $(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))
+  @echo ----- Made recovery image: $(1) --------
+endef
+
 $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
 		$(INSTALLED_RAMDISK_TARGET) \
 		$(INSTALLED_BOOTIMAGE_TARGET) \
@@ -737,37 +860,17 @@
 		$(recovery_build_prop) $(recovery_resource_deps) \
 		$(recovery_fstab) \
 		$(RECOVERY_INSTALL_OTA_KEYS)
-	@echo ----- Making recovery image ------
-	$(hide) rm -rf $(TARGET_RECOVERY_OUT)
-	$(hide) mkdir -p $(TARGET_RECOVERY_OUT)
-	$(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/tmp
-	@echo Copying baseline ramdisk...
-	$(hide) cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
-	@echo Modifying ramdisk contents...
-	$(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
-	$(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
-	$(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
-	$(hide) cp -f $(recovery_sepolicy) $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
-	$(hide) -cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/
-	$(hide) cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/
-	$(hide) cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/
-	$(hide) cp -f $(recovery_font) $(TARGET_RECOVERY_ROOT_OUT)/res/images/font.png
-	$(hide) $(foreach item,$(recovery_resources_private), \
-	  cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)
-	$(hide) $(foreach item,$(recovery_fstab), \
-	  cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)
-	$(hide) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
-	$(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
-	        > $(TARGET_RECOVERY_ROOT_OUT)/default.prop
-	$(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
-	$(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
-	$(hide) $(call assert-max-image-size,$@,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE),raw)
-	@echo ----- Made recovery image: $@ --------
+		$(call build-recoveryimage-target, $@)
 
 $(RECOVERY_RESOURCE_ZIP): $(INSTALLED_RECOVERYIMAGE_TARGET)
 	$(hide) mkdir -p $(dir $@)
 	$(hide) find $(TARGET_RECOVERY_ROOT_OUT)/res -type f | sort | zip -0qrj $@ -@
 
+.PHONY: recoveryimage-nodeps
+recoveryimage-nodeps:
+	@echo "make $@: ignoring dependencies"
+	$(call build-recoveryimage-target, $(INSTALLED_RECOVERYIMAGE_TARGET))
+
 else
 INSTALLED_RECOVERYIMAGE_TARGET :=
 RECOVERY_RESOURCE_ZIP :=
@@ -776,16 +879,11 @@
 .PHONY: recoveryimage
 recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET) $(RECOVERY_RESOURCE_ZIP)
 
-ifneq ($(BOARD_NAND_PAGE_SIZE),)
-mkyaffs2_extra_flags := -c $(BOARD_NAND_PAGE_SIZE)
-else
-mkyaffs2_extra_flags :=
+ifeq ($(BOARD_NAND_PAGE_SIZE),)
 BOARD_NAND_PAGE_SIZE := 2048
 endif
 
-ifneq ($(BOARD_NAND_SPARE_SIZE),)
-mkyaffs2_extra_flags += -s $(BOARD_NAND_SPARE_SIZE)
-else
+ifeq ($(BOARD_NAND_SPARE_SIZE),)
 BOARD_NAND_SPARE_SIZE := 64
 endif
 
@@ -805,6 +903,7 @@
     $(PDK_FUSION_SYSIMG_FILES) \
     $(RECOVERY_RESOURCE_ZIP))
 
+
 FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
 # -----------------------------------------------------------------
 # installed file list
@@ -828,14 +927,36 @@
     $(call intermediates-dir-for,PACKAGING,systemimage)
 BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img
 
+# Create symlink /system/vendor to /vendor if necessary.
+ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
+define create-system-vendor-symlink
+$(hide) if [ -d $(TARGET_OUT)/vendor ] && [ ! -h $(TARGET_OUT)/vendor ]; then \
+  echo 'Non-symlink $(TARGET_OUT)/vendor detected!' 1>&2; \
+  echo 'You cannot install files to $(TARGET_OUT)/vendor while building a separate vendor.img!' 1>&2; \
+  exit 1; \
+fi
+$(hide) ln -sf /vendor $(TARGET_OUT)/vendor
+endef
+else
+define create-system-vendor-symlink
+endef
+endif
+
 # $(1): output file
 define build-systemimage-target
   @echo "Target system fs image: $(1)"
+  $(call create-system-vendor-symlink)
   @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)
   $(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)
+      $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) \
+      || ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\
+           du -sm $(TARGET_OUT) 1>&2;\
+           echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
+           mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
+           exit 1 )
 endef
 
 $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
@@ -865,7 +986,7 @@
 $(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH) | $(ACP)
 	@echo "Install system fs image: $@"
 	$(copy-file-to-target)
-	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE),yaffs)
+	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 
 systemimage: $(INSTALLED_SYSTEMIMAGE)
 
@@ -874,7 +995,7 @@
 	            | $(INTERNAL_USERIMAGES_DEPS)
 	@echo "make $@: ignoring dependencies"
 	$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
-	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE),yaffs)
+	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 
 ifneq (,$(filter systemimage-nodeps snod, $(MAKECMDGOALS)))
 ifeq (true,$(WITH_DEXPREOPT))
@@ -885,10 +1006,11 @@
 #######
 ## system tarball
 define build-systemtarball-target
-    $(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
-    $(MKTARBALL) $(FS_GET_STATS) \
-		$(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
-		$(INSTALLED_SYSTEMTARBALL_TARGET)
+  $(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
+  $(call create-system-vendor-symlink)
+  $(MKTARBALL) $(FS_GET_STATS) \
+    $(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
+    $(INSTALLED_SYSTEMTARBALL_TARGET)
 endef
 
 ifndef SYSTEM_TARBALL_FORMAT
@@ -909,11 +1031,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
@@ -930,7 +1047,11 @@
 		$(TARGET_COPY_OUT_SYSTEM) \
 		$(patsubst $(PRODUCT_OUT)/%, %, $(TARGET_OUT_NOTICE_FILES)) \
 		$(addprefix symbols/,$(PDK_SYMBOL_FILES_LIST))
-ifeq (true,$(PLATFORM_ZIP_ADD_JAVA))
+ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
+	$(hide) cd $(dir $@) && zip -qry $(notdir $@) \
+		$(TARGET_COPY_OUT_VENDOR)
+endif
+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),)
@@ -1002,7 +1123,7 @@
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
       $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET)
-  $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -1057,7 +1178,7 @@
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
       $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt $(INSTALLED_CACHEIMAGE_TARGET)
-  $(hide) $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE),yaffs)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -1076,7 +1197,12 @@
 # vendor partition image
 ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
 INTERNAL_VENDORIMAGE_FILES := \
-    $(filter $(TARGET_OUT_VENDOR)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
+    $(filter $(TARGET_OUT_VENDOR)/%,\
+      $(ALL_DEFAULT_INSTALLED_MODULES)\
+      $(ALL_PDK_FUSION_FILES))
+
+# platform.zip depends on $(INTERNAL_VENDORIMAGE_FILES).
+$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_VENDORIMAGE_FILES)
 
 vendorimage_intermediates := \
     $(call intermediates-dir-for,PACKAGING,vendor)
@@ -1090,7 +1216,7 @@
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
       $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET)
-  $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE),yaffs)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -1117,7 +1243,6 @@
 	  $(HOST_OUT_EXECUTABLES)/mkbootfs \
 	  $(HOST_OUT_EXECUTABLES)/mkbootimg \
 	  $(HOST_OUT_EXECUTABLES)/fs_config \
-	  $(HOST_OUT_EXECUTABLES)/mkyaffs2image \
 	  $(HOST_OUT_EXECUTABLES)/zipalign \
 	  $(HOST_OUT_EXECUTABLES)/bsdiff \
 	  $(HOST_OUT_EXECUTABLES)/imgdiff \
@@ -1126,7 +1251,11 @@
 	  $(HOST_OUT_EXECUTABLES)/mkuserimg.sh \
 	  $(HOST_OUT_EXECUTABLES)/make_ext4fs \
 	  $(HOST_OUT_EXECUTABLES)/simg2img \
-	  $(HOST_OUT_EXECUTABLES)/e2fsck
+	  $(HOST_OUT_EXECUTABLES)/e2fsck \
+	  $(HOST_OUT_EXECUTABLES)/build_verity_tree \
+	  $(HOST_OUT_EXECUTABLES)/verity_signer \
+	  $(HOST_OUT_EXECUTABLES)/append2simg \
+	  $(HOST_OUT_EXECUTABLES)/boot_signer
 
 OTATOOLS := $(DISTTOOLS) \
 	  $(HOST_OUT_EXECUTABLES)/aapt
@@ -1162,11 +1291,11 @@
 endef
 
 built_ota_tools := \
-	$(call intermediates-dir-for,EXECUTABLES,applypatch)/applypatch \
-	$(call intermediates-dir-for,EXECUTABLES,applypatch_static)/applypatch_static \
-	$(call intermediates-dir-for,EXECUTABLES,check_prereq)/check_prereq \
-	$(call intermediates-dir-for,EXECUTABLES,sqlite3)/sqlite3 \
-	$(call intermediates-dir-for,EXECUTABLES,updater)/updater
+	$(call intermediates-dir-for,EXECUTABLES,applypatch,,,$(TARGET_PREFER_32_BIT))/applypatch \
+	$(call intermediates-dir-for,EXECUTABLES,applypatch_static,,,$(TARGET_PREFER_32_BIT))/applypatch_static \
+	$(call intermediates-dir-for,EXECUTABLES,check_prereq,,,$(TARGET_PREFER_32_BIT))/check_prereq \
+	$(call intermediates-dir-for,EXECUTABLES,sqlite3,,,$(TARGET_PREFER_32_BIT))/sqlite3 \
+	$(call intermediates-dir-for,EXECUTABLES,updater,,,$(TARGET_PREFER_32_BIT))/updater
 $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_OTA_TOOLS := $(built_ota_tools)
 
 $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_API_VERSION := $(RECOVERY_API_VERSION)
@@ -1273,6 +1402,12 @@
 ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
 	$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
 endif
+ifdef TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS
+	@# TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS can be empty to indicate that nothing but defaults should be used.
+	$(hide) echo "recovery_mount_options=$(TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
+else
+	$(hide) echo "recovery_mount_options=$(DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
+endif
 	$(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(zip_root)/META/misc_info.txt
 ifdef PRODUCT_EXTRA_RECOVERY_KEYS
@@ -1282,18 +1417,30 @@
 	$(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
+	$(hide) echo "blockimgdiff_versions=1,2" >> $(zip_root)/META/misc_info.txt
+ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
+	# OTA scripts are only interested in fingerprint related properties
+	$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
+endif
 	$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
+	$(hide) ./build/tools/releasetools/make_recovery_patch $(zip_root) $(zip_root)
 	@# Zip everything up, preserving symlinks
 	$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
-	@# Run fs_config on all the system, boot ramdisk, and recovery ramdisk files in the zip, and save the output
+	@# Run fs_config on all the system, vendor, boot ramdisk,
+	@# and recovery ramdisk files in the zip, and save the output
 	$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/filesystem_config.txt
+	$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="VENDOR/" } /^VENDOR\// {print "vendor/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/vendor_filesystem_config.txt
 	$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/boot_filesystem_config.txt
 	$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt
 	$(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/*filesystem_config.txt)
+	$(hide) ./build/tools/releasetools/add_img_to_target_files -p $(HOST_OUT) $@
 
 .PHONY: target-files-package
 target-files-package: $(BUILT_TARGET_FILES_PACKAGE)
 
+ifneq ($(filter $(MAKECMDGOALS),target-files-package),)
+$(call dist-for-goals, target-files-package, $(BUILT_TARGET_FILES_PACKAGE))
+endif
 
 ifneq ($(TARGET_PRODUCT),sdk)
 ifeq ($(filter generic%,$(TARGET_DEVICE)),)
@@ -1317,13 +1464,20 @@
 	@echo "Package OTA: $@"
 	$(hide) MKBOOTIMG=$(MKBOOTIMG) \
 	   ./build/tools/releasetools/ota_from_target_files -v \
+	   --block \
 	   -p $(HOST_OUT) \
 	   -k $(KEY_CERT_PAIR) \
+	   $(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
 	   $(BUILT_TARGET_FILES_PACKAGE) $@
 
 .PHONY: otapackage
 otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
 
+endif    # recovery_fstab is defined
+endif    # TARGET_NO_KERNEL != true
+endif    # TARGET_DEVICE != generic*
+endif    # TARGET_PRODUCT != sdk
+
 # -----------------------------------------------------------------
 # The update package
 
@@ -1335,29 +1489,16 @@
 
 INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
 
-ifeq ($(TARGET_RELEASETOOLS_EXTENSIONS),)
-# default to common dir for device vendor
-$(INTERNAL_UPDATE_PACKAGE_TARGET): extensions := $(TARGET_DEVICE_DIR)/../common
-else
-$(INTERNAL_UPDATE_PACKAGE_TARGET): extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)
-endif
-
 $(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
 	@echo "Package: $@"
 	$(hide) MKBOOTIMG=$(MKBOOTIMG) \
 	   ./build/tools/releasetools/img_from_target_files -v \
-	   -s $(extensions) \
 	   -p $(HOST_OUT) \
 	   $(BUILT_TARGET_FILES_PACKAGE) $@
 
 .PHONY: updatepackage
 updatepackage: $(INTERNAL_UPDATE_PACKAGE_TARGET)
 
-endif    # recovery_fstab is defined
-endif    # TARGET_NO_KERNEL != true
-endif    # TARGET_DEVICE != generic*
-endif    # TARGET_PRODUCT != sdk
-
 # -----------------------------------------------------------------
 # A zip of the symbols directory.  Keep the full paths to make it
 # more obvious where these files came from.
@@ -1369,10 +1510,14 @@
 name := $(name)-symbols-$(FILE_NAME_TAG)
 
 SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
+# For apps_only build we'll establish the dependency later in build/core/main.mk.
+ifndef TARGET_BUILD_APPS
 $(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET)
+endif
+$(SYMBOLS_ZIP):
 	@echo "Package symbols: $@"
 	$(hide) rm -rf $@
-	$(hide) mkdir -p $(dir $@)
+	$(hide) mkdir -p $(dir $@) $(TARGET_OUT_UNSTRIPPED)
 	$(hide) zip -qr $@ $(TARGET_OUT_UNSTRIPPED)
 
 # -----------------------------------------------------------------
@@ -1390,7 +1535,7 @@
 	@echo "Package apps: $@"
 	$(hide) rm -rf $@
 	$(hide) mkdir -p $(dir $@)
-	$(hide) zip -qj $@ $(TARGET_OUT_APPS)/* $(TARGET_OUT_APPS_PRIVILEGED)/*
+	$(hide) zip -qj $@ $(TARGET_OUT_APPS)/*/*.apk $(TARGET_OUT_APPS_PRIVILEGED)/*/*.apk
 
 
 #------------------------------------------------------------------
@@ -1402,7 +1547,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
@@ -1418,12 +1563,13 @@
 	@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); \
-		  zip -qd $@ dummy; \
-		  rm $(dir $@)/dummy; \
+		  touch $(dir $@)/zipdummy; \
+		  (cd $(dir $@) && zip -q $(notdir $@) zipdummy); \
+		  zip -qd $@ zipdummy; \
+		  rm $(dir $@)/zipdummy; \
 		fi
 
 endif # TARGET_BUILD_APPS
@@ -1494,7 +1640,6 @@
 ATREE_FILES := \
 	$(ALL_PREBUILT) \
 	$(ALL_COPIED_HEADERS) \
-	$(ALL_GENERATED_SOURCES) \
 	$(ALL_DEFAULT_INSTALLED_MODULES) \
 	$(INSTALLED_RAMDISK_TARGET) \
 	$(ALL_DOCS) \
@@ -1506,7 +1651,6 @@
 
 sdk_atree_files := \
 	$(atree_dir)/sdk.exclude.atree \
-	$(atree_dir)/sdk.atree \
 	$(atree_dir)/sdk-$(HOST_OS)-$(SDK_HOST_ARCH).atree
 
 # development/build/sdk-android-<abi>.atree is used to differentiate
@@ -1517,6 +1661,14 @@
   sdk_atree_files += $(atree_dir)/sdk-android-$(TARGET_CPU_ABI).atree
 endif
 
+ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ATREE_FILES),)
+sdk_atree_files += $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ATREE_FILES)
+else
+sdk_atree_files += $(atree_dir)/sdk.atree
+endif
+
+include $(BUILD_SYSTEM)/sdk_font.mk
+
 deps := \
 	$(target_notice_file_txt) \
 	$(tools_notice_file_txt) \
@@ -1528,9 +1680,10 @@
 	$(INSTALLED_SDK_BUILD_PROP_TARGET) \
 	$(INSTALLED_BUILD_PROP_TARGET) \
 	$(ATREE_FILES) \
-	$(atree_dir)/sdk.atree \
+	$(sdk_atree_files) \
 	$(HOST_OUT_EXECUTABLES)/atree \
-	$(HOST_OUT_EXECUTABLES)/line_endings
+	$(HOST_OUT_EXECUTABLES)/line_endings \
+	$(SDK_FONT_DEPS)
 
 INTERNAL_SDK_TARGET := $(sdk_dir)/$(sdk_name).zip
 $(INTERNAL_SDK_TARGET): PRIVATE_NAME := $(sdk_name)
@@ -1553,6 +1706,7 @@
 	  fi; \
 	done; \
 	if [ $$FAIL ]; then exit 1; fi
+	$(hide) echo $(notdir $(SDK_FONT_DEPS)) | tr " " "\n"  > $(SDK_FONT_TEMP)/fontsInSdk.txt
 	$(hide) ( \
 		ATREE_STRIP="strip -x" \
 		$(HOST_OUT_EXECUTABLES)/atree \
@@ -1568,6 +1722,7 @@
 			-v "TARGET_ARCH=$(TARGET_ARCH)" \
 			-v "TARGET_CPU_ABI=$(TARGET_CPU_ABI)" \
 			-v "DLL_EXTENSION=$(HOST_SHLIB_SUFFIX)" \
+			-v "FONT_OUT=$(SDK_FONT_TEMP)" \
 			-o $(PRIVATE_DIR) && \
 		cp -f $(target_notice_file_txt) \
 				$(PRIVATE_DIR)/system-images/android-$(PLATFORM_VERSION)/$(TARGET_CPU_ABI)/NOTICE.txt && \
@@ -1584,7 +1739,7 @@
 MAIN_SDK_NAME := $(sdk_name)
 MAIN_SDK_DIR  := $(sdk_dir)
 MAIN_SDK_ZIP  := $(INTERNAL_SDK_TARGET)
-ifneq ($(filter win_sdk,$(MAKECMDGOALS)),)
+ifneq ($(filter win_sdk winsdk-tools,$(MAKECMDGOALS)),)
 include $(TOPDIR)development/build/tools/windows_sdk.mk
 endif
 
@@ -1594,11 +1749,11 @@
 INTERNAL_FINDBUGS_HTML_TARGET := $(PRODUCT_OUT)/findbugs.html
 $(INTERNAL_FINDBUGS_XML_TARGET): $(ALL_FINDBUGS_FILES)
 	@echo UnionBugs: $@
-	$(hide) prebuilt/common/findbugs/bin/unionBugs $(ALL_FINDBUGS_FILES) \
+	$(hide) $(FINDBUGS_DIR)/unionBugs $(ALL_FINDBUGS_FILES) \
 	> $@
 $(INTERNAL_FINDBUGS_HTML_TARGET): $(INTERNAL_FINDBUGS_XML_TARGET)
 	@echo ConvertXmlToText: $@
-	$(hide) prebuilt/common/findbugs/bin/convertXmlToText -html:fancy.xsl \
+	$(hide) $(FINDBUGS_DIR)/convertXmlToText -html:fancy.xsl \
 	$(INTERNAL_FINDBUGS_XML_TARGET) > $@
 
 # -----------------------------------------------------------------
@@ -1610,6 +1765,9 @@
 include $(sort $(wildcard $(BUILD_SYSTEM)/tasks/*.mk))
 -include $(sort $(wildcard vendor/*/build/tasks/*.mk))
 -include $(sort $(wildcard device/*/build/tasks/*.mk))
+# Also the project-specific tasks
+-include $(sort $(wildcard vendor/*/*/build/tasks/*.mk))
+-include $(sort $(wildcard device/*/*/build/tasks/*.mk))
 endif
 
 # -----------------------------------------------------------------
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
new file mode 100644
index 0000000..c641b75
--- /dev/null
+++ b/core/android_manifest.mk
@@ -0,0 +1,39 @@
+# Handle AndroidManifest.xmls
+# Input: LOCAL_MANIFEST_FILE, LOCAL_FULL_MANIFEST_FILE, LOCAL_FULL_LIBS_MANIFEST_FILES
+# Output: full_android_manifest
+
+ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
+  LOCAL_MANIFEST_FILE := AndroidManifest.xml
+endif
+ifdef LOCAL_FULL_MANIFEST_FILE
+  full_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
+else
+  full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
+endif
+
+my_full_libs_manifest_files := $(LOCAL_FULL_LIBS_MANIFEST_FILES)
+my_full_libs_manifest_deps := $(LOCAL_FULL_LIBS_MANIFEST_FILES)
+
+# Set up dependency on aar libraries
+ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
+my_full_libs_manifest_deps += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
+  $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/classes.jar)
+my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
+  $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/AndroidManifest.xml)
+
+LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
+  $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
+endif
+
+# Set up rules to merge library manifest files
+ifdef my_full_libs_manifest_files
+main_android_manifest := $(full_android_manifest)
+full_android_manifest := $(intermediates.COMMON)/AndroidManifest.xml
+$(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
+$(full_android_manifest) : $(main_android_manifest) $(my_full_libs_manifest_deps)
+	@echo "Merge android manifest files: $@ <-- $< $(PRIVATE_LIBS_MANIFESTS)"
+	@mkdir -p $(dir $@)
+	$(hide) $(ANDROID_MANIFEST_MERGER) --main $< --libs $(PRIVATE_LIBS_MANIFESTS) \
+	    --out $@
+
+endif
diff --git a/core/base_rules.mk b/core/base_rules.mk
index e840047..38f04f1 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -114,6 +114,8 @@
   else
   ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
     partition_tag := _VENDOR
+  else ifeq (true,$(LOCAL_OEM_MODULE))
+    partition_tag := _OEM
   else
     # The definition of should-install-to-system will be different depending
     # on which goal (e.g., sdk or just droid) is being built.
@@ -174,9 +176,15 @@
   built_module_path := $(intermediates)
 endif
 LOCAL_BUILT_MODULE := $(built_module_path)/$(my_built_module_stem)
-built_module_path :=
 
 ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+  # Apk and its attachments reside in its own subdir.
+  ifeq ($(LOCAL_MODULE_CLASS),APPS)
+  # framework-res.apk doesn't like the additional layer.
+  ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+    my_module_path := $(my_module_path)/$(LOCAL_MODULE)
+  endif
+  endif
   LOCAL_INSTALLED_MODULE := $(my_module_path)/$(my_installed_module_stem)
 endif
 
@@ -198,19 +206,24 @@
 aidl_preprocess_import :=
 LOCAL_SDK_VERSION:=$(strip $(LOCAL_SDK_VERSION))
 ifdef LOCAL_SDK_VERSION
-ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
+ifneq ($(filter current system_current, $(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS)),)
   # LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS
   aidl_preprocess_import := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
 else
   aidl_preprocess_import := $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_VERSION)/framework.aidl
-endif # !current
+endif # not current or system_current
 else
 # build against the platform.
 LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
 endif # LOCAL_SDK_VERSION
 $(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b $(addprefix -p,$(aidl_preprocess_import)) -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES))
 
-$(aidl_java_sources): $(intermediates.COMMON)/src/%.java: $(TOPDIR)$(LOCAL_PATH)/%.aidl $(LOCAL_ADDITIONAL_DEPENDENCIES) $(AIDL) $(aidl_preprocess_import)
+$(aidl_java_sources): $(intermediates.COMMON)/src/%.java: \
+        $(TOPDIR)$(LOCAL_PATH)/%.aidl \
+        $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+        $(AIDL) \
+        $(aidl_preprocess_import)
 	$(transform-aidl-to-java)
 -include $(aidl_java_sources:%.java=%.P)
 
@@ -230,7 +243,7 @@
 
 # Emit a java source file with constants for the tags, if
 # LOCAL_MODULE_CLASS is "APPS" or "JAVA_LIBRARIES".
-ifneq ($(strip $(filter $(LOCAL_MODULE_CLASS),APPS JAVA_LIBRARIES)),)
+ifneq ($(filter $(LOCAL_MODULE_CLASS),APPS JAVA_LIBRARIES),)
 
 logtags_java_sources := $(patsubst %.logtags,%.java,$(addprefix $(intermediates.COMMON)/src/, $(logtags_sources)))
 logtags_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(logtags_sources))
@@ -386,13 +399,14 @@
 ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
 # LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,android_stubs_current)
+else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,android_system_stubs_current)
 else
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,sdk_v$(LOCAL_SDK_VERSION))
-endif # current
+endif # current or system_current
 endif # LOCAL_SDK_VERSION
 endif # TARGET_
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_STATIC_JAVA_LIBRARIES := $(full_static_java_libs)
 
@@ -423,10 +437,10 @@
 
 # This is set by packages that are linking to other packages that export
 # shared libraries, allowing them to make use of the code in the linked apk.
-LOCAL_APK_LIBRARIES := $(strip $(LOCAL_APK_LIBRARIES))
-ifdef LOCAL_APK_LIBRARIES
+apk_libraries := $(sort $(LOCAL_APK_LIBRARIES) $(LOCAL_RES_LIBRARIES))
+ifneq ($(apk_libraries),)
   link_apk_libraries := \
-      $(foreach lib,$(LOCAL_APK_LIBRARIES), \
+      $(foreach lib,$(apk_libraries), \
         $(call intermediates-dir-for, \
               APPS,$(lib),,COMMON)/classes.jar)
 
@@ -454,6 +468,10 @@
   full_java_lib_deps += $(link_instr_classes_jar)
 endif
 
+endif  # need_compile_java
+
+# We may want to add jar manifest or jar resource files even if there is no java code at all.
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
 jar_manifest_file :=
 ifneq ($(strip $(LOCAL_JAR_MANIFEST)),)
 jar_manifest_file := $(LOCAL_PATH)/$(LOCAL_JAR_MANIFEST)
@@ -462,9 +480,6 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAR_MANIFEST :=
 endif
 
-endif  # need_compile_java
-
-
 ###########################################################
 ## make clean- targets
 ###########################################################
@@ -552,27 +567,27 @@
 ###########################################################
 ## CHECK_BUILD goals
 ###########################################################
-
-ifdef java_alternative_checked_module
-  LOCAL_CHECKED_MODULE := $(java_alternative_checked_module)
-endif
-
+my_checked_module :=
 # If nobody has defined a more specific module for the
 # checked modules, use LOCAL_BUILT_MODULE.
-ifndef LOCAL_CHECKED_MODULE
-  LOCAL_CHECKED_MODULE := $(LOCAL_BUILT_MODULE)
+ifdef LOCAL_CHECKED_MODULE
+  my_checked_module := $(LOCAL_CHECKED_MODULE)
+else ifdef java_alternative_checked_module
+  my_checked_module := $(java_alternative_checked_module)
+else
+  my_checked_module := $(LOCAL_BUILT_MODULE)
 endif
 
 # If they request that this module not be checked, then don't.
 # PLEASE DON'T SET THIS.  ANY PLACES THAT SET THIS WITHOUT
 # GOOD REASON WILL HAVE IT REMOVED.
 ifdef LOCAL_DONT_CHECK_MODULE
-  LOCAL_CHECKED_MODULE :=
+  my_checked_module :=
 endif
 # Don't check build target module defined for the 2nd arch
 ifndef LOCAL_IS_HOST_MODULE
 ifdef LOCAL_2ND_ARCH_VAR_PREFIX
-  LOCAL_CHECKED_MODULE :=
+  my_checked_module :=
 endif
 endif
 
@@ -591,14 +606,14 @@
 ALL_MODULES.$(my_register_name).TAGS := \
     $(ALL_MODULES.$(my_register_name).TAGS) $(my_module_tags)
 ALL_MODULES.$(my_register_name).CHECKED := \
-    $(ALL_MODULES.$(my_register_name).CHECKED) $(LOCAL_CHECKED_MODULE)
+    $(ALL_MODULES.$(my_register_name).CHECKED) $(my_checked_module)
 ALL_MODULES.$(my_register_name).BUILT := \
     $(ALL_MODULES.$(my_register_name).BUILT) $(LOCAL_BUILT_MODULE)
 ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
 ALL_MODULES.$(my_register_name).INSTALLED := \
     $(strip $(ALL_MODULES.$(my_register_name).INSTALLED) $(LOCAL_INSTALLED_MODULE))
 ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
-    $(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED)$(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE))
+    $(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) $(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE))
 endif
 ifdef LOCAL_PICKUP_FILES
 # Files or directories ready to pick up by the build system
@@ -622,6 +637,9 @@
 ifdef LOCAL_2ND_ARCH_VAR_PREFIX
 ALL_MODULES.$(my_register_name).FOR_2ND_ARCH := true
 endif
+ifdef aidl_sources
+ALL_MODULES.$(my_register_name).AIDL_FILES := $(aidl_sources)
+endif
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
 
@@ -632,14 +650,6 @@
 # Keep track of all the tags we've seen.
 ALL_MODULE_TAGS := $(sort $(ALL_MODULE_TAGS) $(my_module_tags))
 
-# Add this module to the tag list of each specified tag.
-# Don't use "+=". If the variable hasn't been set with ":=",
-# it will default to recursive expansion.
-$(foreach tag,$(my_module_tags),\
-    $(eval ALL_MODULE_TAGS.$(tag) := \
-        $(ALL_MODULE_TAGS.$(tag)) \
-        $(LOCAL_INSTALLED_MODULE)))
-
 # Add this module name to the tag list of each specified tag.
 $(foreach tag,$(my_module_tags),\
     $(eval ALL_MODULE_NAME_TAGS.$(tag) += $(my_register_name)))
@@ -662,9 +672,9 @@
 endif
 
 ifdef j_or_n
-$(j_or_n) $(h_or_t) $(j_or_n)-$(h_or_t) : $(LOCAL_CHECKED_MODULE)
+$(j_or_n) $(h_or_t) $(j_or_n)-$(h_or_t) : $(my_checked_module)
 ifneq (,$(filter $(my_module_tags),tests))
-$(j_or_n)-$(h_or_t)-tests $(j_or_n)-tests $(h_or_t)-tests : $(LOCAL_CHECKED_MODULE)
+$(j_or_n)-$(h_or_t)-tests $(j_or_n)-tests $(h_or_t)-tests : $(my_checked_module)
 endif
 endif
 
diff --git a/core/binary.mk b/core/binary.mk
index 48b4081..de908e3 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -9,73 +9,6 @@
 include $(BUILD_SYSTEM)/base_rules.mk
 #######################################
 
-my_ndk_sysroot :=
-my_ndk_sysroot_include :=
-my_ndk_sysroot_lib :=
-ifdef LOCAL_SDK_VERSION
-  ifdef LOCAL_NDK_VERSION
-    $(error $(LOCAL_PATH): LOCAL_NDK_VERSION is now retired.)
-  endif
-  ifdef LOCAL_IS_HOST_MODULE
-    $(error $(LOCAL_PATH): LOCAL_SDK_VERSION cannot be used in host module)
-  endif
-  my_ndk_source_root := $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources
-  my_ndk_sysroot := $(HISTORICAL_NDK_VERSIONS_ROOT)/current/platforms/android-$(LOCAL_SDK_VERSION)/arch-$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
-  my_ndk_sysroot_include := $(my_ndk_sysroot)/usr/include
-  ifeq (x86_64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
-    my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib64
-  else
-    my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib
-  endif
-
-  # Set up the NDK stl variant. Starting from NDK-r5 the c++ stl resides in a separate location.
-  # See ndk/docs/CPLUSPLUS-SUPPORT.html
-  my_ndk_stl_include_path :=
-  my_ndk_stl_shared_lib_fullpath :=
-  my_ndk_stl_shared_lib :=
-  my_ndk_stl_static_lib :=
-  my_ndk_stl_cppflags :=
-  LOCAL_NDK_STL_VARIANT := $(strip $(LOCAL_NDK_STL_VARIANT))
-  ifeq (,$(LOCAL_NDK_STL_VARIANT))
-    LOCAL_NDK_STL_VARIANT := system
-  endif
-  ifneq (1,$(words $(filter system stlport_static stlport_shared c++_static c++_shared gnustl_static, $(LOCAL_NDK_STL_VARIANT))))
-    $(error $(LOCAL_PATH): Unknown LOCAL_NDK_STL_VARIANT $(LOCAL_NDK_STL_VARIANT))
-  endif
-  ifeq (system,$(LOCAL_NDK_STL_VARIANT))
-    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/system/include
-    # for "system" variant, the shared library exists in the system library and -lstdc++ is added by default.
-  else # LOCAL_NDK_STL_VARIANT is not system
-  ifneq (,$(filter stlport_%, $(LOCAL_NDK_STL_VARIANT)))
-    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/stlport/stlport
-    ifeq (stlport_static,$(LOCAL_NDK_STL_VARIANT))
-      my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libstlport_static.a
-    else
-      my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libstlport_shared.so
-      my_ndk_stl_shared_lib := -lstlport_shared
-    endif
-  else # LOCAL_NDK_STL_VARIANT is not stlport_* either
-  ifneq (,$(filter c++_%, $(LOCAL_NDK_STL_VARIANT)))
-    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libcxx/include \
-                               $(my_ndk_source_root)/cxx-stl/llvm-libc++/gabi++/include \
-                               $(my_ndk_source_root)/android/support/include
-    ifeq (c++_static,$(LOCAL_NDK_STL_VARIANT))
-      my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libc++_static.a
-    else
-      my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libc++_shared.so
-      my_ndk_stl_shared_lib := -lc++_shared
-    endif
-    my_ndk_stl_cppflags := -std=c++11
-  else
-    # LOCAL_NDK_STL_VARIANT is gnustl_static
-    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/include \
-                               $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/include
-    my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)/libgnustl_static.a
-  endif
-  endif
-  endif
-endif
-
 ##################################################
 # Compute the dependency of the shared libraries
 ##################################################
@@ -105,13 +38,113 @@
 my_whole_static_libraries := $(LOCAL_WHOLE_STATIC_LIBRARIES)
 my_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
 my_cflags := $(LOCAL_CFLAGS)
+my_conlyflags := $(LOCAL_CONLYFLAGS)
 my_cppflags := $(LOCAL_CPPFLAGS)
 my_ldflags := $(LOCAL_LDFLAGS)
+my_ldlibs := $(LOCAL_LDLIBS)
 my_asflags := $(LOCAL_ASFLAGS)
 my_cc := $(LOCAL_CC)
 my_cxx := $(LOCAL_CXX)
 my_c_includes := $(LOCAL_C_INCLUDES)
 my_generated_sources := $(LOCAL_GENERATED_SOURCES)
+my_native_coverage := $(LOCAL_NATIVE_COVERAGE)
+my_additional_dependencies := $(LOCAL_MODULE_MAKEFILE) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+
+ifdef LOCAL_IS_HOST_MODULE
+my_allow_undefined_symbols := true
+else
+my_allow_undefined_symbols := $(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS))
+endif
+
+my_ndk_sysroot :=
+my_ndk_sysroot_include :=
+my_ndk_sysroot_lib :=
+ifdef LOCAL_SDK_VERSION
+  ifdef LOCAL_NDK_VERSION
+    $(error $(LOCAL_PATH): LOCAL_NDK_VERSION is now retired.)
+  endif
+  ifdef LOCAL_IS_HOST_MODULE
+    $(error $(LOCAL_PATH): LOCAL_SDK_VERSION cannot be used in host module)
+  endif
+  my_ndk_source_root := $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources
+  my_ndk_sysroot := $(HISTORICAL_NDK_VERSIONS_ROOT)/current/platforms/android-$(LOCAL_SDK_VERSION)/arch-$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+  my_ndk_sysroot_include := $(my_ndk_sysroot)/usr/include
+  ifeq (x86_64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
+    my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib64
+  else ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
+    my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/libr6
+  else
+    my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib
+  endif
+
+  # The bionic linker now has support for gnu style hashes (which are much
+  # faster!), but shipping to older devices requires the old style hash.
+  #ifeq ($(shell expr $(LOCAL_SDK_VERSION) >= FIRST_SUPPORTED_VERSION),0)
+    my_ldflags += -Wl,--hash-style=sysv
+  #endif
+
+  # Set up the NDK stl variant. Starting from NDK-r5 the c++ stl resides in a separate location.
+  # See ndk/docs/CPLUSPLUS-SUPPORT.html
+  my_ndk_stl_include_path :=
+  my_ndk_stl_shared_lib_fullpath :=
+  my_ndk_stl_shared_lib :=
+  my_ndk_stl_static_lib :=
+  my_ndk_stl_cppflags :=
+  my_cpu_variant := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)
+  ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
+    my_cpu_variant := mips32r6
+  endif
+  LOCAL_NDK_STL_VARIANT := $(strip $(LOCAL_NDK_STL_VARIANT))
+  ifeq (,$(LOCAL_NDK_STL_VARIANT))
+    LOCAL_NDK_STL_VARIANT := system
+  endif
+  ifneq (1,$(words $(filter system stlport_static stlport_shared c++_static c++_shared gnustl_static, $(LOCAL_NDK_STL_VARIANT))))
+    $(error $(LOCAL_PATH): Unknown LOCAL_NDK_STL_VARIANT $(LOCAL_NDK_STL_VARIANT))
+  endif
+  ifeq (system,$(LOCAL_NDK_STL_VARIANT))
+    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/system/include
+    # for "system" variant, the shared library exists in the system library and -lstdc++ is added by default.
+  else # LOCAL_NDK_STL_VARIANT is not system
+  ifneq (,$(filter stlport_%, $(LOCAL_NDK_STL_VARIANT)))
+    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/stlport/stlport
+    ifeq (stlport_static,$(LOCAL_NDK_STL_VARIANT))
+      my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(my_cpu_variant)/libstlport_static.a
+    else
+      my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(my_cpu_variant)/libstlport_shared.so
+      my_ndk_stl_shared_lib := -lstlport_shared
+    endif
+  else # LOCAL_NDK_STL_VARIANT is not stlport_* either
+  ifneq (,$(filter c++_%, $(LOCAL_NDK_STL_VARIANT)))
+    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libcxx/include \
+                               $(my_ndk_source_root)/cxx-stl/llvm-libc++/gabi++/include \
+                               $(my_ndk_source_root)/android/support/include
+    ifeq (c++_static,$(LOCAL_NDK_STL_VARIANT))
+      my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++_static.a
+    else
+      my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++_shared.so
+      my_ndk_stl_shared_lib := -lc++_shared
+    endif
+    my_ndk_stl_cppflags := -std=c++11
+  else
+    # LOCAL_NDK_STL_VARIANT is gnustl_static
+    my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(my_cpu_variant)/include \
+                               $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/include
+    my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(my_cpu_variant)/libgnustl_static.a
+  endif
+  endif
+  endif
+endif
+
+# MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
+# all code is position independent, and then those warnings get promoted to
+# errors.
+ifndef USE_MINGW
+ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
+my_cflags += -fpie
+else
+my_cflags += -fPIC
+endif
+endif
 
 my_src_files += $(LOCAL_SRC_FILES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_SRC_FILES_$(my_32_64_bit_suffix))
 my_shared_libraries += $(LOCAL_SHARED_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_SHARED_LIBRARIES_$(my_32_64_bit_suffix))
@@ -122,12 +155,29 @@
 my_c_includes += $(LOCAL_C_INCLUDES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_C_INCLUDES_$(my_32_64_bit_suffix))
 my_generated_sources += $(LOCAL_GENERATED_SOURCES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_GENERATED_SOURCES_$(my_32_64_bit_suffix))
 
-my_clang := $(LOCAL_CLANG)
+my_clang := $(strip $(LOCAL_CLANG))
 ifdef LOCAL_CLANG_$(my_32_64_bit_suffix)
-my_clang := $(LOCAL_CLANG_$(my_32_64_bit_suffix))
+my_clang := $(strip $(LOCAL_CLANG_$(my_32_64_bit_suffix)))
 endif
 ifdef LOCAL_CLANG_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
-my_clang := $(LOCAL_CLANG_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
+my_clang := $(strip $(LOCAL_CLANG_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)))
+endif
+
+# clang is enabled by default for host builds
+# enable it unless we've specifically disabled clang above
+ifdef LOCAL_IS_HOST_MODULE
+    ifneq ($(HOST_OS),windows)
+    ifeq ($(my_clang),)
+        my_clang := true
+    endif
+    endif
+endif
+
+# Add option to make clang the default for device build
+ifeq ($(USE_CLANG_PLATFORM_BUILD),true)
+    ifeq ($(my_clang),)
+        my_clang := true
+    endif
 endif
 
 # arch-specific static libraries go first so that generic ones can depend on them
@@ -136,12 +186,7 @@
 
 my_cflags := $(filter-out $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_UNSUPPORTED_CFLAGS),$(my_cflags))
 
-
-# Replace libstdc++ with libc++ if it's seen
-my_libcxx := $(filter libc++, $(my_shared_libraries))
-ifdef my_libcxx
-my_system_shared_libraries := $(filter-out libstdc++, $(my_system_shared_libraries))
-endif
+include $(BUILD_SYSTEM)/cxx_stl_setup.mk
 
 # Add static HAL libraries
 ifdef LOCAL_HAL_STATIC_LIBRARIES
@@ -152,13 +197,7 @@
 b_lib :=
 endif
 
-ifeq ($(strip $(LOCAL_ADDRESS_SANITIZER)),true)
-  my_clang := true
-  my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
-  my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
-  my_shared_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES)
-  my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
-endif
+include $(BUILD_SYSTEM)/config_sanitizers.mk
 
 ifeq ($(strip $($(LOCAL_2ND_ARCH_VAR_PREFIX)WITHOUT_$(my_prefix)CLANG)),true)
   my_clang :=
@@ -169,16 +208,15 @@
   my_static_libraries += $(COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES)
 endif
 
-my_compiler_dependencies :=
-
 ####################################################
 ## Add FDO flags if FDO is turned on and supported
-####################################################
-ifneq ($(strip $(LOCAL_FDO_SUPPORT)),)
+## Please note that we will do option filtering during FDO build.
+## i.e. Os->O2, remove -fno-early-inline and -finline-limit.
+##################################################################
+ifeq ($(strip $(LOCAL_FDO_SUPPORT)), true)
   ifeq ($(strip $(LOCAL_IS_HOST_MODULE)),)
     my_cflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_CFLAGS)
-    my_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_CFLAGS)
-    my_ldflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_CFLAGS)
+    my_ldflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_LDFLAGS)
   endif
 endif
 
@@ -189,30 +227,6 @@
 my_asflags += -D__ASSEMBLY__
 
 
-##########################################################
-## Set up installed module dependency
-## We cannot compute the full path of the LOCAL_SHARED_LIBRARIES for
-## they may cusomize their install path with LOCAL_MODULE_PATH
-##########################################################
-# Get the list of INSTALLED libraries as module names.
-ifdef LOCAL_SDK_VERSION
-  installed_shared_library_module_names := \
-      $(my_shared_libraries)
-else
-  installed_shared_library_module_names := \
-      $(my_system_shared_libraries) $(my_shared_libraries)
-endif
-installed_shared_library_module_names := $(sort $(installed_shared_library_module_names))
-
-# The real dependency will be added after all Android.mks are loaded and the install paths
-# of the shared libraries are determined.
-ifdef LOCAL_INSTALLED_MODULE
-ifdef installed_shared_library_module_names
-$(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
-    $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(installed_shared_library_module_names))
-endif
-endif
-
 ###########################################################
 ## Define PRIVATE_ variables from global vars
 ###########################################################
@@ -229,11 +243,12 @@
 
 ifeq ($(my_clang),true)
 my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_CFLAGS)
+my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_CONLYFLAGS)
 my_target_global_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_CPPFLAGS)
 my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_LDFLAGS)
-my_target_c_includes += $(CLANG_CONFIG_EXTRA_TARGET_C_INCLUDES)
 else
 my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS)
+my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CONLYFLAGS)
 my_target_global_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CPPFLAGS)
 my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LDFLAGS)
 endif # my_clang
@@ -241,6 +256,7 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_PROJECT_INCLUDES := $(my_target_project_includes)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_C_INCLUDES := $(my_target_c_includes)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CFLAGS := $(my_target_global_cflags)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CONLYFLAGS := $(my_target_global_conlyflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CPPFLAGS := $(my_target_global_cppflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_LDFLAGS := $(my_target_global_ldflags)
 
@@ -248,11 +264,13 @@
 
 ifeq ($(my_clang),true)
 my_host_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_HOST_GLOBAL_CFLAGS)
+my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_HOST_GLOBAL_CONLYFLAGS)
 my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_HOST_GLOBAL_CPPFLAGS)
 my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_HOST_GLOBAL_LDFLAGS)
-my_host_c_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_C_INCLUDES) $(CLANG_CONFIG_EXTRA_HOST_C_INCLUDES)
+my_host_c_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_C_INCLUDES)
 else
 my_host_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CFLAGS)
+my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CONLYFLAGS)
 my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CPPFLAGS)
 my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_LDFLAGS)
 my_host_c_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)HOST_C_INCLUDES)
@@ -260,10 +278,40 @@
 
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_C_INCLUDES := $(my_host_c_includes)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_CFLAGS := $(my_host_global_cflags)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_CONLYFLAGS := $(my_host_global_conlyflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_CPPFLAGS := $(my_host_global_cppflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_LDFLAGS := $(my_host_global_ldflags)
 endif # LOCAL_IS_HOST_MODULE
 
+# To enable coverage for a given module, set LOCAL_NATIVE_COVERAGE=true and
+# build with NATIVE_COVERAGE=true in your enviornment. Note that the build
+# system is not sensitive to changes to NATIVE_COVERAGE, so you should do a
+# clean build of your module after toggling it.
+ifeq ($(NATIVE_COVERAGE),true)
+    ifeq ($(my_native_coverage),true)
+        my_cflags += --coverage -O0
+        ifeq ($(my_clang),true)
+            # b/17574078
+            # We currently don't have a prebuilt libclang_rt.profile-<ARCH>.a,
+            # which clang is hardcoded to link if --coverage is passed in the
+            # link stage.  For now we manually link libprofile_rt (which is the
+            # name it is built as from external/compiler-rt).
+            #
+            # Note that clang coverage doesn't play nicely with acov out of the
+            # box. Clang apparently generates .gcno files that aren't compatible
+            # with gcov-4.8.  This can be solved by installing gcc-4.6 and
+            # invoking lcov with `--gcov-tool /usr/bin/gcov-4.6`.
+            #
+            # http://stackoverflow.com/questions/17758126/clang-code-coverage-invalid-output
+            my_static_libraries += libprofile_rt
+        else
+            my_ldflags += --coverage
+        endif
+    endif
+else
+    my_native_coverage := false
+endif
+
 ###########################################################
 ## Define PRIVATE_ variables used by multiple module types
 ###########################################################
@@ -285,7 +333,7 @@
 endif
 
 ifeq ($(strip $(my_cc)),)
-  ifeq ($(strip $(my_clang)),true)
+  ifeq ($(my_clang),true)
     my_cc := $(CLANG)
   else
     my_cc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)CC)
@@ -301,7 +349,7 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CC := $(my_cc)
 
 ifeq ($(strip $(my_cxx)),)
-  ifeq ($(strip $(my_clang)),true)
+  ifeq ($(my_clang),true)
     my_cxx := $(CLANG_CXX)
   else
     my_cxx := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)CXX)
@@ -315,6 +363,7 @@
 endif
 endif
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CXX := $(my_cxx)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CLANG := $(my_clang)
 
 # TODO: support a mix of standard extensions so that this isn't necessary
 LOCAL_CPP_EXTENSION := $(strip $(LOCAL_CPP_EXTENSION))
@@ -326,7 +375,7 @@
 # Certain modules like libdl have to have symbols resolved at runtime and blow
 # up if --no-undefined is passed to the linker.
 ifeq ($(strip $(LOCAL_NO_DEFAULT_COMPILER_FLAGS)),)
-ifeq ($(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS)),)
+ifeq ($(my_allow_undefined_symbols),)
   my_ldflags +=  $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)NO_UNDEFINED_LDFLAGS)
 endif
 endif
@@ -350,7 +399,7 @@
 # actually used (although they are usually empty).
 arm_objects_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)$(arm_objects_mode)_CFLAGS)
 normal_objects_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)$(normal_objects_mode)_CFLAGS)
-ifeq ($(strip $(my_clang)),true)
+ifeq ($(my_clang),true)
 arm_objects_cflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(arm_objects_cflags))
 normal_objects_cflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(normal_objects_cflags))
 endif
@@ -395,6 +444,8 @@
 # This can be disabled with LOCAL_RENDERSCRIPT_FLAGS := -Wno-error
 renderscript_flags := -Wall -Werror
 renderscript_flags += $(LOCAL_RENDERSCRIPT_FLAGS)
+# -m32 or -m64
+renderscript_flags += -m$(my_32_64_bit_suffix)
 
 renderscript_includes := \
     $(TOPDIR)external/clang/lib/Headers \
@@ -465,6 +516,9 @@
 proto_generated_objects := $(addprefix $(proto_generated_obj_dir)/, \
     $(patsubst %.proto,%.pb.o,$(proto_sources_fullpath)))
 
+# Auto-export the generated proto source dir.
+LOCAL_EXPORT_C_INCLUDE_DIRS += $(proto_generated_cc_sources_dir)
+
 # Ensure the transform-proto-to-cc rule is only defined once in multilib build.
 ifndef $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_proto_defined
 $(proto_generated_cc_sources): PRIVATE_PROTO_INCLUDES := $(TOP)
@@ -489,9 +543,17 @@
 my_c_includes += external/protobuf/src $(proto_generated_cc_sources_dir)
 my_cflags += -DGOOGLE_PROTOBUF_NO_RTTI
 ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),full)
-my_static_libraries += libprotobuf-cpp-2.3.0-full
+    ifdef LOCAL_SDK_VERSION
+        my_static_libraries += libprotobuf-cpp-full
+    else
+        my_shared_libraries += libprotobuf-cpp-full
+    endif
 else
-my_static_libraries += libprotobuf-cpp-2.3.0-lite
+    ifdef LOCAL_SDK_VERSION
+        my_static_libraries += libprotobuf-cpp-lite
+    else
+        my_shared_libraries += libprotobuf-cpp-lite
+    endif
 endif
 endif  # $(proto_sources) non-empty
 
@@ -515,7 +577,7 @@
 ifneq ($(strip $(y_yacc_cpps)),)
 $(y_yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
     $(TOPDIR)$(LOCAL_PATH)/%.y \
-    $(lex_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+    $(lex_cpps) $(my_additional_dependencies)
 	$(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
 $(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
 endif
@@ -523,7 +585,7 @@
 ifneq ($(strip $(yy_yacc_cpps)),)
 $(yy_yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
     $(TOPDIR)$(LOCAL_PATH)/%.yy \
-    $(lex_cpps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+    $(lex_cpps) $(my_additional_dependencies)
 	$(call transform-y-to-cpp,$(PRIVATE_CPP_EXTENSION))
 $(yacc_headers): $(intermediates)/%.h: $(intermediates)/%$(LOCAL_CPP_EXTENSION)
 endif
@@ -567,7 +629,7 @@
 $(lex_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
 $(lex_objects): $(intermediates)/%.o: \
     $(intermediates)/%$(LOCAL_CPP_EXTENSION) \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+    $(my_additional_dependencies) \
     $(yacc_headers)
 	$(transform-$(PRIVATE_HOST)cpp-to-o)
 endif
@@ -595,8 +657,7 @@
 $(cpp_objects): $(intermediates)/%.o: \
     $(TOPDIR)$(LOCAL_PATH)/%$(LOCAL_CPP_EXTENSION) \
     $(yacc_cpps) $(proto_generated_headers) \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)cpp-to-o)
 -include $(cpp_objects:%.o=%.P)
 endif
@@ -616,8 +677,7 @@
 $(gen_cpp_objects): $(intermediates)/%.o: \
     $(intermediates)/%$(LOCAL_CPP_EXTENSION) $(yacc_cpps) \
     $(proto_generated_headers) \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)cpp-to-o)
 -include $(gen_cpp_objects:%.o=%.P)
 endif
@@ -631,8 +691,7 @@
 
 ifneq ($(strip $(gen_S_sources)),)
 $(gen_S_objects): $(intermediates)/%.o: $(intermediates)/%.S \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)s-to-o)
 -include $(gen_S_objects:%.o=%.P)
 endif
@@ -642,8 +701,7 @@
 
 ifneq ($(strip $(gen_s_objects)),)
 $(gen_s_objects): $(intermediates)/%.o: $(intermediates)/%.s \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)s-to-o-no-deps)
 -include $(gen_s_objects:%.o=%.P)
 endif
@@ -675,8 +733,7 @@
 
 ifneq ($(strip $(c_objects)),)
 $(c_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.c $(yacc_cpps) $(proto_generated_headers) \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)c-to-o)
 -include $(c_objects:%.o=%.P)
 endif
@@ -694,8 +751,7 @@
 $(gen_c_objects): PRIVATE_ARM_MODE := $(normal_objects_mode)
 $(gen_c_objects): PRIVATE_ARM_CFLAGS := $(normal_objects_cflags)
 $(gen_c_objects): $(intermediates)/%.o: $(intermediates)/%.c $(yacc_cpps) $(proto_generated_headers) \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)c-to-o)
 -include $(gen_c_objects:%.o=%.P)
 endif
@@ -709,8 +765,7 @@
 
 ifneq ($(strip $(objc_objects)),)
 $(objc_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.m $(yacc_cpps) $(proto_generated_headers) \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)m-to-o)
 -include $(objc_objects:%.o=%.P)
 endif
@@ -724,8 +779,7 @@
 
 ifneq ($(strip $(asm_objects_S)),)
 $(asm_objects_S): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.S \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)s-to-o)
 -include $(asm_objects_S:%.o=%.P)
 endif
@@ -735,8 +789,7 @@
 
 ifneq ($(strip $(asm_objects_s)),)
 $(asm_objects_s): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.s \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    | $(my_compiler_dependencies)
+    $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)s-to-o-no-deps)
 -include $(asm_objects_s:%.o=%.P)
 endif
@@ -744,19 +797,42 @@
 asm_objects := $(asm_objects_S) $(asm_objects_s)
 
 
-# .asm for x86 needs to be compiled with yasm.
-ifeq (x86,$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
+# .asm for x86/x86_64 needs to be compiled with yasm.
 asm_sources_asm := $(filter %.asm,$(my_src_files))
 ifneq ($(strip $(asm_sources_asm)),)
 asm_objects_asm := $(addprefix $(intermediates)/,$(asm_sources_asm:.asm=.o))
 $(asm_objects_asm): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.asm \
-    $(LOCAL_ADDITIONAL_DEPENDENCIES)
+    $(my_additional_dependencies)
 	$(transform-asm-to-o)
 
 asm_objects += $(asm_objects_asm)
 endif
+
+
+##########################################################
+## Set up installed module dependency
+## We cannot compute the full path of the LOCAL_SHARED_LIBRARIES for
+## they may cusomize their install path with LOCAL_MODULE_PATH
+##########################################################
+# Get the list of INSTALLED libraries as module names.
+ifdef LOCAL_SDK_VERSION
+  installed_shared_library_module_names := \
+      $(my_shared_libraries)
+else
+  installed_shared_library_module_names := \
+      $(my_shared_libraries) $(my_system_shared_libraries)
 endif
 
+# The real dependency will be added after all Android.mks are loaded and the install paths
+# of the shared libraries are determined.
+ifdef LOCAL_INSTALLED_MODULE
+ifdef installed_shared_library_module_names
+$(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
+    $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(sort $(installed_shared_library_module_names)))
+endif
+endif
+
+
 ####################################################
 ## Import includes
 ####################################################
@@ -766,11 +842,12 @@
       $(call intermediates-dir-for,SHARED_LIBRARIES,$(l),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX))/export_includes) \
     $(foreach l, $(my_static_libraries) $(my_whole_static_libraries), \
       $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX))/export_includes))
-$(import_includes) : $(import_includes_deps)
+$(import_includes): PRIVATE_IMPORT_EXPORT_INCLUDES := $(import_includes_deps)
+$(import_includes) : $(LOCAL_MODULE_MAKEFILE) $(import_includes_deps)
 	@echo Import includes file: $@
 	$(hide) mkdir -p $(dir $@) && rm -f $@
 ifdef import_includes_deps
-	$(hide) for f in $^; do \
+	$(hide) for f in $(PRIVATE_IMPORT_EXPORT_INCLUDES); do \
 	  cat $$f >> $@; \
 	done
 else
@@ -899,15 +976,40 @@
 ###########################################################
 
 ifeq ($(my_clang),true)
+my_cflags += $(LOCAL_CLANG_CFLAGS)
+my_conlyflags += $(LOCAL_CLANG_CONLYFLAGS)
+my_cppflags += $(LOCAL_CLANG_CPPFLAGS)
+my_asflags += $(LOCAL_CLANG_ASFLAGS)
+my_ldflags += $(LOCAL_CLANG_LDFLAGS)
+my_cflags += $(LOCAL_CLANG_CFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_CFLAGS_$(my_32_64_bit_suffix))
+my_conlyflags += $(LOCAL_CLANG_CONLYFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_CONLYFLAGS_$(my_32_64_bit_suffix))
+my_cppflags += $(LOCAL_CLANG_CPPFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_CPPFLAGS_$(my_32_64_bit_suffix))
+my_ldflags += $(LOCAL_CLANG_LDFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_LDFLAGS_$(my_32_64_bit_suffix))
+my_asflags += $(LOCAL_CLANG_ASFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_ASFLAGS_$(my_32_64_bit_suffix))
 my_cflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_cflags))
 my_cppflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_cppflags))
 my_asflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_asflags))
 my_ldflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_ldflags))
 endif
 
+ifeq ($(LOCAL_FDO_SUPPORT), true)
+  build_with_fdo := false
+  ifeq ($(BUILD_FDO_INSTRUMENT), true)
+    build_with_fdo := true
+  endif
+  ifeq ($(BUILD_FDO_OPTIMIZE), true)
+    build_with_fdo := true
+  endif
+  ifeq ($(build_with_fdo), true)
+    my_cflags := $(patsubst -Os,-O2,$(my_cflags))
+    fdo_incompatible_flags=-fno-early-inlining -finline-limit=%
+    my_cflags := $(filter-out $(fdo_incompatible_flags),$(my_cflags))
+  endif
+endif
+
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(my_asflags)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CONLYFLAGS := $(LOCAL_CONLYFLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CONLYFLAGS := $(my_conlyflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CFLAGS := $(my_cflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CPPFLAGS := $(my_cppflags)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RTTI_FLAG := $(LOCAL_RTTI_FLAG)
@@ -915,9 +1017,8 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_C_INCLUDES := $(my_c_includes)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_IMPORT_INCLUDES := $(import_includes)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDFLAGS := $(my_ldflags)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDLIBS := $(LOCAL_LDLIBS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDLIBS := $(my_ldlibs)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_NO_CRT := $(strip $(LOCAL_NO_CRT) $(LOCAL_NO_CRT_$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)))
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LIBCXX := $(my_libcxx)
 
 # this is really the way to get the files onto the command line instead
 # of using $^, because then LOCAL_ADDITIONAL_DEPENDENCIES doesn't work
@@ -945,7 +1046,8 @@
 ###########################################################
 export_includes := $(intermediates)/export_includes
 $(export_includes): PRIVATE_EXPORT_C_INCLUDE_DIRS := $(LOCAL_EXPORT_C_INCLUDE_DIRS)
-$(export_includes) : $(LOCAL_MODULE_MAKEFILE)
+# Make sure .pb.h are already generated before any dependent source files get compiled.
+$(export_includes) : $(LOCAL_MODULE_MAKEFILE) $(proto_generated_headers)
 	@echo Export includes file: $< -- $@
 	$(hide) mkdir -p $(dir $@) && rm -f $@
 ifdef LOCAL_EXPORT_C_INCLUDE_DIRS
diff --git a/core/clang/HOST_x86.mk b/core/clang/HOST_x86.mk
index 510a74d..35cfe60 100644
--- a/core/clang/HOST_x86.mk
+++ b/core/clang/HOST_x86.mk
@@ -11,6 +11,10 @@
 endif
 ifeq ($(HOST_OS),darwin)
 CLANG_CONFIG_x86_HOST_TRIPLE := i686-apple-darwin
+CLANG_CONFIG_x86_HOST_COMBO_EXTRA_ASFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_ASFLAGS)
+CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS)
+CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CPPFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CPPFLAGS)
+CLANG_CONFIG_x86_HOST_COMBO_EXTRA_LDFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_LDFLAGS)
 endif
 ifeq ($(HOST_OS),windows)
 CLANG_CONFIG_x86_HOST_TRIPLE := i686-pc-mingw32
@@ -30,6 +34,12 @@
   $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_x86_HOST_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_x86_HOST_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_HOST_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_x86_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_x86_HOST_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_HOST_EXTRA_CPPFLAGS) \
@@ -55,6 +65,10 @@
   $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_x86_HOST_EXTRA_CFLAGS)
 
+$(clang_2nd_arch_prefix)CLANG_HOST_GLOBAL_CONLYFLAGS := \
+  $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_x86_HOST_EXTRA_CONLYFLAGS)
+
 $(clang_2nd_arch_prefix)CLANG_HOST_GLOBAL_CPPFLAGS := \
   $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_x86_HOST_EXTRA_CPPFLAGS)
diff --git a/core/clang/HOST_x86_64.mk b/core/clang/HOST_x86_64.mk
index 6b94525..c546715 100644
--- a/core/clang/HOST_x86_64.mk
+++ b/core/clang/HOST_x86_64.mk
@@ -11,6 +11,10 @@
 endif
 ifeq ($(HOST_OS),darwin)
 CLANG_CONFIG_x86_64_HOST_TRIPLE := x86_64-apple-darwin
+CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_ASFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_ASFLAGS)
+CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS)
+CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CPPFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CPPFLAGS)
+CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_LDFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_LDFLAGS)
 endif
 ifeq ($(HOST_OS),windows)
 CLANG_CONFIG_x86_64_HOST_TRIPLE := x86_64-pc-mingw64
@@ -30,6 +34,12 @@
   $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_x86_64_HOST_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_x86_64_HOST_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_HOST_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_x86_64_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_x86_64_HOST_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_HOST_EXTRA_CPPFLAGS) \
@@ -55,6 +65,10 @@
   $(call convert-to-host-clang-flags,$(HOST_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_x86_64_HOST_EXTRA_CFLAGS)
 
+CLANG_HOST_GLOBAL_CONLYFLAGS := \
+  $(call convert-to-host-clang-flags,$(HOST_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_x86_64_HOST_EXTRA_CONLYFLAGS)
+
 CLANG_HOST_GLOBAL_CPPFLAGS := \
   $(call convert-to-host-clang-flags,$(HOST_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_x86_64_HOST_EXTRA_CPPFLAGS)
diff --git a/core/clang/HOST_x86_common.mk b/core/clang/HOST_x86_common.mk
index 0241cb6..74b5a69 100644
--- a/core/clang/HOST_x86_common.mk
+++ b/core/clang/HOST_x86_common.mk
@@ -1,53 +1,51 @@
 # Shared by HOST_x86.mk and HOST_x86_64.mk.
 
 ifeq ($(HOST_OS),darwin)
-# nothing required here yet
+CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_ASFLAGS := \
+  -integrated-as
+
+CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS := \
+  -integrated-as
 endif
 
 ifeq ($(HOST_OS),linux)
 CLANG_CONFIG_x86_LINUX_HOST_EXTRA_ASFLAGS := \
   --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
-  --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
-  -no-integrated-as
+  --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot
 
 CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CFLAGS := \
-  --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
-  -no-integrated-as
+  --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)
 
 ifneq ($(strip $($(clang_2nd_arch_prefix)HOST_IS_64_BIT)),)
 CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CPPFLAGS := \
   --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
   --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
-  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.6 \
-  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.6/x86_64-linux \
-  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.6/backward \
-  -no-integrated-as
+  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8 \
+  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/x86_64-linux \
+  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/backward
 
 CLANG_CONFIG_x86_LINUX_HOST_EXTRA_LDFLAGS := \
   --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
   --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
   -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin \
-  -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.6 \
-  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.6 \
-  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/lib64/ \
-  -no-integrated-as
+  -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8 \
+  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8 \
+  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/lib64/
 else
 CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CPPFLAGS := \
   --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
   --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
-  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.6 \
-  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.6/x86_64-linux/32 \
-  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.6/backward \
-  -no-integrated-as
+  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8 \
+  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/x86_64-linux/32 \
+  -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/backward
 
 CLANG_CONFIG_x86_LINUX_HOST_EXTRA_LDFLAGS := \
   --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
   --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
   -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin \
-  -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.6/32 \
-  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.6/32 \
-  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/lib32/ \
-  -no-integrated-as
+  -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8/32 \
+  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8/32 \
+  -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/lib32/
 endif
 endif  # Linux
 
diff --git a/core/clang/TARGET_arm.mk b/core/clang/TARGET_arm.mk
index 595fb56..993755f 100644
--- a/core/clang/TARGET_arm.mk
+++ b/core/clang/TARGET_arm.mk
@@ -19,6 +19,11 @@
   -target $(CLANG_CONFIG_arm_TARGET_TRIPLE) \
   $(CLANG_CONFIG_arm_TARGET_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_arm_TARGET_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_arm_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_arm_TARGET_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
@@ -44,6 +49,10 @@
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_arm_TARGET_EXTRA_CFLAGS)
 
+$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CONLYFLAGS := \
+  $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_arm_TARGET_EXTRA_CONLYFLAGS)
+
 $(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CPPFLAGS := \
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_arm_TARGET_EXTRA_CPPFLAGS)
@@ -53,3 +62,5 @@
   $(CLANG_CONFIG_arm_TARGET_EXTRA_LDFLAGS)
 
 $(clang_2nd_arch_prefix)RS_TRIPLE := armv7-none-linux-gnueabi
+$(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS :=
+$(clang_2nd_arch_prefix)RS_COMPAT_TRIPLE := armv7-none-linux-gnueabi
diff --git a/core/clang/TARGET_arm64.mk b/core/clang/TARGET_arm64.mk
index 98bbeb2..ba6e5f1 100644
--- a/core/clang/TARGET_arm64.mk
+++ b/core/clang/TARGET_arm64.mk
@@ -18,6 +18,11 @@
   $(CLANG_CONFIG_arm64_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_arm64_TARGET_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_arm64_TARGET_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_arm64_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_arm64_TARGET_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
@@ -42,6 +47,10 @@
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_arm64_TARGET_EXTRA_CFLAGS)
 
+CLANG_TARGET_GLOBAL_CONLYFLAGS := \
+  $(call convert-to-clang-flags,$(TARGET_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_arm64_TARGET_EXTRA_CONLYFLAGS)
+
 CLANG_TARGET_GLOBAL_CPPFLAGS := \
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_arm64_TARGET_EXTRA_CPPFLAGS)
@@ -51,3 +60,5 @@
   $(CLANG_CONFIG_arm64_TARGET_EXTRA_LDFLAGS)
 
 RS_TRIPLE := aarch64-linux-android
+RS_TRIPLE_CFLAGS :=
+RS_COMPAT_TRIPLE := aarch64-linux-android
diff --git a/core/clang/TARGET_mips.mk b/core/clang/TARGET_mips.mk
index e70e254..2360181 100644
--- a/core/clang/TARGET_mips.mk
+++ b/core/clang/TARGET_mips.mk
@@ -3,12 +3,13 @@
 
 CLANG_CONFIG_mips_TARGET_TRIPLE := mipsel-linux-android
 CLANG_CONFIG_mips_TARGET_TOOLCHAIN_PREFIX := \
-  $($(clang_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/$(CLANG_CONFIG_mips_TARGET_TRIPLE)/bin
+  $($(clang_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/mips64el-linux-android/bin
 
 CLANG_CONFIG_mips_TARGET_EXTRA_ASFLAGS := \
   $(CLANG_CONFIG_EXTRA_ASFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
   $(CLANG_CONFIG_mips_EXTRA_ASFLAGS) \
+  -fPIC \
   -target $(CLANG_CONFIG_mips_TARGET_TRIPLE) \
   -B$(CLANG_CONFIG_mips_TARGET_TOOLCHAIN_PREFIX)
 
@@ -18,6 +19,11 @@
   $(CLANG_CONFIG_mips_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_mips_TARGET_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_mips_TARGET_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_mips_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_mips_TARGET_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
@@ -42,12 +48,18 @@
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_mips_TARGET_EXTRA_CFLAGS)
 
+$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CONLYFLAGS := \
+  $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_mips_TARGET_EXTRA_CONLYFLAGS)
+
 $(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CPPFLAGS := \
-  $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$(clang_2nd_arch_prefix)$(TARGET_GLOBAL_CPPFLAGS)) \
+  $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_mips_TARGET_EXTRA_CPPFLAGS)
 
 $(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_LDFLAGS := \
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS)) \
   $(CLANG_CONFIG_mips_TARGET_EXTRA_LDFLAGS)
 
-$(clang_2nd_arch_prefix)RS_TRIPLE := mipsel-unknown-linux
+$(clang_2nd_arch_prefix)RS_TRIPLE := armv7-none-linux-gnueabi
+$(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS :=
+RS_COMPAT_TRIPLE := mipsel-linux-android
diff --git a/core/clang/TARGET_mips64.mk b/core/clang/TARGET_mips64.mk
index b2e536c..742be4b 100644
--- a/core/clang/TARGET_mips64.mk
+++ b/core/clang/TARGET_mips64.mk
@@ -18,6 +18,11 @@
   $(CLANG_CONFIG_mips64_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_mips64_TARGET_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_mips64_TARGET_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_mips64_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_mips64_TARGET_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
@@ -42,6 +47,10 @@
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_mips64_TARGET_EXTRA_CFLAGS)
 
+CLANG_TARGET_GLOBAL_CONLYFLAGS := \
+  $(call convert-to-clang-flags,$(TARGET_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_mips64_TARGET_EXTRA_CONLYFLAGS)
+
 CLANG_TARGET_GLOBAL_CPPFLAGS := \
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_mips64_TARGET_EXTRA_CPPFLAGS)
@@ -50,4 +59,6 @@
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_LDFLAGS)) \
   $(CLANG_CONFIG_mips64_TARGET_EXTRA_LDFLAGS)
 
-RS_TRIPLE := mips64el-unknown-linux
+RS_TRIPLE := aarch64-linux-android
+RS_TRIPLE_CFLAGS :=
+RS_COMPAT_TRIPLE := mips64el-linux-android
diff --git a/core/clang/TARGET_x86.mk b/core/clang/TARGET_x86.mk
index 70cb252..3ba34ae 100644
--- a/core/clang/TARGET_x86.mk
+++ b/core/clang/TARGET_x86.mk
@@ -18,7 +18,20 @@
   $(CLANG_CONFIG_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_x86_EXTRA_CFLAGS) \
-  $(CLANG_CONFIG_x86_TARGET_EXTRA_ASFLAGS)
+  $(CLANG_CONFIG_x86_TARGET_EXTRA_ASFLAGS) \
+  -fno-optimize-sibling-calls \
+  -mstackrealign
+
+# http://llvm.org/bugs/show_bug.cgi?id=15086,
+# llvm tail call optimization is wrong for x86.
+# -mstackrealign is needed to realign stack in native code
+# that could be called from JNI, so that movaps instruction
+# will work on assumed stack aligned local variables.
+
+CLANG_CONFIG_x86_TARGET_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_x86_EXTRA_CONLYFLAGS)
 
 CLANG_CONFIG_x86_TARGET_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
@@ -44,6 +57,10 @@
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_x86_TARGET_EXTRA_CFLAGS)
 
+$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CONLYFLAGS := \
+  $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_x86_TARGET_EXTRA_CONLYFLAGS)
+
 $(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CPPFLAGS := \
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_x86_TARGET_EXTRA_CPPFLAGS)
@@ -52,4 +69,6 @@
   $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS)) \
   $(CLANG_CONFIG_x86_TARGET_EXTRA_LDFLAGS)
 
-$(clang_2nd_arch_prefix)RS_TRIPLE := i686-unknown-linux
+$(clang_2nd_arch_prefix)RS_TRIPLE := armv7-none-linux-gnueabi
+$(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS := -D__i386__
+$(clang_2nd_arch_prefix)RS_COMPAT_TRIPLE := i686-linux-android
diff --git a/core/clang/TARGET_x86_64.mk b/core/clang/TARGET_x86_64.mk
index 14944bd..9f8e8b0 100644
--- a/core/clang/TARGET_x86_64.mk
+++ b/core/clang/TARGET_x86_64.mk
@@ -18,6 +18,11 @@
   $(CLANG_CONFIG_x86_64_EXTRA_CFLAGS) \
   $(CLANG_CONFIG_x86_64_TARGET_EXTRA_ASFLAGS)
 
+CLANG_CONFIG_x86_64_TARGET_EXTRA_CONLYFLAGS := \
+  $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
+  $(CLANG_CONFIG_x86_64_EXTRA_CONLYFLAGS)
+
 CLANG_CONFIG_x86_64_TARGET_EXTRA_CPPFLAGS := \
   $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
   $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
@@ -42,6 +47,10 @@
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_CFLAGS)) \
   $(CLANG_CONFIG_x86_64_TARGET_EXTRA_CFLAGS)
 
+CLANG_TARGET_GLOBAL_CONLYFLAGS := \
+  $(call convert-to-clang-flags,$(TARGET_GLOBAL_CONLYFLAGS)) \
+  $(CLANG_CONFIG_x86_64_TARGET_EXTRA_CONLYFLAGS)
+
 CLANG_TARGET_GLOBAL_CPPFLAGS := \
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_CPPFLAGS)) \
   $(CLANG_CONFIG_x86_64_TARGET_EXTRA_CPPFLAGS)
@@ -50,4 +59,6 @@
   $(call convert-to-clang-flags,$(TARGET_GLOBAL_LDFLAGS)) \
   $(CLANG_CONFIG_x86_64_TARGET_EXTRA_LDFLAGS)
 
-RS_TRIPLE := x86_64-unknown-linux
+RS_TRIPLE := aarch64-linux-android
+RS_TRIPLE_CFLAGS := -D__x86_64__
+RS_COMPAT_TRIPLE := x86_64-linux-android
diff --git a/core/clang/arm.mk b/core/clang/arm.mk
index 22c7397..f76a182 100644
--- a/core/clang/arm.mk
+++ b/core/clang/arm.mk
@@ -1,16 +1,23 @@
 # Clang flags for arm arch, target or host.
 
-CLANG_CONFIG_arm_EXTRA_ASFLAGS := \
-  -no-integrated-as
+CLANG_CONFIG_arm_EXTRA_ASFLAGS :=
 
-CLANG_CONFIG_arm_EXTRA_CFLAGS := \
-  -no-integrated-as
+CLANG_CONFIG_arm_EXTRA_CFLAGS :=
 
-CLANG_CONFIG_arm_EXTRA_CPPFLAGS := \
-  -no-integrated-as
+ifneq (,$(filter krait,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
+  # Android's clang support's krait as a CPU whereas GCC doesn't. Specify
+  # -mcpu here rather than the more normal core/combo/arch/arm/armv7-a-neon.mk.
+  CLANG_CONFIG_arm_EXTRA_CFLAGS += -mcpu=krait
+endif
 
-CLANG_CONFIG_arm_EXTRA_LDFLAGS := \
-  -no-integrated-as
+ifeq ($(HOST_OS),darwin)
+  # Darwin is really bad at dealing with idiv/sdiv. Don't use krait on Darwin.
+  CLANG_CONFIG_arm_EXTRA_CFLAGS += -mcpu=cortex-a9
+endif
+
+CLANG_CONFIG_arm_EXTRA_CPPFLAGS :=
+
+CLANG_CONFIG_arm_EXTRA_LDFLAGS :=
 
 # Include common unknown flags
 CLANG_CONFIG_arm_UNKNOWN_CFLAGS := \
@@ -19,9 +26,15 @@
   -fgcse-after-reload \
   -frerun-cse-after-loop \
   -frename-registers \
-  -fno-builtin-sin \
-  -fno-strict-volatile-bitfields \
   -fno-align-jumps \
+  -fno-builtin-sin \
+  -fno-caller-saves \
+  -fno-early-inlining \
+  -fno-move-loop-invariants \
+  -fno-partial-inlining \
+  -fno-strict-volatile-bitfields \
+  -fno-tree-copy-prop \
+  -fno-tree-loop-optimize \
   -Wa,--noexecstack
 
 define subst-clang-incompatible-arm-flags
diff --git a/core/clang/arm64.mk b/core/clang/arm64.mk
index 9fb3670..ab395b3 100644
--- a/core/clang/arm64.mk
+++ b/core/clang/arm64.mk
@@ -1,10 +1,8 @@
 # Clang flags for arm64 arch, target or host.
 
-CLANG_CONFIG_arm64_EXTRA_ASFLAGS := \
-  -no-integrated-as
+CLANG_CONFIG_arm64_EXTRA_ASFLAGS :=
 
-CLANG_CONFIG_arm64_EXTRA_CFLAGS := \
-  -no-integrated-as
+CLANG_CONFIG_arm64_EXTRA_CFLAGS :=
 
 CLANG_CONFIG_arm64_EXTRA_LDFLAGS :=
 
diff --git a/core/clang/config.mk b/core/clang/config.mk
index f50a0cb..72a880f 100644
--- a/core/clang/config.mk
+++ b/core/clang/config.mk
@@ -6,21 +6,33 @@
 WITHOUT_HOST_CLANG := true
 endif
 
-LLVM_PREBUILTS_PATH := prebuilts/clang/$(BUILD_OS)-x86/host/3.5/bin
-LLVM_PREBUILTS_HEADER_PATH := prebuilts/clang/$(BUILD_OS)-x86/host/3.5/lib/clang/3.5/include/
+LLVM_PREBUILTS_VERSION := 3.6
+LLVM_PREBUILTS_PATH := prebuilts/clang/$(BUILD_OS)-x86/host/$(LLVM_PREBUILTS_VERSION)/bin
 
 CLANG := $(LLVM_PREBUILTS_PATH)/clang$(BUILD_EXECUTABLE_SUFFIX)
 CLANG_CXX := $(LLVM_PREBUILTS_PATH)/clang++$(BUILD_EXECUTABLE_SUFFIX)
 LLVM_AS := $(LLVM_PREBUILTS_PATH)/llvm-as$(BUILD_EXECUTABLE_SUFFIX)
 LLVM_LINK := $(LLVM_PREBUILTS_PATH)/llvm-link$(BUILD_EXECUTABLE_SUFFIX)
 
-CLANG_TBLGEN := $(HOST_OUT_EXECUTABLES)/clang-tblgen$(BUILD_EXECUTABLE_SUFFIX)
-LLVM_TBLGEN := $(HOST_OUT_EXECUTABLES)/llvm-tblgen$(BUILD_EXECUTABLE_SUFFIX)
+CLANG_TBLGEN := $(BUILD_OUT_EXECUTABLES)/clang-tblgen$(BUILD_EXECUTABLE_SUFFIX)
+LLVM_TBLGEN := $(BUILD_OUT_EXECUTABLES)/llvm-tblgen$(BUILD_EXECUTABLE_SUFFIX)
 
+# The C/C++ compiler can be wrapped by setting the CC/CXX_WRAPPER vars.
+ifdef CC_WRAPPER
+  ifneq ($(CC_WRAPPER),$(firstword $(CLANG)))
+    CLANG := $(CC_WRAPPER) $(CLANG)
+  endif
+endif
+ifdef CXX_WRAPPER
+  ifneq ($(CXX_WRAPPER),$(firstword $(CLANG_CXX)))
+    CLANG_CXX := $(CXX_WRAPPER) $(CLANG_CXX)
+  endif
+endif
 
 # Clang flags for all host or target rules
 CLANG_CONFIG_EXTRA_ASFLAGS :=
 CLANG_CONFIG_EXTRA_CFLAGS :=
+CLANG_CONFIG_EXTRA_CONLYFLAGS := -std=gnu99
 CLANG_CONFIG_EXTRA_CPPFLAGS :=
 CLANG_CONFIG_EXTRA_LDFLAGS :=
 
@@ -31,17 +43,33 @@
 CLANG_CONFIG_EXTRA_CFLAGS += \
   -Werror=int-conversion
 
+# Workaround for ccache with clang.
+# See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html.
+CLANG_CONFIG_EXTRA_CFLAGS += \
+  -Wno-unused-command-line-argument
+
+# Disable -Winconsistent-missing-override until we can clean up the existing
+# codebase for it.
+CLANG_CONFIG_EXTRA_CPPFLAGS += \
+  -Wno-inconsistent-missing-override
+
 CLANG_CONFIG_UNKNOWN_CFLAGS := \
-  -funswitch-loops \
-  -fno-tree-sra \
+  -finline-functions \
   -finline-limit=64 \
+  -fno-canonical-system-headers \
+  -fno-tree-sra \
+  -fprefetch-loop-arrays \
+  -funswitch-loops \
+  -Wmaybe-uninitialized \
+  -Wno-error=maybe-uninitialized \
+  -Wno-free-nonheap-object \
+  -Wno-literal-suffix \
+  -Wno-maybe-uninitialized \
+  -Wno-old-style-declaration \
   -Wno-psabi \
   -Wno-unused-but-set-variable \
   -Wno-unused-but-set-parameter \
-  -Wmaybe-uninitialized \
-  -Wno-maybe-uninitialized \
-  -Wno-error=maybe-uninitialized \
-  -fno-canonical-system-headers
+  -Wno-unused-local-typedefs
 
 # Clang flags for all host rules
 CLANG_CONFIG_HOST_EXTRA_ASFLAGS :=
@@ -75,17 +103,19 @@
 include $(BUILD_SYSTEM)/clang/TARGET_$(TARGET_2ND_ARCH).mk
 endif
 
-
-# Clang compiler-specific libc headers
-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
+ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan_$(TARGET_ARCH)_android
+ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS := -fsanitize=address -fno-omit-frame-pointer
 ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS := -Wl,-u,__asan_preinit
-ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES := libdl libasan_preload
+
+ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES := libdl $(ADDRESS_SANITIZER_RUNTIME_LIBRARY)
 ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES := libasan
 
 # This allows us to use the superset of functionality that compiler-rt
 # provides to Clang (for supporting features like -ftrapv).
 COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES := libcompiler_rt-extras
+
+ifeq ($(HOST_PREFER_32_BIT),true)
+# We don't have 32-bit prebuilt libLLVM/libclang, so force to build them from source.
+FORCE_BUILD_LLVM_COMPONENTS := true
+endif
diff --git a/core/clang/mips.mk b/core/clang/mips.mk
index cef7823..08daf40 100644
--- a/core/clang/mips.mk
+++ b/core/clang/mips.mk
@@ -7,18 +7,10 @@
 # Include common unknown flags
 CLANG_CONFIG_mips_UNKNOWN_CFLAGS := \
   $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
-  -EL \
-  -mips32 \
-  -mips32r2 \
-  -mhard-float \
   -fno-strict-volatile-bitfields \
   -fgcse-after-reload \
   -frerun-cse-after-loop \
   -frename-registers \
-  -march=mips32r2 \
-  -mtune=mips32r2 \
-  -march=mips32 \
-  -mtune=mips32 \
   -msynci \
   -mno-fused-madd
 
diff --git a/core/clang/mips64.mk b/core/clang/mips64.mk
index 9d1117b..612175c 100644
--- a/core/clang/mips64.mk
+++ b/core/clang/mips64.mk
@@ -1,7 +1,5 @@
 # Clang flags for mips64 arch, target or host.
 
-$(warning Untested mips64 clang flags, fix me!)
-
 CLANG_CONFIG_mips64_EXTRA_ASFLAGS :=
 CLANG_CONFIG_mips64_EXTRA_CFLAGS :=
 CLANG_CONFIG_mips64_EXTRA_LDFLAGS :=
@@ -9,18 +7,10 @@
 # Include common unknown flags
 CLANG_CONFIG_mips64_UNKNOWN_CFLAGS := \
   $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
-  -EL \
-  -mips32 \
-  -mips32r2 \
-  -mhard-float \
   -fno-strict-volatile-bitfields \
   -fgcse-after-reload \
   -frerun-cse-after-loop \
   -frename-registers \
-  -march=mips32r2 \
-  -mtune=mips32r2 \
-  -march=mips32 \
-  -mtune=mips32 \
   -msynci \
   -mno-fused-madd
 
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index 8731457..cf980d8 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -132,23 +132,11 @@
 
 previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
 
-# TODO: this special case for the sdk is only necessary while "sdk"
-# is a valid make target.  Eventually, it will just be a product, at
-# which point TARGET_PRODUCT will handle it and we can avoid this check
-# of MAKECMDGOALS.  The "addprefix" is just to keep things pretty.
-ifneq ($(TARGET_PRODUCT),sdk)
-  building_sdk := $(addprefix -,$(filter sdk,$(MAKECMDGOALS)))
-else
-  # Don't bother with this extra part when explicitly building the sdk product.
-  building_sdk :=
-endif
-
 # A change in the list of aapt configs warrants an installclean, too.
 aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG))
 
 current_build_config := \
-    $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(aapt_config_list)}
-building_sdk :=
+    $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)-{$(aapt_config_list)}
 aapt_config_list :=
 force_installclean := false
 
@@ -214,13 +202,17 @@
 	$(PRODUCT_OUT)/recovery \
 	$(PRODUCT_OUT)/root \
 	$(PRODUCT_OUT)/system \
+	$(PRODUCT_OUT)/vendor \
+	$(PRODUCT_OUT)/oem \
 	$(PRODUCT_OUT)/dex_bootjars \
 	$(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
 	$(PRODUCT_OUT)/obj/FAKE \
 	$(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \
+	$(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libfs_mgr_intermediates \
 	$(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \
 	$(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \
-	$(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates
+	$(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \
+	$(PRODUCT_OUT)/obj/ETC/init.environ.rc_intermediates
 
 # The files/dirs to delete during a dataclean, which removes any files
 # in the staging and emulator data partitions.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 93ec226..7837ae3 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -20,15 +20,18 @@
 LOCAL_MODULE_CLASS:=
 LOCAL_MODULE_SUFFIX:=
 LOCAL_PACKAGE_NAME:=
+LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES:=
 LOCAL_OVERRIDES_PACKAGES:=
 LOCAL_EXPORT_PACKAGE_RESOURCES:=
 LOCAL_MANIFEST_PACKAGE_NAME:=
+LOCAL_PACKAGE_SPLITS:=
 LOCAL_REQUIRED_MODULES:=
 LOCAL_ACP_UNAVAILABLE:=
 LOCAL_MODULE_TAGS:=
 LOCAL_SRC_FILES:=
 LOCAL_PREBUILT_OBJ_FILES:=
 LOCAL_STATIC_JAVA_LIBRARIES:=
+LOCAL_STATIC_JAVA_AAR_LIBRARIES:=
 LOCAL_STATIC_LIBRARIES:=
 # Group static libraries with "-Wl,--start-group" and "-Wl,--end-group" when linking.
 LOCAL_GROUP_STATIC_LIBRARIES:=
@@ -45,11 +48,16 @@
 LOCAL_ASFLAGS:=
 LOCAL_CFLAGS:=
 LOCAL_CPPFLAGS:=
+LOCAL_CLANG_ASFLAGS:=
+LOCAL_CLANG_CFLAGS:=
+LOCAL_CLANG_CONLYFLAGS:=
+LOCAL_CLANG_CPPFLAGS:=
 LOCAL_CONLYFLAGS:=
 LOCAL_RTTI_FLAG:=
 LOCAL_C_INCLUDES:=
 LOCAL_EXPORT_C_INCLUDE_DIRS:=
 LOCAL_LDFLAGS:=
+LOCAL_CLANG_LDFLAGS:=
 LOCAL_LDLIBS:=
 LOCAL_AAPT_FLAGS:=
 LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
@@ -88,10 +96,12 @@
 LOCAL_STRIP_MODULE:=
 LOCAL_JNI_SHARED_LIBRARIES:=
 LOCAL_JNI_SHARED_LIBRARIES_ABI:=
+LOCAL_JNI_SHARED_LIBRARIES_ZIP_OPTIONS:=
 LOCAL_PREBUILT_JNI_LIBS:=
 LOCAL_JAR_MANIFEST:=
 LOCAL_INSTRUMENTATION_FOR:=
 LOCAL_APK_LIBRARIES:=
+LOCAL_RES_LIBRARIES:=
 LOCAL_MANIFEST_INSTRUMENTATION_FOR:=
 LOCAL_AIDL_INCLUDES:=
 LOCAL_JARJAR_RULES:=
@@ -111,6 +121,7 @@
 LOCAL_WARNINGS_ENABLE:=
 LOCAL_FULL_MANIFEST_FILE:=
 LOCAL_MANIFEST_FILE:=
+LOCAL_FULL_LIBS_MANIFEST_FILES:=
 LOCAL_RENDERSCRIPT_INCLUDES:=
 LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE:=
 LOCAL_RENDERSCRIPT_CC:=
@@ -120,11 +131,13 @@
 LOCAL_RENDERSCRIPT_TARGET_API:=
 LOCAL_DEX_PREOPT:= # '',true,false,nostripping
 LOCAL_DEX_PREOPT_IMAGE_LOCATION:=
+LOCAL_DEX_PREOPT_FLAGS:=
 LOCAL_PROTOC_OPTIMIZE_TYPE:= # lite(default),micro,nano,full
 LOCAL_PROTOC_FLAGS:=
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
 LOCAL_NO_CRT:=
 LOCAL_PROPRIETARY_MODULE:=
+LOCAL_OEM_MODULE:=
 LOCAL_PRIVILEGED_MODULE:=
 LOCAL_MODULE_OWNER:=
 LOCAL_CTS_TEST_PACKAGE:=
@@ -133,15 +146,19 @@
 LOCAL_ADDRESS_SANITIZER:=
 LOCAL_JAR_EXCLUDE_FILES:=
 LOCAL_JAR_PACKAGES:=
+LOCAL_JAR_EXCLUDE_PACKAGES:=
 LOCAL_LINT_FLAGS:=
 LOCAL_SOURCE_FILES_ALL_GENERATED:= # '',true
 # Don't delete the META_INF dir when merging static Java libraries.
 LOCAL_DONT_DELETE_JAR_META_INF:=
+LOCAL_DONT_DELETE_JAR_DIRS:=
 LOCAL_ADDITIONAL_CERTIFICATES:=
 LOCAL_PREBUILT_MODULE_FILE:=
+LOCAL_POST_LINK_CMD:=
 LOCAL_POST_INSTALL_CMD:=
 LOCAL_DIST_BUNDLED_BINARIES:=
 LOCAL_HAL_STATIC_LIBRARIES:=
+LOCAL_RMTYPEDEFS:=
 LOCAL_NO_SYNTAX_CHECK:=
 LOCAL_NO_STATIC_ANALYZER:=
 LOCAL_32_BIT_ONLY:= # '',true
@@ -151,15 +168,24 @@
 LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH:=
 LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN:=
 LOCAL_MODULE_HOST_ARCH:=
+LOCAL_NO_FPIE :=
+LOCAL_CXX_STL := default
+LOCAL_NATIVE_COVERAGE :=
+LOCAL_DPI_VARIANTS:=
+LOCAL_DPI_FILE_STEM:=
 
 # arch specific variables
 LOCAL_SRC_FILES_$(TARGET_ARCH):=
 LOCAL_CFLAGS_$(TARGET_ARCH):=
+LOCAL_CLANG_CFLAGS_$(TARGET_ARCH):=
 LOCAL_CPPFLAGS_$(TARGET_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(TARGET_ARCH):=
 LOCAL_C_INCLUDES_$(TARGET_ARCH):=
 LOCAL_ASFLAGS_$(TARGET_ARCH):=
+LOCAL_CLANG_ASFLAGS_$(TARGET_ARCH):=
 LOCAL_NO_CRT_$(TARGET_ARCH):=
 LOCAL_LDFLAGS_$(TARGET_ARCH):=
+LOCAL_CLANG_LDFLAGS_$(TARGET_ARCH):=
 LOCAL_SHARED_LIBRARIES_$(TARGET_ARCH):=
 LOCAL_STATIC_LIBRARIES_$(TARGET_ARCH):=
 LOCAL_WHOLE_STATIC_LIBRARIES_$(TARGET_ARCH):=
@@ -170,11 +196,15 @@
 ifdef TARGET_2ND_ARCH
 LOCAL_SRC_FILES_$(TARGET_2ND_ARCH):=
 LOCAL_CFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CLANG_CFLAGS_$(TARGET_2ND_ARCH):=
 LOCAL_CPPFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(TARGET_2ND_ARCH):=
 LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH):=
 LOCAL_ASFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CLANG_ASFLAGS_$(TARGET_2ND_ARCH):=
 LOCAL_NO_CRT_$(TARGET_2ND_ARCH):=
 LOCAL_LDFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CLANG_LDFLAGS_$(TARGET_2ND_ARCH):=
 LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH):=
 LOCAL_STATIC_LIBRARIES_$(TARGET_2ND_ARCH):=
 LOCAL_WHOLE_STATIC_LIBRARIES_$(TARGET_2ND_ARCH):=
@@ -185,11 +215,15 @@
 endif
 LOCAL_SRC_FILES_$(HOST_ARCH):=
 LOCAL_CFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_CFLAGS_$(HOST_ARCH):=
 LOCAL_CPPFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(HOST_ARCH):=
 LOCAL_C_INCLUDES_$(HOST_ARCH):=
 LOCAL_ASFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_ASFLAGS_$(HOST_ARCH):=
 LOCAL_NO_CRT_$(HOST_ARCH):=
 LOCAL_LDFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_LDFLAGS_$(HOST_ARCH):=
 LOCAL_SHARED_LIBRARIES_$(HOST_ARCH):=
 LOCAL_STATIC_LIBRARIES_$(HOST_ARCH):=
 LOCAL_WHOLE_STATIC_LIBRARIES_$(HOST_ARCH):=
@@ -199,11 +233,15 @@
 ifdef HOST_2ND_ARCH
 LOCAL_SRC_FILES_$(HOST_2ND_ARCH):=
 LOCAL_CFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_CFLAGS_$(HOST_2ND_ARCH):=
 LOCAL_CPPFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(HOST_2ND_ARCH):=
 LOCAL_C_INCLUDES_$(HOST_2ND_ARCH):=
 LOCAL_ASFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_ASFLAGS_$(HOST_2ND_ARCH):=
 LOCAL_NO_CRT_$(HOST_2ND_ARCH):=
 LOCAL_LDFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_LDFLAGS_$(HOST_2ND_ARCH):=
 LOCAL_SHARED_LIBRARIES_$(HOST_2ND_ARCH):=
 LOCAL_STATIC_LIBRARIES_$(HOST_2ND_ARCH):=
 LOCAL_WHOLE_STATIC_LIBRARIES_$(HOST_2ND_ARCH):=
@@ -230,6 +268,14 @@
 LOCAL_LDFLAGS_64:=
 LOCAL_ASFLAGS_32:=
 LOCAL_ASFLAGS_64:=
+LOCAL_CLANG_CFLAGS_32:=
+LOCAL_CLANG_CFLAGS_64:=
+LOCAL_CLANG_CPPFLAGS_32:=
+LOCAL_CLANG_CPPFLAGS_64:=
+LOCAL_CLANG_LDFLAGS_32:=
+LOCAL_CLANG_LDFLAGS_64:=
+LOCAL_CLANG_ASFLAGS_32:=
+LOCAL_CLANG_ASFLAGS_64:=
 LOCAL_C_INCLUDES_32:=
 LOCAL_C_INCLUDES_64:=
 LOCAL_MODULE_PATH_32:=
diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
index 4a2bfe3..7fa48ff 100644
--- a/core/combo/HOST_darwin-x86.mk
+++ b/core/combo/HOST_darwin-x86.mk
@@ -33,19 +33,8 @@
 
 $(combo_2nd_arch_prefix)HOST_TOOLCHAIN_ROOT := prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1
 $(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_ROOT)/bin/i686-apple-darwin$(gcc_darwin_version)
-# Don't do anything if the toolchain is not there
-ifneq (,$(strip $(wildcard $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)-gcc)))
 $(combo_2nd_arch_prefix)HOST_CC  := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)-gcc
 $(combo_2nd_arch_prefix)HOST_CXX := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)-g++
-ifeq ($(mac_sdk_version),10.8)
-# Mac SDK 10.8 no longer has stdarg.h, etc
-host_toolchain_header := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_ROOT)/lib/gcc/i686-apple-darwin$(gcc_darwin_version)/4.2.1/include
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -isystem $(host_toolchain_header)
-endif
-else
-$(combo_2nd_arch_prefix)HOST_CC := gcc
-$(combo_2nd_arch_prefix)HOST_CXX := g++
-endif # $(HOST_TOOLCHAIN_PREFIX)-gcc exists
 
 # gcc location for clang; to be updated when clang is updated
 # HOST_TOOLCHAIN_ROOT is a Darwin-specific define
@@ -54,6 +43,7 @@
 $(combo_2nd_arch_prefix)HOST_AR := $(AR)
 
 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -isysroot $(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version) -DMACOSX_DEPLOYMENT_TARGET=$(mac_sdk_version)
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CPPFLAGS += -isystem $(mac_sdk_path)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
 $(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -isysroot $(mac_sdk_root) -Wl,-syslibroot,$(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version)
 
 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -fPIC -funwind-tables
diff --git a/core/combo/HOST_darwin-x86_64.mk b/core/combo/HOST_darwin-x86_64.mk
index 8ad3ba7..c06933d 100644
--- a/core/combo/HOST_darwin-x86_64.mk
+++ b/core/combo/HOST_darwin-x86_64.mk
@@ -17,8 +17,6 @@
 # Configuration for Darwin (Mac OS X) on x86_64.
 # Included by combo/select.mk
 
-HOST_IS_64_BIT := true
-
 HOST_GLOBAL_CFLAGS += -m64
 HOST_GLOBAL_LDFLAGS += -m64
 
@@ -35,19 +33,8 @@
 
 HOST_TOOLCHAIN_ROOT := prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1
 HOST_TOOLCHAIN_PREFIX := $(HOST_TOOLCHAIN_ROOT)/bin/i686-apple-darwin$(gcc_darwin_version)
-# Don't do anything if the toolchain is not there
-ifneq (,$(strip $(wildcard $(HOST_TOOLCHAIN_PREFIX)-gcc)))
 HOST_CC  := $(HOST_TOOLCHAIN_PREFIX)-gcc
 HOST_CXX := $(HOST_TOOLCHAIN_PREFIX)-g++
-ifeq ($(mac_sdk_version),10.8)
-# Mac SDK 10.8 no longer has stdarg.h, etc
-host_toolchain_header := $(HOST_TOOLCHAIN_ROOT)/lib/gcc/i686-apple-darwin$(gcc_darwin_version)/4.2.1/include
-HOST_GLOBAL_CFLAGS += -isystem $(host_toolchain_header)
-endif
-else
-HOST_CC := gcc
-HOST_CXX := g++
-endif # $(HOST_TOOLCHAIN_PREFIX)-gcc exists
 
 # gcc location for clang; to be updated when clang is updated
 # HOST_TOOLCHAIN_ROOT is a Darwin-specific define
@@ -56,6 +43,7 @@
 HOST_AR := $(AR)
 
 HOST_GLOBAL_CFLAGS += -isysroot $(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version) -DMACOSX_DEPLOYMENT_TARGET=$(mac_sdk_version)
+HOST_GLOBAL_CPPFLAGS += -isystem $(mac_sdk_path)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
 HOST_GLOBAL_LDFLAGS += -isysroot $(mac_sdk_root) -Wl,-syslibroot,$(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version)
 
 HOST_GLOBAL_CFLAGS += -fPIC -funwind-tables
diff --git a/core/combo/HOST_linux-x86.mk b/core/combo/HOST_linux-x86.mk
index c931937..93a1287 100644
--- a/core/combo/HOST_linux-x86.mk
+++ b/core/combo/HOST_linux-x86.mk
@@ -18,20 +18,17 @@
 # Included by combo/select.mk
 
 ifeq ($(strip $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)),)
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/bin/x86_64-linux-
+$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/bin/x86_64-linux-
 endif
-# Don't do anything if the toolchain is not there
-ifneq (,$(strip $(wildcard $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)gcc)))
 $(combo_2nd_arch_prefix)HOST_CC  := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)gcc
 $(combo_2nd_arch_prefix)HOST_CXX := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)g++
 $(combo_2nd_arch_prefix)HOST_AR  := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)ar
-endif # $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)gcc exists
 
 # gcc location for clang; to be updated when clang is updated
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/
+$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/
 
 # We expect SSE3 floating point math.
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -mstackrealign -msse3 -mfpmath=sse -m32 -Wa,--noexecstack
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -msse3 -mfpmath=sse -m32 -Wa,--noexecstack -march=prescott
 $(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -m32 -Wl,-z,noexecstack
 
 ifneq ($(strip $(BUILD_HOST_static)),)
@@ -43,7 +40,7 @@
   -no-canonical-prefixes \
   -include $(call select-android-config-h,linux-x86)
 
-# Disable new longjmp in glibc 2.11 and later. See bug 2967937.
+# Disable new longjmp in glibc 2.11 and later. See bug 2967937. Same for 2.15?
 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
 
 # Workaround differences in inttypes.h between host and target.
diff --git a/core/combo/HOST_linux-x86_64.mk b/core/combo/HOST_linux-x86_64.mk
index 8f3a311..3685712 100644
--- a/core/combo/HOST_linux-x86_64.mk
+++ b/core/combo/HOST_linux-x86_64.mk
@@ -17,20 +17,15 @@
 # Configuration for builds hosted on linux-x86_64.
 # Included by combo/select.mk
 
-HOST_IS_64_BIT := true
-
 ifeq ($(strip $(HOST_TOOLCHAIN_PREFIX)),)
-HOST_TOOLCHAIN_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/bin/x86_64-linux-
+HOST_TOOLCHAIN_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/bin/x86_64-linux-
 endif
-# Don't do anything if the toolchain is not there
-ifneq (,$(strip $(wildcard $(HOST_TOOLCHAIN_PREFIX)gcc)))
 HOST_CC  := $(HOST_TOOLCHAIN_PREFIX)gcc
 HOST_CXX := $(HOST_TOOLCHAIN_PREFIX)g++
 HOST_AR  := $(HOST_TOOLCHAIN_PREFIX)ar
-endif # $(HOST_TOOLCHAIN_PREFIX)gcc exists
 
 # gcc location for clang; to be updated when clang is updated
-HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/
+HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/
 
 HOST_GLOBAL_CFLAGS += -m64 -Wa,--noexecstack
 HOST_GLOBAL_LDFLAGS += -m64 -Wl,-z,noexecstack
@@ -45,7 +40,7 @@
   -no-canonical-prefixes \
   -include $(call select-android-config-h,linux-x86)
 
-# Disable new longjmp in glibc 2.11 and later. See bug 2967937.
+# Disable new longjmp in glibc 2.11 and later. See bug 2967937. Same for 2.15?
 HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
 
 # Workaround differences in inttypes.h between host and target.
diff --git a/core/combo/HOST_windows-x86.mk b/core/combo/HOST_windows-x86.mk
index 4d871d8..b71ac16 100644
--- a/core/combo/HOST_windows-x86.mk
+++ b/core/combo/HOST_windows-x86.mk
@@ -24,13 +24,18 @@
 
 # Settings to use MinGW has a cross-compiler under Linux
 ifneq ($(findstring Linux,$(UNAME)),)
-ifneq ($(strip $(USE_MINGW)),)
+ifdef USE_MINGW
 HOST_ACP_UNAVAILABLE := true
 TOOLS_EXE_SUFFIX :=
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -DUSE_MINGW
-TOOLS_PREFIX := /usr/bin/i586-mingw32msvc-
-$(combo_2nd_arch_prefix)HOST_C_INCLUDES += /usr/lib/gcc/i586-mingw32msvc/3.4.4/include
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LD_DIRS += -L/usr/i586-mingw32msvc/lib
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -DUSE_MINGW -DWIN32_LEAN_AND_MEAN
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -Wno-unused-parameter
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += --sysroot=prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -m32
+$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -m32
+TOOLS_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/bin/x86_64-w64-mingw32-
+$(combo_2nd_arch_prefix)HOST_C_INCLUDES += prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/include
+$(combo_2nd_arch_prefix)HOST_C_INCLUDES += prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/lib/gcc/x86_64-w64-mingw32/4.8.3/include
+$(combo_2nd_arch_prefix)HOST_GLOBAL_LD_DIRS += -Lprebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib32
 endif # USE_MINGW
 endif # Linux
 
diff --git a/core/combo/HOST_windows-x86_64.mk b/core/combo/HOST_windows-x86_64.mk
index 9edc619..bd392ea 100644
--- a/core/combo/HOST_windows-x86_64.mk
+++ b/core/combo/HOST_windows-x86_64.mk
@@ -22,11 +22,9 @@
 TOOLS_PREFIX := #prebuilt/windows/host/bin/
 TOOLS_EXE_SUFFIX := .exe
 
-HOST_IS_64_BIT := true
-
 # Settings to use MinGW has a cross-compiler under Linux
 ifneq ($(findstring Linux,$(UNAME)),)
-ifneq ($(strip $(USE_MINGW)),)
+ifdef USE_MINGW
 HOST_ACP_UNAVAILABLE := true
 TOOLS_EXE_SUFFIX :=
 HOST_GLOBAL_CFLAGS += -DUSE_MINGW
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 4fe0bcd..8059b2a 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -35,10 +35,10 @@
 endif
 
 # Decouple NDK library selection with platform compiler version
-$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.8
+$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.9
 
 ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.8
+$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.9
 else
 $(combo_2nd_arch_prefix)TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
@@ -49,6 +49,7 @@
 endif
 
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
+include $(BUILD_SYSTEM)/combo/fdo.mk
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
@@ -94,7 +95,7 @@
 android_config_h := $(call select-android-config-h,linux-arm)
 
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += \
-			-msoft-float -fpic -fPIE \
+			-msoft-float \
 			-ffunction-sections \
 			-fdata-sections \
 			-funwind-tables \
@@ -113,8 +114,8 @@
 # "-Wall -Werror" due to a commom idiom "ALOGV(mesg)" where ALOGV is turned
 # 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 \
+ifneq ($(filter 4.6 4.6.% 4.7 4.7.% 4.8 4.9, $($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)),)
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -fno-builtin-sin \
 			-fno-strict-volatile-bitfields
 endif
 
@@ -132,9 +133,11 @@
 			-Wl,-z,noexecstack \
 			-Wl,-z,relro \
 			-Wl,-z,now \
+			-Wl,--build-id=md5 \
 			-Wl,--warn-shared-textrel \
 			-Wl,--fatal-warnings \
 			-Wl,--icf=safe \
+			-Wl,--hash-style=gnu \
 			$(arch_variant_ldflags)
 
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -mthumb-interwork
@@ -152,7 +155,6 @@
 
 libc_root := bionic/libc
 libm_root := bionic/libm
-libstdc++_root := bionic/libstdc++
 
 
 ## on some hosts, the target cross-compiler is not available so do not run this command
@@ -164,39 +166,10 @@
         $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-libgcc-file-name)
 $(combo_2nd_arch_prefix)TARGET_LIBATOMIC := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) \
         $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libatomic.a)
-target_libgcov := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
-        -print-file-name=libgcov.a)
+$(combo_2nd_arch_prefix)TARGET_LIBGCOV := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) \
+        $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libgcov.a)
 endif
 
-# Define FDO (Feedback Directed Optimization) options.
-
-$(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS:=
-$(combo_2nd_arch_prefix)TARGET_FDO_LIB:=
-
-ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
-  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
-  # The profile will be generated on /data/local/tmp/profile on the device.
-  $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
-  $(combo_2nd_arch_prefix)TARGET_FDO_LIB := $(target_libgcov)
-else
-  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
-  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
-  ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH)),)
-    $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_$(combo_2nd_arch_prefix)ARCH)/$(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT)
-  else
-    ifeq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH))),)
-      $(warning Custom $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
-    endif
-  endif
-
-  # If the FDO profile directory can't be found, then FDO is off.
-  ifneq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH))),)
-    $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-use=$($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
-    $(combo_2nd_arch_prefix)TARGET_FDO_LIB := $(target_libgcov)
-  endif
-endif
-
-
 KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
 KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/asm-$(TARGET_$(combo_2nd_arch_prefix)ARCH)
 KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
@@ -204,7 +177,6 @@
 $(combo_2nd_arch_prefix)TARGET_C_INCLUDES := \
 	$(libc_root)/arch-arm/include \
 	$(libc_root)/include \
-	$(libstdc++_root)/include \
 	$(KERNEL_HEADERS) \
 	$(libm_root)/include \
 	$(libm_root)/include/arm \
@@ -218,83 +190,6 @@
 
 $(combo_2nd_arch_prefix)TARGET_STRIP_MODULE:=true
 
-$(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+$(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
-$(combo_2nd_arch_prefix)TARGET_CUSTOM_LD_COMMAND := true
-
-define $(combo_2nd_arch_prefix)transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-	-nostdlib -Wl,-soname,$(notdir $@) \
-	-Wl,--gc-sections \
-	-Wl,-shared,-Bsymbolic \
-	-shared \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define $(combo_2nd_arch_prefix)transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -fPIE -pie \
-	-Wl,-dynamic-linker,/system/bin/linker \
-	-Wl,--gc-sections \
-	-Wl,-z,nocopyreloc \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define $(combo_2nd_arch_prefix)transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bstatic \
-	-Wl,--gc-sections \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(call normalize-target-libraries,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
-	-Wl,--start-group \
-	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	-Wl,--end-group \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
-endef
+$(combo_2nd_arch_prefix)TARGET_LINKER := /system/bin/linker
diff --git a/core/combo/TARGET_linux-arm64.mk b/core/combo/TARGET_linux-arm64.mk
index 4bb665c..07a1de9 100644
--- a/core/combo/TARGET_linux-arm64.mk
+++ b/core/combo/TARGET_linux-arm64.mk
@@ -35,7 +35,7 @@
 endif
 
 # Decouple NDK library selection with platform compiler version
-TARGET_NDK_GCC_VERSION := 4.8
+TARGET_NDK_GCC_VERSION := 4.9
 
 ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
 TARGET_GCC_VERSION := 4.9
@@ -43,14 +43,13 @@
 TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
 
-TARGET_IS_64_BIT := true
-
 TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
 ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
 $(error Unknown ARM architecture version: $(TARGET_ARCH_VARIANT))
 endif
 
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
+include $(BUILD_SYSTEM)/combo/fdo.mk
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
@@ -74,7 +73,6 @@
 android_config_h := $(call select-android-config-h,linux-arm64)
 
 TARGET_GLOBAL_CFLAGS += \
-			-fpic -fPIE \
 			-fstack-protector \
 			-ffunction-sections \
 			-fdata-sections \
@@ -93,6 +91,7 @@
 TARGET_GLOBAL_CFLAGS += \
     -Werror=pointer-to-int-cast \
     -Werror=int-to-pointer-cast \
+    -Werror=implicit-function-declaration \
 
 TARGET_GLOBAL_CFLAGS += -fno-strict-volatile-bitfields
 
@@ -110,11 +109,16 @@
 			-Wl,-z,noexecstack \
 			-Wl,-z,relro \
 			-Wl,-z,now \
+			-Wl,--build-id=md5 \
 			-Wl,--warn-shared-textrel \
 			-Wl,--fatal-warnings \
 			-Wl,-maarch64linux \
+			-Wl,--hash-style=gnu \
 			$(arch_variant_ldflags)
 
+# Disable transitive dependency library symbol resolving.
+TARGET_GLOBAL_LDFLAGS += -Wl,--allow-shlib-undefined
+
 TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
 
 # More flags/options can be added here
@@ -128,12 +132,13 @@
 
 libc_root := bionic/libc
 libm_root := bionic/libm
-libstdc++_root := bionic/libstdc++
 
 TARGET_LIBGCC := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
 	-print-libgcc-file-name)
 TARGET_LIBATOMIC := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
 	-print-file-name=libatomic.a)
+TARGET_LIBGCOV := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
+	-print-file-name=libgcov.a)
 
 KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
 KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/asm-$(TARGET_ARCH)
@@ -142,7 +147,6 @@
 TARGET_C_INCLUDES := \
 	$(libc_root)/arch-arm64/include \
 	$(libc_root)/include \
-	$(libstdc++_root)/include \
 	$(KERNEL_HEADERS) \
 	$(libm_root)/include \
 	$(libm_root)/include/arm64 \
@@ -156,83 +160,6 @@
 
 TARGET_STRIP_MODULE:=true
 
-TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
-TARGET_CUSTOM_LD_COMMAND := true
-
-define transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-	-nostdlib -Wl,-soname,$(notdir $@) \
-	-Wl,--gc-sections \
-	-Wl,-shared,-Bsymbolic \
-	-shared \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -fPIE -pie \
-	-Wl,-dynamic-linker,/system/bin/linker64 \
-	-Wl,--gc-sections \
-	-Wl,-z,nocopyreloc \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bstatic \
-	-Wl,--gc-sections \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(call normalize-target-libraries,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
-	-Wl,--start-group \
-	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	-Wl,--end-group \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
-endef
+TARGET_LINKER := /system/bin/linker64
diff --git a/core/combo/TARGET_linux-mips.mk b/core/combo/TARGET_linux-mips.mk
index f52c375..55566eb 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -35,10 +35,10 @@
 endif
 
 # Decouple NDK library selection with platform compiler version
-$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.8
+$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.9
 
 ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.8
+$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.9
 else
 $(combo_2nd_arch_prefix)TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
@@ -49,11 +49,12 @@
 endif
 
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
+include $(BUILD_SYSTEM)/combo/fdo.mk
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
-$(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-$($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)
-$(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/mipsel-linux-android-
+$(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mips64el-linux-android-$($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)
+$(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/mips64el-linux-android-
 endif
 
 $(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
@@ -83,7 +84,6 @@
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += \
 			$(TARGET_mips_CFLAGS) \
 			-U__unix -U__unix__ -Umips \
-			-fpic -fPIE\
 			-ffunction-sections \
 			-fdata-sections \
 			-funwind-tables \
@@ -96,24 +96,6 @@
 			-include $(android_config_h) \
 			-I $(dir $(android_config_h))
 
-# This warning causes dalvik not to build with gcc 4.6+ and -Werror.
-# We cannot turn it off blindly since the option is not available
-# in gcc-4.4.x.
-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-strict-volatile-bitfields
-endif
-
-# This is to avoid the dreaded warning compiler message:
-#   note: the mangling of 'va_list' has changed in GCC 4.4
-#
-# The fact that the mangling changed does not affect the NDK ABI
-# very fortunately (since none of the exposed APIs used va_list
-# in their exported C++ functions). Also, GCC 4.5 has already
-# removed the warning from the compiler.
-#
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -Wno-psabi
-
 ifneq ($(ARCH_MIPS_PAGE_SHIFT),)
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -DPAGE_SHIFT=$(ARCH_MIPS_PAGE_SHIFT)
 endif
@@ -122,10 +104,14 @@
 			-Wl,-z,noexecstack \
 			-Wl,-z,relro \
 			-Wl,-z,now \
+			-Wl,--build-id=md5 \
 			-Wl,--warn-shared-textrel \
 			-Wl,--fatal-warnings \
 			$(arch_variant_ldflags)
 
+# Disable transitive dependency library symbol resolving.
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--allow-shlib-undefined
+
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
 
 # More flags/options can be added here
@@ -139,7 +125,6 @@
 
 libc_root := bionic/libc
 libm_root := bionic/libm
-libstdc++_root := bionic/libstdc++
 
 
 ## on some hosts, the target cross-compiler is not available so do not run this command
@@ -155,39 +140,10 @@
 ifneq ($(LIBGCC_EH),libgcc_eh.a)
   $(combo_2nd_arch_prefix)TARGET_LIBGCC += $(LIBGCC_EH)
 endif
-target_libgcov := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
+$(combo_2nd_arch_prefix)TARGET_LIBGCOV := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
         --print-file-name=libgcov.a)
 endif
 
-# Define FDO (Feedback Directed Optimization) options.
-
-$(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS:=
-$(combo_2nd_arch_prefix)TARGET_FDO_LIB:=
-
-ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
-  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
-  # The profile will be generated on /data/local/tmp/profile on the device.
-  $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
-  $(combo_2nd_arch_prefix)TARGET_FDO_LIB := $(target_libgcov)
-else
-  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
-  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
-  ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH)),)
-    $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_$(combo_2nd_arch_prefix)ARCH)/$(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT)
-  else
-    ifeq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH))),)
-      $(warning Custom $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
-    endif
-  endif
-
-  # If the FDO profile directory can't be found, then FDO is off.
-  ifneq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH))),)
-    $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-use=$($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
-    $(combo_2nd_arch_prefix)TARGET_FDO_LIB := $(target_libgcov)
-  endif
-endif
-
-
 KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
 KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/asm-mips # mips covers both mips and mips64.
 KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
@@ -195,7 +151,6 @@
 $(combo_2nd_arch_prefix)TARGET_C_INCLUDES := \
 	$(libc_root)/arch-mips/include \
 	$(libc_root)/include \
-	$(libstdc++_root)/include \
 	$(KERNEL_HEADERS) \
 	$(libm_root)/include \
 	$(libm_root)/include/mips \
@@ -209,83 +164,6 @@
 
 $(combo_2nd_arch_prefix)TARGET_STRIP_MODULE:=true
 
-$(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+$(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
-$(combo_2nd_arch_prefix)TARGET_CUSTOM_LD_COMMAND := true
-
-define $(combo_2nd_arch_prefix)transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-	-nostdlib -Wl,-soname,$(notdir $@) \
-	-Wl,--gc-sections \
-	-Wl,-shared,-Bsymbolic \
-	-shared \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define $(combo_2nd_arch_prefix)transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -fPIE -pie \
-	-Wl,-dynamic-linker,/system/bin/linker \
-	-Wl,--gc-sections \
-	-Wl,-z,nocopyreloc \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define $(combo_2nd_arch_prefix)transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bstatic \
-	-Wl,--gc-sections \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(call normalize-target-libraries,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
-	-Wl,--start-group \
-	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	-Wl,--end-group \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
-endef
+$(combo_2nd_arch_prefix)TARGET_LINKER := /system/bin/linker
diff --git a/core/combo/TARGET_linux-mips64.mk b/core/combo/TARGET_linux-mips64.mk
index e9f5adb..c6f9f29 100644
--- a/core/combo/TARGET_linux-mips64.mk
+++ b/core/combo/TARGET_linux-mips64.mk
@@ -18,7 +18,7 @@
 # Included by combo/select.mk
 
 # You can set TARGET_ARCH_VARIANT to use an arch version other
-# than mips64. Each value should correspond to a file named
+# than mips64r6. Each value should correspond to a file named
 # $(BUILD_COMBOS)/arch/<name>.mk which must contain
 # makefile variable definitions similar to the preprocessor
 # defines in build/core/combo/include/arch/<combo>/AndroidConfig.h. Their
@@ -31,29 +31,25 @@
 # version.
 #
 ifeq ($(strip $(TARGET_ARCH_VARIANT)),)
-TARGET_ARCH_VARIANT := mips64r2
+TARGET_ARCH_VARIANT := mips64r6
 endif
 
 # Decouple NDK library selection with platform compiler version
-TARGET_NDK_GCC_VERSION := 4.8
+TARGET_NDK_GCC_VERSION := 4.9
 
 ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-TARGET_GCC_VERSION := 4.8
+TARGET_GCC_VERSION := 4.9
 else
 TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
 
-TARGET_IS_64_BIT := true
-
 TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
 ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
 $(error Unknown MIPS architecture variant: $(TARGET_ARCH_VARIANT))
 endif
 
-# TODO: Enable Clang when its mips64 prebuilt is added
-WITHOUT_TARGET_CLANG := true
-
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
+include $(BUILD_SYSTEM)/combo/fdo.mk
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
@@ -88,7 +84,6 @@
 TARGET_GLOBAL_CFLAGS += \
 			$(TARGET_mips_CFLAGS) \
 			-U__unix -U__unix__ -Umips \
-			-fpic -fPIE\
 			-ffunction-sections \
 			-fdata-sections \
 			-funwind-tables \
@@ -101,23 +96,11 @@
 			-include $(android_config_h) \
 			-I $(dir $(android_config_h))
 
-# This warning causes dalvik not to build with gcc 4.6+ and -Werror.
-# We cannot turn it off blindly since the option is not available
-# in gcc-4.4.x.
-ifneq ($(filter 4.6 4.6.% 4.7 4.7.% 4.8, $(TARGET_GCC_VERSION)),)
-TARGET_GLOBAL_CFLAGS += -Wno-unused-but-set-variable \
-                        -fno-strict-volatile-bitfields
-endif
-
-# This is to avoid the dreaded warning compiler message:
-#   note: the mangling of 'va_list' has changed in GCC 4.4
-#
-# The fact that the mangling changed does not affect the NDK ABI
-# very fortunately (since none of the exposed APIs used va_list
-# in their exported C++ functions). Also, GCC 4.5 has already
-# removed the warning from the compiler.
-#
-TARGET_GLOBAL_CFLAGS += -Wno-psabi
+# Help catch common 32/64-bit errors.
+TARGET_GLOBAL_CFLAGS += \
+    -Werror=pointer-to-int-cast \
+    -Werror=int-to-pointer-cast \
+    -Werror=implicit-function-declaration \
 
 ifneq ($(ARCH_MIPS_PAGE_SHIFT),)
 TARGET_GLOBAL_CFLAGS += -DPAGE_SHIFT=$(ARCH_MIPS_PAGE_SHIFT)
@@ -127,6 +110,7 @@
 			-Wl,-z,noexecstack \
 			-Wl,-z,relro \
 			-Wl,-z,now \
+			-Wl,--build-id=md5 \
 			-Wl,--warn-shared-textrel \
 			-Wl,--fatal-warnings \
 			$(arch_variant_ldflags)
@@ -144,7 +128,6 @@
 
 libc_root := bionic/libc
 libm_root := bionic/libm
-libstdc++_root := bionic/libstdc++
 libthread_db_root := bionic/libthread_db
 
 
@@ -161,39 +144,10 @@
 ifneq ($(LIBGCC_EH),libgcc_eh.a)
   TARGET_LIBGCC += $(LIBGCC_EH)
 endif
-target_libgcov := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
+TARGET_LIBGCOV := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
         --print-file-name=libgcov.a)
 endif
 
-# Define FDO (Feedback Directed Optimization) options.
-
-TARGET_FDO_CFLAGS:=
-TARGET_FDO_LIB:=
-
-ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
-  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
-  # The profile will be generated on /data/local/tmp/profile on the device.
-  TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
-  TARGET_FDO_LIB := $(target_libgcov)
-else
-  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
-  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
-  ifeq ($(strip $(TARGET_FDO_PROFILE_PATH)),)
-    TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT)
-  else
-    ifeq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
-      $(warning Custom TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
-    endif
-  endif
-
-  # If the FDO profile directory can't be found, then FDO is off.
-  ifneq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
-    TARGET_FDO_CFLAGS := -fprofile-use=$(TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
-    TARGET_FDO_LIB := $(target_libgcov)
-  endif
-endif
-
-
 KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
 KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/asm-mips
 # TODO: perhaps use $(libc_root)/kernel/uapi/asm-$(TARGET_ARCH) instead of asm-mips ?
@@ -202,7 +156,6 @@
 TARGET_C_INCLUDES := \
 	$(libc_root)/arch-mips64/include \
 	$(libc_root)/include \
-	$(libstdc++_root)/include \
 	$(KERNEL_HEADERS) \
 	$(libm_root)/include \
 	$(libm_root)/include/mips \
@@ -220,81 +173,4 @@
 
 TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
 
-TARGET_CUSTOM_LD_COMMAND := true
-
-define transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-	-nostdlib -Wl,-soname,$(notdir $@) \
-	-Wl,--gc-sections \
-	-shared \
-	-Wl,-shared,-Bsymbolic \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -fPIE -pie \
-	-Wl,-dynamic-linker,/system/bin/linker64 \
-	-Wl,--gc-sections \
-	-Wl,-z,nocopyreloc \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bstatic \
-	-Wl,--gc-sections \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(call normalize-target-libraries,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
-	-Wl,--start-group \
-	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	-Wl,--end-group \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
-endef
+TARGET_LINKER := /system/bin/linker64
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
index bc13fb9..f17a514 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -41,7 +41,7 @@
 endif
 
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
-
+include $(BUILD_SYSTEM)/combo/fdo.mk
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
@@ -62,43 +62,14 @@
 	$(shell $($(combo_2nd_arch_prefix)TARGET_CC) -m32 -print-file-name=libgcc.a)
 $(combo_2nd_arch_prefix)TARGET_LIBATOMIC := \
 	$(shell $($(combo_2nd_arch_prefix)TARGET_CC) -m32 -print-file-name=libatomic.a)
-target_libgcov := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
-	-print-file-name=libgcov.a)
+$(combo_2nd_arch_prefix)TARGET_LIBGCOV := \
+	$(shell $($(combo_2nd_arch_prefix)TARGET_CC) -m32 -print-file-name=libgcov.a)
 endif
 
 $(combo_2nd_arch_prefix)TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
 libc_root := bionic/libc
 libm_root := bionic/libm
-libstdc++_root := bionic/libstdc++
-
-# Define FDO (Feedback Directed Optimization) options.
-
-$(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS:=
-$(combo_2nd_arch_prefix)TARGET_FDO_LIB:=
-
-ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
-  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
-  # The profile will be generated on /data/local/tmp/profile on the device.
-  $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
-  $(combo_2nd_arch_prefix)TARGET_FDO_LIB := $(target_libgcov)
-else
-  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
-  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
-  ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH)),)
-    $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_$(combo_2nd_arch_prefix)ARCH)/$(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT)
-  else
-    ifeq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH))),)
-      $(warning Custom $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
-    endif
-  endif
-
-  # If the FDO profile directory can't be found, then FDO is off.
-  ifneq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH))),)
-    $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-use=$($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
-    $(combo_2nd_arch_prefix)TARGET_FDO_LIB := $(target_libgcov)
-  endif
-endif
 
 KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
 KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/asm-x86 # x86 covers both x86 and x86_64.
@@ -112,18 +83,15 @@
 			-Werror=format-security \
 			-D_FORTIFY_SOURCE=2 \
 			-Wstrict-aliasing=2 \
-			-fPIC -fPIE \
 			-ffunction-sections \
 			-finline-functions \
 			-finline-limit=300 \
-			-fno-inline-functions-called-once \
 			-fno-short-enums \
 			-fstrict-aliasing \
 			-funswitch-loops \
 			-funwind-tables \
 			-fstack-protector \
 			-m32 \
-			-msse2 \
 			-no-canonical-prefixes \
 			-fno-canonical-system-headers \
 			-include $(android_config_h) \
@@ -154,14 +122,15 @@
 
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,-z,relro -Wl,-z,now
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--build-id=md5
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--warn-shared-textrel
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--fatal-warnings
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--gc-sections
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--hash-style=gnu
 
 $(combo_2nd_arch_prefix)TARGET_C_INCLUDES := \
 	$(libc_root)/arch-x86/include \
 	$(libc_root)/include \
-	$(libstdc++_root)/include \
 	$(KERNEL_HEADERS) \
 	$(libm_root)/include \
 	$(libm_root)/include/i387 \
@@ -175,78 +144,8 @@
 
 $(combo_2nd_arch_prefix)TARGET_STRIP_MODULE:=true
 
-$(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+$(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
-$(combo_2nd_arch_prefix)TARGET_CUSTOM_LD_COMMAND := true
-define $(combo_2nd_arch_prefix)transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	 -nostdlib -Wl,-soname,$(notdir $@) \
-	 -shared -Bsymbolic \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O)) \
-	$(PRIVATE_LDLIBS)
-endef
+$(combo_2nd_arch_prefix)TARGET_LINKER := /system/bin/linker
 
-define $(combo_2nd_arch_prefix)transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	-nostdlib -Bdynamic \
-	-Wl,-z,nocopyreloc \
-	-fPIE -pie \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define $(combo_2nd_arch_prefix)transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	-nostdlib -Bstatic \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	-Wl,--start-group \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	-Wl,--end-group \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
-endef
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_YASM_FLAGS := -f elf32 -m x86
diff --git a/core/combo/TARGET_linux-x86_64.mk b/core/combo/TARGET_linux-x86_64.mk
index 43e12b1..c945b3e 100644
--- a/core/combo/TARGET_linux-x86_64.mk
+++ b/core/combo/TARGET_linux-x86_64.mk
@@ -31,8 +31,6 @@
 TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
 
-TARGET_IS_64_BIT := true
-
 # Include the arch-variant-specific configuration file.
 # Its role is to define various ARCH_X86_HAVE_XXX feature macros,
 # plus initial values for TARGET_GLOBAL_CFLAGS
@@ -43,7 +41,7 @@
 endif
 
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
-
+include $(BUILD_SYSTEM)/combo/fdo.mk
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
@@ -64,43 +62,14 @@
 	$(shell $(TARGET_CC) -m64 -print-file-name=libgcc.a)
 TARGET_LIBATOMIC := \
 	$(shell $(TARGET_CC) -m64 -print-file-name=libatomic.a)
-target_libgcov := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
-	-print-file-name=libgcov.a)
+TARGET_LIBGCOV := \
+	$(shell $(TARGET_CC) -m64 -print-file-name=libgcov.a)
 endif
 
 TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
 libc_root := bionic/libc
 libm_root := bionic/libm
-libstdc++_root := bionic/libstdc++
-
-# Define FDO (Feedback Directed Optimization) options.
-
-TARGET_FDO_CFLAGS:=
-TARGET_FDO_LIB:=
-
-ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
-  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
-  # The profile will be generated on /data/local/tmp/profile on the device.
-  TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
-  TARGET_FDO_LIB := $(target_libgcov)
-else
-  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
-  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
-  ifeq ($(strip $(TARGET_FDO_PROFILE_PATH)),)
-    TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT)
-  else
-    ifeq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
-      $(warning Custom TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
-    endif
-  endif
-
-  # If the FDO profile directory can't be found, then FDO is off.
-  ifneq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
-    TARGET_FDO_CFLAGS := -fprofile-use=$(TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
-    TARGET_FDO_LIB := $(target_libgcov)
-  endif
-endif
 
 KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
 KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/asm-x86 # x86 covers both x86 and x86_64.
@@ -112,11 +81,9 @@
 			-Werror=format-security \
 			-D_FORTIFY_SOURCE=2 \
 			-Wstrict-aliasing=2 \
-			-fPIC -fPIE \
 			-ffunction-sections \
 			-finline-functions \
 			-finline-limit=300 \
-			-fno-inline-functions-called-once \
 			-fno-short-enums \
 			-fstrict-aliasing \
 			-funswitch-loops \
@@ -130,6 +97,7 @@
 TARGET_GLOBAL_CFLAGS += \
     -Werror=pointer-to-int-cast \
     -Werror=int-to-pointer-cast \
+    -Werror=implicit-function-declaration \
 
 android_config_h := $(call select-android-config-h,target_linux-x86)
 TARGET_ANDROID_CONFIG_CFLAGS := -include $(android_config_h) -I $(dir $(android_config_h))
@@ -160,14 +128,15 @@
 
 TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
 TARGET_GLOBAL_LDFLAGS += -Wl,-z,relro -Wl,-z,now
+TARGET_GLOBAL_LDFLAGS += -Wl,--build-id=md5
 TARGET_GLOBAL_LDFLAGS += -Wl,--warn-shared-textrel
 TARGET_GLOBAL_LDFLAGS += -Wl,--fatal-warnings
 TARGET_GLOBAL_LDFLAGS += -Wl,--gc-sections
+TARGET_GLOBAL_LDFLAGS += -Wl,--hash-style=gnu
 
 TARGET_C_INCLUDES := \
 	$(libc_root)/arch-x86_64/include \
 	$(libc_root)/include \
-	$(libstdc++_root)/include \
 	$(KERNEL_HEADERS) \
 	$(libm_root)/include \
 	$(libm_root)/include/amd64 \
@@ -181,78 +150,8 @@
 
 TARGET_STRIP_MODULE:=true
 
-TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
-TARGET_CUSTOM_LD_COMMAND := true
-define transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	 -nostdlib -Wl,-soname,$(notdir $@) \
-	 -shared -Bsymbolic \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O))
-endef
+TARGET_LINKER := /system/bin/linker64
 
-define transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	-nostdlib -Bdynamic \
-	-Wl,-z,nocopyreloc \
-	-fPIE -pie \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
-	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-	-o $@ \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
-
-define transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	-nostdlib -Bstatic \
-	-o $@ \
-	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
-	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_ALL_OBJECTS) \
-	-Wl,--whole-archive \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-	-Wl,--no-whole-archive \
-	-Wl,--start-group \
-	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(PRIVATE_TARGET_FDO_LIB) \
-	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(if $(PRIVATE_LIBCXX),,$(PRIVATE_TARGET_LIBGCC)) \
-	-Wl,--end-group \
-	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
-	$(PRIVATE_LDLIBS)
-endef
+TARGET_GLOBAL_YASM_FLAGS := -f elf64 -m amd64
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index c6603db..d535afc 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -7,7 +7,15 @@
 ARCH_ARM_HAVE_NEON              := true
 
 ifneq (,$(filter cortex-a15 krait denver,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
+	# TODO: krait is not a cortex-a15, we set the variant to cortex-a15 so that
+	#       hardware divide operations are generated. This should be removed and a
+	#       krait CPU variant added to GCC. For clang we specify -mcpu for krait in
+	#       core/clang/arm.mk.
 	arch_variant_cflags := -mcpu=cortex-a15
+
+	# Fake an ARM compiler flag as these processors support LPAE which GCC/clang
+	# don't advertise.
+	arch_variant_cflags += -D__ARM_FEATURE_LPAE=1
 else
 ifeq ($(strip $(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)),cortex-a8)
 	arch_variant_cflags := -mcpu=cortex-a8
diff --git a/core/combo/arch/mips/mips32-fp.mk b/core/combo/arch/mips/mips32-fp.mk
index e60bdac..8320e93 100644
--- a/core/combo/arch/mips/mips32-fp.mk
+++ b/core/combo/arch/mips/mips32-fp.mk
@@ -4,11 +4,9 @@
 ARCH_MIPS_HAS_FPU	:=true
 ARCH_HAVE_ALIGNED_DOUBLES :=true
 arch_variant_cflags := \
-    -EL \
-    -march=mips32 \
-    -mtune=mips32 \
     -mips32 \
-    -mhard-float
+    -mfp32 \
+    -modd-spreg \
 
 arch_variant_ldflags := \
-    -EL
+    -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32.mk b/core/combo/arch/mips/mips32.mk
deleted file mode 100644
index 35ef0d8..0000000
--- a/core/combo/arch/mips/mips32.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-# Configuration for Android on MIPS.
-# Generating binaries for MIPS32/soft-float/little-endian
-
-arch_variant_cflags := \
-    -EL \
-    -march=mips32 \
-    -mtune=mips32 \
-    -mips32 \
-    -msoft-float
-
-arch_variant_ldflags := \
-    -EL
diff --git a/core/combo/arch/mips/mips32r2-fp-xburst.mk b/core/combo/arch/mips/mips32r2-fp-xburst.mk
index 8b0fef1..2b4f714 100644
--- a/core/combo/arch/mips/mips32r2-fp-xburst.mk
+++ b/core/combo/arch/mips/mips32r2-fp-xburst.mk
@@ -5,13 +5,11 @@
 ARCH_MIPS_HAS_FPU :=true
 ARCH_HAVE_ALIGNED_DOUBLES :=true
 arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
     -mips32r2 \
-    -mhard-float \
+    -mfp32 \
+    -modd-spreg \
     -mno-fused-madd \
     -Wa,-mmxu
 
 arch_variant_ldflags := \
-    -EL
+    -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2-fp.mk b/core/combo/arch/mips/mips32r2-fp.mk
index 08d91df..9acb018 100644
--- a/core/combo/arch/mips/mips32r2-fp.mk
+++ b/core/combo/arch/mips/mips32r2-fp.mk
@@ -4,12 +4,10 @@
 ARCH_MIPS_HAS_FPU	:=true
 ARCH_HAVE_ALIGNED_DOUBLES :=true
 arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
     -mips32r2 \
-    -mhard-float \
+    -mfp32 \
+    -modd-spreg \
     -msynci
 
 arch_variant_ldflags := \
-    -EL
+    -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2.mk b/core/combo/arch/mips/mips32r2.mk
deleted file mode 100644
index 16ce76f..0000000
--- a/core/combo/arch/mips/mips32r2.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-# Configuration for Android on MIPS.
-# Generating binaries for MIPS32R2/soft-float/little-endian
-
-arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
-    -mips32r2 \
-    -msoft-float \
-    -msynci
-
-arch_variant_ldflags := \
-    -EL
diff --git a/core/combo/arch/mips/mips32r2dsp-fp.mk b/core/combo/arch/mips/mips32r2dsp-fp.mk
index fe2b1fe..c4b49b6 100644
--- a/core/combo/arch/mips/mips32r2dsp-fp.mk
+++ b/core/combo/arch/mips/mips32r2dsp-fp.mk
@@ -6,13 +6,11 @@
 ARCH_MIPS_HAS_FPU       :=true
 ARCH_HAVE_ALIGNED_DOUBLES :=true
 arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
     -mips32r2 \
-    -mhard-float \
+    -mfp32 \
+    -modd-spreg \
     -mdsp \
     -msynci
 
 arch_variant_ldflags := \
-    -EL
+    -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2dsp.mk b/core/combo/arch/mips/mips32r2dsp.mk
deleted file mode 100644
index 8a8976c..0000000
--- a/core/combo/arch/mips/mips32r2dsp.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Configuration for Android on MIPS.
-# Generating binaries for MIPS32R2/soft-float/little-endian/dsp
-
-ARCH_MIPS_HAS_DSP  	:=true
-ARCH_MIPS_DSP_REV	:=1
-
-arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
-    -mips32r2 \
-    -msoft-float \
-    -mdsp \
-    -msynci
-
-arch_variant_ldflags := \
-    -EL
diff --git a/core/combo/arch/mips/mips32r2dspr2-fp.mk b/core/combo/arch/mips/mips32r2dspr2-fp.mk
index 7e882b3..8b05ffc 100644
--- a/core/combo/arch/mips/mips32r2dspr2-fp.mk
+++ b/core/combo/arch/mips/mips32r2dspr2-fp.mk
@@ -6,13 +6,11 @@
 ARCH_MIPS_HAS_FPU       :=true
 ARCH_HAVE_ALIGNED_DOUBLES :=true
 arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
     -mips32r2 \
-    -mhard-float \
+    -mfp32 \
+    -modd-spreg \
     -mdspr2 \
     -msynci
 
 arch_variant_ldflags := \
-    -EL
+    -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2dspr2.mk b/core/combo/arch/mips/mips32r2dspr2.mk
deleted file mode 100644
index c311523..0000000
--- a/core/combo/arch/mips/mips32r2dspr2.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Configuration for Android on MIPS.
-# Generating binaries for MIPS32R2/soft-float/little-endian/dsp
-
-ARCH_MIPS_HAS_DSP  	:=true
-ARCH_MIPS_DSP_REV	:=2
-
-arch_variant_cflags := \
-    -EL \
-    -march=mips32r2 \
-    -mtune=mips32r2 \
-    -mips32r2 \
-    -msoft-float \
-    -mdspr2 \
-    -msynci
-
-arch_variant_ldflags := \
-    -EL
diff --git a/core/combo/arch/mips/mips32r6.mk b/core/combo/arch/mips/mips32r6.mk
new file mode 100644
index 0000000..315aa60
--- /dev/null
+++ b/core/combo/arch/mips/mips32r6.mk
@@ -0,0 +1,12 @@
+# Configuration for Android on MIPS.
+# Generating binaries for MIPS32R6/hard-float/little-endian
+
+ARCH_MIPS_REV6 := true
+arch_variant_cflags := \
+    -mips32r6 \
+    -mfp64 \
+    -mno-odd-spreg \
+    -msynci
+
+arch_variant_ldflags := \
+    -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips64/mips64r2.mk b/core/combo/arch/mips64/mips64r2.mk
index 298aeaf..c5710d0 100644
--- a/core/combo/arch/mips64/mips64r2.mk
+++ b/core/combo/arch/mips64/mips64r2.mk
@@ -1,14 +1,10 @@
 # Configuration for Android on mips64r2.
 
+# This target is for temporary use only, until mips64r6 is supported by Android's qemu.
+
 ARCH_MIPS_HAS_FPU	:=true
 ARCH_HAVE_ALIGNED_DOUBLES :=true
 arch_variant_cflags := \
-    -EL \
-    -march=mips64r2 \
-    -mtune=mips64r2 \
     -mips64r2 \
-    -mhard-float \
     -msynci
 
-arch_variant_ldflags := \
-    -EL
diff --git a/core/combo/arch/mips64/mips64r6.mk b/core/combo/arch/mips64/mips64r6.mk
new file mode 100644
index 0000000..443de20
--- /dev/null
+++ b/core/combo/arch/mips64/mips64r6.mk
@@ -0,0 +1,7 @@
+# Configuration for Android on mips64r6.
+
+ARCH_MIPS_REV6 := true
+arch_variant_cflags := \
+    -mips64r6 \
+    -msynci
+
diff --git a/core/combo/arch/x86/x86-atom.mk b/core/combo/arch/x86/atom.mk
similarity index 95%
rename from core/combo/arch/x86/x86-atom.mk
rename to core/combo/arch/x86/atom.mk
index 508a0af..3800350 100644
--- a/core/combo/arch/x86/x86-atom.mk
+++ b/core/combo/arch/x86/atom.mk
@@ -11,6 +11,5 @@
 # CFLAGS for this arch
 arch_variant_cflags := \
 	-march=atom \
-	-mstackrealign \
 	-mfpmath=sse \
 
diff --git a/core/combo/arch/x86/haswell.mk b/core/combo/arch/x86/haswell.mk
index a00e0a6..b3922c0 100644
--- a/core/combo/arch/x86/haswell.mk
+++ b/core/combo/arch/x86/haswell.mk
@@ -7,10 +7,11 @@
 ARCH_X86_HAVE_SSE4_2 := true
 ARCH_X86_HAVE_AES_NI := true
 ARCH_X86_HAVE_AVX    := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE  := true
 
 # CFLAGS for this arch
 arch_variant_cflags := \
 	-march=core-avx2 \
-	-mstackrealign \
 	-mfpmath=sse \
 
diff --git a/core/combo/arch/x86/ivybridge.mk b/core/combo/arch/x86/ivybridge.mk
index 02dc1e0..c9fc33b 100644
--- a/core/combo/arch/x86/ivybridge.mk
+++ b/core/combo/arch/x86/ivybridge.mk
@@ -7,10 +7,11 @@
 ARCH_X86_HAVE_SSE4_2 := true
 ARCH_X86_HAVE_AES_NI := true
 ARCH_X86_HAVE_AVX    := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE  := false
 
 # CFLAGS for this arch
 arch_variant_cflags := \
 	-march=core-avx-i \
-	-mstackrealign \
 	-mfpmath=sse \
 
diff --git a/core/combo/arch/x86/sandybridge.mk b/core/combo/arch/x86/sandybridge.mk
index dfa540c..bca5953 100644
--- a/core/combo/arch/x86/sandybridge.mk
+++ b/core/combo/arch/x86/sandybridge.mk
@@ -2,13 +2,16 @@
 # Generating binaries for SandyBridge processors.
 #
 ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4   := true
 ARCH_X86_HAVE_SSE4_1 := true
 ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
 ARCH_X86_HAVE_AVX    := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE  := false
 
 # CFLAGS for this arch
 arch_variant_cflags := \
 	-march=corei7-avx \
-	-mstackrealign \
 	-mfpmath=sse \
 
diff --git a/core/combo/arch/x86/silvermont.mk b/core/combo/arch/x86/silvermont.mk
index 3a8718d..d064b1d 100644
--- a/core/combo/arch/x86/silvermont.mk
+++ b/core/combo/arch/x86/silvermont.mk
@@ -15,6 +15,5 @@
 # CFLAGS for this arch
 arch_variant_cflags := \
 	-march=slm \
-	-mstackrealign \
 	-mfpmath=sse \
 
diff --git a/core/combo/arch/x86/x86.mk b/core/combo/arch/x86/x86.mk
index 73706c4..f070426 100644
--- a/core/combo/arch/x86/x86.mk
+++ b/core/combo/arch/x86/x86.mk
@@ -13,11 +13,7 @@
 ARCH_X86_HAVE_POPCNT := false
 
 
-# XXX: This flag is probably redundant, because it should be set by default
-# by our toolchain binaries. However, there have been reports that this may
-# not always work as intended, so keep it unless we have the time to check
-# everything properly.
-
+# Some intrinsic functions used by libcxx only exist for prescott or newer CPUs.
 arch_variant_cflags := \
-    -march=i686 \
+    -march=prescott \
 
diff --git a/core/combo/arch/x86_64/haswell.mk b/core/combo/arch/x86_64/haswell.mk
index 9cf95b3..6067eee 100644
--- a/core/combo/arch/x86_64/haswell.mk
+++ b/core/combo/arch/x86_64/haswell.mk
@@ -7,6 +7,8 @@
 ARCH_X86_HAVE_SSE4_2 := true
 ARCH_X86_HAVE_AES_NI := true
 ARCH_X86_HAVE_AVX    := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE  := true
 
 # CFLAGS for this arch
 arch_variant_cflags := \
diff --git a/core/combo/arch/x86_64/ivybridge.mk b/core/combo/arch/x86_64/ivybridge.mk
index 7b95190..90e23a9 100644
--- a/core/combo/arch/x86_64/ivybridge.mk
+++ b/core/combo/arch/x86_64/ivybridge.mk
@@ -7,6 +7,8 @@
 ARCH_X86_HAVE_SSE4_2 := true
 ARCH_X86_HAVE_AES_NI := true
 ARCH_X86_HAVE_AVX    := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE  := false
 
 # CFLAGS for this arch
 arch_variant_cflags := \
diff --git a/core/combo/arch/x86_64/sandybridge.mk b/core/combo/arch/x86_64/sandybridge.mk
index a443b6b..865548c 100644
--- a/core/combo/arch/x86_64/sandybridge.mk
+++ b/core/combo/arch/x86_64/sandybridge.mk
@@ -2,9 +2,13 @@
 # Generating binaries for SandyBridge processors.
 #
 ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4   := true
 ARCH_X86_HAVE_SSE4_1 := true
 ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
 ARCH_X86_HAVE_AVX    := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE  := false
 
 # CFLAGS for this arch
 arch_variant_cflags := \
diff --git a/core/combo/arch/x86_64/x86_64-atom.mk b/core/combo/arch/x86_64/x86_64-atom.mk
deleted file mode 100755
index 64b07a0..0000000
--- a/core/combo/arch/x86_64/x86_64-atom.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-# This file contains feature macro definitions specific to the
-# 'x86_64-atom' arch variant. This is an extension of the 'x86_64' base variant
-# that adds Atom-specific features.
-#
-# See build/core/combo/arch/x86_64/x86_64.mk for differences.
-#
-ARCH_X86_HAVE_SSSE3 := true
-ARCH_X86_HAVE_MOVBE := true
-ARCH_X86_HAVE_POPCNT := false   # popcnt is not supported by current Atom CPUs
-
-# CFLAGS for this arch
-arch_variant_cflags := \
-	-march=atom
diff --git a/core/combo/fdo.mk b/core/combo/fdo.mk
new file mode 100644
index 0000000..9e331b6
--- /dev/null
+++ b/core/combo/fdo.mk
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2006 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.
+#
+
+# Setup FDO related flags.
+
+$(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS:=
+
+ifeq ($(strip $(BUILD_FDO_INSTRUMENT)), true)
+  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
+  # The profile will be generated on /sdcard/fdo_profile on the device.
+  $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-generate=/sdcard/fdo_profile -DANDROID_FDO
+  $(combo_2nd_arch_prefix)TARGET_FDO_LDFLAGS := -lgcov -lgcc
+else
+  ifeq ($(strip $(BUILD_FDO_OPTIMIZE)), true)
+    # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
+    ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH)),)
+      $(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH := vendor/google_data/fdo_profile
+    endif
+
+    ifneq ($(strip $(wildcard $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH)/$(PRODUCT_OUT))),)
+      $(combo_2nd_arch_prefix)TARGET_FDO_CFLAGS := -fprofile-use=$($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH) -DANDROID_FDO -fprofile-correction -Wcoverage-mismatch -Wno-error
+    else
+      $(warning Profile directory $($(combo_2nd_arch_prefix)TARGET_FDO_PROFILE_PATH)/$(PRODUCT_OUT) does not exist. Turn off FDO.)
+    endif
+  endif
+endif
diff --git a/core/combo/include/arch/darwin-x86/AndroidConfig.h b/core/combo/include/arch/darwin-x86/AndroidConfig.h
index 44de4cd..6ddfdb1 100644
--- a/core/combo/include/arch/darwin-x86/AndroidConfig.h
+++ b/core/combo/include/arch/darwin-x86/AndroidConfig.h
@@ -33,150 +33,6 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have the futex syscall?
- */
-
-/* #define HAVE_FUTEX */
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_MACOSX_IPC
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-/* #define  HAVE_SYS_SENDFILE_H 1 */
-
-/*
- * Define this if you build against MSVCRT.DLL
- */
-/* #define HAVE_MS_C_RUNTIME */
-
-/*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS
-
-/*
- * Define this if we have localtime_r().
- */
-#define HAVE_LOCALTIME_R 1
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-/* #define HAVE_IOCTL */
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-/* #define HAVE_POSIX_CLOCKS */
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#if (defined(__ppc__) || defined(__ppc64__))
-#   define HAVE_BIG_ENDIAN
-#elif (defined(__i386__) || defined(__x86_64__))
-#   define HAVE_LITTLE_ENDIAN
-#endif
-
-/*
- * We need to choose between 32-bit and 64-bit off_t.  All of our code should
- * agree on the same size.  For desktop systems, use 64-bit values,
- * because some of our libraries (e.g. wxWidgets) expect to be built that way.
- */
-#define _FILE_OFFSET_BITS 64
-#define _LARGEFILE_SOURCE 1
-
-/*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-/* #define HAVE_OFF64_T */
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-/* #define HAVE_GETTID */
-
-
-/*
  * Add any extra platform-specific defines here.
  */
 #define _THREAD_SAFE
@@ -187,119 +43,23 @@
 /* #define HAVE_MALLOC_H */
 
 /*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if we include <sys/mount.h> for statfs()
- */
-#define INCLUDE_SYS_MOUNT_FOR_STATFS 1
-
-/*
- * What CPU architecture does this platform use?
- */
-#if (defined(__ppc__) || defined(__ppc64__))
-#   define ARCH_PPC
-#elif (defined(__i386__) || defined(__x86_64__))
-#   define ARCH_X86
-#endif
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.dylib"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- *
- * For tools apps, we'll treat is as not case sensitive.
- */
-/* #define OS_CASE_SENSITIVE */
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
  * Define if the strlcpy() function exists on the system.
  */
 #define HAVE_STRLCPY 1
 
 /*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-#define HAVE_FUNOPEN 1
-
-/*
- * Define if writev() exists
- */
-#define HAVE_WRITEV 1
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
- */
-#define HAVE_BSD_QSORT_R 1
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#define HAVE_GNU_QSORT_R 0
-
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/core/combo/include/arch/linux-arm/AndroidConfig.h b/core/combo/include/arch/linux-arm/AndroidConfig.h
index 0eb6c72..b1c963e 100644
--- a/core/combo/include/arch/linux-arm/AndroidConfig.h
+++ b/core/combo/include/arch/linux-arm/AndroidConfig.h
@@ -33,313 +33,33 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have pthread_setname_np()?
- *
- * (HAVE_PTHREAD_SETNAME_NP is used by WebKit to enable a function with
- * the same name but different parameters, so we can't use that here.)
- */
-#define HAVE_ANDROID_PTHREAD_SETNAME_NP
-
-/*
- * Do we have the futex syscall?
- */
-#define HAVE_FUTEX
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_ANDROID_IPC
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H 1
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#define  HAVE_SYS_SENDFILE_H 1
-
-/*
- * Define this if you build against MSVCRT.DLL
- */
-/* #define HAVE_MS_C_RUNTIME */
-
-/*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H 1
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS
-
-/*
- * Define this if we have localtime_r().
- */
-/* #define HAVE_LOCALTIME_R 1 */
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-#define HAVE_IOCTL
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-#define HAVE_POSIX_CLOCKS
-
-/*
- * Define this if we have linux style epoll()
- */
-#define HAVE_EPOLL
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#define HAVE_ENDIAN_H
-#define HAVE_LITTLE_ENDIAN
-
-/*
- * We need to choose between 32-bit and 64-bit off_t.  All of our code should
- * agree on the same size.  For desktop systems, use 64-bit values,
- * because some of our libraries (e.g. wxWidgets) expect to be built that way.
- */
-/* #define _FILE_OFFSET_BITS 64 */
-/* #define _LARGEFILE_SOURCE 1 */
-
-/*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-#define HAVE_GETTID
-
-/* 
- * Defined if we have the sched_setscheduler() call
- */
-#define HAVE_SCHED_SETSCHEDULER
-
-/*
- * Add any extra platform-specific defines here.
- */
-#ifndef __linux__
-#define __linux__
-#endif
-
-/*
  * Define if we have <malloc.h> header
  */
 #define HAVE_MALLOC_H
 
-/* 
+/*
  * Define if we're running on *our* linux on device or emulator.
  */
 #define HAVE_ANDROID_OS 1
 
 /*
- * Define if we have Linux-style non-filesystem Unix Domain Sockets
- */
-#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
-
-/*
- * Define if we have Linux's inotify in <sys/inotify.h>.
- */
-#define HAVE_INOTIFY 1
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-#define HAVE_LIBC_SYSTEM_PROPERTIES 1
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-/* #define HAVE_SYSTEM_PROPERTY_SERVER */
-
-/*
- * What CPU architecture does this platform use?
- */
-#define ARCH_ARM
-
-/*
- * Define if the size of enums is as short as possible,
- */
-/* #define HAVE_SHORT_ENUMS */
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- */
-#define OS_CASE_SENSITIVE
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
  * Define if the strlcpy() function exists on the system.
  */
 #define HAVE_STRLCPY 1
 
 /*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-#define HAVE_FUNOPEN 1
-
-/*
- * Define if prctl() exists
- */
-#define HAVE_PRCTL 1
-
-/*
- * Define if writev() exists
- */
-#define HAVE_WRITEV 1
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
- */
-#define HAVE_BSD_QSORT_R 0
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#define HAVE_GNU_QSORT_R 0
-
 #endif /* _ANDROID_CONFIG_H */
diff --git a/core/combo/include/arch/linux-arm64/AndroidConfig.h b/core/combo/include/arch/linux-arm64/AndroidConfig.h
index bcbda8f..c1e9e59 100644
--- a/core/combo/include/arch/linux-arm64/AndroidConfig.h
+++ b/core/combo/include/arch/linux-arm64/AndroidConfig.h
@@ -33,165 +33,6 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have pthread_setname_np()?
- *
- * (HAVE_PTHREAD_SETNAME_NP is used by WebKit to enable a function with
- * the same name but different parameters, so we can't use that here.)
- */
-#define HAVE_ANDROID_PTHREAD_SETNAME_NP
-
-/*
- * Do we have the futex syscall?
- */
-#define HAVE_FUTEX
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_ANDROID_IPC
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H 1
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#define  HAVE_SYS_SENDFILE_H 1
-
-/*
- * Define this if you build against MSVCRT.DLL
- */
-/* #define HAVE_MS_C_RUNTIME */
-
-/*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H 1
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS
-
-/*
- * Define this if we have localtime_r().
- */
-/* #define HAVE_LOCALTIME_R 1 */
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-#define HAVE_IOCTL
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-#define HAVE_POSIX_CLOCKS
-
-/*
- * Define this if we have linux style epoll()
- */
-#define HAVE_EPOLL
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#define HAVE_ENDIAN_H
-#define HAVE_LITTLE_ENDIAN
-
-#define _FILE_OFFSET_BITS 64
-/* #define _LARGEFILE_SOURCE 1 */
-
-/*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-#define HAVE_GETTID
-
-/*
- * Defined if we have the sched_setscheduler() call
- */
-#define HAVE_SCHED_SETSCHEDULER
-
-/*
- * Add any extra platform-specific defines here.
- */
-#ifndef __linux__
-#define __linux__
-#endif
-
-/*
  * Define if we have <malloc.h> header
  */
 #define HAVE_MALLOC_H
@@ -202,139 +43,23 @@
 #define HAVE_ANDROID_OS 1
 
 /*
- * Define if we have Linux-style non-filesystem Unix Domain Sockets
- */
-#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
-
-/*
- * Define if we have Linux's inotify in <sys/inotify.h>.
- */
-#define HAVE_INOTIFY 1
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-#define HAVE_LIBC_SYSTEM_PROPERTIES 1
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-/* #define HAVE_SYSTEM_PROPERTY_SERVER */
-
-/*
- * What CPU architecture does this platform use?
- */
-#define ARCH_AARCH64
-
-/*
- * Define if the size of enums is as short as possible,
- */
-/* #define HAVE_SHORT_ENUMS */
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- */
-#define OS_CASE_SENSITIVE
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
  * Define if the strlcpy() function exists on the system.
  */
 #define HAVE_STRLCPY 1
 
 /*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-#define HAVE_FUNOPEN 1
-
-/*
- * Define if prctl() exists
- */
-#define HAVE_PRCTL 1
-
-/*
- * Define if writev() exists
- */
-#define HAVE_WRITEV 1
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
- */
-#define HAVE_BSD_QSORT_R 0
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#define HAVE_GNU_QSORT_R 0
-
 #endif /* _ANDROID_CONFIG_H */
diff --git a/core/combo/include/arch/linux-mips/AndroidConfig.h b/core/combo/include/arch/linux-mips/AndroidConfig.h
index 076d711..ac0c9e1 100644
--- a/core/combo/include/arch/linux-mips/AndroidConfig.h
+++ b/core/combo/include/arch/linux-mips/AndroidConfig.h
@@ -33,187 +33,11 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have pthread_setname_np()?
- *
- * (HAVE_PTHREAD_SETNAME_NP is used by WebKit to enable a function with
- * the same name but different parameters, so we can't use that here.)
- */
-#define HAVE_ANDROID_PTHREAD_SETNAME_NP
-
-/*
- * Do we have the futex syscall?
- */
-#define HAVE_FUTEX
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_ANDROID_IPC
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H 1
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#define  HAVE_SYS_SENDFILE_H 1
-
-/*
  * Define this if you build against MSVCRT.DLL
  */
 /* #define HAVE_MS_C_RUNTIME */
 
 /*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H 1
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS
-
-/*
- * Define this if we have localtime_r().
- */
-/* #define HAVE_LOCALTIME_R */
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-#define HAVE_IOCTL
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-#define HAVE_POSIX_CLOCKS
-
-/*
- * Define this if we have linux style epoll()
- */
-#define HAVE_EPOLL
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#define HAVE_ENDIAN_H
-#if defined(__MIPSEB__)
-#define HAVE_BIG_ENDIAN
-#endif
-#if defined(__MIPSEL__)
-#define HAVE_LITTLE_ENDIAN
-#endif
-
-/*
- * We need to choose between 32-bit and 64-bit off_t.  All of our code should
- * agree on the same size.  For desktop systems, use 64-bit values,
- * because some of our libraries (e.g. wxWidgets) expect to be built that way.
- */
-/* #define _FILE_OFFSET_BITS 64 */
-/* #define _LARGEFILE_SOURCE 1 */
-
-/*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-#define HAVE_GETTID
-
-/*
- * Defined if we have the sched_setscheduler() call
- */
-#define HAVE_SCHED_SETSCHEDULER
-
-/*
- * Add any extra platform-specific defines here.
- */
-#ifndef __linux__
-#define __linux__ 1
-#endif
-
-#ifndef __linux
-#define __linux 1
-#endif
-
-#ifdef __unix__
-#undef __unix__
-#endif
-
-#ifdef __unix
-#undef __unix
-#endif
-
-/*
  * Define if we have <malloc.h> header
  */
 #define HAVE_MALLOC_H
@@ -224,134 +48,23 @@
 #define HAVE_ANDROID_OS 1
 
 /*
- * Define if we have Linux-style non-filesystem Unix Domain Sockets
- */
-#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
-
-/*
- * Define if we have Linux's inotify in <sys/inotify.h>.
- */
-#define HAVE_INOTIFY 1
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-#define HAVE_LIBC_SYSTEM_PROPERTIES 1
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-/* #define HAVE_SYSTEM_PROPERTY_SERVER */
-
-/*
- * What CPU architecture does this platform use?
- */
-#define ARCH_MIPS 1
-
-/*
- * Define if the size of enums is as short as possible,
- */
-/* #define HAVE_SHORT_ENUMS */
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- */
-#define OS_CASE_SENSITIVE
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
  * Define if the strlcpy() function exists on the system.
  */
 #define HAVE_STRLCPY 1
 
 /*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-#define HAVE_FUNOPEN 1
-
-/*
- * Define if prctl() exists
- */
-#define HAVE_PRCTL 1
-
-/*
- * Define if writev() exists
- */
-#define HAVE_WRITEV 1
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Whether or not _Unwind_Context is defined as a struct.
- */
-#define HAVE_UNWIND_CONTEXT_STRUCT 1
-
 #endif /* _ANDROID_CONFIG_H */
diff --git a/core/combo/include/arch/linux-mips64/AndroidConfig.h b/core/combo/include/arch/linux-mips64/AndroidConfig.h
index 7ded3ce..b86c676 100644
--- a/core/combo/include/arch/linux-mips64/AndroidConfig.h
+++ b/core/combo/include/arch/linux-mips64/AndroidConfig.h
@@ -33,177 +33,6 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have pthread_setname_np()?
- *
- * (HAVE_PTHREAD_SETNAME_NP is used by WebKit to enable a function with
- * the same name but different parameters, so we can't use that here.)
- */
-#define HAVE_ANDROID_PTHREAD_SETNAME_NP
-
-/*
- * Do we have the futex syscall?
- */
-#define HAVE_FUTEX
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_ANDROID_IPC
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H 1
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#define  HAVE_SYS_SENDFILE_H 1
-
-/*
- * Define this if you build against MSVCRT.DLL
- */
-/* #define HAVE_MS_C_RUNTIME */
-
-/*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H 1
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS
-
-/*
- * Define this if we have localtime_r().
- */
-/* #define HAVE_LOCALTIME_R */
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-#define HAVE_IOCTL
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-#define HAVE_POSIX_CLOCKS
-
-/*
- * Define this if we have linux style epoll()
- */
-#define HAVE_EPOLL
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#define HAVE_ENDIAN_H
-#define HAVE_LITTLE_ENDIAN
-
-#define _FILE_OFFSET_BITS 64
-/* #define _LARGEFILE_SOURCE 1 */
-
-/*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-#define HAVE_GETTID
-
-/*
- * Defined if we have the sched_setscheduler() call
- */
-#define HAVE_SCHED_SETSCHEDULER
-
-/*
- * Add any extra platform-specific defines here.
- */
-#ifndef __linux__
-#define __linux__ 1
-#endif
-
-#ifndef __linux
-#define __linux 1
-#endif
-
-#ifdef __unix__
-#undef __unix__
-#endif
-
-#ifdef __unix
-#undef __unix
-#endif
-
-/*
  * Define if we have <malloc.h> header
  */
 #define HAVE_MALLOC_H
@@ -214,134 +43,23 @@
 #define HAVE_ANDROID_OS 1
 
 /*
- * Define if we have Linux-style non-filesystem Unix Domain Sockets
- */
-#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
-
-/*
- * Define if we have Linux's inotify in <sys/inotify.h>.
- */
-#define HAVE_INOTIFY 1
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-#define HAVE_LIBC_SYSTEM_PROPERTIES 1
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-/* #define HAVE_SYSTEM_PROPERTY_SERVER */
-
-/*
- * What CPU architecture does this platform use?
- */
-#define ARCH_MIPS64 1
-
-/*
- * Define if the size of enums is as short as possible,
- */
-/* #define HAVE_SHORT_ENUMS */
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- */
-#define OS_CASE_SENSITIVE
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
  * Define if the strlcpy() function exists on the system.
  */
 #define HAVE_STRLCPY 1
 
 /*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-#define HAVE_FUNOPEN 1
-
-/*
- * Define if prctl() exists
- */
-#define HAVE_PRCTL 1
-
-/*
- * Define if writev() exists
- */
-#define HAVE_WRITEV 1
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Whether or not _Unwind_Context is defined as a struct.
- */
-#define HAVE_UNWIND_CONTEXT_STRUCT 1
-
 #endif /* _ANDROID_CONFIG_H */
diff --git a/core/combo/include/arch/linux-x86/AndroidConfig.h b/core/combo/include/arch/linux-x86/AndroidConfig.h
index ebb95b0..a2897bc 100644
--- a/core/combo/include/arch/linux-x86/AndroidConfig.h
+++ b/core/combo/include/arch/linux-x86/AndroidConfig.h
@@ -33,120 +33,6 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have the futex syscall?
- */
-
-#define HAVE_FUTEX
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_SYSV_IPC
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H 1
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#define  HAVE_SYS_SENDFILE_H 1
-
-/*
- * Define this if you build against MSVCRT.DLL
- */
-/* #define HAVE_MS_C_RUNTIME */
-
-/*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H 1
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS
-
-/*
- * Define this if we have localtime_r().
- */
-#define HAVE_LOCALTIME_R 1
-
-/*
- * Define this if we have gethostbyname_r().
- */
-#define HAVE_GETHOSTBYNAME_R
-
-/*
- * Define this if we have ioctl().
- */
-#define HAVE_IOCTL
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-#define HAVE_POSIX_CLOCKS
-
-/*
- * Define this if we have linux style epoll()
- */
-#define HAVE_EPOLL
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#define HAVE_ENDIAN_H
-#define HAVE_LITTLE_ENDIAN
-
-/*
  * We need to choose between 32-bit and 64-bit off_t.  All of our code should
  * agree on the same size.  For desktop systems, use 64-bit values,
  * because some of our libraries (e.g. wxWidgets) expect to be built that way.
@@ -155,175 +41,23 @@
 #define _LARGEFILE_SOURCE 1
 
 /*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 1
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-/* #define HAVE_GETTID */
-
-/* 
- * Defined if we have the sched_setscheduler() call
- */
-#define HAVE_SCHED_SETSCHEDULER
-
-/*
- * Add any extra platform-specific defines here.
- */
-
-/*
  * Define if we have <malloc.h> header
  */
 #define HAVE_MALLOC_H
 
 /*
- * Define if we have Linux-style non-filesystem Unix Domain Sockets
- */
-
-/*
- * What CPU architecture does this platform use?
- */
-#define ARCH_X86
-
-
-/*
- * Define if we have Linux's inotify in <sys/inotify.h>.
- */
-/*#define HAVE_INOTIFY 1*/
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-/* #define HAVE_LIBC_SYSTEM_PROPERTIES */
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-#define HAVE_SYSTEM_PROPERTY_SERVER
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- */
-#define OS_CASE_SENSITIVE
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
- * Define if the strlcpy() function exists on the system.
- */
-/* #define HAVE_STRLCPY 1 */
-
-/*
- * Define if the open_memstream() function exists on the system.
- */
-#define HAVE_OPEN_MEMSTREAM 1
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-/* #define HAVE_FUNOPEN 1 */
-
-/*
- * Define if prctl() exists
- */
-#define HAVE_PRCTL 1
-
-/*
- * Define if writev() exists
- */
-#define HAVE_WRITEV 1
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
- */
-#define HAVE_BSD_QSORT_R 0
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
-#define HAVE_GNU_QSORT_R 1
-#else
-#define HAVE_GNU_QSORT_R 0
-#endif
-
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/core/combo/include/arch/target_linux-x86/AndroidConfig.h b/core/combo/include/arch/target_linux-x86/AndroidConfig.h
index 5b56b51..676913c 100644
--- a/core/combo/include/arch/target_linux-x86/AndroidConfig.h
+++ b/core/combo/include/arch/target_linux-x86/AndroidConfig.h
@@ -19,316 +19,33 @@
  */
 
 /*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
- */
-#define HAVE_PTHREADS
-
-/*
- * Do we have pthread_setname_np()?
- *
- * (HAVE_PTHREAD_SETNAME_NP is used by WebKit to enable a function with
- * the same name but different parameters, so we can't use that here.)
- */
-#define HAVE_ANDROID_PTHREAD_SETNAME_NP
-
-/*
- * Do we have the futex syscall?
- */
-#define HAVE_FUTEX
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
-#define HAVE_ANDROID_IPC 1
-
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
-#define  HAVE_POSIX_FILEMAP 1
-
-/*
- * Define this if you have <termio.h>
- */
-#define  HAVE_TERMIO_H 1
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#define  HAVE_SYS_SENDFILE_H 1
-
-/*
- * Define this if you build against have Microsoft C runtime (MSVCRT.DLL)
- */
-/* #define HAVE_MS_C_RUNTIME */
-
-/*
- * Define this if you have sys/uio.h
- */
-#define  HAVE_SYS_UIO_H 1
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-#define HAVE_SYMLINKS 1
-
-/*
- * Define this if we have localtime_r().
- */
-/* #define HAVE_LOCALTIME_R 1 */
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-#define HAVE_IOCTL
-
-/*
- * Define this if we want to use WinSock.
- */
-/* #define HAVE_WINSOCK */
-
-/*
- * Define this if have clock_gettime() and friends
- *
- */
-#define HAVE_POSIX_CLOCKS
-
-/*
- * Define this if we have linux style epoll()
- */
-#define HAVE_EPOLL
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#define HAVE_ENDIAN_H
-#define HAVE_LITTLE_ENDIAN
-
-/*
- * We need to choose between 32-bit and 64-bit off_t.  All of our code should
- * agree on the same size.  For desktop systems, use 64-bit values,
- * because some of our libraries (e.g. wxWidgets) expect to be built that way.
- */
-#if __LP64__
-#define _FILE_OFFSET_BITS 64
-#endif
-/* #define _LARGEFILE_SOURCE 1 */
-
-/*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Defined if we have the gettid() system call.
- */
-#define HAVE_GETTID
-
-/* 
- * Defined if we have the sched_setscheduler() call
- */
-#define HAVE_SCHED_SETSCHEDULER
-
-/*
- * Add any extra platform-specific defines here.
- */
-#ifndef __linux__
-#define __linux__
-#endif
-
-/*
  * Define if we have <malloc.h> header
  */
 #define HAVE_MALLOC_H
 
-/* 
+/*
  * Define if we're running on *our* linux on device or emulator.
  */
 #define HAVE_ANDROID_OS 1
 
 /*
- * Define if we have Linux-style non-filesystem Unix Domain Sockets
- */
-#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
-
-/*
- * Define if we have Linux's inotify in <sys/inotify.h>.
- */
-#define HAVE_INOTIFY 1
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-#define HAVE_MADVISE 1
-
-/*
- * Define if we have Linux's dbus 
- */
-/* #define HAVE_DBUS 1 */
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-#define HAVE_TM_GMTOFF 1
-
-/*
- * Define if dirent struct has d_type field
- */
-#define HAVE_DIRENT_D_TYPE 1
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-#define HAVE_LIBC_SYSTEM_PROPERTIES 1
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-/* #define HAVE_SYSTEM_PROPERTY_SERVER */
-
-/*
- * What CPU architecture does this platform use?
- */
-#define ARCH_X86
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '/'
 
 /*
- * Is the filesystem case sensitive?
- */
-#define OS_CASE_SENSITIVE
-
-/*
- * Define if <sys/socket.h> exists.
- */
-#define HAVE_SYS_SOCKET_H 1
-
-/*
  * Define if the strlcpy() function exists on the system.
  */
 #define HAVE_STRLCPY 1
 
 /*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-#define HAVE_FUNOPEN 1
-
-/*
- * Define if prctl() exists
- */
-#define HAVE_PRCTL 1
-
-/*
- * Whether or not _Unwind_Context is defined as a struct.
- */
-#define HAVE_UNWIND_CONTEXT_STRUCT
-
-/*
  * Define if <stdint.h> exists.
  */
 #define HAVE_STDINT_H 1
 
 /*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H 1
-
-/*
- * Define if <sched.h> exists.
- */
-#define HAVE_SCHED_H 1
-
-/*
- * Define if pread() exists
- */
-#define HAVE_PREAD 1
-
-/*
- * Define if we have st_mtim in struct stat
- */
-#define HAVE_STAT_ST_MTIM 1
-
-/*
  * Define if printf() supports %zd for size_t arguments
  */
 #define HAVE_PRINTF_ZD 1
 
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
- */
-#define HAVE_BSD_QSORT_R 0
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#define HAVE_GNU_QSORT_R 0
-
 #endif /* _ANDROID_CONFIG_H */
diff --git a/core/combo/include/arch/windows/AndroidConfig.h b/core/combo/include/arch/windows/AndroidConfig.h
index 0a52674..e7eb837 100644
--- a/core/combo/include/arch/windows/AndroidConfig.h
+++ b/core/combo/include/arch/windows/AndroidConfig.h
@@ -55,136 +55,22 @@
 #  endif
 #endif
 
-/*
- * Threading model.  Choose one:
- *
- * HAVE_PTHREADS - use the pthreads library.
- * HAVE_WIN32_THREADS - use Win32 thread primitives.
- */
-#define HAVE_WIN32_THREADS
-
-/*
- * Do we have the futex syscall?
- */
-
-/* #define HAVE_FUTEX */
-
-
-/*
- * Process creation model.  Choose one:
- *
- * HAVE_FORKEXEC - use fork() and exec()
- * HAVE_WIN32_PROC - use CreateProcess()
- */
-#ifdef __CYGWIN__
-#  define HAVE_FORKEXEC
-#else
-#  define HAVE_WIN32_PROC
-#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).
- * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
- * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
- * HAVE_ANDROID_IPC - use Android versions (?, mmap).
- */
+/* TODO: replace references to this. */
 #define HAVE_WIN32_IPC
 
-/*
- * Memory-mapping model. Choose one:
- *
- * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
- * HAVE_WIN32_FILEMAP - use Win32 filemaps
- */
 #ifdef __CYGWIN__
-#define  HAVE_POSIX_FILEMAP
-#else
-#define  HAVE_WIN32_FILEMAP
-#endif
-
-/*
- * Define this if you have <termio.h>
- */
-#ifdef __CYGWIN__
-#  define  HAVE_TERMIO_H
-#endif
-
-/*
- * Define this if you have <sys/sendfile.h>
- */
-#ifdef __CYGWIN__
-#  define  HAVE_SYS_SENDFILE_H 1
+#error "CYGWIN is unsupported for platform builds"
 #endif
 
 /*
  * Define this if you build against MSVCRT.DLL
  */
-#ifndef __CYGWIN__
-#  define HAVE_MS_C_RUNTIME
-#endif
-
-/*
- * Define this if you have sys/uio.h
- */
-#ifdef __CYGWIN__
-#define  HAVE_SYS_UIO_H
-#endif
-
-
-/*
- * Define this if we have localtime_r().
- */
-/* #define HAVE_LOCALTIME_R 1 */
-
-/*
- * Define this if we have gethostbyname_r().
- */
-/* #define HAVE_GETHOSTBYNAME_R */
-
-/*
- * Define this if we have ioctl().
- */
-/* #define HAVE_IOCTL */
+#define HAVE_MS_C_RUNTIME
 
 /*
  * Define this if we want to use WinSock.
  */
-#ifndef __CYGWIN__
 #define HAVE_WINSOCK
-#endif
-
-/*
- * Define this if your platforms implements symbolic links
- * in its filesystems
- */
-/* #define HAVE_SYMLINKS */
-
-/*
- * Define this if have clock_gettime() and friends
- */
-/* #define HAVE_POSIX_CLOCKS */
-
-/*
- * Endianness of the target machine.  Choose one:
- *
- * HAVE_ENDIAN_H -- have endian.h header we can include.
- * HAVE_LITTLE_ENDIAN -- we are little endian.
- * HAVE_BIG_ENDIAN -- we are big endian.
- */
-#ifdef __CYGWIN__
-#define HAVE_ENDIAN_H
-#endif
-
-#define HAVE_LITTLE_ENDIAN
 
 /*
  * We need to choose between 32-bit and 64-bit off_t.  All of our code should
@@ -195,50 +81,6 @@
 #define _LARGEFILE_SOURCE 1
 
 /*
- * Define if platform has off64_t (and lseek64 and other xxx64 functions)
- */
-#define HAVE_OFF64_T
-
-/*
- * Defined if we have the backtrace() call for retrieving a stack trace.
- * Needed for CallStack to operate; if not defined, CallStack is
- * non-functional.
- */
-#define HAVE_BACKTRACE 0
-
-/*
- * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
- * not defined, stack crawls will be displayed with raw mangled symbols
- */
-#define HAVE_CXXABI 0
-
-/*
- * Define if tm struct has tm_gmtoff field
- */
-/* #define HAVE_TM_GMTOFF 1 */
-
-/*
- * Define if dirent struct has d_type field
- */
-/* #define HAVE_DIRENT_D_TYPE 1 */
-
-/*
- * Define if libc includes Android system properties implementation.
- */
-/* #define HAVE_LIBC_SYSTEM_PROPERTIES */
-
-/*
- * Define if system provides a system property server (should be
- * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
- */
-/* #define HAVE_SYSTEM_PROPERTY_SERVER */
-
-/*
- * Define if we have madvise() in <sys/mman.h>
- */
-/*#define HAVE_MADVISE 1*/
-
-/*
  * Add any extra platform-specific defines here.
  */
 #define WIN32 1                 /* stock Cygwin doesn't define these */
@@ -248,115 +90,15 @@
 #define HAVE_WINDOWS_PATHS      /* needed by simulator */
 
 /*
- * What CPU architecture does this platform use?
- */
-#define ARCH_X86
-
-/*
- * sprintf() format string for shared library naming.
- */
-#define OS_SHARED_LIB_FORMAT_STR    "lib%s.dll"
-
-/*
- * type for the third argument to mincore().
- */
-#define MINCORE_POINTER_TYPE unsigned char *
-
-/*
  * The default path separator for the platform
  */
 #define OS_PATH_SEPARATOR '\\'
 
 /*
- * Is the filesystem case sensitive?
- */
-/* #define OS_CASE_SENSITIVE */
-
-/*
- * Define if <sys/socket.h> exists.
- * Cygwin has it, but not MinGW.
- */
-#ifdef USE_MINGW
-/* #define HAVE_SYS_SOCKET_H */
-#else
-#define HAVE_SYS_SOCKET_H 1
-#endif
-
-/*
- * Define if the strlcpy() function exists on the system.
- */
-/* #define HAVE_STRLCPY 1 */
-
-/*
- * Define if the open_memstream() function exists on the system.
- */
-/* #define HAVE_OPEN_MEMSTREAM 1 */
-
-/*
- * Define if the BSD funopen() function exists on the system.
- */
-/* #define HAVE_FUNOPEN 1 */
-
-/*
- * Define if <winsock2.h> exists.
- * Only MinGW has it.
- */
-#ifdef USE_MINGW
-#define HAVE_WINSOCK2_H 1
-#else
-/* #define HAVE_WINSOCK2_H */
-#endif
-
-/*
  * Various definitions missing in MinGW
  */
 #ifdef USE_MINGW
 #define S_IRGRP 0
 #endif
 
-/*
- * Define if writev() exists.
- */
-/* #define HAVE_WRITEV */
-
-/*
- * Define if <stdint.h> exists.
- */
-/* #define HAVE_STDINT_H */
-
-/*
- * Define if <stdbool.h> exists.
- */
-#define HAVE_STDBOOL_H
-
-/*
- * Define if <sched.h> exists.
- */
-/* #define HAVE_SCHED_H */
-
-/*
- * Define if pread() exists
- */
-/* #define HAVE_PREAD 1 */
-
-/*
- * Define if we have st_mtim in struct stat
- */
-/* #define HAVE_STAT_ST_MTIM 1 */
-
-/*
- * Define if printf() supports %zd for size_t arguments
- */
-/* #define HAVE_PRINTF_ZD 1 */
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
- */
-#define HAVE_BSD_QSORT_R 0
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#define HAVE_GNU_QSORT_R 0
-
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/core/combo/javac.mk b/core/combo/javac.mk
index 7f91aa9..fb43ea4 100644
--- a/core/combo/javac.mk
+++ b/core/combo/javac.mk
@@ -9,11 +9,7 @@
 #   COMMON_JAVAC -- Java compiler command with common arguments
 #
 
-ifneq ($(LEGACY_USE_JAVA6),)
-common_jdk_flags := -target 1.5 -Xmaxerrs 9999999
-else
 common_jdk_flags := -source 1.7 -target 1.7 -Xmaxerrs 9999999
-endif
 
 # Use the indexer wrapper to index the codebase instead of the javac compiler
 ifeq ($(ALTERNATE_JAVAC),)
diff --git a/core/combo/mac_version.mk b/core/combo/mac_version.mk
index b49feee..6defba7 100644
--- a/core/combo/mac_version.mk
+++ b/core/combo/mac_version.mk
@@ -9,7 +9,7 @@
 
 build_mac_version := $(shell sw_vers -productVersion)
 
-mac_sdk_versions_supported :=  10.6 10.7 10.8
+mac_sdk_versions_supported :=  10.6 10.7 10.8 10.9
 ifneq ($(strip $(MAC_SDK_VERSION)),)
 mac_sdk_version := $(MAC_SDK_VERSION)
 ifeq ($(filter $(mac_sdk_version),$(mac_sdk_versions_supported)),)
diff --git a/core/combo/select.mk b/core/combo/select.mk
index e18cb1b..01f9322 100644
--- a/core/combo/select.mk
+++ b/core/combo/select.mk
@@ -33,22 +33,6 @@
 $(combo_var_prefix)AR := $(AR)
 $(combo_var_prefix)STRIP := $(STRIP)
 
-$(combo_var_prefix)BINDER_MINI := 0
-
-$(combo_var_prefix)HAVE_EXCEPTIONS := 0
-$(combo_var_prefix)HAVE_UNIX_FILE_PATH := 1
-$(combo_var_prefix)HAVE_WINDOWS_FILE_PATH := 0
-$(combo_var_prefix)HAVE_RTTI := 1
-$(combo_var_prefix)HAVE_CALL_STACKS := 1
-$(combo_var_prefix)HAVE_64BIT_IO := 1
-$(combo_var_prefix)HAVE_CLOCK_TIMERS := 1
-$(combo_var_prefix)HAVE_PTHREAD_RWLOCK := 1
-$(combo_var_prefix)HAVE_STRNLEN := 1
-$(combo_var_prefix)HAVE_STRERROR_R_STRRET := 1
-$(combo_var_prefix)HAVE_STRLCPY := 0
-$(combo_var_prefix)HAVE_STRLCAT := 0
-$(combo_var_prefix)HAVE_KERNEL_MODULES := 0
-
 $(combo_var_prefix)GLOBAL_CFLAGS := -fno-exceptions -Wno-multichar
 $(combo_var_prefix)RELEASE_CFLAGS := -O2 -g -fno-strict-aliasing
 $(combo_var_prefix)GLOBAL_CPPFLAGS :=
@@ -82,6 +66,10 @@
   # on a workstation.
   export CCACHE_BASEDIR := /
 
+  # Workaround for ccache with clang.
+  # See http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html
+  export CCACHE_CPP2 := true
+
   CCACHE_HOST_TAG := $(HOST_PREBUILT_TAG)
   # If we are cross-compiling Windows binaries on Linux
   # then use the linux ccache binary instead.
@@ -102,6 +90,11 @@
   endif
 endif
 
+# Stash the original values of CC and CXX so we can still use the non-wrapped
+# values later.
+$(combo_2nd_arch_prefix)CC_BARE := $($(combo_var_prefix)CC)
+$(combo_2nd_arch_prefix)CXX_BARE := $($(combo_var_prefix)CXX)
+
 # The C/C++ compiler can be wrapped by setting the CC/CXX_WRAPPER vars.
 ifdef CC_WRAPPER
   ifneq ($(CC_WRAPPER),$(firstword $($(combo_var_prefix)CC)))
diff --git a/core/config.mk b/core/config.mk
index 0ecb5c5..d6449d5 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -18,6 +18,14 @@
 empty :=
 space := $(empty) $(empty)
 comma := ,
+# Note that make will eat the newline just before endef.
+define newline
+
+
+endef
+# Unfortunately you can't simply define backslash as \ or \\.
+backslash := \a
+backslash := $(patsubst %a,%,$(backslash))
 
 # Tell python not to spam the source tree with .pyc files.  This
 # only has an effect on python 2.6 and above.
@@ -37,13 +45,13 @@
 	$(TOPDIR)frameworks/native/include \
 	$(TOPDIR)frameworks/native/opengl/include \
 	$(TOPDIR)frameworks/av/include \
-	$(TOPDIR)frameworks/base/include \
-	$(TOPDIR)external/skia/include
+	$(TOPDIR)frameworks/base/include
 SRC_HOST_HEADERS:=$(TOPDIR)tools/include
 SRC_LIBRARIES:= $(TOPDIR)libs
 SRC_SERVERS:= $(TOPDIR)servers
 SRC_TARGET_DIR := $(TOPDIR)build/target
 SRC_API_DIR := $(TOPDIR)prebuilts/sdk/api
+SRC_SYSTEM_API_DIR := $(TOPDIR)prebuilts/sdk/system-api
 
 # Some specific paths to tools
 SRC_DROIDDOC_DIR := $(TOPDIR)build/tools/droiddoc
@@ -61,10 +69,8 @@
 BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk
 BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
 BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
-BUILD_RAW_STATIC_LIBRARY := $(BUILD_SYSTEM)/raw_static_library.mk
 BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
 BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
-BUILD_RAW_EXECUTABLE:= $(BUILD_SYSTEM)/raw_executable.mk
 BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
 BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
 BUILD_PHONY_PACKAGE:= $(BUILD_SYSTEM)/phony_package.mk
@@ -77,6 +83,7 @@
 BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
 BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
 BUILD_NATIVE_TEST := $(BUILD_SYSTEM)/native_test.mk
+BUILD_NATIVE_BENCHMARK := $(BUILD_SYSTEM)/native_benchmark.mk
 BUILD_HOST_NATIVE_TEST := $(BUILD_SYSTEM)/host_native_test.mk
 
 BUILD_SHARED_TEST_LIBRARY := $(BUILD_SYSTEM)/shared_test_lib.mk
@@ -109,9 +116,15 @@
 COMMON_GLOBAL_CFLAGS:= -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith
 COMMON_RELEASE_CFLAGS:= -DNDEBUG -UDEBUG
 
-COMMON_GLOBAL_CPPFLAGS:= $(COMMON_GLOBAL_CFLAGS) -Wsign-promo
+COMMON_GLOBAL_CPPFLAGS:= $(COMMON_GLOBAL_CFLAGS) -Wsign-promo -std=gnu++11
 COMMON_RELEASE_CPPFLAGS:= $(COMMON_RELEASE_CFLAGS)
 
+GLOBAL_CFLAGS_NO_OVERRIDE :=  \
+    -Werror=int-to-pointer-cast \
+    -Werror=pointer-to-int-cast \
+
+GLOBAL_CPPFLAGS_NO_OVERRIDE :=
+
 # Set the extensions used for various packages
 COMMON_PACKAGE_SUFFIX := .zip
 COMMON_JAVA_PACKAGE_SUFFIX := .jar
@@ -381,13 +394,19 @@
 else
 MKBOOTIMG := $(BOARD_CUSTOM_MKBOOTIMG)
 endif
-MKYAFFS2 := $(HOST_OUT_EXECUTABLES)/mkyaffs2image$(HOST_EXECUTABLE_SUFFIX)
 APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
 FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
-MKEXT2IMG := $(HOST_OUT_EXECUTABLES)/genext2fs$(HOST_EXECUTABLE_SUFFIX)
 MAKE_EXT4FS := $(HOST_OUT_EXECUTABLES)/make_ext4fs$(HOST_EXECUTABLE_SUFFIX)
 MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg.sh
-MKEXT2BOOTIMG := external/genext2fs/mkbootimg_ext2.sh
+ifeq ($(HOST_OS),linux)
+MAKE_SQUASHFS := $(HOST_OUT_EXECUTABLES)/mksquashfs$(HOST_EXECUTABLE_SUFFIX)
+MKSQUASHFSUSERIMG := $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh
+else
+MAKE_SQUASHFS :=
+MKSQUASHFSUSERIMG :=
+endif
+MAKE_F2FS := $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX)
+MKF2FSUSERIMG := $(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh
 SIMG2IMG := $(HOST_OUT_EXECUTABLES)/simg2img$(HOST_EXECUTABLE_SUFFIX)
 E2FSCK := $(HOST_OUT_EXECUTABLES)/e2fsck$(HOST_EXECUTABLE_SUFFIX)
 MKTARBALL := build/tools/mktarball.sh
@@ -399,6 +418,11 @@
 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
+APPEND2SIMG := $(HOST_OUT_EXECUTABLES)/append2simg
+VERITY_SIGNER := $(HOST_OUT_EXECUTABLES)/verity_signer
+BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree
+BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer
 
 # ACP is always for the build OS, not for the host OS
 ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX)
@@ -406,9 +430,13 @@
 # dx is java behind a shell script; no .exe necessary.
 DX := $(HOST_OUT_EXECUTABLES)/dx
 ZIPALIGN := $(HOST_OUT_EXECUTABLES)/zipalign$(HOST_EXECUTABLE_SUFFIX)
-FINDBUGS := prebuilt/common/findbugs/bin/findbugs
+FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
+FINDBUGS := $(FINDBUGS_DIR)/findbugs
 EMMA_JAR := external/emma/lib/emma$(COMMON_JAVA_PACKAGE_SUFFIX)
 
+# Tool to merge AndroidManifest.xmls
+ANDROID_MANIFEST_MERGER := java -classpath prebuilts/devtools/tools/lib/manifest-merger.jar com.android.manifmerger.Main merge
+
 YACC_HEADER_SUFFIX:= .hpp
 
 # Don't use column under Windows, cygwin or not
@@ -418,17 +446,7 @@
 COLUMN:= column
 endif
 
-ifeq ($(HOST_OS),darwin)
-ifeq ($(LEGACY_USE_JAVA6),)
 HOST_JDK_TOOLS_JAR:= $(shell $(BUILD_SYSTEM)/find-jdk-tools-jar.sh)
-else
-# Deliberately set to blank for Java 6 installations on MacOS. These
-# versions allegedly use a non-standard directory structure.
-HOST_JDK_TOOLS_JAR :=
-endif
-else
-HOST_JDK_TOOLS_JAR:= $(shell $(BUILD_SYSTEM)/find-jdk-tools-jar.sh)
-endif
 
 ifneq ($(HOST_JDK_TOOLS_JAR),)
 ifeq ($(wildcard $(HOST_JDK_TOOLS_JAR)),)
@@ -523,26 +541,26 @@
 
 # allow overriding default Java libraries on a per-target basis
 ifeq ($(TARGET_DEFAULT_JAVA_LIBRARIES),)
-  TARGET_DEFAULT_JAVA_LIBRARIES := core-libart core-junit ext framework framework2
+  TARGET_DEFAULT_JAVA_LIBRARIES := core-libart core-junit ext framework
 endif
 
-TARGET_CPU_SMP ?= true
-
 # Flags for DEX2OAT
 DEX2OAT_TARGET_ARCH := $(TARGET_ARCH)
-DEX2OAT_TARGET_CPU_VARIANT := $(TARGET_CPU_VARIANT)
-DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES := default
-ifneq (,$(filter $(DEX2OAT_TARGET_CPU_VARIANT),cortex-a7 cortex-a15 krait denver))
-  DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES := div
+ifeq ($(TARGET_CPU_VARIANT),)
+ifeq ($(TARGET_ARCH_VARIANT),)
+DEX2OAT_TARGET_CPU_VARIANT := default
+else
+DEX2OAT_TARGET_CPU_VARIANT := $(TARGET_ARCH_VARIANT)
 endif
+else
+DEX2OAT_TARGET_CPU_VARIANT := $(TARGET_CPU_VARIANT)
+endif
+DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES := default
 
 ifdef TARGET_2ND_ARCH
 $(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH := $(TARGET_2ND_ARCH)
 $(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT := $(TARGET_2ND_CPU_VARIANT)
 $(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES := default
-ifneq (,$(filter $($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT),cortex-a7 cortex-a15 krait denver))
-  $(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES := div
-endif
 endif
 
 # define clang/llvm tools and global flags
@@ -576,7 +594,13 @@
     $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/android.jar,%, \
     $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/android.jar)))
 
+# We don't have prebuilt system_current SDK yet.
+TARGET_AVAILABLE_SDK_VERSIONS := $(TARGET_AVAILABLE_SDK_VERSIONS)
+
 INTERNAL_PLATFORM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/public_api.txt
+INTERNAL_PLATFORM_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/removed.txt
+INTERNAL_PLATFORM_SYSTEM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-api.txt
+INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/system-removed.txt
 
 # This is the standard way to name a directory containing prebuilt target
 # objects. E.g., prebuilt/$(TARGET_PREBUILT_TAG)/libc.so
@@ -587,8 +611,12 @@
 
 # Set up RS prebuilt variables for compatibility library
 
-RS_PREBUILT_CLCORE := prebuilts/sdk/renderscript/lib/$(TARGET_ARCH)/libclcore.bc
+RS_PREBUILT_CLCORE := prebuilts/sdk/renderscript/lib/$(TARGET_ARCH)/librsrt_$(TARGET_ARCH).bc
 RS_PREBUILT_LIBPATH := -L prebuilts/ndk/8/platforms/android-9/arch-$(TARGET_ARCH)/usr/lib
 RS_PREBUILT_COMPILER_RT := prebuilts/sdk/renderscript/lib/$(TARGET_ARCH)/libcompiler_rt.a
 
+# API Level lists for Renderscript Compat lib.
+RSCOMPAT_32BIT_ONLY_API_LEVELS := 8 9 10 11 12 13 14 15 16 17 18 19 20
+RSCOMPAT_NO_USAGEIO_API_LEVELS := 8 9 10 11 12 13
+
 include $(BUILD_SYSTEM)/dumpvar.mk
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
new file mode 100644
index 0000000..a1964a9
--- /dev/null
+++ b/core/config_sanitizers.mk
@@ -0,0 +1,32 @@
+##############################################
+## Perform configuration steps for sanitizers.
+##############################################
+
+# Configure SANITIZE_HOST.
+ifdef LOCAL_IS_HOST_MODULE
+ifeq ($(SANITIZE_HOST),true)
+ifneq ($(strip $(LOCAL_CLANG)),false)
+ifneq ($(strip $(LOCAL_ADDRESS_SANITIZER)),false)
+    LOCAL_ADDRESS_SANITIZER := true
+endif
+endif
+endif
+endif
+
+# Configure address sanitizer.
+ifeq ($(strip $(LOCAL_ADDRESS_SANITIZER)),true)
+  my_clang := true
+  # Frame pointer based unwinder in ASan requires ARM frame setup.
+  LOCAL_ARM_MODE := arm
+  my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
+  my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
+  ifdef LOCAL_IS_HOST_MODULE
+      my_ldflags += -fsanitize=address
+      # -nodefaultlibs (provided with libc++) prevents the driver from linking
+      # libraries needed with -fsanitize=address. http://b/18650275
+      my_ldlibs += -ldl -lpthread
+  else
+      my_shared_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES)
+      my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
+  endif
+endif
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
new file mode 100644
index 0000000..265d8cb
--- /dev/null
+++ b/core/cxx_stl_setup.mk
@@ -0,0 +1,95 @@
+#############################################################
+## Set up flags based on LOCAL_CXX_STL.
+## Input variables: LOCAL_CXX_STL
+## Output variables: My_cflags, my_c_includes, my_shared_libraries, etc.
+#############################################################
+
+# Select the appropriate C++ STL
+ifeq ($(strip $(LOCAL_CXX_STL)),default)
+    ifndef LOCAL_SDK_VERSION
+        # Platform code. Select the appropriate STL.
+        ifndef USE_MINGW
+            my_cxx_stl := libc++
+            ifdef LOCAL_IS_HOST_MODULE
+                ifneq (,$(BUILD_HOST_static))
+                    my_cxx_stl := libc++_static
+                endif
+            endif
+        else
+            # libc++ is not supported on mingw.
+            my_cxx_stl := libstdc++
+        endif
+    else
+        my_cxx_stl := ndk
+    endif
+else
+    my_cxx_stl := $(strip $(LOCAL_CXX_STL))
+endif
+
+# Yes, this is actually what the clang driver does.
+HOST_linux_dynamic_gcclibs := -lgcc_s -lgcc -lc -lgcc_s -lgcc
+HOST_linux_static_gcclibs := -Wl,--start-group -lgcc -lgcc_eh -lc -Wl,--end-group
+HOST_darwin_dynamic_gcclibs := -lc -lSystem
+HOST_darwin_static_gcclibs := NO_STATIC_HOST_BINARIES_ON_DARWIN
+
+my_link_type := dynamic
+ifdef LOCAL_IS_HOST_MODULE
+    ifneq (,$(BUILD_HOST_static))
+        my_link_type := static
+    endif
+    ifeq (-static,$(filter -static,$(my_ldflags)))
+        my_link_type := static
+    endif
+else
+    ifeq (true,$(LOCAL_FORCE_STATIC_EXECUTABLE))
+        my_link_type := static
+    endif
+endif
+
+ifneq ($(filter $(my_cxx_stl),libc++ libc++_static),)
+    my_cflags += -D_USING_LIBCXX
+    my_c_includes += external/libcxx/include
+    ifeq ($(my_cxx_stl),libc++)
+        my_shared_libraries += libc++
+    else
+        my_static_libraries += libc++_static
+    endif
+
+    ifdef LOCAL_IS_HOST_MODULE
+        my_cppflags += -nostdinc++
+        my_ldflags += -nodefaultlibs
+        my_ldlibs += -lpthread -lm
+        my_ldlibs += $($(my_prefix)$(HOST_OS)_$(my_link_type)_gcclibs)
+    endif
+else ifneq ($(filter $(my_cxx_stl),stlport stlport_static),)
+    ifndef LOCAL_IS_HOST_MODULE
+        my_c_includes += external/stlport/stlport bionic/libstdc++/include \
+                         bionic
+        ifeq ($(my_cxx_stl),stlport)
+            my_shared_libraries += libstdc++ libstlport
+        else
+            my_static_libraries += libstdc++ libstlport_static
+        endif
+    endif
+else ifeq ($(my_cxx_stl),ndk)
+    # Using an NDK STL. Handled farther up in this file.
+    ifndef LOCAL_IS_HOST_MODULE
+        my_system_shared_libraries += libstdc++
+    endif
+else ifeq ($(my_cxx_stl),libstdc++)
+    # Using bionic's basic libstdc++. Not actually an STL. Only around until the
+    # tree is in good enough shape to not need it.
+    ifndef LOCAL_IS_HOST_MODULE
+        my_c_includes += bionic/libstdc++/include
+        my_system_shared_libraries += libstdc++
+    endif
+    # Host builds will use GNU libstdc++.
+else ifeq ($(my_cxx_stl),none)
+    ifdef LOCAL_IS_HOST_MODULE
+        my_cppflags += -nostdinc++
+        my_ldflags += -nodefaultlibs
+        my_ldlibs += $($(my_prefix)$(HOST_OS)_$(my_link_type)_gcclibs)
+    endif
+else
+    $(error $(my_cxx_stl) is not a supported STL.)
+endif
diff --git a/core/definitions.mk b/core/definitions.mk
index 441c186..fb91e13 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -684,7 +684,7 @@
 # any of those tags.
 # $(1): tag list
 define modules-for-tag-list
-$(sort $(foreach tag,$(1),$(ALL_MODULE_TAGS.$(tag))))
+$(sort $(foreach tag,$(1),$(foreach m,$(ALL_MODULE_NAME_TAGS.$(tag)),$(ALL_MODULES.$(m).INSTALLED))))
 endef
 
 # Same as modules-for-tag-list, but operates on
@@ -879,13 +879,13 @@
 @echo "Renderscript compatibility: $(notdir $@) <= $(notdir $<)"
 $(hide) mkdir -p $(dir $@)
 $(hide) $(BCC_COMPAT) -O3 -o $(dir $@)/$(notdir $(<:.bc=.o)) -fPIC -shared \
-	-rt-path $(RS_PREBUILT_CLCORE) -mtriple $(RS_TRIPLE) $<
+	-rt-path $(RS_PREBUILT_CLCORE) -mtriple $(RS_COMPAT_TRIPLE) $<
 $(hide) $(PRIVATE_CXX) -shared -Wl,-soname,$(notdir $@) -nostdlib \
 	-Wl,-rpath,\$$ORIGIN/../lib \
 	$(dir $@)/$(notdir $(<:.bc=.o)) \
 	$(RS_PREBUILT_COMPILER_RT) \
-	-o $@ -L prebuilts/gcc/ \
-	-L $(TARGET_OUT_INTERMEDIATE_LIBRARIES) $(RS_PREBUILT_LIBPATH) \
+	-o $@ $(TARGET_GLOBAL_LDFLAGS) -Wl,--hash-style=sysv -L prebuilts/gcc/ \
+	$(RS_PREBUILT_LIBPATH) -L $(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
 	-lRSSupport -lm -lc
 endef
 
@@ -990,6 +990,8 @@
 	$(PRIVATE_CFLAGS) \
 	$(PRIVATE_CPPFLAGS) \
 	$(PRIVATE_DEBUG_CFLAGS) \
+	$(GLOBAL_CFLAGS_NO_OVERRIDE) \
+	$(GLOBAL_CPPFLAGS_NO_OVERRIDE) \
 	-MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
 $(transform-d-to-p)
 endef
@@ -1013,6 +1015,7 @@
 	-c \
 	$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 	    $(PRIVATE_TARGET_GLOBAL_CFLAGS) \
+	    $(PRIVATE_TARGET_GLOBAL_CONLYFLAGS) \
 	    $(PRIVATE_ARM_CFLAGS) \
 	 ) \
 	 $(1) \
@@ -1021,7 +1024,11 @@
 
 define transform-c-to-o-no-deps
 @echo "target $(PRIVATE_ARM_MODE) C: $(PRIVATE_MODULE) <= $<"
-$(call transform-c-or-s-to-o-no-deps, $(PRIVATE_CFLAGS) $(PRIVATE_CONLYFLAGS) $(PRIVATE_DEBUG_CFLAGS))
+$(call transform-c-or-s-to-o-no-deps, \
+    $(PRIVATE_CFLAGS) \
+    $(PRIVATE_CONLYFLAGS) \
+    $(PRIVATE_DEBUG_CFLAGS) \
+    $(GLOBAL_CFLAGS_NO_OVERRIDE))
 endef
 
 define transform-s-to-o-no-deps
@@ -1044,7 +1051,7 @@
 @mkdir -p $(dir $@)
 $(hide) $(YASM) \
     $(addprefix -I , $(PRIVATE_C_INCLUDES)) \
-    -f elf32 -m x86 \
+    $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_YASM_FLAGS) \
     $(PRIVATE_ASFLAGS) \
     -o $@ $<
 endef
@@ -1111,6 +1118,7 @@
 	-c \
 	$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 	    $(PRIVATE_HOST_GLOBAL_CFLAGS) \
+	    $(PRIVATE_HOST_GLOBAL_CONLYFLAGS) \
 	 ) \
 	$(1) \
 	-MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
@@ -1176,22 +1184,41 @@
 
 # $(1): the full path of the source static library.
 define _extract-and-include-single-target-whole-static-lib
-@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(1)]"
+@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(strip $(1))]"
 $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
     rm -rf $$ldir; \
     mkdir -p $$ldir; \
+    cp $(1) $$ldir; \
+    lib_to_include=$$ldir/$(notdir $(1)); \
     filelist=; \
+    subdir=0; \
     for f in `$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) t $(1)`; do \
-        $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) p $(1) $$f > $$ldir/$$f; \
-        filelist="$$filelist $$ldir/$$f"; \
+        if [ -e $$ldir/$$f ]; then \
+            mkdir $$ldir/$$subdir; \
+            ext=$$subdir/; \
+            subdir=$$((subdir+1)); \
+            $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) m $$lib_to_include $$f; \
+        else \
+            ext=; \
+        fi; \
+        $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) p $$lib_to_include $$f > $$ldir/$$ext$$f; \
+        filelist="$$filelist $$ldir/$$ext$$f"; \
     done ; \
     $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \
         $(PRIVATE_ARFLAGS) $@ $$filelist
 
 endef
 
+# $(1): the full path of the source static library.
+define extract-and-include-whole-static-libs-first
+$(if $(strip $(1)),
+@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(strip $(1))]"
+$(hide) cp $(1) $@)
+endef
+
 define extract-and-include-target-whole-static-libs
-$(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
+$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)))
+$(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \
     $(call _extract-and-include-single-target-whole-static-lib, $(lib)))
 endef
 
@@ -1213,14 +1240,25 @@
 
 # $(1): the full path of the source static library.
 define _extract-and-include-single-host-whole-static-lib
-@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(1)]"
+@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(strip $(1))]"
 $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
     rm -rf $$ldir; \
     mkdir -p $$ldir; \
+    cp $(1) $$ldir; \
+    lib_to_include=$$ldir/$(notdir $(1)); \
     filelist=; \
+    subdir=0; \
     for f in `$($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_AR) t $(1) | \grep '\.o$$'`; do \
-        $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_AR) p $(1) $$f > $$ldir/$$f; \
-        filelist="$$filelist $$ldir/$$f"; \
+        if [ -e $$ldir/$$f ]; then \
+           mkdir $$ldir/$$subdir; \
+           ext=$$subdir/; \
+           subdir=$$((subdir+1)); \
+           $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_AR) m $$lib_to_include $$f; \
+        else \
+           ext=; \
+        fi; \
+        $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_AR) p $$lib_to_include $$f > $$ldir/$$ext$$f; \
+        filelist="$$filelist $$ldir/$$ext$$f"; \
     done ; \
     $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_ARFLAGS) \
         $(PRIVATE_ARFLAGS) $@ $$filelist
@@ -1228,7 +1266,8 @@
 endef
 
 define extract-and-include-host-whole-static-libs
-$(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
+$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)))
+$(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \
     $(call _extract-and-include-single-host-whole-static-lib, $(lib)))
 endef
 
@@ -1269,6 +1308,7 @@
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(if $(filter true,$(NATIVE_COVERAGE)),-lgcov) \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_LDLIBS)
@@ -1292,26 +1332,13 @@
 ## Commands for running gcc to link a shared library or package
 ###########################################################
 
-#echo >$@.vers "{"; \
-#echo >>$@.vers " global:"; \
-#$(BUILD_SYSTEM)/filter_symbols.sh $(TARGET_NM) "  " ";" $(filter %.o,$^) | sort -u >>$@.vers; \
-#echo >>$@.vers " local:"; \
-#echo >>$@.vers "  *;"; \
-#echo >>$@.vers "};"; \
-
-#	-Wl,--version-script=$@.vers \
-
-# ld just seems to be so finicky with command order that we allow
-# it to be overriden en-masse see combo/linux-arm.make for an example.
-ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
 define transform-o-to-shared-lib-inner
 $(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
-	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	-Wl,-rpath,\$$ORIGIN/../lib \
-	-shared -Wl,-soname,$(notdir $@) \
-	$(PRIVATE_LDFLAGS) \
+	-nostdlib -Wl,-soname,$(notdir $@) \
+	-Wl,--gc-sections \
+	$(if $(filter true,$(PRIVATE_CLANG)),-shared,-Wl$(comma)-shared) \
 	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
 	$(PRIVATE_ALL_OBJECTS) \
 	-Wl,--whole-archive \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
@@ -1319,16 +1346,22 @@
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_TARGET_LIBATOMIC) \
+	$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_LIBGCOV)) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O)) \
 	$(PRIVATE_LDLIBS)
 endef
-endif
 
 define transform-o-to-shared-lib
 @mkdir -p $(dir $@)
 @echo "target SharedLib: $(PRIVATE_MODULE) ($@)"
-$($(PRIVATE_2ND_ARCH_VAR_PREFIX)transform-o-to-shared-lib-inner)
+$(transform-o-to-shared-lib-inner)
 endef
 
 
@@ -1360,14 +1393,15 @@
 ## Commands for running gcc to link an executable
 ###########################################################
 
-ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
 define transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) \
-	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+$(hide) $(PRIVATE_CXX) -pie \
+	-nostdlib -Bdynamic \
+	-Wl,-dynamic-linker,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_LINKER) \
+	-Wl,--gc-sections \
+	-Wl,-z,nocopyreloc \
 	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
 	-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
-	-Wl,-rpath,\$$ORIGIN/../lib \
-	$(PRIVATE_LDFLAGS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
 	$(PRIVATE_ALL_OBJECTS) \
 	-Wl,--whole-archive \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
@@ -1375,35 +1409,65 @@
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_TARGET_LIBATOMIC) \
+	$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_LIBGCOV)) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O)) \
 	$(PRIVATE_LDLIBS)
 endef
-endif
 
 define transform-o-to-executable
 @mkdir -p $(dir $@)
 @echo "target Executable: $(PRIVATE_MODULE) ($@)"
-$($(PRIVATE_2ND_ARCH_VAR_PREFIX)transform-o-to-executable-inner)
+$(transform-o-to-executable-inner)
 endef
 
 
 ###########################################################
-## Commands for running gcc to link a statically linked
-## executable.  In practice, we only use this on arm, so
-## the other platforms don't have the
-## transform-o-to-static-executable defined
+## Commands for linking a static executable. In practice,
+## we only use this on arm, so the other platforms don't
+## have transform-o-to-static-executable defined.
+## Clang driver needs -static to create static executable.
+## However, bionic/linker uses -shared to overwrite.
+## Linker for x86 targets does not allow coexistance of -static and -shared,
+## so we add -static only if -shared is not used.
 ###########################################################
 
-ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
 define transform-o-to-static-executable-inner
+$(hide) $(PRIVATE_CXX) \
+	-nostdlib -Bstatic \
+	$(if $(filter $(PRIVATE_LDFLAGS),-shared),,-static) \
+	-Wl,--gc-sections \
+	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(call normalize-target-libraries,$(filter-out %libcompiler_rt.a,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))))) \
+	-Wl,--start-group \
+	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+	$(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+	$(PRIVATE_TARGET_LIBATOMIC) \
+	$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_LIBGCOV)) \
+	$(call normalize-target-libraries,$(filter %libcompiler_rt.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	-Wl,--end-group \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
 endef
-endif
 
 define transform-o-to-static-executable
 @mkdir -p $(dir $@)
 @echo "target StaticExecutable: $(PRIVATE_MODULE) ($@)"
-$($(PRIVATE_2ND_ARCH_VAR_PREFIX)transform-o-to-static-executable-inner)
+$(transform-o-to-static-executable-inner)
 endef
 
 
@@ -1413,7 +1477,11 @@
 ifdef BUILD_HOST_static
 HOST_FPIE_FLAGS :=
 else
-HOST_FPIE_FLAGS := -fPIE -pie
+HOST_FPIE_FLAGS := -pie
+# Force the correct entry point to workaround a bug in binutils that manifests with -pie
+ifeq ($(HOST_OS),windows)
+HOST_FPIE_FLAGS += -Wl,-e_mainCRTStartup
+endif
 endif
 
 ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
@@ -1426,13 +1494,13 @@
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(if $(filter true,$(NATIVE_COVERAGE)),-lgcov) \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-Wl,-rpath-link=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES) \
 	-Wl,-rpath,\$$ORIGIN/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
 	$($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_LD_DIRS) \
 	$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 		$(PRIVATE_HOST_GLOBAL_LDFLAGS) \
-		$(HOST_FPIE_FLAGS) \
 	) \
 	$(PRIVATE_LDFLAGS) \
 	-o $@ \
@@ -1568,7 +1636,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
@@ -1593,12 +1661,22 @@
     -name $(word 1, $(PRIVATE_JAR_EXCLUDE_FILES)) \
     $(addprefix -o -name , $(wordlist 2, 999, $(PRIVATE_JAR_EXCLUDE_FILES))) \
     | xargs rm -rf)
-$(if $(PRIVATE_JAR_PACKAGES), $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -mindepth 1 -type d \
-    $(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_JAR_PACKAGES), \
+    $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -mindepth 1 -type f \
+        $(foreach pkg, $(PRIVATE_JAR_PACKAGES), \
+            -not -path $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))/\*) -delete ; \
+        find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -empty -delete)
+$(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) rm -rf \
+    $(foreach pkg, $(PRIVATE_JAR_EXCLUDE_PACKAGES), \
+        $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))))
+$(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) .)
+$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
 endef
 
 define transform-java-to-classes.jar
@@ -1644,12 +1722,22 @@
     -name $(word 1, $(PRIVATE_JAR_EXCLUDE_FILES)) \
     $(addprefix -o -name , $(wordlist 2, 999, $(PRIVATE_JAR_EXCLUDE_FILES))) \
     | xargs rm -rf)
-$(if $(PRIVATE_JAR_PACKAGES), $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -mindepth 1 -type d \
-    $(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_JAR_PACKAGES), \
+    $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -mindepth 1 -type f \
+        $(foreach pkg, $(PRIVATE_JAR_PACKAGES), \
+            -not -path $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))/\*) -delete ; \
+        find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -empty -delete)
+$(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) rm -rf \
+    $(foreach pkg, $(PRIVATE_JAR_EXCLUDE_PACKAGES), \
+        $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))))
+$(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) .)
+$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
 $(hide) mv $(PRIVATE_CLASS_INTERMEDIATES_DIR)/newstamp $(PRIVATE_CLASS_INTERMEDIATES_DIR)/stamp
 endef
 
@@ -1671,9 +1759,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) \
@@ -1690,10 +1779,21 @@
 # so we need to give it something.
 define create-empty-package
 @mkdir -p $(dir $@)
-$(hide) touch $(dir $@)dummy
-$(hide) (cd $(dir $@) && jar cf $(notdir $@) dummy)
-$(hide) zip -qd $@ dummy
-$(hide) rm $(dir $@)dummy
+$(hide) touch $(dir $@)zipdummy
+$(hide) (cd $(dir $@) && jar cf $(notdir $@) zipdummy)
+$(hide) zip -qd $@ zipdummy
+$(hide) rm $(dir $@)zipdummy
+endef
+
+# Copy an arhchive file and delete any class files and empty folders inside.
+# $(1): the source archive file.
+# $(2): the destination archive file.
+define initialize-package-file
+@mkdir -p $(dir $(2))
+$(hide) cp -f $(1) $(2)
+$(hide) zip -qd $(2) "*.class" \
+    $(if $(strip $(PRIVATE_DONT_DELETE_JAR_DIRS)),,"*/") \
+    || true # Ignore the error when nothing to delete.
 endef
 
 #TODO: we kinda want to build different asset packages for
@@ -1708,7 +1808,7 @@
 define add-assets-to-package
 $(hide) $(AAPT) package -u $(PRIVATE_AAPT_FLAGS) \
     $(addprefix -c , $(PRIVATE_PRODUCT_AAPT_CONFIG)) \
-    $(addprefix --preferred-configurations , $(PRIVATE_PRODUCT_AAPT_PREF_CONFIG)) \
+    $(addprefix --preferred-density , $(PRIVATE_PRODUCT_AAPT_PREF_CONFIG)) \
     $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
     $(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
     $(addprefix -A , $(PRIVATE_ASSET_DIR)) \
@@ -1737,38 +1837,22 @@
 $(foreach abi,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI),\
   $(call _add-jni-shared-libs-to-package-per-abi,$(abi),\
     $(patsubst $(abi):%,%,$(filter $(abi):%,$(PRIVATE_JNI_SHARED_LIBRARIES)))))
-$(hide) (cd $(dir $@) && zip -r $(notdir $@) lib)
+$(hide) (cd $(dir $@) && zip -r $(PRIVATE_JNI_SHARED_LIBRARIES_ZIP_OPTIONS) $(notdir $@) lib)
 $(hide) rm -rf $(dir $@)lib
 endef
 
 #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.
+# $(1) destination package
 #
-define add-java-resources-to-package
-$(call dump-words-to-file, $(PRIVATE_EXTRA_JAR_ARGS), $(dir $@)jar-arg-list)
-$(hide) jar uf $@ @$(dir $@)jar-arg-list
-@rm -f $(dir $@)jar-arg-list
-endef
-
-# Add java resources carried by static Java libraries.
-#
-define add-carried-java-resources
-$(hide) if [ -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) ] ; then \
-    java_res_jar_flags=$$(find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -type f -a -not -name "*.class" \
-        | sed -e "s?^$(PRIVATE_CLASS_INTERMEDIATES_DIR)/? -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) ?"); \
-    if [ -n "$$java_res_jar_flags" ] ; then \
-        echo $$java_res_jar_flags >$(dir $@)java_res_jar_flags; \
-        jar uf $@ $$java_res_jar_flags; \
-    fi; \
-fi
+define add-java-resources-to
+$(call dump-words-to-file, $(PRIVATE_EXTRA_JAR_ARGS), $(1).jar-arg-list)
+$(hide) jar uf $(1) @$(1).jar-arg-list
+@rm -f $(1).jar-arg-list
 endef
 
 # Sign a package using the specified key/cert.
@@ -1781,12 +1865,15 @@
 $(hide) mv $@.signed $@
 endef
 
-# Align STORED entries of a package on 4-byte boundaries
-# to make them easier to mmap.
+# Align STORED entries of a package on 4-byte boundaries to make them easier to mmap.
 #
 define align-package
 $(hide) mv $@ $@.unaligned
-$(hide) $(ZIPALIGN) -f 4 $@.unaligned $@.aligned
+$(hide) $(ZIPALIGN) \
+    -f \
+    $(if $(findstring true, $(PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES)),-p ,) \
+    4 \
+    $@.unaligned $@.aligned
 $(hide) mv $@.aligned $@
 endef
 
@@ -1812,7 +1899,6 @@
 define transform-host-java-to-package
 @echo "host Java: $(PRIVATE_MODULE) ($(PRIVATE_CLASS_INTERMEDIATES_DIR))"
 $(call compile-java,$(HOST_JAVAC),$(PRIVATE_BOOTCLASSPATH))
-$(if $(PRIVATE_EXTRA_JAR_ARGS), $(call add-java-resources-to-package))
 endef
 
 ###########################################################
@@ -1996,8 +2082,8 @@
 endef
 
 # $(1): The file(s) to check (often $@)
-# $(2): The maximum total image size, in decimal bytes
-# $(3): the type of filesystem "yaffs" or "raw"
+# $(2): The maximum total image size, in decimal bytes.
+#    Make sure to take into account any reserved space needed for the FS.
 #
 # If $(2) is empty, evaluates to "true"
 #
@@ -2010,15 +2096,9 @@
   total=$$(( $$( echo "$$size" ) )); \
   printname=$$(echo -n "$(1)" | tr " " +); \
   img_blocksize=$(call image-size-from-data-size,$(BOARD_FLASH_BLOCK_SIZE)); \
-  if [ "$(3)" == "yaffs" ]; then \
-    reservedblocks=8; \
-  else \
-    reservedblocks=0; \
-  fi; \
   twoblocks=$$((img_blocksize * 2)); \
   onepct=$$((((($(2) / 100) - 1) / img_blocksize + 1) * img_blocksize)); \
-  reserve=$$(((twoblocks > onepct ? twoblocks : onepct) + \
-               reservedblocks * img_blocksize)); \
+  reserve=$$((twoblocks > onepct ? twoblocks : onepct)); \
   maxsize=$$(($(2) - reserve)); \
   echo "$$printname maxsize=$$maxsize blocksize=$$img_blocksize total=$$total reserve=$$reserve"; \
   if [ "$$total" -gt "$$maxsize" ]; then \
@@ -2040,8 +2120,7 @@
 # $(2): The partition size.
 define assert-max-image-size
 $(if $(2), \
-  $(call assert-max-file-size,$(1),$(call image-size-from-data-size,$(2))), \
-  true)
+  $(call assert-max-file-size,$(1),$(call image-size-from-data-size,$(2))))
 endef
 
 
@@ -2140,17 +2219,19 @@
 #    $(1)  target
 #    $(2)  stable api file
 #    $(3)  api file to be tested
-#    $(4)  arguments for apicheck
-#    $(5)  command to run if apicheck failed
-#    $(6)  target dependent on this api check
-#    $(7)  additional dependencies
+#    $(4)  stable removed api file
+#    $(5)  removed api file to be tested
+#    $(6)  arguments for apicheck
+#    $(7)  command to run if apicheck failed
+#    $(8)  target dependent on this api check
+#    $(9)  additional dependencies
 define check-api
-$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp: $(2) $(3) $(APICHECK) $(7)
+$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp: $(2) $(3) $(4) $(APICHECK) $(9)
 	@echo "Checking API:" $(1)
-	$(hide) ( $(APICHECK_COMMAND) $(4) $(2) $(3) || ( $(5) ; exit 38 ) )
+	$(hide) ( $(APICHECK_COMMAND) $(6) $(2) $(3) $(4) $(5) || ( $(7) ; exit 38 ) )
 	$(hide) mkdir -p $$(dir $$@)
 	$(hide) touch $$@
-$(6): $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp
+$(8): $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp
 endef
 
 ## Whether to build from source if prebuilt alternative exists
@@ -2177,11 +2258,13 @@
 $(if $(call if-build-from-source,$(2),$(3)),$(eval include $(1)))
 endef
 
-## Return the arch for the source file of a prebuilt
+# Return the arch for the source file of a prebuilt
+# Return "none" if no matching arch found, so the result can be passed to
+# LOCAL_MODULE_TARGET_ARCH.
 # $(1) the list of archs supported by the prebuilt
 define get-prebuilt-src-arch
 $(strip $(if $(filter $(TARGET_ARCH),$(1)),$(TARGET_ARCH),\
-  $(if $(filter $(TARGET_2ND_ARCH),$(1)),$(TARGET_2ND_ARCH))))
+  $(if $(filter $(TARGET_2ND_ARCH),$(1)),$(TARGET_2ND_ARCH),none)))
 endef
 
 ###########################################################
@@ -2195,6 +2278,7 @@
 
 # Include any vendor specific definitions.mk file
 -include $(TOPDIR)vendor/*/build/core/definitions.mk
+-include $(TOPDIR)device/*/build/core/definitions.mk
 
 # broken:
 #	$(foreach file,$^,$(if $(findstring,.a,$(suffix $file)),-l$(file),$(file)))
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 76fc130..8b555e0 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -3,19 +3,22 @@
 #
 ####################################
 
-ifneq ($(DALVIK_VM_LIB),)
-
 # list of boot classpath jars for dexpreopt
 DEXPREOPT_BOOT_JARS := $(subst $(space),:,$(PRODUCT_BOOT_JARS))
 DEXPREOPT_BOOT_JARS_MODULES := $(PRODUCT_BOOT_JARS)
 PRODUCT_BOOTCLASSPATH := $(subst $(space),:,$(foreach m,$(DEXPREOPT_BOOT_JARS_MODULES),/system/framework/$(m).jar))
 
+PRODUCT_SYSTEM_SERVER_CLASSPATH := $(subst $(space),:,$(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),/system/framework/$(m).jar))
+
 DEXPREOPT_BUILD_DIR := $(OUT_DIR)
 DEXPREOPT_PRODUCT_DIR_FULL_PATH := $(PRODUCT_OUT)/dex_bootjars
 DEXPREOPT_PRODUCT_DIR := $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(DEXPREOPT_PRODUCT_DIR_FULL_PATH))
 DEXPREOPT_BOOT_JAR_DIR := system/framework
 DEXPREOPT_BOOT_JAR_DIR_FULL_PATH := $(DEXPREOPT_PRODUCT_DIR_FULL_PATH)/$(DEXPREOPT_BOOT_JAR_DIR)
 
+# The default value for LOCAL_DEX_PREOPT
+DEX_PREOPT_DEFAULT ?= true
+
 # $(1): the .jar or .apk to remove classes.dex
 define dexpreopt-remove-classes.dex
 $(hide) zip --quiet --delete $(1) classes.dex; \
@@ -44,36 +47,17 @@
 
 $(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),$(eval $(call _dexpreopt-boot-jar-remove-classes.dex,$(b))))
 
-# Conditionally include Dalvik support.
-ifeq ($(DALVIK_VM_LIB),libdvm.so)
-include $(BUILD_SYSTEM)/dex_preopt_libdvm.mk
-endif
-
-# Unconditionally include ART support because its used run dex2oat on the host for tests.
 include $(BUILD_SYSTEM)/dex_preopt_libart.mk
 
 # Define dexpreopt-one-file based on current default runtime.
 # $(1): the input .jar or .apk file
 # $(2): the output .odex file
-ifeq ($(DALVIK_VM_LIB),libdvm.so)
-define dexpreopt-one-file
-$(call dexopt-one-file,$(1),$(2))
-endef
-
-DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS := $(DEXOPT_DEPENDENCY)
-DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT := $(DEXPREOPT_BOOT_ODEXS)
-else
 define dexpreopt-one-file
 $(call dex2oat-one-file,$(1),$(2))
 endef
 
-DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS := $(DEX2OATD_DEPENDENCY)
+DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS := $(DEX2OAT_DEPENDENCY)
 DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT := $(DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME)
 ifdef TARGET_2ND_ARCH
 $(TARGET_2ND_ARCH_VAR_PREFIX)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME)
 endif  # TARGET_2ND_ARCH
-endif  # DALVIK_VM_LIB
-else
-$(warning No DALVIK_VM_LIB, disable dexpreopt.)
-WITH_DEXPREOPT := false
-endif  # DALVIK_VM_LIB is defined.
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 411af75..bee5d40 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -16,15 +16,43 @@
 DEX2OATD_DEPENDENCY := $(DEX2OAT_DEPENDENCY)
 DEX2OATD_DEPENDENCY += $(DEX2OATD)
 
-PRELOADED_CLASSES := frameworks/base/preloaded-classes
+# Use the first preloaded-classes file in PRODUCT_COPY_FILES.
+PRELOADED_CLASSES := $(call word-colon,1,$(firstword \
+    $(filter %system/etc/preloaded-classes,$(PRODUCT_COPY_FILES))))
+
+# Use the first compiled-classes file in PRODUCT_COPY_FILES.
+COMPILED_CLASSES := $(call word-colon,1,$(firstword \
+    $(filter %system/etc/compiled-classes,$(PRODUCT_COPY_FILES))))
+
+# Default to debug version to help find bugs.
+# Set USE_DEX2OAT_DEBUG to false for only building non-debug versions.
+ifneq ($(USE_DEX2OAT_DEBUG), false)
+DEX2OAT = $(DEX2OATD)
+DEX2OAT_DEPENDENCY = $(DEX2OATD_DEPENDENCY)
+endif
 
 # start of image reserved address space
 LIBART_IMG_HOST_BASE_ADDRESS   := 0x60000000
-
-ifeq ($(TARGET_ARCH),mips)
-LIBART_IMG_TARGET_BASE_ADDRESS := 0x30000000
-else
 LIBART_IMG_TARGET_BASE_ADDRESS := 0x70000000
+
+define get-product-default-property
+$(strip $(patsubst $(1)=%,%,$(filter $(1)=%,$(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))))
+endef
+
+DEX2OAT_IMAGE_XMS := $(call get-product-default-property,dalvik.vm.image-dex2oat-Xms)
+DEX2OAT_IMAGE_XMX := $(call get-product-default-property,dalvik.vm.image-dex2oat-Xmx)
+DEX2OAT_XMS := $(call get-product-default-property,dalvik.vm.dex2oat-Xms)
+DEX2OAT_XMX := $(call get-product-default-property,dalvik.vm.dex2oat-Xmx)
+
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),mips mips64))
+# MIPS specific overrides.
+# For MIPS the ART image is loaded at a lower address. This causes issues
+# with the image overlapping with memory on the host cross-compiling and
+# building the image. We therefore limit the Xmx value. This isn't done
+# via a property as we want the larger Xmx value if we're running on a
+# MIPS device.
+LIBART_IMG_TARGET_BASE_ADDRESS := 0x30000000
+DEX2OAT_XMX := 128m
 endif
 
 ########################################################################
@@ -67,13 +95,17 @@
 define dex2oat-one-file
 $(hide) rm -f $(2)
 $(hide) mkdir -p $(dir $(2))
-$(hide) $(DEX2OATD) \
-	--runtime-arg -Xms64m --runtime-arg -Xmx64m \
+$(hide) $(DEX2OAT) \
+	--runtime-arg -Xms$(DEX2OAT_XMS) --runtime-arg -Xmx$(DEX2OAT_XMX) \
 	--boot-image=$(PRIVATE_DEX_PREOPT_IMAGE_LOCATION) \
 	--dex-file=$(1) \
 	--dex-location=$(PRIVATE_DEX_LOCATION) \
 	--oat-file=$(2) \
 	--android-root=$(PRODUCT_OUT)/system \
 	--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
-	--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+	--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
+	--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
+	--include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols \
+	--abort-on-hard-verifier-error \
+	$(PRIVATE_DEX_PREOPT_FLAGS)
 endef
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 70130b6..2569d73 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -27,9 +27,17 @@
 # The .oat with symbols
 $(my_2nd_arch_prefix)LIBART_TARGET_BOOT_OAT_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)$(patsubst %.art,%.oat,$($(my_2nd_arch_prefix)LIBART_BOOT_IMAGE_FILENAME))
 
-$(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE :=
-ifneq ($(PRODUCT_DEX_PREOPT_IMAGE_IN_DATA),true)
 $(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE := $(PRODUCT_OUT)$($(my_2nd_arch_prefix)LIBART_BOOT_IMAGE_FILENAME)
+
+# Compile boot.oat as position-independent code if WITH_DEXPREOPT_PIC=true
+ifeq (true,$(WITH_DEXPREOPT_PIC))
+  PRODUCT_DEX_PREOPT_BOOT_FLAGS += --compile-pic
+endif
+
+# If we have a compiled-classes file, create a parameter.
+COMPILED_CLASSES_FLAGS :=
+ifneq ($(COMPILED_CLASSES),)
+  COMPILED_CLASSES_FLAGS := --compiled-classes=$(COMPILED_CLASSES)
 endif
 
 # The rule to install boot.art and boot.oat
@@ -39,11 +47,12 @@
 
 $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_2ND_ARCH_VAR_PREFIX := $(my_2nd_arch_prefix)
 # Use dex2oat debug version for better error reporting
-$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(DEX2OATD_DEPENDENCY)
+$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(DEX2OAT_DEPENDENCY)
 	@echo "target dex2oat: $@ ($?)"
 	@mkdir -p $(dir $@)
 	@mkdir -p $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))
-	$(hide) $(DEX2OATD) --runtime-arg -Xms256m --runtime-arg -Xmx256m --image-classes=$(PRELOADED_CLASSES) \
+	$(hide) $(DEX2OAT) --runtime-arg -Xms$(DEX2OAT_IMAGE_XMS) --runtime-arg -Xmx$(DEX2OAT_IMAGE_XMX) \
+		--image-classes=$(PRELOADED_CLASSES) \
 		$(addprefix --dex-file=,$(LIBART_TARGET_BOOT_DEX_FILES)) \
 		$(addprefix --dex-location=,$(LIBART_TARGET_BOOT_DEX_LOCATIONS)) \
 		--oat-symbols=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED) \
@@ -51,5 +60,7 @@
 		--oat-location=$(patsubst %.art,%.oat,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_BOOT_IMAGE_FILENAME)) \
 		--image=$@ --base=$(LIBART_IMG_TARGET_BASE_ADDRESS) \
 		--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
+		--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
 		--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
-		--android-root=$(PRODUCT_OUT)/system
+		--android-root=$(PRODUCT_OUT)/system --include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols \
+		$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(COMPILED_CLASSES_FLAGS)
diff --git a/core/dex_preopt_libdvm.mk b/core/dex_preopt_libdvm.mk
deleted file mode 100644
index 23a54e1e..0000000
--- a/core/dex_preopt_libdvm.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-####################################
-# dexpreopt support for Dalvik
-#
-####################################
-
-DEXOPT := $(HOST_OUT_EXECUTABLES)/dexopt$(HOST_EXECUTABLE_SUFFIX)
-DEXPREOPT := dalvik/tools/dex-preopt
-
-DEXPREOPT_DEXOPT := $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(DEXOPT))
-
-DEXPREOPT_BOOT_ODEXS := $(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),\
-    $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(b).odex)
-
-# If the target is a uniprocessor, then explicitly tell the preoptimizer
-# that fact. (By default, it always optimizes for an SMP target.)
-ifeq ($(TARGET_CPU_SMP),true)
-    DEXPREOPT_UNIPROCESSOR :=
-else
-    DEXPREOPT_UNIPROCESSOR := --uniprocessor
-endif
-
-# By default, do not run rerun dexopt if the tool changes.
-# Comment out the | to force dex2oat to rerun on after all changes.
-DEXOPT_DEPENDENCY := |
-DEXOPT_DEPENDENCY += $(DEXPREOPT) $(DEXOPT)
-
-# $(1): the input .jar or .apk file
-# $(2): the output .odex file
-define dexopt-one-file
-$(hide) rm -f $(2)
-$(hide) mkdir -p $(dir $(2))
-$(hide) $(DEXPREOPT) \
-        --dexopt=$(DEXPREOPT_DEXOPT) \
-        --build-dir=$(DEXPREOPT_BUILD_DIR) \
-        --product-dir=$(DEXPREOPT_PRODUCT_DIR) \
-        --boot-dir=$(DEXPREOPT_BOOT_JAR_DIR) \
-        --boot-jars=$(DEXPREOPT_BOOT_JARS) \
-        $(DEXPREOPT_UNIPROCESSOR) \
-        $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(1)) \
-        $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(2))
-endef
-
-# Special rules for building odex files for boot jars that override java_library.mk rules
-
-# $(1): boot jar module name
-define _dexpreopt-boot-odex
-_dbj_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1).jar
-_dbj_odex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1).odex
-_dbj_src_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(1),,COMMON)/javalib.jar
-$$(_dbj_odex): PRIVATE_DBJ_JAR := $$(_dbj_jar)
-$$(_dbj_odex) : $$(_dbj_src_jar) | $(ACP) $(DEXPREOPT) $(DEXOPT)
-	@echo "Dexpreopt Boot Jar: $$@"
-	$(hide) mkdir -p $$(dir $$(PRIVATE_DBJ_JAR)) && $(ACP) -fp $$< $$(PRIVATE_DBJ_JAR)
-	$$(call dexopt-one-file,$$(PRIVATE_DBJ_JAR),$$@)
-
-_dbj_jar :=
-_dbj_odex :=
-_dbj_src_jar :=
-endef
-
-$(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),$(eval $(call _dexpreopt-boot-odex,$(b))))
-
-# $(1): the rest list of boot jars
-define _build-dexpreopt-boot-jar-dependency-pair
-$(if $(filter 1,$(words $(1)))$(filter 0,$(words $(1))),,\
-	$(eval _bdbjdp_target := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(word 2,$(1)).odex) \
-	$(eval _bdbjdp_dep := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(word 1,$(1)).odex) \
-	$(eval $(call add-dependency,$(_bdbjdp_target),$(_bdbjdp_dep))) \
-	$(eval $(call _build-dexpreopt-boot-jar-dependency-pair,$(wordlist 2,999,$(1)))))
-endef
-
-define _build-dexpreopt-boot-jar-dependency
-$(call _build-dexpreopt-boot-jar-dependency-pair,$(DEXPREOPT_BOOT_JARS_MODULES))
-endef
-
-$(eval $(call _build-dexpreopt-boot-jar-dependency))
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index caaa16d..aef5cd1 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -9,11 +9,18 @@
 else # WITH_DEXPREOPT=true
   ifeq (,$(TARGET_BUILD_APPS)) # TARGET_BUILD_APPS empty
     ifndef LOCAL_DEX_PREOPT # LOCAL_DEX_PREOPT undefined
-      ifeq (,$(LOCAL_APK_LIBRARIES)) # LOCAL_APK_LIBRARIES empty
-        LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT)
-      else # LOCAL_APK_LIBRARIES not empty
-        LOCAL_DEX_PREOPT := nostripping
-      endif # LOCAL_APK_LIBRARIES not empty
+      ifneq ($(filter $(TARGET_OUT)/%,$(my_module_path)),) # Installed to system.img.
+        ifeq (,$(LOCAL_APK_LIBRARIES)) # LOCAL_APK_LIBRARIES empty
+          # If we have product-specific config for this module?
+          ifeq (disable,$(DEXPREOPT.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG))
+            LOCAL_DEX_PREOPT := false
+          else
+            LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT)
+          endif
+        else # LOCAL_APK_LIBRARIES not empty
+          LOCAL_DEX_PREOPT := nostripping
+        endif # LOCAL_APK_LIBRARIES not empty
+      endif # Installed to system.img.
     endif # LOCAL_DEX_PREOPT undefined
   endif # TARGET_BUILD_APPS empty
 endif # WITH_DEXPREOPT=true
@@ -23,13 +30,15 @@
 ifdef LOCAL_UNINSTALLABLE_MODULE
 LOCAL_DEX_PREOPT :=
 endif
-ifeq (,$(strip $(all_java_sources)$(full_static_java_libs)$(my_prebuilt_src_file))) # contains no java code
+ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file))) # contains no java code
 LOCAL_DEX_PREOPT :=
 endif
-# if module oat file requested in data, disable LOCAL_DEX_PREOPT, will default location to dalvik-cache
-ifneq (,$(filter $(LOCAL_MODULE),$(PRODUCT_DEX_PREOPT_PACKAGES_IN_DATA)))
+# if WITH_DEXPREOPT_BOOT_IMG_ONLY=true and module is not in boot class path skip
+ifeq (true,$(WITH_DEXPREOPT_BOOT_IMG_ONLY))
+ifeq ($(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
 LOCAL_DEX_PREOPT :=
 endif
+endif
 
 built_odex :=
 installed_odex :=
@@ -37,90 +46,54 @@
 ifdef LOCAL_DEX_PREOPT
 dexpreopt_boot_jar_module := $(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE))
 ifdef dexpreopt_boot_jar_module
-ifeq ($(DALVIK_VM_LIB),libdvm.so)
-built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
-installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex
-built_installed_odex := $(built_odex):$(installed_odex)
-else # libdvm.so
 # For libart, the boot jars' odex files are replaced by $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE).
 # We use this installed_odex trick to get boot.art installed.
 installed_odex := $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
 # Append the odex for the 2nd arch if we have one.
 installed_odex += $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
-endif # libdvm.so
 else  # boot jar
-ifeq ($(DALVIK_VM_LIB),libdvm.so)
-built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
-installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex
-built_installed_odex := $(built_odex):$(installed_odex)
-
-$(built_odex) : $(DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
-                $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS)
-else # libart
 ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
 # For a Java library, we build odex for both 1st arch and 2nd arch, if we have one.
 # #################################################
 # Odex for the 1st arch
-built_odex := $(call get-odex-file-path,$(DEX2OAT_TARGET_ARCH),$(LOCAL_BUILT_MODULE))
-ifdef LOCAL_DEX_PREOPT_IMAGE_LOCATION
-my_dex_preopt_image_location := $(LOCAL_DEX_PREOPT_IMAGE_LOCATION)
-else
-my_dex_preopt_image_location := $(DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
-endif
-my_dex_preopt_image_filename := $(call get-image-file-path,$(DEX2OAT_TARGET_ARCH),$(my_dex_preopt_image_location))
-$(built_odex): PRIVATE_2ND_ARCH_VAR_PREFIX :=
-$(built_odex): PRIVATE_DEX_LOCATION := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
-$(built_odex): PRIVATE_DEX_PREOPT_IMAGE_LOCATION := $(my_dex_preopt_image_location)
-$(built_odex) : $(DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
-                $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
-                $(my_dex_preopt_image_filename)
-installed_odex := $(call get-odex-file-path,$(DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
-built_installed_odex := $(built_odex):$(installed_odex)
+my_2nd_arch_prefix :=
+include $(BUILD_SYSTEM)/setup_one_odex.mk
 # #################################################
 # Odex for the 2nd arch
 ifdef TARGET_2ND_ARCH
-built_odex2 := $(call get-odex-file-path,$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH),$(LOCAL_BUILT_MODULE))
-ifdef LOCAL_DEX_PREOPT_IMAGE_LOCATION
-my_dex_preopt_image_location := $(LOCAL_DEX_PREOPT_IMAGE_LOCATION)
-else
-my_dex_preopt_image_location := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
-endif
-my_dex_preopt_image_filename := $(call get-image-file-path,$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH),$(my_dex_preopt_image_location))
-$(built_odex2): PRIVATE_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
-$(built_odex2): PRIVATE_DEX_LOCATION := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
-$(built_odex2): PRIVATE_DEX_PREOPT_IMAGE_LOCATION := $(my_dex_preopt_image_location)
-$(built_odex2) : $($(TARGET_2ND_ARCH_VAR_PREFIX)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
-                 $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
-                 $(my_dex_preopt_image_filename)
-
-installed_odex2 := $(call get-odex-file-path,$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
-built_odex += $(built_odex2)
-installed_odex += $(installed_odex2)
-built_installed_odex += $(built_odex2):$(installed_odex2)
+my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
+include $(BUILD_SYSTEM)/setup_one_odex.mk
 endif  # TARGET_2ND_ARCH
 # #################################################
 else  # must be APPS
-# For an app, we build for the multilib arch it's targeted for.
-built_odex := $(call get-odex-file-path,$($(LOCAL_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH),$(LOCAL_BUILT_MODULE))
-ifdef LOCAL_DEX_PREOPT_IMAGE_LOCATION
-my_dex_preopt_image_location := $(LOCAL_DEX_PREOPT_IMAGE_LOCATION)
-else
-my_dex_preopt_image_location := $($(LOCAL_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
-endif
-my_dex_preopt_image_filename := $(call get-image-file-path,$($(LOCAL_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH),$(my_dex_preopt_image_location))
-$(built_odex): PRIVATE_2ND_ARCH_VAR_PREFIX := $(LOCAL_2ND_ARCH_VAR_PREFIX)
-$(built_odex): PRIVATE_DEX_LOCATION := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
-$(built_odex): PRIVATE_DEX_PREOPT_IMAGE_LOCATION := $(my_dex_preopt_image_location)
-$(built_odex) : $($(LOCAL_2ND_ARCH_VAR_PREFIX)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
-                $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
-                $(my_dex_preopt_image_filename)
-installed_odex := $(call get-odex-file-path,$($(LOCAL_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
-built_installed_odex := $(built_odex):$(installed_odex)
+# The preferred arch
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+include $(BUILD_SYSTEM)/setup_one_odex.mk
+ifdef TARGET_2ND_ARCH
+ifeq ($(LOCAL_MULTILIB),both)
+# The non-preferred arch
+my_2nd_arch_prefix := $(if $(LOCAL_2ND_ARCH_VAR_PREFIX),,$(TARGET_2ND_ARCH_VAR_PREFIX))
+include $(BUILD_SYSTEM)/setup_one_odex.mk
+endif  # LOCAL_MULTILIB is both
+endif  # TARGET_2ND_ARCH
 endif  # LOCAL_MODULE_CLASS
-endif # libart
-endif # boot jar
+endif  # boot jar
 
 ifdef built_odex
+ifndef LOCAL_DEX_PREOPT_FLAGS
+LOCAL_DEX_PREOPT_FLAGS := $(DEXPREOPT.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG)
+ifndef LOCAL_DEX_PREOPT_FLAGS
+LOCAL_DEX_PREOPT_FLAGS := $(PRODUCT_DEX_PREOPT_DEFAULT_FLAGS)
+endif
+endif
+
+# Compile apps with position-independent code if WITH_DEXPREOPT_PIC=true
+ifeq (true,$(WITH_DEXPREOPT_PIC))
+  LOCAL_DEX_PREOPT_FLAGS += --compile-pic
+endif
+
+$(built_odex): PRIVATE_DEX_PREOPT_FLAGS := $(LOCAL_DEX_PREOPT_FLAGS)
+
 # Use pattern rule - we may have multiple installed odex files.
 # Ugly syntax - See the definition get-odex-file-path.
 $(installed_odex) : $(dir $(LOCAL_INSTALLED_MODULE))%$(notdir $(word 1,$(installed_odex))) \
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
new file mode 100644
index 0000000..0e8cbdf
--- /dev/null
+++ b/core/dpi_specific_apk.mk
@@ -0,0 +1,70 @@
+# Set up rules to build dpi-specific apk, with whatever else from the base apk.
+# Input variable: my_dpi, and all other variables set up in package_internal.mk.
+#
+
+dpi_apk_name := $(LOCAL_MODULE)_$(my_dpi)
+dpi_intermediate := $(call intermediates-dir-for,APPS,$(dpi_apk_name))
+built_dpi_apk := $(dpi_intermediate)/package.apk
+
+# Set up all the target-specific variables.
+$(built_dpi_apk): PRIVATE_MODULE := $(dpi_apk_name)
+$(built_dpi_apk): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) $(PRODUCT_AAPT_FLAGS) $($(LOCAL_PACKAGE_NAME)_aapt_flags_$(my_dpi))
+# Clear PRIVATE_PRODUCT_AAPT_CONFIG to include everything by default.
+$(built_dpi_apk): PRIVATE_PRODUCT_AAPT_CONFIG :=
+$(built_dpi_apk): PRIVATE_PRODUCT_AAPT_PREF_CONFIG := $(my_dpi)
+$(built_dpi_apk): PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
+$(built_dpi_apk): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
+$(built_dpi_apk): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
+$(built_dpi_apk): PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
+ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION)))
+$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
+else
+$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
+endif
+$(built_dpi_apk): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
+$(built_dpi_apk): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_INSTRUMENTATION_FOR)
+$(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
+$(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
+$(built_dpi_apk): PRIVATE_DEX_FILE := $(built_dex)
+# Note that PRIVATE_CLASS_INTERMEDIATES_DIR points to the base apk's intermediate dir.
+$(built_dpi_apk): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates)/classes
+$(built_dpi_apk): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
+$(built_dpi_apk): PRIVATE_PRIVATE_KEY := $(private_key)
+$(built_dpi_apk): PRIVATE_CERTIFICATE := $(certificate)
+$(built_dpi_apk): PRIVATE_ADDITIONAL_CERTIFICATES := $(foreach c,\
+    $(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
+
+# Set up dependenncies and the build recipe.
+$(built_dpi_apk) : $(R_file_stamp)
+$(built_dpi_apk) : $(all_library_res_package_export_deps)
+$(built_dpi_apk) : $(built_dex)
+$(built_dpi_apk) : $(private_key) $(certificate) $(SIGNAPK_JAR)
+$(built_dpi_apk) : $(AAPT) | $(ZIPALIGN)
+$(built_dpi_apk) : $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
+	@echo "target Package: $(PRIVATE_MODULE) ($@)"
+	$(create-empty-package)
+	$(add-assets-to-package)
+ifneq ($(jni_shared_libraries),)
+	$(add-jni-shared-libs-to-package)
+endif
+ifneq ($(full_classes_jar),)
+	$(add-dex-to-package)
+endif
+	$(add-carried-java-resources)
+ifneq ($(extra_jar_args),)
+	$(add-java-resources-to-package)
+endif
+	$(sign-package)
+	$(align-package)
+
+# Set up global variables to register this apk to the higher-level dependency graph.
+ALL_MODULES += $(dpi_apk_name)
+ALL_MODULES.$(dpi_apk_name).CLASS := APPS
+ALL_MODULES.$(dpi_apk_name).BUILT := $(built_dpi_apk)
+PACKAGES := $(PACKAGES) $(dpi_apk_name)
+PACKAGES.$(dpi_apk_name).PRIVATE_KEY := $(private_key)
+PACKAGES.$(dpi_apk_name).CERTIFICATE := $(certificate)
+
+# Phony targets used by "apps_only".
+.PHONY: $(dpi_apk_name)
+$(dpi_apk_name) : $(built_dpi_apk)
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index ecfe3dc..41f135c 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -64,12 +64,15 @@
     # Use android_stubs_current if LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
     LOCAL_JAVA_LIBRARIES := android_stubs_current $(LOCAL_JAVA_LIBRARIES)
     $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_stubs_current)
+  else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
+    LOCAL_JAVA_LIBRARIES := android_system_stubs_current $(LOCAL_JAVA_LIBRARIES)
+    $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_system_stubs_current)
   else
     LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
     $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(LOCAL_SDK_VERSION))
   endif
 else
-  LOCAL_JAVA_LIBRARIES := core-libart ext framework framework2 $(LOCAL_JAVA_LIBRARIES)
+  LOCAL_JAVA_LIBRARIES := core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
   $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core-libart)
 endif  # LOCAL_SDK_VERSION
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
@@ -134,15 +137,13 @@
 $(full_target): PRIVATE_IN_CUSTOM_ASSET_DIR := $(LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR)/$(LOCAL_DROIDDOC_CUSTOM_ASSET_DIR)
 $(full_target): PRIVATE_OUT_ASSET_DIR := $(out_dir)/$(LOCAL_DROIDDOC_ASSET_DIR)
 $(full_target): PRIVATE_OUT_CUSTOM_ASSET_DIR := $(out_dir)/$(LOCAL_DROIDDOC_CUSTOM_ASSET_DIR)
+
+html_dir_files :=
 ifneq ($(strip $(LOCAL_DROIDDOC_HTML_DIR)),)
 $(full_target): PRIVATE_DROIDDOC_HTML_DIR := -htmldir $(LOCAL_PATH)/$(LOCAL_DROIDDOC_HTML_DIR)
+html_dir_files := $(shell find $(LOCAL_PATH)/$(LOCAL_DROIDDOC_HTML_DIR) -type f)
 else
-$(full_target): PRIVATE_DROIDDOC_HTML_DIR := 
-endif
-ifneq ($(strip $(LOCAL_ADDITIONAL_HTML_DIR)),)
-$(full_target): PRIVATE_ADDITIONAL_HTML_DIR := -htmldir2 $(LOCAL_PATH)/$(LOCAL_ADDITIONAL_HTML_DIR)
-else
-$(full_target): PRIVATE_ADDITIONAL_HTML_DIR :=
+$(full_target): PRIVATE_DROIDDOC_HTML_DIR :=
 endif
 ifneq ($(strip $(LOCAL_ADDITIONAL_HTML_DIR)),)
 $(full_target): PRIVATE_ADDITIONAL_HTML_DIR := -htmldir2 $(LOCAL_PATH)/$(LOCAL_ADDITIONAL_HTML_DIR)
@@ -153,9 +154,14 @@
 # TODO: not clear if this is used any more
 $(full_target): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
 
-html_dir_files := $(shell find $(LOCAL_PATH)/$(LOCAL_DROIDDOC_HTML_DIR) -type f)
-
-$(full_target): $(full_src_files) $(droiddoc_templates) $(droiddoc) $(html_dir_files) $(full_java_lib_deps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(full_target): \
+        $(full_src_files) \
+        $(droiddoc_templates) \
+        $(droiddoc) \
+        $(html_dir_files) \
+        $(full_java_lib_deps) \
+        $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Docs droiddoc: $(PRIVATE_OUT_DIR)
 	$(hide) mkdir -p $(dir $@)
 	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index 396199c..08fb176 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -17,16 +17,13 @@
 # know its results before base_rules.mk is included.
 include $(BUILD_SYSTEM)/configure_module_stem.mk
 
-# base_rules.make defines $(intermediates), but we need its value
-# before we include base_rules.  Make a guess, and verify that
-# it's correct once the real value is defined.
-guessed_intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX))
+intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX))
 
 # Define the target that is the unmodified output of the linker.
 # The basename of this target must be the same as the final output
 # binary name, because it's used to set the "soname" in the binary.
 # The includer of this file will define a rule to build this target.
-linked_module := $(guessed_intermediates)/LINKED/$(my_built_module_stem)
+linked_module := $(intermediates)/LINKED/$(my_built_module_stem)
 
 ALL_ORIGINAL_DYNAMIC_BINARIES += $(linked_module)
 
@@ -41,11 +38,6 @@
 include $(BUILD_SYSTEM)/binary.mk
 ###################################
 
-# Make sure that our guess at the value of intermediates was correct.
-ifneq ($(intermediates),$(guessed_intermediates))
-$(error Internal error: guessed path '$(guessed_intermediates)' doesn't match '$(intermediates))
-endif
-
 ###########################################################
 ## Compress
 ###########################################################
@@ -110,6 +102,15 @@
 $(strip_output): PRIVATE_READELF := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_READELF)
 $(strip_output): $(strip_input) | $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
 	$(transform-to-stripped-keep-symbols)
+
+# A product may be configured to strip everything in some build variants.
+# We do the stripping as a post-install command so that LOCAL_BUILT_MODULE
+# is still with the symbols and we don't need to clean it (and relink) when
+# you switch build variant.
+ifneq ($(filter $(STRIP_EVERYTHING_BUILD_VARIANTS),$(TARGET_BUILD_VARIANT)),)
+$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := \
+  $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP) --strip-all $(LOCAL_INSTALLED_MODULE)
+endif
 else
 # Don't strip the binary, just copy it.  We can't skip this step
 # because a copy of the binary must appear at LOCAL_BUILT_MODULE.
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 9caf7c0..43774ea 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -58,7 +58,7 @@
 # Under Linux, if USE_MINGW is set, we change HOST_OS to Windows to build the
 # Windows SDK. Only a subset of tools and SDK will manage to build properly.
 ifeq ($(HOST_OS),linux)
-ifneq ($(USE_MINGW),)
+ifdef USE_MINGW
   HOST_OS := windows
 endif
 endif
@@ -67,30 +67,11 @@
 $(error Unable to determine HOST_OS from uname -sm: $(UNAME)!)
 endif
 
-# TODO: Replace BUILD_HOST_64bit with a flag that forces 32-bit build,
-# after we default to 64-bit host build.
-ifeq (,$(BUILD_HOST_64bit))
-# Default to 32-bit-by-default multilib host build.
-HOST_PREFER_32_BIT := true
-ifeq ($(HOST_PREFER_32_BIT),true)
-BUILD_HOST_64bit := true
-endif
-endif
-
 # HOST_ARCH
 ifneq (,$(findstring x86_64,$(UNAME)))
   HOST_ARCH := x86_64
   HOST_2ND_ARCH := x86
-else ifneq (,$(findstring 86,$(UNAME)))
-  # It's not officially supported!
-  HOST_ARCH := x86
-  HOST_2ND_ARCH :=
-endif
-
-ifeq ($(HOST_PREFER_32_BIT),true)
-SDK_HOST_ARCH := x86
-else
-SDK_HOST_ARCH := $(HOST_ARCH)
+  HOST_IS_64_BIT := true
 endif
 
 BUILD_ARCH := $(HOST_ARCH)
@@ -125,11 +106,21 @@
 # Define them here so they can be used in product config files.
 TARGET_COPY_OUT_SYSTEM := system
 TARGET_COPY_OUT_DATA := data
-TARGET_COPY_OUT_VENDOR := system/vendor
+TARGET_COPY_OUT_OEM := oem
 TARGET_COPY_OUT_ROOT := root
 TARGET_COPY_OUT_RECOVERY := recovery
+###########################################
+# Define TARGET_COPY_OUT_VENDOR to a placeholder, for at this point
+# we don't know if the device wants to build a separate vendor.img
+# or just build vendor stuff into system.img.
+# A device can set up TARGET_COPY_OUT_VENDOR to "vendor" in its
+# BoardConfig.mk.
+# We'll substitute with the real value after loading BoardConfig.mk.
+_vendor_path_placeholder := ||VENDOR-PATH-PH||
+TARGET_COPY_OUT_VENDOR := $(_vendor_path_placeholder)
+###########################################
 
-# Read the product specs so we an get TARGET_DEVICE and other
+# Read the product specs so we can get TARGET_DEVICE and other
 # variables that we need in order to locate the output files.
 include $(BUILD_SYSTEM)/product_config.mk
 
@@ -139,6 +130,17 @@
 $(error must be empty or one of: eng user userdebug)
 endif
 
+# Build host as 32-bit for SDK build.
+ifneq ($(filter $(MAKECMDGOALS),win_sdk sdk),)
+HOST_PREFER_32_BIT := true
+endif
+ifdef USE_MINGW
+# We only build sdk host tools in the MinGW windows build.
+# Build it as 32-bit as well.
+HOST_PREFER_32_BIT := true
+endif
+SDK_HOST_ARCH := x86
+
 # Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)
 # or under vendor/*/$(TARGET_DEVICE).  Search in both places, but
 # make sure only one exists.
@@ -162,6 +164,17 @@
 TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
 board_config_mk :=
 
+###########################################
+# Now we can substitute with the real value of TARGET_COPY_OUT_VENDOR
+ifeq ($(TARGET_COPY_OUT_VENDOR),$(_vendor_path_placeholder))
+TARGET_COPY_OUT_VENDOR := system/vendor
+else ifeq ($(filter vendor system/vendor,$(TARGET_COPY_OUT_VENDOR)),)
+$(error TARGET_COPY_OUT_VENDOR must be either 'vendor' or 'system/vendor', seeing '$(TARGET_COPY_OUT_VENDOR)'.)
+endif
+PRODUCT_COPY_FILES := $(subst $(_vendor_path_placeholder),$(TARGET_COPY_OUT_VENDOR),$(PRODUCT_COPY_FILES))
+###########################################
+
+
 # ---------------------------------------------------------------
 # Set up configuration for target machine.
 # The following must be set:
@@ -170,6 +183,9 @@
 
 TARGET_OS := linux
 # TARGET_ARCH should be set by BoardConfig.mk and will be checked later
+ifneq ($(filter %64,$(TARGET_ARCH)),)
+TARGET_IS_64_BIT := true
+endif
 
 # the target build type defaults to release
 ifneq ($(TARGET_BUILD_TYPE),debug)
@@ -218,11 +234,7 @@
 BUILD_OUT_EXECUTABLES := $(BUILD_OUT)/bin
 
 HOST_OUT_EXECUTABLES := $(HOST_OUT)/bin
-ifeq (x86_64,$(HOST_ARCH))
 HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib64
-else
-HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib
-endif
 HOST_OUT_JAVA_LIBRARIES := $(HOST_OUT)/framework
 HOST_OUT_SDK_ADDON := $(HOST_OUT)/sdk_addon
 
@@ -231,6 +243,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
@@ -245,7 +258,11 @@
 
 # The default host library path.
 # It always points to the path where we build libraries in the default bitness.
-HOST_LIBRARY_PATH := $(HOST_OUT)/lib
+ifeq ($(HOST_PREFER_32_BIT),true)
+HOST_LIBRARY_PATH := $($(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)
+else
+HOST_LIBRARY_PATH := $(HOST_OUT_SHARED_LIBRARIES)
+endif
 
 TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj
 TARGET_OUT_HEADERS := $(TARGET_OUT_INTERMEDIATES)/include
@@ -258,7 +275,7 @@
 TARGET_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM)
 TARGET_OUT_EXECUTABLES := $(TARGET_OUT)/bin
 TARGET_OUT_OPTIONAL_EXECUTABLES := $(TARGET_OUT)/xbin
-ifneq ($(filter %64,$(TARGET_ARCH)),)
+ifeq ($(TARGET_IS_64_BIT),true)
 # /system/lib always contains 32-bit libraries,
 # and /system/lib64 (if present) always contains 64-bit libraries.
 TARGET_OUT_SHARED_LIBRARIES := $(TARGET_OUT)/lib64
@@ -292,19 +309,24 @@
 TARGET_OUT_DATA_KEYLAYOUT := $(TARGET_OUT_KEYLAYOUT)
 TARGET_OUT_DATA_KEYCHARS := $(TARGET_OUT_KEYCHARS)
 TARGET_OUT_DATA_ETC := $(TARGET_OUT_ETC)
+ifeq ($(TARGET_IS_64_BIT),true)
+TARGET_OUT_DATA_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest64
+else
 TARGET_OUT_DATA_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest
+endif
 TARGET_OUT_DATA_FAKE := $(TARGET_OUT_DATA)/fake_packages
 
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_DATA_EXECUTABLES)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_SHARED_LIBRARIES := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_APPS := $(TARGET_OUT_DATA_APPS)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest
 
 TARGET_OUT_CACHE := $(PRODUCT_OUT)/cache
 
 TARGET_OUT_VENDOR := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)
 TARGET_OUT_VENDOR_EXECUTABLES := $(TARGET_OUT_VENDOR)/bin
 TARGET_OUT_VENDOR_OPTIONAL_EXECUTABLES := $(TARGET_OUT_VENDOR)/xbin
-ifneq ($(filter %64,$(TARGET_ARCH)),)
+ifeq ($(TARGET_IS_64_BIT),true)
 TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(TARGET_OUT_VENDOR)/lib64
 else
 TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(TARGET_OUT_VENDOR)/lib
@@ -317,9 +339,26 @@
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(TARGET_OUT_VENDOR)/lib
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS := $(TARGET_OUT_VENDOR_APPS)
 
+TARGET_OUT_OEM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_OEM)
+TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM)/bin
+ifneq ($(filter %64,$(TARGET_ARCH)),)
+TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib64
+else
+TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib
+endif
+# We don't expect Java libraries in the oem.img.
+# TARGET_OUT_OEM_JAVA_LIBRARIES:= $(TARGET_OUT_OEM)/framework
+TARGET_OUT_OEM_APPS := $(TARGET_OUT_OEM)/app
+TARGET_OUT_OEM_ETC := $(TARGET_OUT_OEM)/etc
+
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM_EXECUTABLES)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_APPS := $(TARGET_OUT_OEM_APPS)
+
 TARGET_OUT_UNSTRIPPED := $(PRODUCT_OUT)/symbols
 TARGET_OUT_EXECUTABLES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/bin
 TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/lib
+TARGET_OUT_VENDOR_SHARED_LIBRARIES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/$(TARGET_COPY_OUT_VENDOR)/lib
 TARGET_ROOT_OUT_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)
 TARGET_ROOT_OUT_SBIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/sbin
 TARGET_ROOT_OUT_BIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/bin
@@ -342,8 +381,6 @@
 TARGET_INSTALLER_ROOT_OUT := $(TARGET_INSTALLER_OUT)/root
 TARGET_INSTALLER_SYSTEM_OUT := $(TARGET_INSTALLER_OUT)/root/system
 
-TARGET_FACTORY_RAMDISK_OUT := $(PRODUCT_OUT)/factory_ramdisk
-
 COMMON_MODULE_CLASSES := TARGET-NOTICE_FILES HOST-NOTICE_FILES HOST-JAVA_LIBRARIES
 
 ifeq (,$(strip $(DIST_DIR)))
diff --git a/core/executable_internal.mk b/core/executable_internal.mk
index 2e380b6..ebb6867 100644
--- a/core/executable_internal.mk
+++ b/core/executable_internal.mk
@@ -26,9 +26,16 @@
 
 include $(BUILD_SYSTEM)/dynamic_binary.mk
 
+# Check for statically linked libc
+ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+ifneq ($(filter $(my_static_libraries),libc),)
+$(error $(LOCAL_PATH): $(LOCAL_MODULE) is statically linking libc to dynamic executable, please remove libc from static libs or set LOCAL_FORCE_STATIC_EXECUTABLE := true)
+endif
+endif
+
 # Define PRIVATE_ variables from global vars
 my_target_global_ld_dirs := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS)
-my_target_fdo_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_LIB)
+my_target_libgcov := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCOV)
 my_target_libgcc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCC)
 my_target_libatomic := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBATOMIC)
 my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_DYNAMIC_O)
@@ -48,7 +55,7 @@
 endif
 $(linked_module): PRIVATE_TARGET_GLOBAL_LD_DIRS := $(my_target_global_ld_dirs)
 $(linked_module): PRIVATE_TARGET_GLOBAL_LDFLAGS := $(my_target_global_ldflags)
-$(linked_module): PRIVATE_TARGET_FDO_LIB := $(my_target_fdo_lib)
+$(linked_module): PRIVATE_TARGET_LIBGCOV := $(my_target_libgcov)
 $(linked_module): PRIVATE_TARGET_LIBGCC := $(my_target_libgcc)
 $(linked_module): PRIVATE_TARGET_LIBATOMIC := $(my_target_libatomic)
 $(linked_module): PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O := $(my_target_crtbegin_dynamic_o)
@@ -57,8 +64,10 @@
 $(linked_module): PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)
 
 ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+$(linked_module): PRIVATE_POST_LINK_CMD := $(LOCAL_POST_LINK_CMD)
 $(linked_module): $(my_target_crtbegin_static_o) $(all_objects) $(all_libraries) $(my_target_crtend_o)
 	$(transform-o-to-static-executable)
+	$(PRIVATE_POST_LINK_CMD)
 else
 $(linked_module): $(my_target_crtbegin_dynamic_o) $(all_objects) $(all_libraries) $(my_target_crtend_o)
 	$(transform-o-to-executable)
diff --git a/core/executable_prefer_symlink.mk b/core/executable_prefer_symlink.mk
index f66a5f2..2326e83 100644
--- a/core/executable_prefer_symlink.mk
+++ b/core/executable_prefer_symlink.mk
@@ -8,17 +8,27 @@
 # configuration. Note that we require the TARGET_IS_64_BIT
 # check because 32 bit targets may not define TARGET_PREFER_32_BIT_APPS
 # et al. since those variables make no sense in that context.
-
 ifneq ($(LOCAL_IS_HOST_MODULE),true)
   my_symlink := $(addprefix $(TARGET_OUT)/bin/, $(LOCAL_MODULE))
   ifeq ($(TARGET_IS_64_BIT),true)
-    ifneq ($(TARGET_PREFER_32_BIT_APPS),true)
-$(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_64)
+    ifeq ($(TARGET_SUPPORTS_64_BIT_APPS)|$(TARGET_SUPPORTS_32_BIT_APPS),true|true)
+      # We support both 32 and 64 bit apps, so we will have to
+      # base our decision on whether the target prefers one or the
+      # other.
+      ifeq ($(TARGET_PREFER_32_BIT_APPS),true)
+        $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
+      else
+        $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_64)
+      endif
+    else ifeq ($(TARGET_SUPPORTS_64_BIT_APPS),true)
+      # We support only 64 bit apps.
+      $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_64)
     else
-$(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
+      # We support only 32 bit apps.
+      $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
     endif
   else
-$(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
+    $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
   endif
 else
   my_symlink := $(addprefix $(HOST_OUT)/bin/, $(LOCAL_MODULE))
diff --git a/core/find-jdk-tools-jar.sh b/core/find-jdk-tools-jar.sh
index f150a9a..0224829 100755
--- a/core/find-jdk-tools-jar.sh
+++ b/core/find-jdk-tools-jar.sh
@@ -2,7 +2,13 @@
 if [ "x$ANDROID_JAVA_HOME" != x ] && [ -e "$ANDROID_JAVA_HOME/lib/tools.jar" ] ; then
     echo $ANDROID_JAVA_HOME/lib/tools.jar
 else
-    JAVAC=$(which javac)
+    JAVAC=$(realpath $(which javac) 2>/dev/null)
+    if [ -z "$JAVAC" ]; then
+        JAVAC=$(readlink -f $(which javac) 2>/dev/null)
+    fi
+    if [ -z "$JAVAC" ]; then
+        JAVAC=$(which javac)
+    fi
     if [ -z "$JAVAC" ] ; then
         exit 1
     fi
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index e15bde2..f8264ee 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -20,6 +20,7 @@
 # They will be compiled against libcore and not the host JRE.
 #
 
+ifeq ($(HOST_OS),linux)
 USE_CORE_LIB_BOOTCLASSPATH := true
 
 #######################################
@@ -67,9 +68,16 @@
 $(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_JAR_EXCLUDE_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)
+$(full_classes_compiled_jar): \
+        $(java_sources) \
+        $(java_resource_sources) \
+        $(full_java_lib_deps) \
+        $(jar_manifest_file) \
+        $(proto_java_sources_file_stamp) \
+        $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-java-to-package)
 
 # Run jarjar if necessary, otherwise just copy the file.
@@ -94,13 +102,13 @@
 	$(transform-classes.jar-to-dex)
 
 $(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
+$(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
+$(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
 $(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources)
 	@echo "Host Jar: $(PRIVATE_MODULE) ($@)"
-	$(create-empty-package)
+	$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@)
 	$(add-dex-to-package)
-	$(add-carried-java-resources)
-ifneq ($(extra_jar_args),)
-	$(add-java-resources-to-package)
-endif
 
 USE_CORE_LIB_BOOTCLASSPATH :=
+
+endif
diff --git a/core/host_dalvik_static_java_library.mk b/core/host_dalvik_static_java_library.mk
index 3ae74e4..9e5aaa3 100644
--- a/core/host_dalvik_static_java_library.mk
+++ b/core/host_dalvik_static_java_library.mk
@@ -19,6 +19,7 @@
 # These libraries will be compiled against libcore and not the host
 # JRE.
 #
+ifeq ($(HOST_OS),linux)
 
 USE_CORE_LIB_BOOTCLASSPATH := true
 LOCAL_JAVA_LIBRARIES += core-libart-hostdex
@@ -26,3 +27,5 @@
 include $(BUILD_SYSTEM)/host_java_library.mk
 
 USE_CORE_LIB_BOOTCLASSPATH :=
+
+endif
diff --git a/core/host_executable.mk b/core/host_executable.mk
index bf3cde1..0091f3f 100644
--- a/core/host_executable.mk
+++ b/core/host_executable.mk
@@ -13,6 +13,10 @@
 endif
 endif
 
+ifeq ($(LOCAL_NO_FPIE),)
+LOCAL_LDFLAGS += $(HOST_FPIE_FLAGS)
+endif
+
 ifeq ($(my_module_multilib),both)
 ifeq ($(LOCAL_MODULE_PATH_32)$(LOCAL_MODULE_STEM_32),)
 $(error $(LOCAL_PATH): LOCAL_MODULE_STEM_32 or LOCAL_MODULE_PATH_32 is required for LOCAL_MULTILIB := both for module $(LOCAL_MODULE))
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index e5ebb11..b751c5f 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -20,21 +20,71 @@
 
 #######################################
 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) \
-		$(jar_manifest_file) $(proto_java_sources_file_stamp) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(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_JAR_EXCLUDE_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_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-java-to-package)
diff --git a/core/host_java_library_common.mk b/core/host_java_library_common.mk
index 973afa0..cd9e679 100644
--- a/core/host_java_library_common.mk
+++ b/core/host_java_library_common.mk
@@ -29,12 +29,12 @@
 proto_sources := $(filter %.proto,$(LOCAL_SRC_FILES))
 ifneq ($(proto_sources),)
 ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),micro)
-    LOCAL_JAVA_LIBRARIES += host-libprotobuf-java-2.3.0-micro
+    LOCAL_JAVA_LIBRARIES += host-libprotobuf-java-micro
 else
   ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),nano)
-    LOCAL_JAVA_LIBRARIES += host-libprotobuf-java-2.3.0-nano
+    LOCAL_JAVA_LIBRARIES += host-libprotobuf-java-nano
   else
-    LOCAL_JAVA_LIBRARIES += host-libprotobuf-java-2.3.0-lite
+    LOCAL_JAVA_LIBRARIES += host-libprotobuf-java-lite
   endif
 endif
 endif
diff --git a/core/host_shared_library_internal.mk b/core/host_shared_library_internal.mk
index d9769d3..f1b3311 100644
--- a/core/host_shared_library_internal.mk
+++ b/core/host_shared_library_internal.mk
@@ -40,7 +40,11 @@
 
 include $(BUILD_SYSTEM)/binary.mk
 
-$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(LOCAL_BUILT_MODULE): \
+        $(all_objects) \
+        $(all_libraries) \
+        $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-o-to-shared-lib)
 
 endif  # skip_build_from_source
diff --git a/core/host_test_internal.mk b/core/host_test_internal.mk
index 426c400..e0070c1 100644
--- a/core/host_test_internal.mk
+++ b/core/host_test_internal.mk
@@ -2,14 +2,14 @@
 ## Shared definitions for all host test compilations.
 #####################################################
 
-LOCAL_CFLAGS += -DGTEST_OS_LINUX -DGTEST_HAS_STD_STRING -O0 -g
-LOCAL_C_INCLUDES +=  external/gtest/include
-
-ifneq ($(filter libc++,$(LOCAL_SHARED_LIBRARIES)),)
-LOCAL_STATIC_LIBRARIES += libgtest_libc++_host libgtest_main_libc++_host
+ifeq ($(HOST_OS),windows)
+LOCAL_CFLAGS += -DGTEST_OS_WINDOWS
 else
-LOCAL_STATIC_LIBRARIES += libgtest_host libgtest_main_host
-LOCAL_SHARED_LIBRARIES +=
+LOCAL_CFLAGS += -DGTEST_OS_LINUX
+LOCAL_LDLIBS += -lpthread
 endif
 
-LOCAL_LDLIBS += -lpthread
+LOCAL_CFLAGS += -DGTEST_HAS_STD_STRING -O0 -g
+LOCAL_C_INCLUDES +=  external/gtest/include
+
+LOCAL_STATIC_LIBRARIES += libgtest_host libgtest_main_host
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index eb90c50..c28bb15 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -18,7 +18,7 @@
           $(LOCAL_JNI_SHARED_LIBRARIES)))
 
 # App-specific lib path.
-my_app_lib_path :=  $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES)/$(basename $(my_installed_module_stem))
+my_app_lib_path := $(dir $(LOCAL_INSTALLED_MODULE))lib/$(TARGET_$(my_2nd_arch_prefix)ARCH)
 my_extracted_jni_libs :=
 
 ifdef my_embed_jni
@@ -54,16 +54,20 @@
 # The jni libaries will be installed to the system.img.
 my_jni_filenames := $(notdir $(my_jni_shared_libraries))
 # Make sure the JNI libraries get installed
-$(LOCAL_INSTALLED_MODULE) : | $(addprefix $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES)/, $(my_jni_filenames))
+my_shared_library_path := $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES)
+$(LOCAL_INSTALLED_MODULE) : | $(addprefix $(my_shared_library_path)/, $(my_jni_filenames))
 
 # Create symlink in the app specific lib path
 ifdef LOCAL_POST_INSTALL_CMD
 # Add a shell command separator
 LOCAL_POST_INSTALL_CMD += ;
 endif
+
+my_symlink_target_dir := $(patsubst $(PRODUCT_OUT)%,%,\
+    $(my_shared_library_path))
 LOCAL_POST_INSTALL_CMD += \
   mkdir -p $(my_app_lib_path) \
-  $(foreach lib, $(my_jni_filenames), ;ln -sf ../$(lib) $(my_app_lib_path)/$(lib))
+  $(foreach lib, $(my_jni_filenames), ;ln -sf $(my_symlink_target_dir)/$(lib) $(my_app_lib_path)/$(lib))
 $(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
 
 # Clear jni_shared_libraries to not embed it into the apk.
@@ -96,9 +100,15 @@
 my_prebuilt_jni_libs := $(addprefix $(LOCAL_PATH)/, \
     $(filter-out @%, $(my_prebuilt_jni_libs)))
 ifdef my_prebuilt_jni_libs
+ifdef my_embed_jni
+# Embed my_prebuilt_jni_libs to the apk
+my_jni_shared_libraries += $(my_prebuilt_jni_libs)
+else # not my_embed_jni
+# Install my_prebuilt_jni_libs as separate files.
 $(foreach lib, $(my_prebuilt_jni_libs), \
     $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
 
 $(LOCAL_INSTALLED_MODULE) : | $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
+endif  # my_embed_jni
 endif  # inner my_prebuilt_jni_libs
 endif  # outer my_prebuilt_jni_libs
diff --git a/core/java.mk b/core/java.mk
index 8863ac2..c47ea22 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -26,6 +26,8 @@
       ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
         # Use android_stubs_current if LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
         LOCAL_JAVA_LIBRARIES := android_stubs_current $(LOCAL_JAVA_LIBRARIES)
+      else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
+        LOCAL_JAVA_LIBRARIES := android_system_stubs_current $(LOCAL_JAVA_LIBRARIES)
       else
         LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
       endif
@@ -40,16 +42,19 @@
 proto_sources := $(filter %.proto,$(LOCAL_SRC_FILES))
 ifneq ($(proto_sources),)
 ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),micro)
-    LOCAL_STATIC_JAVA_LIBRARIES += libprotobuf-java-2.3.0-micro
+    LOCAL_STATIC_JAVA_LIBRARIES += libprotobuf-java-micro
 else
   ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),nano)
-    LOCAL_STATIC_JAVA_LIBRARIES += libprotobuf-java-2.3.0-nano
+    LOCAL_STATIC_JAVA_LIBRARIES += libprotobuf-java-nano
   else
-    LOCAL_STATIC_JAVA_LIBRARIES += libprotobuf-java-2.3.0-lite
+    LOCAL_STATIC_JAVA_LIBRARIES += libprotobuf-java-lite
   endif
 endif
 endif
 
+# LOCAL_STATIC_JAVA_AAR_LIBRARIES are special LOCAL_STATIC_JAVA_LIBRARIES
+LOCAL_STATIC_JAVA_LIBRARIES := $(strip $(LOCAL_STATIC_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES))
+
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
 
 LOCAL_BUILT_MODULE_STEM := $(strip $(LOCAL_BUILT_MODULE_STEM))
@@ -72,10 +77,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 +101,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)
@@ -142,7 +147,7 @@
 else
 ifneq (,$(LOCAL_SDK_VERSION))
 # Set target-api for LOCAL_SDK_VERSIONs other than current.
-ifneq (,$(filter-out current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION)))
 renderscript_target_api := $(LOCAL_SDK_VERSION)
 endif
 endif  # LOCAL_SDK_VERSION is set
@@ -158,7 +163,7 @@
 renderscript_flags += $(LOCAL_RENDERSCRIPT_FLAGS)
 
 # prepend the RenderScript system include path
-ifneq ($(filter-out current,$(LOCAL_SDK_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current,$(LOCAL_SDK_VERSION))),)
+ifneq ($(filter-out current system_current,$(LOCAL_SDK_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current,$(LOCAL_SDK_VERSION))),)
 # if a numeric LOCAL_SDK_VERSION, or current LOCAL_SDK_VERSION with TARGET_BUILD_APPS
 LOCAL_RENDERSCRIPT_INCLUDES := \
     $(HISTORICAL_SDK_VERSIONS_ROOT)/renderscript/clang-include \
@@ -188,8 +193,20 @@
 
 ifneq ($(LOCAL_RENDERSCRIPT_COMPATIBILITY),)
 bc_files := $(patsubst %.fs,%.bc, $(patsubst %.rs,%.bc, $(notdir $(renderscript_sources))))
+
+
+ifeq ($(filter $(RSCOMPAT_32BIT_ONLY_API_LEVELS),$(renderscript_target_api)),)
+ifeq ($(TARGET_IS_64_BIT),true)
+renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/bc64/
+else
+renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/bc32/
+endif
+else
+renderscript_intermediate.bc_folder := $(renderscript_intermediate.COMMON)/res/raw/
+endif
+
 rs_generated_bc := $(addprefix \
-    $(renderscript_intermediate.COMMON)/res/raw/, $(bc_files))
+    $(renderscript_intermediate.bc_folder), $(bc_files))
 
 renderscript_intermediate := $(intermediates)/renderscript
 
@@ -207,14 +224,20 @@
 rs_jni_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/librsjni.so
 LOCAL_JNI_SHARED_LIBRARIES += libRSSupport librsjni
 
+rs_support_io_lib :=
+# check if the target api level support USAGE_IO
+ifeq ($(filter $(RSCOMPAT_NO_USAGEIO_API_LEVELS),$(renderscript_target_api)),)
+rs_support_io_lib := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/libRSSupportIO.so
+LOCAL_JNI_SHARED_LIBRARIES += libRSSupportIO
+endif
 
 
 $(rs_compatibility_jni_libs): $(RenderScript_file_stamp) $(RS_PREBUILT_CLCORE) \
-    $(rs_support_lib) $(rs_jni_lib) $(rs_compiler_rt)
+    $(rs_support_lib) $(rs_support_io_lib) $(rs_jni_lib) $(rs_compiler_rt)
 $(rs_compatibility_jni_libs): $(BCC_COMPAT)
 $(rs_compatibility_jni_libs): PRIVATE_CXX := $(TARGET_CXX)
 $(rs_compatibility_jni_libs): $(renderscript_intermediate)/librs.%.so: \
-    $(renderscript_intermediate.COMMON)/res/raw/%.bc
+    $(renderscript_intermediate.bc_folder)%.bc
 	$(transform-bc-to-so)
 
 endif
@@ -321,6 +344,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,10 +355,19 @@
 $(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_JAR_EXCLUDE_PACKAGES := $(LOCAL_JAR_EXCLUDE_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) \
-        $(proto_java_sources_file_stamp) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(full_classes_compiled_jar): \
+        $(java_sources) \
+        $(java_resource_sources) \
+        $(full_java_lib_deps) \
+        $(jar_manifest_file) \
+        $(layers_file) \
+        $(RenderScript_file_stamp) \
+        $(proto_java_sources_file_stamp) \
+        $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-java-to-classes.jar)
 
 $(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
@@ -378,7 +414,7 @@
 
 # Run proguard if necessary, otherwise just copy the file.
 ifdef LOCAL_PROGUARD_ENABLED
-ifneq ($(filter-out full custom nosystem obfuscation optimization,$(LOCAL_PROGUARD_ENABLED)),)
+ifneq ($(filter-out full custom nosystem obfuscation optimization shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
     $(warning while processing: $(LOCAL_MODULE))
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
 endif
@@ -395,6 +431,9 @@
 # If this is a test package, add proguard keep flags for tests.
 ifneq ($(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS)),)
 proguard_flags += -include $(BUILD_SYSTEM)/proguard_tests.flags
+ifeq ($(filter shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
+proguard_flags += -dontshrink # don't shrink tests by default
+endif # shrinktests
 endif # test package
 ifeq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)
 # By default no obfuscation
@@ -470,7 +509,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
@@ -497,7 +538,7 @@
 $(findbugs_html) : $(findbugs_xml)
 	@mkdir -p $(dir $@)
 	@echo ConvertXmlToText: $@
-	$(hide) prebuilt/common/findbugs/bin/convertXmlToText -html:fancy.xsl $(PRIVATE_XML_FILE) \
+	$(hide) $(FINDBUGS_DIR)/convertXmlToText -html:fancy.xsl $(PRIVATE_XML_FILE) \
 	> $@
 
 $(LOCAL_MODULE)-findbugs : $(findbugs_html)
diff --git a/core/java_library.mk b/core/java_library.mk
index dffc7d9..b4e3eaa 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -58,9 +58,6 @@
 endif
 	@echo "target Static Jar: $(PRIVATE_MODULE) ($@)"
 	$(copy-file-to-target)
-ifneq ($(extra_jar_args),)
-	$(add-java-resources-to-package)
-endif
 
 $(LOCAL_BUILT_MODULE): $(common_javalib.jar)
 	$(copy-file-to-target)
@@ -68,14 +65,12 @@
 else # !LOCAL_IS_STATIC_JAVA_LIBRARY
 
 $(common_javalib.jar): PRIVATE_DEX_FILE := $(built_dex)
+$(common_javalib.jar): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
+$(common_javalib.jar): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
 $(common_javalib.jar) : $(built_dex) $(java_resource_sources)
 	@echo "target Jar: $(PRIVATE_MODULE) ($@)"
-	$(create-empty-package)
+	$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@)
 	$(add-dex-to-package)
-	$(add-carried-java-resources)
-ifneq ($(extra_jar_args),)
-	$(add-java-resources-to-package)
-endif
 
 ifdef LOCAL_DEX_PREOPT
 ifneq ($(dexpreopt_boot_jar_module),) # boot jar
@@ -85,12 +80,6 @@
 	$(call copy-file-to-target)
 
 # For libart boot jars, we don't have .odex files.
-ifeq ($(DALVIK_VM_LIB),libdvm.so)
-dexpreopted_boot_odex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module).odex
-$(built_odex) : $(dexpreopted_boot_odex) | $(ACP)
-	$(call copy-file-to-target)
-endif
-
 else # ! boot jar
 $(built_odex): PRIVATE_MODULE := $(LOCAL_MODULE)
 # Use pattern rule - we may have multiple built odex files.
diff --git a/core/main.mk b/core/main.mk
index c65fe3c..981ecef 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -79,7 +79,8 @@
     cacheimage-nodeps \
     vendorimage-nodeps \
     ramdisk-nodeps \
-    bootimage-nodeps
+    bootimage-nodeps \
+    recoveryimage-nodeps
 
 ifneq ($(filter $(dont_bother_goals), $(MAKECMDGOALS)),)
 dont_bother := true
@@ -140,18 +141,18 @@
 javac_version_str := $(shell unset _JAVA_OPTIONS && javac -version 2>&1)
 
 # Check for the correct version of java, should be 1.7 by
-# default, and 1.6 if LEGACY_USE_JAVA6 is set.
-ifeq ($(LEGACY_USE_JAVA6),)
+# default, and 1.8 if EXPERIMENTAL_USE_JAVA8 is set
+ifneq ($(EXPERIMENTAL_USE_JAVA8),)
+required_version := "1.8.x"
+required_javac_version := "1.8"
+java_version := $(shell echo '$(java_version_str)' | grep 'openjdk .*[ "]1\.8[\. "$$]')
+javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.8[\. "$$]')
+else # default
 required_version := "1.7.x"
 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 LEGACY_USE_JAVA6
-required_version := "1.6.x"
-required_javac_version := "1.6"
-java_version := $(shell echo '$(java_version_str)' | grep '^java .*[ "]1\.6[\. "$$]')
-javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.6[\. "$$]')
-endif # if LEGACY_USE_JAVA6
+endif # if EXPERIMENTAL_USE_JAVA8
 
 ifeq ($(strip $(java_version)),)
 $(info ************************************************************)
@@ -170,13 +171,10 @@
 # Check for the current JDK.
 #
 # For Java 1.7, we require OpenJDK on linux and Oracle JDK on Mac OS.
-# For Java 1.6, we require Oracle for all host OSes.
 requires_openjdk := false
-ifeq ($(LEGACY_USE_JAVA6),)
 ifeq ($(HOST_OS), linux)
 requires_openjdk := true
 endif
-endif
 
 
 # Check for the current jdk
@@ -185,12 +183,8 @@
 # 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 You asked for an OpenJDK 7 build but your version is)
 $(info $(java_version_str).)
-$(info Please follow the machine setup instructions at)
-$(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
 $(info ************************************************************)
 $(error stop)
 endif # java version is not OpenJdk
@@ -281,8 +275,8 @@
 ifneq ($(filter-out $(INTERNAL_VALID_VARIANTS),$(TARGET_BUILD_VARIANT)),)
 $(info ***************************************************************)
 $(info ***************************************************************)
-$(info Invalid variant: $(TARGET_BUILD_VARIANT)
-$(info Valid values are: $(INTERNAL_VALID_VARIANTS)
+$(info Invalid variant: $(TARGET_BUILD_VARIANT))
+$(info Valid values are: $(INTERNAL_VALID_VARIANTS))
 $(info ***************************************************************)
 $(info ***************************************************************)
 $(error stopping)
@@ -312,6 +306,21 @@
 is_sdk_build := true
 endif
 
+# Add build properties for ART. These define system properties used by installd
+# to pass flags to dex2oat.
+ADDITIONAL_BUILD_PROPERTIES += persist.sys.dalvik.vm.lib.2=libart
+ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).variant=$(DEX2OAT_TARGET_CPU_VARIANT)
+ifneq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
+  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).features=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+endif
+
+ifdef TARGET_2ND_ARCH
+  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).variant=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT)
+  ifneq ($($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),)
+    ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).features=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
+  endif
+endif
+
 ## user/userdebug ##
 
 user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
@@ -324,23 +333,19 @@
   ifeq ($(user_variant),userdebug)
     # Pick up some extra useful tools
     tags_to_install += debug
-
-    # Enable Dalvik lock contention logging for userdebug builds.
-    ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.lockprof.threshold=500
   else
     # Disable debugging in plain user builds.
     enable_target_debugging :=
   endif
 
-  # Turn on Dalvik preoptimization for libdvm.so user builds, but only if not
+  # Turn on Dalvik preoptimization for user builds, but only if not
   # explicitly disabled and the build is running on Linux (since host
   # Dalvik isn't built for non-Linux hosts).
   ifeq (,$(WITH_DEXPREOPT))
-    ifeq ($(DALVIK_VM_LIB),libdvm.so)
-      ifeq ($(user_variant),user)
-        ifeq ($(HOST_OS),linux)
-          WITH_DEXPREOPT := true
-        endif
+    ifeq ($(user_variant),user)
+      ifeq ($(HOST_OS),linux)
+        # TODO: turn on WITH_DEXPREOPT for libart user builds.
+        # WITH_DEXPREOPT := true
       endif
     endif
   endif
@@ -360,6 +365,8 @@
 ifeq (true,$(strip $(enable_target_debugging)))
   # Target is more debuggable and adbd is on by default
   ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1
+  # Enable Dalvik lock contention logging.
+  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.lockprof.threshold=500
   # Include the debugging/testing OTA keys in this build.
   INCLUDE_TEST_OTA_KEYS := true
 else # !enable_target_debugging
@@ -377,10 +384,12 @@
           $(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES))) \
           ro.setupwizard.mode=OPTIONAL
 endif
-# Don't even verify the image on eng builds to speed startup
-ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.image-dex2oat-flags=--compiler-filter=verify-none
-# Don't compile apps on eng builds to speed startup
-ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.dex2oat-flags=--compiler-filter=interpret-only
+ifndef is_sdk_build
+  # Don't even verify the image on eng builds to speed startup
+  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.image-dex2oat-filter=verify-none
+  # Don't compile apps on eng builds to speed startup
+  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.dex2oat-filter=interpret-only
+endif
 endif
 
 ## sdk ##
@@ -391,7 +400,7 @@
 sdk_repo_goal := $(strip $(filter sdk_repo,$(MAKECMDGOALS)))
 MAKECMDGOALS := $(strip $(filter-out sdk_repo,$(MAKECMDGOALS)))
 
-ifneq ($(words $(filter-out $(INTERNAL_MODIFIER_TARGETS) checkbuild,$(MAKECMDGOALS))),1)
+ifneq ($(words $(filter-out $(INTERNAL_MODIFIER_TARGETS) checkbuild emulator_tests target-files-package,$(MAKECMDGOALS))),1)
 $(error The 'sdk' target may not be specified with any other targets)
 endif
 
@@ -405,16 +414,6 @@
 
 BUILD_WITHOUT_PV := true
 
-## precise GC ##
-
-ifneq ($(filter dalvik.gc.type-precise,$(PRODUCT_TAGS)),)
-  # Enabling type-precise GC results in larger optimized DEX files.  The
-  # additional storage requirements for ".odex" files can cause /system
-  # to overflow on some devices, so this is configured separately for
-  # each product.
-  ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.dexopt-flags=m=y
-endif
-
 ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
 
 # enable vm tracing in files for now to help track
@@ -768,12 +767,8 @@
   $(foreach m, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES), \
     $(if $(strip $(ALL_MODULES.$(m).INSTALLED) $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).INSTALLED)),,\
       $(eval dangling_modules += $(m))))
-  ifneq ($(TARGET_IS_64_BIT),true)
-    # We know those 64-bit modules don't exist in the 32-bit SDK build.
-    dangling_modules := $(filter-out %64,$(dangling_modules))
-  endif
   ifneq ($(dangling_modules),)
-    $(error Module names '$(dangling_modules)' in PRODUCT_PACKAGES has nothing to install!)
+    $(warning: Modules '$(dangling_modules)' in PRODUCT_PACKAGES have nothing to install!)
   endif
   $(foreach m, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES_DEBUG), \
     $(if $(strip $(ALL_MODULES.$(m).INSTALLED)),,\
@@ -845,12 +840,6 @@
 .PHONY: ramdisk
 ramdisk: $(INSTALLED_RAMDISK_TARGET)
 
-.PHONY: factory_ramdisk
-factory_ramdisk: $(INSTALLED_FACTORY_RAMDISK_TARGET)
-
-.PHONY: factory_bundle
-factory_bundle: $(INSTALLED_FACTORY_BUNDLE_TARGET)
-
 .PHONY: systemtarball
 systemtarball: $(INSTALLED_SYSTEMTARBALL_TARGET)
 
@@ -933,6 +922,9 @@
   $(PROGUARD_DICT_ZIP) : $(apps_only_installed_files)
   $(call dist-for-goals,apps_only, $(PROGUARD_DICT_ZIP))
 
+  $(SYMBOLS_ZIP) : $(apps_only_installed_files)
+  $(call dist-for-goals,apps_only, $(SYMBOLS_ZIP))
+
 .PHONY: apps_only
 apps_only: $(unbundled_build_modules)
 
@@ -957,14 +949,13 @@
     $(BUILT_TARGET_FILES_PACKAGE) \
     $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
     $(INSTALLED_RAMDISK_TARGET) \
-    $(INSTALLED_FACTORY_RAMDISK_TARGET) \
-    $(INSTALLED_FACTORY_BUNDLE_TARGET) \
    )
 
   # Put a copy of the radio/bootloader files in the dist dir.
   $(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) \
@@ -972,6 +963,7 @@
       $(PACKAGE_STATS_FILE) \
     )
   endif
+  endif
 
   ifeq ($(EMMA_INSTRUMENT),true)
     $(EMMA_META_ZIP) : $(INSTALLED_SYSTEMIMAGE)
@@ -1011,6 +1003,12 @@
 target-native-tests : native-target-tests
 tests : host-tests target-tests
 
+# To catch more build breakage, check build tests modules in eng and userdebug builds.
+ifneq ($(TARGET_BUILD_PDK),true)
+ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
+droidcore : target-tests host-tests
+endif
+endif
 
 .PHONY: lintall
 
@@ -1035,7 +1033,7 @@
 
 .PHONY: clean
 clean:
-	@rm -rf $(OUT_DIR)
+	@rm -rf $(OUT_DIR)/*
 	@echo "Entire build directory removed."
 
 .PHONY: clobber
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/native_benchmark.mk b/core/native_benchmark.mk
new file mode 100644
index 0000000..431e40a
--- /dev/null
+++ b/core/native_benchmark.mk
@@ -0,0 +1,12 @@
+###########################################
+## A thin wrapper around BUILD_EXECUTABLE
+## Common flags for native benchmarks are added.
+###########################################
+
+LOCAL_STATIC_LIBRARIES += libbenchmark
+
+ifndef LOCAL_MODULE_PATH
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 380f7bf..e389b04 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -52,16 +52,6 @@
 endif
 LOCAL_MODULE := $(LOCAL_PACKAGE_NAME)
 
-ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
-LOCAL_MANIFEST_FILE := AndroidManifest.xml
-endif
-
-# If you need to put the MANIFEST_FILE outside of LOCAL_PATH
-# you can use FULL_MANIFEST_FILE
-ifeq ($(strip $(LOCAL_FULL_MANIFEST_FILE)),)
-LOCAL_FULL_MANIFEST_FILE := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
-endif
-
 ifneq ($(strip $(LOCAL_MODULE_CLASS)),)
 $(error $(LOCAL_PATH): Package modules may not set LOCAL_MODULE_CLASS)
 endif
@@ -78,8 +68,15 @@
 LOCAL_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) -z
 endif
 
+ifdef LOCAL_PACKAGE_SPLITS
+LOCAL_AAPT_FLAGS += $(addprefix --split ,$(LOCAL_PACKAGE_SPLITS))
+endif
+
+need_compile_asset :=
 ifeq (,$(LOCAL_ASSET_DIR))
 LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
+else
+need_compile_asset := true
 endif
 
 # LOCAL_RESOURCE_DIR may point to resource generated during the build
@@ -98,8 +95,18 @@
 
 LOCAL_RESOURCE_DIR := $(package_resource_overlays) $(LOCAL_RESOURCE_DIR)
 
-all_assets := $(call find-subdir-assets,$(LOCAL_ASSET_DIR))
-all_assets := $(addprefix $(LOCAL_ASSET_DIR)/,$(patsubst assets/%,%,$(all_assets)))
+all_assets := $(strip \
+    $(foreach dir, $(LOCAL_ASSET_DIR), \
+      $(addprefix $(dir)/, \
+        $(patsubst assets/%,%, \
+          $(call find-subdir-assets, $(dir)) \
+         ) \
+       ) \
+     ))
+
+ifneq ($(all_assets),)
+need_compile_asset := true
+endif
 
 all_resources := $(strip \
     $(foreach dir, $(LOCAL_RESOURCE_DIR), \
@@ -116,10 +123,11 @@
 
 all_res_assets := $(strip $(all_assets) $(all_resources))
 
-package_expected_intermediates_COMMON := $(call local-intermediates-dir,COMMON)
+intermediates.COMMON := $(call local-intermediates-dir,COMMON)
+
 # If no assets or resources were found, clear the directory variables so
 # we don't try to build them.
-ifeq (,$(all_assets))
+ifneq (true,$(need_compile_asset))
 LOCAL_ASSET_DIR:=
 endif
 ifneq (true,$(need_compile_res))
@@ -129,11 +137,12 @@
 # Make sure that R_file_stamp inherits the proper PRIVATE vars.
 # If R.stamp moves, be sure to update the framework makefile,
 # which has intimate knowledge of its location.
-R_file_stamp := $(package_expected_intermediates_COMMON)/src/R.stamp
+R_file_stamp := $(intermediates.COMMON)/src/R.stamp
 LOCAL_INTERMEDIATE_TARGETS += $(R_file_stamp)
 endif
 
 LOCAL_BUILT_MODULE_STEM := package.apk
+LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk
 
 LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
 ifndef LOCAL_PROGUARD_ENABLED
@@ -148,7 +157,7 @@
 proguard_options_file :=
 ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
 ifeq ($(need_compile_res),true)
-    proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options
+    proguard_options_file := $(intermediates.COMMON)/proguard_options
 endif # need_compile_res
 endif # !custom
 LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
@@ -184,6 +193,8 @@
 
 rs_compatibility_jni_libs :=
 
+include $(BUILD_SYSTEM)/android_manifest.mk
+
 #################################
 include $(BUILD_SYSTEM)/java.mk
 #################################
@@ -193,10 +204,9 @@
   LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION)
 endif
 
-full_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
 $(LOCAL_INTERMEDIATE_TARGETS): \
     PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
-ifneq (,$(filter-out current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION)))
 $(LOCAL_INTERMEDIATE_TARGETS): \
     PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
 else
@@ -214,11 +224,6 @@
 # At the same time, this will copy the R.java file to a central
 # 'R' directory to make it easier to add the files to an IDE.
 #
-#TODO: use PRIVATE_SOURCE_INTERMEDIATES_DIR instead of
-#      $(intermediates.COMMON)/src
-ifneq ($(package_expected_intermediates_COMMON),$(intermediates.COMMON))
-  $(error $(LOCAL_MODULE): internal error: expected intermediates.COMMON "$(package_expected_intermediates_COMMON)" != intermediates.COMMON "$(intermediates.COMMON)")
-endif
 
 $(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
 			$(intermediates.COMMON)/public_resources.xml
@@ -244,6 +249,7 @@
 
 $(proguard_options_file): $(R_file_stamp)
 
+resource_export_package :=
 ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
 # Put this module's resources into a PRODUCT-agnositc package that
 # other packages can use to build their own PRODUCT-agnostic R.java (etc.)
@@ -283,7 +289,7 @@
 # Most packages should link against the resources defined by framework-res.
 # Even if they don't have their own resources, they may use framework
 # resources.
-ifneq ($(filter-out current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current,$(LOCAL_SDK_RES_VERSION))),)
+ifneq ($(filter-out current system_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current,$(LOCAL_SDK_RES_VERSION))),)
 # for released sdk versions, the platform resources were built into android.jar.
 framework_res_package_export := \
     $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_RES_VERSION)/android.jar
@@ -297,14 +303,29 @@
 framework_res_package_export_deps := \
     $(dir $(framework_res_package_export))src/R.stamp
 endif # LOCAL_SDK_RES_VERSION
-$(R_file_stamp): $(framework_res_package_export_deps)
+all_library_res_package_exports := \
+    $(framework_res_package_export) \
+    $(foreach lib,$(LOCAL_RES_LIBRARIES),\
+        $(call intermediates-dir-for,APPS,$(lib),,COMMON)/package-export.apk)
+
+all_library_res_package_export_deps := \
+    $(framework_res_package_export_deps) \
+    $(foreach lib,$(LOCAL_RES_LIBRARIES),\
+        $(call intermediates-dir-for,APPS,$(lib),,COMMON)/src/R.stamp)
+
+$(resource_export_package) $(R_file_stamp) $(LOCAL_BUILT_MODULE): $(all_library_res_package_export_deps)
 $(LOCAL_INTERMEDIATE_TARGETS): \
-    PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
+    PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
 endif # LOCAL_NO_STANDARD_LIBRARIES
 
 ifneq ($(full_classes_jar),)
 $(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
+# Use the jarjar processed arhive as the initial package file.
+$(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
 $(LOCAL_BUILT_MODULE): $(built_dex)
+else
+$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE :=
+$(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE :=
 endif # full_classes_jar
 
 include $(BUILD_SYSTEM)/install_jni_libs.mk
@@ -348,6 +369,8 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
 # PRIVATE_JNI_SHARED_LIBRARIES_ABI is a list of ABI names.
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
+$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ZIP_OPTIONS := $(LOCAL_JNI_SHARED_LIBRARIES_ZIP_OPTIONS)
+$(LOCAL_BUILT_MODULE): PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES := $(LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES)
 ifneq ($(TARGET_BUILD_APPS),)
     # Include all resources for unbundled apps.
     LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
@@ -357,11 +380,18 @@
     $(LOCAL_BUILT_MODULE): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
 else
     $(LOCAL_BUILT_MODULE): PRIVATE_PRODUCT_AAPT_CONFIG := $(PRODUCT_AAPT_CONFIG)
+ifdef LOCAL_PACKAGE_SPLITS
+    $(LOCAL_BUILT_MODULE): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
+else
     $(LOCAL_BUILT_MODULE): PRIVATE_PRODUCT_AAPT_PREF_CONFIG := $(PRODUCT_AAPT_PREF_CONFIG)
 endif
+endif
+$(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
 $(LOCAL_BUILT_MODULE): $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
-	$(create-empty-package)
+	$(if $(PRIVATE_SOURCE_ARCHIVE),\
+	  $(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@),\
+	  $(create-empty-package))
 	$(add-assets-to-package)
 ifneq ($(jni_shared_libraries),)
 	$(add-jni-shared-libs-to-package)
@@ -369,10 +399,6 @@
 ifneq ($(full_classes_jar),)
 	$(add-dex-to-package)
 endif
-	$(add-carried-java-resources)
-ifneq ($(extra_jar_args),)
-	$(add-java-resources-to-package)
-endif
 	$(sign-package)
 ifdef LOCAL_DEX_PREOPT
 ifneq (nostripping,$(LOCAL_DEX_PREOPT))
@@ -383,10 +409,21 @@
 	$(align-package)
 
 ###############################
+## Build dpi-specific apks, if it's apps_only build.
+ifdef TARGET_BUILD_APPS
+ifdef LOCAL_DPI_VARIANTS
+$(foreach d, $(LOCAL_DPI_VARIANTS), \
+  $(eval my_dpi := $(d)) \
+  $(eval include $(BUILD_SYSTEM)/dpi_specific_apk.mk))
+endif
+endif
+
+###############################
 ## Rule to build the odex file
 ifdef LOCAL_DEX_PREOPT
 $(built_odex): PRIVATE_DEX_FILE := $(built_dex)
-$(built_odex) : $(built_dex)
+# Use pattern rule - we may have multiple built odex files.
+$(built_odex) : $(dir $(LOCAL_BUILT_MODULE))% : $(built_dex)
 	$(hide) mkdir -p $(dir $@) && rm -f $@
 	$(add-dex-to-package)
 	$(hide) mv $@ $@.input
@@ -394,6 +431,44 @@
 	$(hide) rm $@.input
 endif
 
+###############################
+## APK splits
+ifdef LOCAL_PACKAGE_SPLITS
+# LOCAL_PACKAGE_SPLITS is a list of resource labels.
+# aapt will convert comma inside resource lable to underscore in the file names.
+my_split_suffixes := $(subst $(comma),_,$(LOCAL_PACKAGE_SPLITS))
+built_apk_splits := $(foreach s,$(my_split_suffixes),$(built_module_path)/package_$(s).apk)
+installed_apk_splits := $(foreach s,$(my_split_suffixes),$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
+
+# The splits should have been built in the same command building the base apk.
+# This rule just runs signing and zipalign etc.
+# Note that we explicily check the existence of the split apk and remove the
+# built base apk if the split apk isn't there.
+# That way the build system will rerun the aapt after the user changes the splitting parameters.
+$(built_apk_splits): PRIVATE_PRIVATE_KEY := $(private_key)
+$(built_apk_splits): PRIVATE_CERTIFICATE := $(certificate)
+$(built_apk_splits) : $(built_module_path)/%.apk : $(LOCAL_BUILT_MODULE)
+	$(hide) if [ ! -f $@ ]; then \
+	  echo 'No $@ generated, check your apk splitting parameters.' 1>&2; \
+	  rm $<; exit 1; \
+	fi
+	$(sign-package)
+	$(align-package)
+
+# Rules to install the splits
+$(installed_apk_splits) : $(my_module_path)/$(LOCAL_MODULE)_%.apk : $(built_module_path)/package_%.apk | $(ACP)
+	@echo "Install: $@"
+	$(copy-file-to-new-target)
+
+# Register the additional built and installed files.
+ALL_MODULES.$(my_register_name).INSTALLED += $(installed_apk_splits)
+ALL_MODULES.$(my_register_name).BUILT_INSTALLED += \
+  $(foreach s,$(my_split_suffixes),$(built_module_path)/package_$(s).apk:$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
+
+# Make sure to install the splits when you run "make <module_name>".
+$(my_register_name): $(installed_apk_splits)
+endif # LOCAL_PACKAGE_SPLITS
+
 # Save information about this package
 PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
 PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_FILES := $(all_resources)
@@ -418,7 +493,7 @@
 	@rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) cp $< $@
 	$(hide) zip -d $@ $(foreach f,$(PRIVATE_JNI_SHARED_LIBRARIES),\*/$(f))
-	$(call align-package)
+	$(align-package)
 
 $(call dist-for-goals, apps_only, $(apk_jni_stripped):$(dist_subdir)/$(LOCAL_PACKAGE_NAME).apk)
 
diff --git a/core/pathmap.mk b/core/pathmap.mk
index 28661c2..2532707 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -27,12 +27,9 @@
 # A mapping from shorthand names to include directories.
 #
 pathmap_INCL := \
-    bootloader:bootable/bootloader/legacy/include \
     camera:system/media/camera/include \
-    corecg:external/skia/include/core \
     frameworks-base:frameworks/base/include \
     frameworks-native:frameworks/native/include \
-    graphics:external/skia/include/core \
     libc:bionic/libc/include \
     libhardware:hardware/libhardware/include \
     libhardware_legacy:hardware/libhardware_legacy/include \
@@ -51,6 +48,7 @@
     audio-route:system/media/audio_route/include \
     wilhelm:frameworks/wilhelm/include \
     wilhelm-ut:frameworks/wilhelm/src/ut \
+    mediandk:frameworks/av/media/ndk/ \
     speex:external/speex/include
 
 #
@@ -86,6 +84,7 @@
 	    drm \
 	    opengl \
 	    sax \
+	    telecomm \
 	    telephony \
 	    wifi \
 	    keystore \
@@ -105,23 +104,38 @@
 # A list of all source roots under frameworks/support.
 #
 FRAMEWORKS_SUPPORT_SUBDIRS := \
+        annotations \
         v4 \
         v7/gridlayout \
         v7/appcompat \
+        v7/cardview \
         v7/mediarouter \
+        v7/palette \
+        v7/recyclerview \
         v8/renderscript \
-        v13
+        v13 \
+        v17/leanback
+
+#
+# A list of all source roots under frameworks/multidex.
+#
+FRAMEWORKS_MULTIDEX_SUBDIRS := \
+        multidex/library/src \
+        multidex/instrumentation/src
 
 #
 # 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))) \
+    android-support-multidex \
+    android-support-multidex-instrumentation
 
diff --git a/core/pdk_config.mk b/core/pdk_config.mk
index 9590d70..838754f 100644
--- a/core/pdk_config.mk
+++ b/core/pdk_config.mk
@@ -18,9 +18,14 @@
 
 # if PDK_FUSION_PLATFORM_ZIP is specified, do not override.
 ifndef PDK_FUSION_PLATFORM_ZIP
+# Most PDK project paths should be using vendor/pdk/TARGET_DEVICE
+# but some legacy ones (e.g. mini_armv7a_neon generic PDK) were setup
+# with vendor/pdk/TARGET_PRODUCT.
 _pdk_fusion_default_platform_zip = $(wildcard \
 vendor/pdk/$(TARGET_DEVICE)/$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)/platform/platform.zip \
-vendor/pdk/$(TARGET_DEVICE)/$(patsubst aosp_%,full_%,$(TARGET_PRODUCT))-$(TARGET_BUILD_VARIANT)/platform/platform.zip)
+vendor/pdk/$(TARGET_DEVICE)/$(patsubst aosp_%,full_%,$(TARGET_PRODUCT))-$(TARGET_BUILD_VARIANT)/platform/platform.zip \
+vendor/pdk/$(TARGET_PRODUCT)/$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)/platform/platform.zip \
+vendor/pdk/$(TARGET_PRODUCT)/$(patsubst aosp_%,full_%,$(TARGET_PRODUCT))-$(TARGET_BUILD_VARIANT)/platform/platform.zip)
 ifneq (,$(_pdk_fusion_default_platform_zip))
 PDK_FUSION_PLATFORM_ZIP := $(word 1, $(_pdk_fusion_default_platform_zip))
 TARGET_BUILD_PDK := true
@@ -37,29 +42,41 @@
 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-libart_intermediates \
 	target/common/obj/JAVA_LIBRARIES/core-junit_intermediates \
 	target/common/obj/JAVA_LIBRARIES/ext_intermediates \
 	target/common/obj/JAVA_LIBRARIES/framework_intermediates \
-	target/common/obj/JAVA_LIBRARIES/framework2_intermediates \
 	target/common/obj/JAVA_LIBRARIES/android.test.runner_intermediates \
 	target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates \
 	target/common/obj/JAVA_LIBRARIES/voip-common_intermediates \
+	target/common/obj/JAVA_LIBRARIES/ims-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 +134,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 +159,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 $< $@
@@ -170,12 +192,16 @@
 ifneq (,$(filter platform platform-java, $(MAKECMDGOALS))$(filter true,$(TARGET_BUILD_PDK)))
 # files under $(PRODUCT_OUT)/symbols to help debugging.
 # Source not included to PDK due to dependency issue, so provide symbols instead.
+
+# We may not be building all of them.
+# The platform.zip just silently ignores the nonexistent ones.
 PDK_SYMBOL_FILES_LIST := \
-	system/bin/app_process
+    system/bin/app_process32 \
+    system/bin/app_process64
 
 ifdef PDK_FUSION_PLATFORM_ZIP
 # symbols should be explicitly pulled for fusion build
-$(foreach f,$(PDK_SYMBOL_FILES_LIST),\
+$(foreach f,$(filter $(PDK_SYMBOL_FILES_LIST), $(_pdk_fusion_file_list)),\
   $(eval $(call add-dependency,$(PRODUCT_OUT)/$(f),$(PRODUCT_OUT)/symbols/$(f))))
 endif # PLATFORM_ZIP
 endif # platform.zip build or PDK
diff --git a/core/phony_package.mk b/core/phony_package.mk
index b534335..30e198c 100644
--- a/core/phony_package.mk
+++ b/core/phony_package.mk
@@ -7,7 +7,7 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(LOCAL_BUILT_MODULE): $(LOCAL_MODULE_MAKEFILE) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(hide) echo "Fake: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
diff --git a/core/post_clean.mk b/core/post_clean.mk
index 213c43c..0273ff2 100644
--- a/core/post_clean.mk
+++ b/core/post_clean.mk
@@ -15,6 +15,7 @@
 # Clean steps that need global knowledge of individual modules.
 # This file must be included after all Android.mks have been loaded.
 
+#######################################################
 # Checks the current build configurations against the previous build,
 # clean artifacts in TARGET_COMMON_OUT_ROOT if necessary.
 # If a package's resource overlay has been changed, its R class needs to be
@@ -51,3 +52,45 @@
 previous_package_overlay_config :=
 current_package_overlay_config :=
 current_all_packages_config :=
+
+#######################################################
+# Check if we need to delete obsolete aidl-generated java files.
+# When an aidl file gets deleted (or renamed), the generated java file is obsolete.
+previous_aidl_config := $(TARGET_OUT_COMMON_INTERMEDIATES)/previous_aidl_config.mk
+current_aidl_config := $(TARGET_OUT_COMMON_INTERMEDIATES)/current_aidl_config.mk
+
+$(shell rm -rf $(current_aidl_config) \
+  && mkdir -p $(dir $(current_aidl_config))\
+  && touch $(current_aidl_config))
+-include $(previous_aidl_config)
+
+intermediates_to_clean :=
+modules_with_aidl_files :=
+$(foreach p, $(ALL_MODULES), \
+  $(if $(ALL_MODULES.$(p).AIDL_FILES),\
+    $(eval modules_with_aidl_files += $(p))\
+    $(shell echo 'AIDL_FILES.$(p) := $(ALL_MODULES.$(p).AIDL_FILES)' >> $(current_aidl_config)))\
+  $(if $(filter-out $(ALL_MODULES.$(p).AIDL_FILES),$(AIDL_FILES.$(p))),\
+    $(eval intermediates_to_clean += $(ALL_MODULES.$(p).INTERMEDIATE_SOURCE_DIR))))
+intermediates_to_clean := $(strip $(intermediates_to_clean))
+ifdef intermediates_to_clean
+$(info *** Obsolete aidl-generated files detected, clean intermediate files...)
+$(info *** rm -rf $(intermediates_to_clean))
+$(shell rm -rf $(intermediates_to_clean))
+intermediates_to_clean :=
+endif
+
+# For modules not loaded by the current build (e.g. you are running mm/mmm),
+# we copy the info from the previous bulid.
+$(foreach p, $(filter-out $(ALL_MODULES),$(MODULES_WITH_AIDL_FILES)),\
+  $(shell echo 'AIDL_FILES.$(p) := $(AIDL_FILES.$(p))' >> $(current_aidl_config)))
+MODULES_WITH_AIDL_FILES := $(sort $(MODULES_WITH_AIDL_FILES) $(modules_with_aidl_files))
+$(shell echo 'MODULES_WITH_AIDL_FILES := $(MODULES_WITH_AIDL_FILES)' >> $(current_aidl_config))
+
+# Now current becomes previous.
+$(shell mv -f $(current_aidl_config) $(previous_aidl_config))
+
+MODULES_WITH_AIDL_FILES :=
+modules_with_aidl_files :=
+previous_aidl_config :=
+current_aidl_config :=
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index 33f5dc6..d3f9d1a 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -17,6 +17,7 @@
 my_skip_non_preferred_arch :=
 
 # check if first arch is supported
+LOCAL_2ND_ARCH_VAR_PREFIX :=
 include $(BUILD_SYSTEM)/module_arch_supported.mk
 ifeq ($(my_module_arch_supported),true)
 # first arch is supported
@@ -24,6 +25,10 @@
 ifneq ($(my_module_multilib),both)
 my_skip_non_preferred_arch := true
 endif # $(my_module_multilib)
+# For apps, we don't want to set up the prebuilt apk rule twice even if "LOCAL_MULTILIB := both".
+ifeq (APPS,$(LOCAL_MODULE_CLASS))
+my_skip_non_preferred_arch := true
+endif
 endif # $(my_module_arch_supported)
 
 ifndef my_skip_non_preferred_arch
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index b5e5189..fc0f56c 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -54,6 +54,11 @@
 endif
 endif
 
+ifeq ($(LOCAL_MODULE_CLASS),APPS)
+LOCAL_BUILT_MODULE_STEM := package.apk
+LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk
+endif
+
 ifeq ($(LOCAL_STRIP_MODULE),true)
   ifdef LOCAL_IS_HOST_MODULE
     $(error Cannot strip host module LOCAL_PATH=$(LOCAL_PATH))
@@ -91,23 +96,40 @@
 # of the shared libraries are determined.
 ifdef LOCAL_INSTALLED_MODULE
 ifdef LOCAL_SHARED_LIBRARIES
+my_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
+# Extra shared libraries introduced by LOCAL_CXX_STL.
+include $(BUILD_SYSTEM)/cxx_stl_setup.mk
 $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
-  $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(LOCAL_SHARED_LIBRARIES))
+  $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
 
 # We also need the LOCAL_BUILT_MODULE dependency,
 # since we use -rpath-link which points to the built module's path.
-built_shared_libraries := \
+my_built_shared_libraries := \
     $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
     $(addsuffix $($(my_prefix)SHLIB_SUFFIX), \
-        $(LOCAL_SHARED_LIBRARIES)))
-$(LOCAL_BUILT_MODULE) : $(built_shared_libraries)
+        $(my_shared_libraries)))
+$(LOCAL_BUILT_MODULE) : $(my_built_shared_libraries)
 endif
 endif
 
 endif  # LOCAL_STRIP_MODULE not true
 
+ifeq ($(LOCAL_MODULE_CLASS),APPS)
 PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
 
+# Select dpi-specific source
+ifdef LOCAL_DPI_VARIANTS
+my_dpi := $(firstword $(filter $(LOCAL_DPI_VARIANTS),$(PRODUCT_AAPT_PREF_CONFIG) $(PRODUCT_AAPT_PREBUILT_DPI)))
+ifdef my_dpi
+ifdef LOCAL_DPI_FILE_STEM
+my_prebuilt_dpi_file_stem := $(LOCAL_DPI_FILE_STEM)
+else
+my_prebuilt_dpi_file_stem := $(LOCAL_MODULE)_%.apk
+endif
+my_prebuilt_src_file := $(dir $(my_prebuilt_src_file))$(subst %,$(my_dpi),$(my_prebuilt_dpi_file_stem))
+endif  # my_dpi
+endif  # LOCAL_DPI_VARIANTS
+
 rs_compatibility_jni_libs :=
 include $(BUILD_SYSTEM)/install_jni_libs.mk
 
@@ -125,11 +147,9 @@
   $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
 endif
 ifeq ($(LOCAL_CERTIFICATE),)
-  ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
-    # It is now a build error to add a prebuilt .apk without
-    # specifying a key for it.
-    $(error No LOCAL_CERTIFICATE specified for prebuilt "$(my_prebuilt_src_file)")
-  endif
+  # It is now a build error to add a prebuilt .apk without
+  # specifying a key for it.
+  $(error No LOCAL_CERTIFICATE specified for prebuilt "$(my_prebuilt_src_file)")
 else ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
   # The magic string "PRESIGNED" means this package is already checked
   # signed with its release key.
@@ -153,16 +173,17 @@
   $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
 endif
 
-ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
-
-# Disable dex-preopt of prebuilts to save space
+# Disable dex-preopt of prebuilts to save space, if requested.
+ifeq ($(DONT_DEXPREOPT_PREBUILTS),true)
 LOCAL_DEX_PREOPT := false
+endif
 
 #######################################
 # defines built_odex along with rule to install odex
 include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
 #######################################
 # Sign and align non-presigned .apks.
+$(built_module) : PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES := $(LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES)
 $(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)
 	$(transform-prebuilt-to-target)
 ifdef extracted_jni_libs
@@ -185,6 +206,42 @@
 	$(call dexpreopt-one-file,$<,$@)
 endif
 
+###############################
+## Install split apks.
+ifdef LOCAL_PACKAGE_SPLITS
+# LOCAL_PACKAGE_SPLITS is a list of apks to be installed.
+built_apk_splits := $(addprefix $(built_module_path)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
+installed_apk_splits := $(addprefix $(my_module_path)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
+
+# Rules to sign and zipalign the split apks.
+my_src_dir := $(sort $(dir $(LOCAL_PACKAGE_SPLITS)))
+ifneq (1,$(words $(my_src_dir)))
+$(error You must put all the split source apks in the same folder: $(LOCAL_PACKAGE_SPLITS))
+endif
+my_src_dir := $(LOCAL_PATH)/$(my_src_dir)
+
+$(built_apk_splits) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
+$(built_apk_splits) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+$(built_apk_splits) : $(built_module_path)/%.apk : $(my_src_dir)/%.apk | $(ACP)
+	$(copy-file-to-new-target)
+	$(sign-package)
+	$(align-package)
+
+# Rules to install the split apks.
+$(installed_apk_splits) : $(my_module_path)/%.apk : $(built_module_path)/%.apk | $(ACP)
+	@echo "Install: $@"
+	$(copy-file-to-new-target)
+
+# Register the additional built and installed files.
+ALL_MODULES.$(my_register_name).INSTALLED += $(installed_apk_splits)
+ALL_MODULES.$(my_register_name).BUILT_INSTALLED += \
+  $(foreach s,$(LOCAL_PACKAGE_SPLITS),$(built_module_path)/$(notdir $(s)):$(my_module_path)/$(notdir $(s)))
+
+# Make sure to install the splits when you run "make <module_name>".
+$(my_register_name): $(installed_apk_splits)
+
+endif # LOCAL_PACKAGE_SPLITS
+
 else # LOCAL_MODULE_CLASS != APPS
 ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
 $(built_module) : $(my_prebuilt_src_file)
@@ -207,10 +264,26 @@
 # while the deps should be in the common dir, so we make a copy in the common dir.
 # For nonstatic library, $(common_javalib_jar) is the dependency file,
 # while $(common_classes_jar) is used to link.
-common_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),,COMMON)/classes.jar
-common_javalib_jar := $(dir $(common_classes_jar))javalib.jar
+common_classes_jar := $(intermediates.COMMON)/classes.jar
+common_javalib_jar := $(intermediates.COMMON)/javalib.jar
 
-$(common_classes_jar) : $(my_prebuilt_src_file) | $(ACP)
+$(common_classes_jar) $(common_javalib_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
+
+ifneq ($(filter %.aar, $(my_prebuilt_src_file)),)
+# This is .aar file, archive of classes.jar and Android resources.
+my_src_jar := $(intermediates.COMMON)/aar/classes.jar
+
+$(my_src_jar) : $(my_prebuilt_src_file)
+	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
+	$(hide) unzip -qo -d $(dir $@) $<
+	# Make sure the extracted classes.jar has a new timestamp.
+	$(hide) touch $@
+
+else
+# This is jar file.
+my_src_jar := $(my_prebuilt_src_file)
+endif
+$(common_classes_jar) : $(my_src_jar) | $(ACP)
 	$(transform-prebuilt-to-target)
 
 $(common_javalib_jar) : $(common_classes_jar) | $(ACP)
@@ -220,6 +293,6 @@
 $(built_module) : $(common_javalib_jar)
 endif # TARGET JAVA_LIBRARIES
 
-$(built_module) : $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(built_module) : $(LOCAL_MODULE_MAKEFILE) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 
 my_prebuilt_src_file :=
diff --git a/core/product.mk b/core/product.mk
index fd405ad..d3df582 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -70,6 +70,7 @@
     PRODUCT_LOCALES \
     PRODUCT_AAPT_CONFIG \
     PRODUCT_AAPT_PREF_CONFIG \
+    PRODUCT_AAPT_PREBUILT_DPI \
     PRODUCT_PACKAGES \
     PRODUCT_PACKAGES_DEBUG \
     PRODUCT_PACKAGES_ENG \
@@ -85,20 +86,28 @@
     PRODUCT_EXTRA_RECOVERY_KEYS \
     PRODUCT_PACKAGE_OVERLAYS \
     DEVICE_PACKAGE_OVERLAYS \
-    PRODUCT_TAGS \
+    PRODUCT_SDK_ATREE_FILES \
     PRODUCT_SDK_ADDON_NAME \
     PRODUCT_SDK_ADDON_COPY_FILES \
     PRODUCT_SDK_ADDON_COPY_MODULES \
     PRODUCT_SDK_ADDON_DOC_MODULES \
+    PRODUCT_SDK_ADDON_SYS_IMG_SOURCE_PROP \
     PRODUCT_DEFAULT_WIFI_CHANNELS \
     PRODUCT_DEFAULT_DEV_CERTIFICATE \
     PRODUCT_RESTRICT_VENDOR_FILES \
     PRODUCT_VENDOR_KERNEL_HEADERS \
-    PRODUCT_FACTORY_RAMDISK_MODULES \
-    PRODUCT_FACTORY_BUNDLE_MODULES \
-    PRODUCT_RUNTIMES \
     PRODUCT_BOOT_JARS \
-    PRODUCT_DEX_PREOPT_IMAGE_IN_DATA \
+    PRODUCT_SUPPORTS_VERITY \
+    PRODUCT_OEM_PROPERTIES \
+    PRODUCT_SYSTEM_PROPERTY_BLACKLIST \
+    PRODUCT_SYSTEM_SERVER_JARS \
+    PRODUCT_VERITY_SIGNING_KEY \
+    PRODUCT_SYSTEM_VERITY_PARTITION \
+    PRODUCT_VENDOR_VERITY_PARTITION \
+    PRODUCT_DEX_PREOPT_MODULE_CONFIGS \
+    PRODUCT_DEX_PREOPT_DEFAULT_FLAGS \
+    PRODUCT_DEX_PREOPT_BOOT_FLAGS \
+
 
 define dump-product
 $(info ==== $(1) ====)\
@@ -210,6 +219,7 @@
 
 _product_stash_var_list := $(_product_var_list) \
 	PRODUCT_BOOTCLASSPATH \
+	PRODUCT_SYSTEM_SERVER_CLASSPATH \
 	TARGET_ARCH \
 	TARGET_ARCH_VARIANT \
 	TARGET_CPU_VARIANT \
@@ -228,7 +238,6 @@
 	TARGET_PROVIDES_INIT_RC \
 	TARGET_CPU_ABI \
 	TARGET_CPU_ABI2 \
-	TARGET_CPU_SMP \
 
 
 _product_stash_var_list += \
@@ -243,17 +252,25 @@
 	BOARD_BOOTIMAGE_PARTITION_SIZE \
 	BOARD_RECOVERYIMAGE_PARTITION_SIZE \
 	BOARD_SYSTEMIMAGE_PARTITION_SIZE \
+	BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE \
+	BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE \
 	BOARD_USERDATAIMAGE_PARTITION_SIZE \
 	BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE \
 	BOARD_CACHEIMAGE_PARTITION_SIZE \
 	BOARD_FLASH_BLOCK_SIZE \
-	BOARD_SYSTEMIMAGE_PARTITION_SIZE \
+	BOARD_VENDORIMAGE_PARTITION_SIZE \
+	BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE \
 	BOARD_INSTALLER_CMDLINE \
 
 
 _product_stash_var_list += \
 	DEFAULT_SYSTEM_DEV_CERTIFICATE \
-	WITH_DEXPREOPT
+	WITH_DEXPREOPT \
+	WITH_DEXPREOPT_BOOT_IMG_ONLY
+
+_product_stash_var_list += \
+	GLOBAL_CFLAGS_NO_OVERRIDE \
+	GLOBAL_CPPFLAGS_NO_OVERRIDE \
 
 #
 # Stash values of the variables in _product_stash_var_list.
@@ -286,3 +303,14 @@
 define add-to-product-copy-files-if-exists
 $(if $(wildcard $(word 1,$(subst :, ,$(1)))),$(1))
 endef
+
+# whitespace placeholder when we record module's dex-preopt config.
+_PDPMC_SP_PLACE_HOLDER := |@SP@|
+# Set up dex-preopt config for a module.
+# $(1) list of module names
+# $(2) the modules' dex-preopt config
+define add-product-dex-preopt-module-config
+$(eval _c := $(subst $(space),$(_PDPMC_SP_PLACE_HOLDER),$(strip $(2))))\
+$(eval PRODUCT_DEX_PREOPT_MODULE_CONFIGS += \
+  $(foreach m,$(1),$(m)=$(_c)))
+endef
diff --git a/core/product_config.mk b/core/product_config.mk
index 9468362..5240ae7 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -248,39 +248,10 @@
 
 
 #############################################################################
-# TODO: Remove this hack once only 1 runtime is left.
-# Include the runtime product makefile based on the product's PRODUCT_RUNTIMES
-$(call clear-var-list, $(_product_var_list))
-
-# Set PRODUCT_RUNTIMES, allowing buildspec to override using OVERRIDE_RUNTIMES
-product_runtimes := $(sort $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_RUNTIMES))
-ifneq ($(OVERRIDE_RUNTIMES),)
-  $(info Overriding PRODUCT_RUNTIMES=$(product_runtimes) with $(OVERRIDE_RUNTIMES))
-  product_runtimes := $(OVERRIDE_RUNTIMES)
-endif
-$(foreach runtime, $(product_runtimes), $(eval include $(SRC_TARGET_DIR)/product/$(runtime).mk))
-$(foreach v, $(_product_var_list), $(if $($(v)),\
-    $(eval PRODUCTS.$(INTERNAL_PRODUCT).$(v) += $(sort $($(v))))))
-
-$(call clear-var-list, $(_product_var_list))
-# Now we can assign to PRODUCT_RUNTIMES
-PRODUCT_RUNTIMES := $(product_runtimes)
-product_runtimes :=
-
-PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PROPERTY_OVERRIDES += persist.sys.dalvik.vm.lib.2=$(DALVIK_VM_LIB)
-
-ifeq ($(words $(PRODUCT_RUNTIMES)),1)
-  # If we only have one runtime, we can strip classes.dex by default during dex_preopt
-  DEX_PREOPT_DEFAULT := true
-else
-  # If we have more than one, we leave the classes.dex alone for post-boot analysis
-  DEX_PREOPT_DEFAULT := nostripping
-endif
-
-#############################################################################
 
 # A list of module names of BOOTCLASSPATH (jar files)
 PRODUCT_BOOT_JARS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_BOOT_JARS))
+PRODUCT_SYSTEM_SERVER_JARS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_SERVER_JARS))
 
 # Find the device that this product maps to.
 TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
@@ -303,26 +274,16 @@
 endif
 
 # Add PRODUCT_LOCALES to PRODUCT_AAPT_CONFIG
-PRODUCT_AAPT_CONFIG := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_CONFIG))
-PRODUCT_AAPT_CONFIG := $(PRODUCT_LOCALES) $(PRODUCT_AAPT_CONFIG)
+PRODUCT_AAPT_CONFIG := $(strip $(PRODUCT_LOCALES) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_CONFIG))
 PRODUCT_AAPT_PREF_CONFIG := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_PREF_CONFIG))
+PRODUCT_AAPT_PREBUILT_DPI := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_PREBUILT_DPI))
 
-# Default to medium-density assets.
-# (Can be overridden in the device config, e.g.: PRODUCT_AAPT_CONFIG += hdpi)
-PRODUCT_AAPT_CONFIG := $(strip \
-    $(PRODUCT_AAPT_CONFIG) \
-    $(if $(filter %dpi,$(PRODUCT_AAPT_CONFIG)),,mdpi))
-PRODUCT_AAPT_PREF_CONFIG := $(strip $(PRODUCT_AAPT_PREF_CONFIG))
-
-# 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 := \
-    $(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_PREF_CONFIG)))
 
 # product-scoped aapt flags
 PRODUCT_AAPT_FLAGS :=
@@ -388,9 +349,6 @@
 DEVICE_PACKAGE_OVERLAYS := \
         $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).DEVICE_PACKAGE_OVERLAYS))
 
-# An list of whitespace-separated words.
-PRODUCT_TAGS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_TAGS))
-
 # The list of product-specific kernel header dirs
 PRODUCT_VENDOR_KERNEL_HEADERS := \
     $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_KERNEL_HEADERS)
@@ -410,6 +368,20 @@
 PRODUCT_EXTRA_RECOVERY_KEYS := $(sort \
     $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_EXTRA_RECOVERY_KEYS))
 
-# If there is no room in /system for the image, place it in /data
-PRODUCT_DEX_PREOPT_IMAGE_IN_DATA := \
-    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEX_PREOPT_IMAGE_IN_DATA))
+PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := \
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEX_PREOPT_DEFAULT_FLAGS))
+PRODUCT_DEX_PREOPT_BOOT_FLAGS := \
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEX_PREOPT_BOOT_FLAGS))
+# Resolve and setup per-module dex-preopot configs.
+PRODUCT_DEX_PREOPT_MODULE_CONFIGS := \
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEX_PREOPT_MODULE_CONFIGS))
+# If a module has multiple setups, the first takes precedence.
+_pdpmc_modules :=
+$(foreach c,$(PRODUCT_DEX_PREOPT_MODULE_CONFIGS),\
+  $(eval m := $(firstword $(subst =,$(space),$(c))))\
+  $(if $(filter $(_pdpmc_modules),$(m)),,\
+    $(eval _pdpmc_modules += $(m))\
+    $(eval cf := $(patsubst $(m)=%,%,$(c)))\
+    $(eval cf := $(subst $(_PDPMC_SP_PLACE_HOLDER),$(space),$(cf)))\
+    $(eval DEXPREOPT.$(TARGET_PRODUCT).$(m).CONFIG := $(cf))))
+_pdpmc_modules :=
diff --git a/core/proguard_basic_keeps.flags b/core/proguard_basic_keeps.flags
index af0e05d..4a85db0 100644
--- a/core/proguard_basic_keeps.flags
+++ b/core/proguard_basic_keeps.flags
@@ -49,12 +49,16 @@
 # -keep class * extends android.preference.Preference
 # -keep class * extends android.app.BackupAgent
 
-#-keep class * implements android.os.Parcelable {
-#  public static final android.os.Parcelable$Creator *;
-#}
+# Parcelable CREATORs must be kept for Parcelable functionality
+-keep class * implements android.os.Parcelable {
+  public static final ** CREATOR;
+}
 
 # The support library contains references to newer platform versions.
 # Don't warn about those in case this app is linking against an older
 # platform version.  We know about them, and they are safe.
 # See proguard-android.txt in the SDK package.
 -dontwarn android.support.**
+
+# Less spammy.
+-dontnote
diff --git a/core/proguard_tests.flags b/core/proguard_tests.flags
index 4481a1b..1f840bc 100644
--- a/core/proguard_tests.flags
+++ b/core/proguard_tests.flags
@@ -1,5 +1,6 @@
 # Keep everything for tests
--dontshrink
+# This flag has been moved to the makefiles and is set for tests by default.
+#-dontshrink
 
 # But we may want to obfuscate if the main app gets obfuscated.
 # This flag has been moved to the makefiles.
diff --git a/core/raw_executable.mk b/core/raw_executable.mk
deleted file mode 100644
index b64173a..0000000
--- a/core/raw_executable.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_SUFFIX := 
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-
-include $(BUILD_SYSTEM)/binary.mk
-
-$(LOCAL_BUILT_MODULE) : PRIVATE_ELF_FILE := $(intermediates)/$(PRIVATE_MODULE).elf
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIBS := `$(TARGET_CC) -mthumb-interwork -print-libgcc-file-name`
-
-$(all_objects) : PRIVATE_TARGET_PROJECT_INCLUDES :=
-$(all_objects) : PRIVATE_TARGET_C_INCLUDES :=
-$(all_objects) : PRIVATE_TARGET_GLOBAL_CFLAGS :=
-$(all_objects) : PRIVATE_TARGET_GLOBAL_CPPFLAGS :=
-
-$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries)
-	@$(mkdir -p $(dir $@)
-	@echo "target Linking: $(PRIVATE_MODULE)"
-	$(hide) $(TARGET_LD) \
-		$(addprefix --script ,$(PRIVATE_LINK_SCRIPT)) \
-		$(PRIVATE_RAW_EXECUTABLE_LDFLAGS) \
-		-o $(PRIVATE_ELF_FILE) \
-		$(PRIVATE_ALL_OBJECTS) \
-		--start-group $(PRIVATE_ALL_STATIC_LIBRARIES) --end-group \
-		$(PRIVATE_LIBS)
-	$(hide) $(TARGET_OBJCOPY) -O binary $(PRIVATE_ELF_FILE) $@
diff --git a/core/raw_static_library.mk b/core/raw_static_library.mk
deleted file mode 100644
index 14a404d..0000000
--- a/core/raw_static_library.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-
-LOCAL_RAW_STATIC_LIBRARY:=true
-
-include $(BUILD_SYSTEM)/static_library_internal.mk
diff --git a/core/sdk_font.mk b/core/sdk_font.mk
new file mode 100644
index 0000000..204403d
--- /dev/null
+++ b/core/sdk_font.mk
@@ -0,0 +1,66 @@
+###############################################################################
+# Fonts shipped with the SDK need to be renamed for Java to handle them
+# properly. Hence, a special script is used to rename the fonts. We bundle all
+# the fonts that are shipped on a newer non-space-constrained device. However,
+# OpenType fonts used on these devices are not supported by Java. Their
+# replacements are added separately.
+###############################################################################
+
+
+# The script that renames the font.
+sdk_font_rename_script := frameworks/base/tools/layoutlib/rename_font/build_font_single.py
+
+# Location of the fonttools library that the above script depends on.
+fonttools_lib := external/fonttools/Lib
+
+# A temporary location to store the renamed fonts. atree picks all files in
+# this directory and bundles it with the SDK.
+SDK_FONT_TEMP := $(call intermediates-dir-for,PACKAGING,sdk-fonts,HOST,COMMON)
+
+# The font configuration files - system_fonts.xml, fallback_fonts.xml etc.
+sdk_font_config := $(wildcard frameworks/base/data/fonts/*.xml)
+sdk_font_config :=  $(addprefix $(SDK_FONT_TEMP)/, $(notdir $(sdk_font_config)))
+
+$(sdk_font_config): $(SDK_FONT_TEMP)/%.xml: \
+			frameworks/base/data/fonts/%.xml
+	$(hide) mkdir -p $(dir $@)
+	$(hide) cp -vf $< $@
+
+# List of fonts on the device that we want to ship. This is all .ttf fonts.
+sdk_fonts_device := $(filter $(TARGET_OUT)/fonts/%.ttf, $(INTERNAL_SYSTEMIMAGE_FILES))
+sdk_fonts_device := $(addprefix $(SDK_FONT_TEMP)/, $(notdir $(sdk_fonts_device)))
+
+# Macro to rename the font.
+sdk_rename_font = PYTHONPATH=$$PYTHONPATH:$(fonttools_lib) $(sdk_font_rename_script) \
+	    $1 $2
+
+# TODO: If the font file is a symlink, reuse the font renamed from the symlink
+# target.
+$(sdk_fonts_device): $(SDK_FONT_TEMP)/%.ttf: $(TARGET_OUT)/fonts/%.ttf \
+			$(sdk_font_rename_script)
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(call sdk_rename_font,$<,$@)
+
+# List of all dependencies - all fonts and configuration files.
+SDK_FONT_DEPS := $(sdk_fonts_device) $(sdk_font_config)
+
+# Define a macro to create rule for addititional fonts that we want to include
+# in the SDK.
+# $1 Output font name
+# $2 Source font path
+define sdk-extra-font-rule
+fontfullname := $$(SDK_FONT_TEMP)/$1
+ifeq ($$(filter $$(fontfullname),$$(sdk_fonts_device)),)
+SDK_FONT_DEPS += $$(fontfullname)
+$$(fontfullname): $2 $$(sdk_font_rename_script)
+	$$(hide) mkdir -p $$(dir $$@)
+	$$(hide) $$(call sdk_rename_font,$$<,$$@)
+endif
+fontfullname :=
+endef
+
+# These extra fonts are used as a replacement for OpenType fonts.
+$(eval $(call sdk-extra-font-rule,NanumGothic.ttf,external/naver-fonts/NanumGothic.ttf))
+$(eval $(call sdk-extra-font-rule,DroidSansFallback.ttf,frameworks/base/data/fonts/DroidSansFallbackFull.ttf))
+
+sdk-extra-font-rule :=
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
new file mode 100644
index 0000000..ec8a28a
--- /dev/null
+++ b/core/setup_one_odex.mk
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Set up variables and dependency for one odex file
+# Input variables: my_2nd_arch_prefix
+# Output(modified) variables: built_odex, installed_odex, built_installed_odex
+
+my_built_odex := $(call get-odex-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_BUILT_MODULE))
+ifdef LOCAL_DEX_PREOPT_IMAGE_LOCATION
+my_dex_preopt_image_location := $(LOCAL_DEX_PREOPT_IMAGE_LOCATION)
+else
+my_dex_preopt_image_location := $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
+endif
+my_dex_preopt_image_filename := $(call get-image-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(my_dex_preopt_image_location))
+$(my_built_odex): PRIVATE_2ND_ARCH_VAR_PREFIX := $(my_2nd_arch_prefix)
+$(my_built_odex): PRIVATE_DEX_LOCATION := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
+$(my_built_odex): PRIVATE_DEX_PREOPT_IMAGE_LOCATION := $(my_dex_preopt_image_location)
+$(my_built_odex) : $($(my_2nd_arch_prefix)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
+    $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
+    $(my_dex_preopt_image_filename)
+
+my_installed_odex := $(call get-odex-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
+
+built_odex += $(my_built_odex)
+installed_odex += $(my_installed_odex)
+built_installed_odex += $(my_built_odex):$(my_installed_odex)
diff --git a/core/shared_library_internal.mk b/core/shared_library_internal.mk
index abef11f..1fda794 100644
--- a/core/shared_library_internal.mk
+++ b/core/shared_library_internal.mk
@@ -40,7 +40,7 @@
 
 # Define PRIVATE_ variables from global vars
 my_target_global_ld_dirs := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS)
-my_target_fdo_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_LIB)
+my_target_libgcov := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCOV)
 my_target_libgcc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCC)
 my_target_libatomic := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBATOMIC)
 my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_SO_O)
@@ -58,15 +58,19 @@
 endif
 $(linked_module): PRIVATE_TARGET_GLOBAL_LD_DIRS := $(my_target_global_ld_dirs)
 $(linked_module): PRIVATE_TARGET_GLOBAL_LDFLAGS := $(my_target_global_ldflags)
-$(linked_module): PRIVATE_TARGET_FDO_LIB := $(my_target_fdo_lib)
+$(linked_module): PRIVATE_TARGET_LIBGCOV := $(my_target_libgcov)
 $(linked_module): PRIVATE_TARGET_LIBGCC := $(my_target_libgcc)
 $(linked_module): PRIVATE_TARGET_LIBATOMIC := $(my_target_libatomic)
 $(linked_module): PRIVATE_TARGET_CRTBEGIN_SO_O := $(my_target_crtbegin_so_o)
 $(linked_module): PRIVATE_TARGET_CRTEND_SO_O := $(my_target_crtend_so_o)
 
-$(linked_module): $(all_objects) $(all_libraries) \
-                  $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-                  $(my_target_crtbegin_so_o) $(my_target_crtend_so_o)
+$(linked_module): \
+        $(all_objects) \
+        $(all_libraries) \
+        $(my_target_crtbegin_so_o) \
+        $(my_target_crtend_so_o) \
+        $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-o-to-shared-lib)
 
 endif  # skip_build_from_source
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 79b7292..02078e0 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -67,14 +67,7 @@
 ifeq (true,$(need_compile_res))
 R_file_stamp := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/R.stamp
 
-ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
-  LOCAL_MANIFEST_FILE := AndroidManifest.xml
-endif
-ifdef LOCAL_FULL_MANIFEST_FILE
-  full_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
-else
-  full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
-endif
+include $(BUILD_SYSTEM)/android_manifest.mk
 
 LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
 ifeq ($(LOCAL_SDK_RES_VERSION),)
@@ -85,7 +78,7 @@
 framework_res_package_export_deps :=
 # Please refer to package.mk
 ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-ifneq ($(filter-out current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current,$(LOCAL_SDK_RES_VERSION))),)
+ifneq ($(filter-out current system_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current,$(LOCAL_SDK_RES_VERSION))),)
 framework_res_package_export := \
     $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_RES_VERSION)/android.jar
 framework_res_package_export_deps := $(framework_res_package_export)
@@ -105,7 +98,7 @@
 $(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := $(intermediates.COMMON)/public_resources.xml
 $(R_file_stamp): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
 $(R_file_stamp): PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
-ifneq (,$(filter-out current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION)))
 $(R_file_stamp): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
 else
 $(R_file_stamp): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
diff --git a/core/target_test_internal.mk b/core/target_test_internal.mk
index 87503ea..f8a9f04 100644
--- a/core/target_test_internal.mk
+++ b/core/target_test_internal.mk
@@ -5,18 +5,11 @@
 LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING
 
 LOCAL_C_INCLUDES += external/gtest/include
-ifneq ($(filter libc++,$(LOCAL_SHARED_LIBRARIES)),)
-LOCAL_STATIC_LIBRARIES += libgtest_libc++ libgtest_main_libc++
-else
-LOCAL_STATIC_LIBRARIES += libgtest libgtest_main
 
 ifndef LOCAL_SDK_VERSION
-LOCAL_C_INCLUDES += bionic \
-                    bionic/libstdc++/include \
-                    external/stlport/stlport
-LOCAL_SHARED_LIBRARIES += libstlport
-LOCAL_STATIC_LIBRARIES += libstdc++
-endif
+LOCAL_STATIC_LIBRARIES += libgtest libgtest_main
+else
+LOCAL_STATIC_LIBRARIES += libgtest_ndk libgtest_main_ndk
 endif
 
 ifdef LOCAL_MODULE_PATH
@@ -31,5 +24,5 @@
 $(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH_64 when building test $(LOCAL_MODULE))
 endif
 
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)64/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
index 00b78b9..683a075 100644
--- a/core/tasks/apicheck.mk
+++ b/core/tasks/apicheck.mk
@@ -31,6 +31,11 @@
              )\
         ))
 
+.PHONY: check-public-api
+checkapi : check-public-api
+
+.PHONY: update-api
+
 # INTERNAL_PLATFORM_API_FILE is the one build by droiddoc.
 # Note that since INTERNAL_PLATFORM_API_FILE is the byproduct of api-stubs module,
 # (See frameworks/base/Android.mk)
@@ -39,35 +44,89 @@
 # Check that the API we're building hasn't broken the last-released
 # SDK version.
 $(eval $(call check-api, \
-    checkapi-last, \
+    checkpublicapi-last, \
     $(SRC_API_DIR)/$(last_released_sdk_version).txt, \
     $(INTERNAL_PLATFORM_API_FILE), \
+    frameworks/base/api/removed.txt, \
+    $(INTERNAL_PLATFORM_REMOVED_API_FILE), \
     -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 -hide 26 -hide 27 \
     -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
     -error 16 -error 17 -error 18 , \
     cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
-    checkapi, \
+    check-public-api, \
     $(call doc-timestamp-for,api-stubs) \
     ))
 
 # Check that the API we're building hasn't changed from the not-yet-released
 # SDK version.
 $(eval $(call check-api, \
-    checkapi-current, \
+    checkpublicapi-current, \
     frameworks/base/api/current.txt, \
     $(INTERNAL_PLATFORM_API_FILE), \
+    frameworks/base/api/removed.txt, \
+    $(INTERNAL_PLATFORM_REMOVED_API_FILE), \
     -error 2 -error 3 -error 4 -error 5 -error 6 \
     -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
     -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
     -error 25 -error 26 -error 27, \
     cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    checkapi, \
+    check-public-api, \
     $(call doc-timestamp-for,api-stubs) \
     ))
 
-.PHONY: update-api
-update-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP)
+.PHONY: update-public-api
+update-public-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP)
 	@echo Copying current.txt
 	$(hide) $(ACP) $(INTERNAL_PLATFORM_API_FILE) frameworks/base/api/current.txt
+	@echo Copying removed.txt
+	$(hide) $(ACP) $(INTERNAL_PLATFORM_REMOVED_API_FILE) frameworks/base/api/removed.txt
+
+update-api : update-public-api
+
+#####################Check System API#####################
+.PHONY: check-system-api
+checkapi : check-system-api
+
+# Check that the System API we're building hasn't broken the last-released
+# SDK version.
+$(eval $(call check-api, \
+    checksystemapi-last, \
+    $(SRC_SYSTEM_API_DIR)/$(last_released_sdk_version).txt, \
+    $(INTERNAL_PLATFORM_SYSTEM_API_FILE), \
+    frameworks/base/api/system-removed.txt, \
+    $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE), \
+    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 -hide 26 -hide 27 \
+    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+    -error 16 -error 17 -error 18 , \
+    cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
+    check-system-api, \
+    $(call doc-timestamp-for,system-api-stubs) \
+    ))
+
+# Check that the System API we're building hasn't changed from the not-yet-released
+# SDK version.
+$(eval $(call check-api, \
+    checksystemapi-current, \
+    frameworks/base/api/system-current.txt, \
+    $(INTERNAL_PLATFORM_SYSTEM_API_FILE), \
+    frameworks/base/api/system-removed.txt, \
+    $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE), \
+    -error 2 -error 3 -error 4 -error 5 -error 6 \
+    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
+    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
+    -error 25 -error 26 -error 27, \
+    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
+    check-system-api, \
+    $(call doc-timestamp-for,system-api-stubs) \
+    ))
+
+.PHONY: update-system-api
+update-api : update-system-api
+
+update-system-api: $(INTERNAL_PLATFORM_SYSTEM_API_FILE) | $(ACP)
+	@echo Copying system-current.txt
+	$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_API_FILE) frameworks/base/api/system-current.txt
+	@echo Copying system-removed.txt
+	$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE) frameworks/base/api/system-removed.txt
 
 endif
diff --git a/core/tasks/boot_jars_package_check.mk b/core/tasks/boot_jars_package_check.mk
new file mode 100644
index 0000000..188c267
--- /dev/null
+++ b/core/tasks/boot_jars_package_check.mk
@@ -0,0 +1,46 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Rules to check if classes in the boot jars are from the whitelisted packages.
+#
+
+ifneq ($(SKIP_BOOT_JARS_CHECK),true)
+ifneq ($(TARGET_BUILD_PDK),true)
+ifdef PRODUCT_BOOT_JARS
+
+intermediates := $(call intermediates-dir-for, PACKAGING, boot-jars-package-check,,COMMON)
+stamp := $(intermediates)/stamp
+built_boot_jars := $(foreach j, $(PRODUCT_BOOT_JARS), \
+  $(call intermediates-dir-for, JAVA_LIBRARIES, $(j),,COMMON)/classes.jar)
+script := build/core/tasks/check_boot_jars/check_boot_jars.py
+whitelist_file := build/core/tasks/check_boot_jars/package_whitelist.txt
+
+$(stamp): PRIVATE_BOOT_JARS := $(built_boot_jars)
+$(stamp): PRIVATE_SCRIPT := $(script)
+$(stamp): PRIVATE_WHITELIST := $(whitelist_file)
+$(stamp) : $(built_boot_jars) $(script) $(whitelist_file)
+	@echo "Check package name for $(PRIVATE_BOOT_JARS)"
+	$(hide) $(PRIVATE_SCRIPT) $(PRIVATE_WHITELIST) $(PRIVATE_BOOT_JARS)
+	$(hide) mkdir -p $(dir $@) && touch $@
+
+.PHONY: check-boot-jars
+check-boot-jars : $(stamp)
+
+# Run check-boot-jars by default
+droidcore : check-boot-jars
+
+endif  # PRODUCT_BOOT_JARS
+endif  # TARGET_BUILD_PDK not true
+endif  # SKIP_BOOT_JARS_CHECK not true
diff --git a/core/tasks/check_boot_jars/check_boot_jars.py b/core/tasks/check_boot_jars/check_boot_jars.py
new file mode 100755
index 0000000..89d9ee8
--- /dev/null
+++ b/core/tasks/check_boot_jars/check_boot_jars.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+
+"""
+Check boot jars.
+
+Usage: check_boot_jars.py <package_whitelist_file> <jar1> <jar2> ...
+"""
+import logging
+import os.path
+import re
+import subprocess
+import sys
+
+
+# The compiled whitelist RE.
+whitelist_re = None
+
+
+def LoadWhitelist(filename):
+  """ Load and compile whitelist regular expressions from filename.
+  """
+  lines = []
+  with open(filename, 'r') as f:
+    for line in f:
+      line = line.strip()
+      if not line or line.startswith('#'):
+        continue
+      lines.append(line)
+  combined_re = r'^(%s)$' % '|'.join(lines)
+  global whitelist_re
+  try:
+    whitelist_re = re.compile(combined_re)
+  except re.error:
+    logging.exception(
+        'Cannot compile package whitelist regular expression: %r',
+        combined_re)
+    whitelist_re = None
+    return False
+  return True
+
+
+def CheckJar(jar):
+  """Check a jar file.
+  """
+  # Get the list of files inside the jar file.
+  p = subprocess.Popen(args='jar tf %s' % jar,
+      stdout=subprocess.PIPE, shell=True)
+  stdout, _ = p.communicate()
+  if p.returncode != 0:
+    return False
+  items = stdout.split()
+  for f in items:
+    if f.endswith('.class'):
+      package_name = os.path.dirname(f)
+      package_name = package_name.replace('/', '.')
+      # Skip class without a package name
+      if package_name and not whitelist_re.match(package_name):
+        print >> sys.stderr, ('Error: %s: unknown package name of class file %s'
+                              % (jar, f))
+        return False
+  return True
+
+
+def main(argv):
+  if len(argv) < 2:
+    print __doc__
+    sys.exit(1)
+
+  if not LoadWhitelist(argv[0]):
+    sys.exit(1)
+
+  passed = True
+  for jar in argv[1:]:
+    if not CheckJar(jar):
+      passed = False
+  if not passed:
+    return 1
+
+  return 0
+
+
+if __name__ == '__main__':
+  main(sys.argv[1:])
diff --git a/core/tasks/check_boot_jars/package_whitelist.txt b/core/tasks/check_boot_jars/package_whitelist.txt
new file mode 100644
index 0000000..4d62615
--- /dev/null
+++ b/core/tasks/check_boot_jars/package_whitelist.txt
@@ -0,0 +1,214 @@
+# Boot jar package name whitelist.
+# Each line is interpreted as a regular expression.
+
+###################################################
+# core-libart.jar
+java\.awt\.font
+java\.beans
+java\.io
+java\.lang
+java\.lang\.annotation
+java\.lang\.ref
+java\.lang\.reflect
+java\.math
+java\.net
+java\.nio
+java\.nio\.channels
+java\.nio\.channels\.spi
+java\.nio\.charset
+java\.nio\.charset\.spi
+java\.security
+java\.security\.acl
+java\.security\.cert
+java\.security\.interfaces
+java\.security\.spec
+java\.sql
+java\.text
+java\.util
+java\.util\.concurrent
+java\.util\.concurrent\.atomic
+java\.util\.concurrent\.locks
+java\.util\.jar
+java\.util\.logging
+java\.util\.prefs
+java\.util\.regex
+java\.util\.zip
+javax\.crypto
+javax\.crypto\.interfaces
+javax\.crypto\.spec
+javax\.net
+javax\.net\.ssl
+javax\.security\.auth
+javax\.security\.auth\.callback
+javax\.security\.auth\.login
+javax\.security\.auth\.x500
+javax\.security\.cert
+javax\.sql
+javax\.xml
+javax\.xml\.datatype
+javax\.xml\.namespace
+javax\.xml\.parsers
+javax\.xml\.transform
+javax\.xml\.transform\.dom
+javax\.xml\.transform\.sax
+javax\.xml\.transform\.stream
+javax\.xml\.validation
+javax\.xml\.xpath
+sun\.misc
+org\.w3c\.dom
+org\.w3c\.dom\.ls
+org\.w3c\.dom\.traversal
+
+# TODO: Move these internal org.apache.harmony classes to libcore.*
+org\.apache\.harmony\.crypto\.internal
+org\.apache\.harmony\.dalvik
+org\.apache\.harmony\.dalvik\.ddmc
+org\.apache\.harmony\.luni\.internal\.util
+org\.apache\.harmony\.security
+org\.apache\.harmony\.security\.asn1
+org\.apache\.harmony\.security\.fortress
+org\.apache\.harmony\.security\.pkcs10
+org\.apache\.harmony\.security\.pkcs7
+org\.apache\.harmony\.security\.pkcs8
+org\.apache\.harmony\.security\.provider\.crypto
+org\.apache\.harmony\.security\.utils
+org\.apache\.harmony\.security\.x501
+org\.apache\.harmony\.security\.x509
+org\.apache\.harmony\.security\.x509\.tsp
+org\.apache\.harmony\.xml
+org\.apache\.harmony\.xml\.dom
+org\.apache\.harmony\.xml\.parsers
+
+org\.json
+org\.xmlpull\.v1
+org\.xmlpull\.v1\.sax2
+
+# TODO:  jarjar org.kxml2.io to com.android org\.kxml2\.io
+org\.kxml2\.io
+org\.xml
+org\.xml\.sax
+org\.xml\.sax\.ext
+org\.xml\.sax\.helpers
+
+dalvik\..*
+libcore\..*
+android\..*
+com\.android\..*
+
+
+###################################################
+# core-junit.jar
+junit\.extensions
+junit\.framework
+
+
+###################################################
+# ext.jar
+# TODO: jarjar javax.sip to com.android
+javax\.sip
+javax\.sip\.address
+javax\.sip\.header
+javax\.sip\.message
+
+# TODO: jarjar org.apache.commons to com.android
+org\.apache\.commons\.codec
+org\.apache\.commons\.codec\.binary
+org\.apache\.commons\.codec\.language
+org\.apache\.commons\.codec\.net
+org\.apache\.commons\.logging
+org\.apache\.commons\.logging\.impl
+org\.apache\.http
+org\.apache\.http\.auth
+org\.apache\.http\.auth\.params
+org\.apache\.http\.client
+org\.apache\.http\.client\.entity
+org\.apache\.http\.client\.methods
+org\.apache\.http\.client\.params
+org\.apache\.http\.client\.protocol
+org\.apache\.http\.client\.utils
+org\.apache\.http\.conn
+org\.apache\.http\.conn\.params
+org\.apache\.http\.conn\.routing
+org\.apache\.http\.conn\.scheme
+org\.apache\.http\.conn\.ssl
+org\.apache\.http\.conn\.util
+org\.apache\.http\.cookie
+org\.apache\.http\.cookie\.params
+org\.apache\.http\.entity
+org\.apache\.http\.impl
+org\.apache\.http\.impl\.auth
+org\.apache\.http\.impl\.client
+org\.apache\.http\.impl\.client
+org\.apache\.http\.impl\.conn
+org\.apache\.http\.impl\.conn\.tsccm
+org\.apache\.http\.impl\.cookie
+org\.apache\.http\.impl\.entity
+org\.apache\.http\.impl\.io
+org\.apache\.http\.impl\.io
+org\.apache\.http\.io
+org\.apache\.http\.message
+org\.apache\.http\.params
+org\.apache\.http\.protocol
+org\.apache\.http\.util
+
+# TODO: jarjar gov.nist to com.android
+gov\.nist\.core
+gov\.nist\.core\.net
+gov\.nist\.javax\.sip
+gov\.nist\.javax\.sip\.address
+gov\.nist\.javax\.sip\.clientauthutils
+gov\.nist\.javax\.sip\.header
+gov\.nist\.javax\.sip\.header\.extensions
+gov\.nist\.javax\.sip\.header\.ims
+gov\.nist\.javax\.sip\.message
+gov\.nist\.javax\.sip\.parser
+gov\.nist\.javax\.sip\.parser\.extensions
+gov\.nist\.javax\.sip\.parser\.ims
+gov\.nist\.javax\.sip\.stack
+
+org\.ccil\.cowan\.tagsoup
+org\.ccil\.cowan\.tagsoup\.jaxp
+
+###################################################
+# framework.jar
+javax\.microedition\.khronos\.opengles
+javax\.microedition\.khronos\.egl
+
+android
+
+
+###################################################
+# telephony-common.jar
+com\.google\..*
+
+
+###################################################
+# apache-xml.jar
+org\.apache\.xml\.res
+org\.apache\.xml\.utils
+org\.apache\.xml\.utils\.res
+org\.apache\.xml\.dtm
+org\.apache\.xml\.dtm\.ref
+org\.apache\.xml\.dtm\.ref\.dom2dtm
+org\.apache\.xml\.dtm\.ref\.sax2dtm
+org\.apache\.xml\.serializer
+org\.apache\.xml\.serializer\.utils
+org\.apache\.xml\.serializer\.dom3
+org\.apache\.xpath
+org\.apache\.xpath\.operations
+org\.apache\.xpath\.domapi
+org\.apache\.xpath\.functions
+org\.apache\.xpath\.res
+org\.apache\.xpath\.axes
+org\.apache\.xpath\.objects
+org\.apache\.xpath\.patterns
+org\.apache\.xpath\.jaxp
+org\.apache\.xpath\.compiler
+org\.apache\.xalan
+org\.apache\.xalan\.res
+org\.apache\.xalan\.templates
+org\.apache\.xalan\.serialize
+org\.apache\.xalan\.extensions
+org\.apache\.xalan\.processor
+org\.apache\.xalan\.transformer
+org\.apache\.xalan\.xslt
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index c521fa3..2ce5dbc 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -17,8 +17,7 @@
 
 cts_name := android-cts
 
-DDMLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/ddmlib-prebuilt.jar
-junit_host_jar := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
+JUNIT_HOST_JAR := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
 HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
 TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
 CTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar
@@ -48,6 +47,7 @@
 	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.libcore.package.okhttp \
 	android.core.tests.runner
 
 # The list of test packages that apache-harmony-tests (external/apache-harmony/Android.mk)
@@ -58,19 +58,33 @@
 	android.core.tests.libcore.package.harmony_prefs \
 	android.core.tests.libcore.package.harmony_sql
 
+
+CTS_TEST_JAR_LIST := \
+        cts-junit \
+	CtsJdwp
+
 # 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)
+CTS_TEST_JAR_FILES := $(foreach c,$(CTS_TEST_JAR_LIST),$(call intermediates-dir-for,JAVA_LIBRARIES,$(c))/javalib.jar)
 
 -include cts/CtsTestCaseList.mk
 CTS_CASE_LIST := $(CTS_CORE_CASE_LIST) $(CTS_TEST_CASE_LIST)
 
+# A module may have mutliple installed files (e.g. split apks)
+CTS_CASE_LIST_APKS :=
+CTS_CASE_LIST_APKS_DIR := $(cts_dir)/$(cts_name)/repository/testcases/
+$(foreach m, $(CTS_CASE_LIST),\
+  $(foreach fp, $(ALL_MODULES.$(m).BUILT_INSTALLED),\
+    $(eval pair := $(subst :,$(space),$(fp)))\
+    $(eval built := $(word 1,$(pair)))\
+    $(eval installed := $(CTS_CASE_LIST_APKS_DIR)/$(notdir $(word 2,$(pair))))\
+    $(eval $(call copy-one-file, $(built), $(installed)))\
+    $(eval CTS_CASE_LIST_APKS += $(installed))))
+
 DEFAULT_TEST_PLAN := $(cts_dir)/$(cts_name)/resource/plans
-CTS_TEST_CASE_LIST_FILES := $(foreach c, $(CTS_TEST_CASE_LIST), $(call intermediates-dir-for,APPS,$(c))/package.apk)
-$(cts_dir)/all_cts_files_stamp: PRIVATE_JUNIT_HOST_JAR := $(junit_host_jar)
-$(cts_dir)/all_cts_files_stamp: $(CTS_CORE_CASES) $(CTS_TEST_CASES) $(CTS_TEST_CASE_LIST_FILES) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(ACP)
+$(cts_dir)/all_cts_files_stamp: $(CTS_CORE_CASES) $(CTS_TEST_CASES) $(CTS_CASE_LIST_APKS) $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(ACP) $(CTS_TEST_JAR_FILES)
 # Make necessary directory for CTS
-	$(hide) rm -rf $(PRIVATE_CTS_DIR)
 	$(hide) mkdir -p $(TMP_DIR)
 	$(hide) mkdir -p $(PRIVATE_DIR)/docs
 	$(hide) mkdir -p $(PRIVATE_DIR)/tools
@@ -78,9 +92,9 @@
 	$(hide) mkdir -p $(PRIVATE_DIR)/repository/plans
 # Copy executable and JARs to CTS directory
 	$(hide) $(ACP) -fp $(VMTESTSTF_JAR) $(PRIVATE_DIR)/repository/testcases
-	$(hide) $(ACP) -fp $(DDMLIB_JAR) $(PRIVATE_JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(PRIVATE_DIR)/tools
+	$(hide) $(ACP) -fp $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(PRIVATE_DIR)/tools
 # Change mode of the executables
-	$(foreach apk,$(CTS_CASE_LIST),$(call copy-testcase-apk,$(apk)))
+	$(foreach jar,$(CTS_TEST_JAR_LIST),$(call copy-testcase-jar,$(jar)))
 	$(foreach testcase,$(CTS_TEST_CASES),$(call copy-testcase,$(testcase)))
 	$(hide) touch $@
 
@@ -90,29 +104,32 @@
 # $2 : The AndroidManifest.xml corresponding to the test package
 # $3 : The jar file name on PRIVATE_CLASSPATH containing junit tests to search for
 # $4 : The package prefix of classes to include, possible empty
-# $5 : The directory containing vogar expectations files
-# $6 : The Android.mk corresponding to the test package (required for host-side tests only)
+# $5 : The architecture of the current build
+# $6 : The directory containing vogar expectations files
+# $7 : The Android.mk corresponding to the test package (required for host-side tests only)
 define generate-core-test-description
 @echo "Generate core-test description ("$(notdir $(1))")"
 $(hide) java -Xmx256M \
-	-Xbootclasspath/a:$(PRIVATE_CLASSPATH) \
-	-classpath $(PRIVATE_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_OUT_JAVA_LIBRARIES)/junit.jar:$(HOST_JDK_TOOLS_JAR) \
-	$(PRIVATE_PARAMS) CollectAllTests $(1) $(2) $(3) "$(4)" $(5) $(6)
+	-Xbootclasspath/a:$(PRIVATE_CLASSPATH):$(JUNIT_HOST_JAR) \
+	-classpath $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR) \
+	$(PRIVATE_PARAMS) CollectAllTests $(1) $(2) $(3) "$(4)" $(5) $(6) $(7)
 endef
 
 CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)
 CONSCRYPT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,conscrypt,,COMMON)
 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)
+OKHTTP_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp-nojarjar,,COMMON)
+OKHTTPTESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp-tests-nojarjar,,COMMON)
+OKHTTP_REPACKAGED_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp,,COMMON)
+APACHEHARMONYTESTS_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:$(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
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(CONSCRYPT_INTERMEDIATES)/classes.jar:$(BOUNCYCASTLE_INTERMEDIATES)/classes.jar:$(APACHEXML_INTERMEDIATES)/classes.jar:$(APACHEHARMONYTESTS_INTERMEDIATES)/classes.jar:$(OKHTTP_INTERMEDIATES)/classes.jar:$(OKHTTPTESTS_INTERMEDIATES)/classes.jar:$(OKHTTP_REPACKAGED_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 \
@@ -136,6 +153,7 @@
 	$(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_TESTCASES_OUT)/android.core.tests.libcore.package.okhttp.xml \
 
 $(CTS_CORE_XMLS): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 # Why does this depend on javalib.jar instead of classes.jar?  Because
@@ -143,155 +161,161 @@
 # 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 $(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_CORE_XMLS_DEPS := $(CTS_CORE_CASES) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(JUNIT_HOST_JAR) $(CORE_INTERMEDIATES)/javalib.jar $(BOUNCYCASTLE_INTERMEDIATES)/javalib.jar $(APACHEXML_INTERMEDIATES)/javalib.jar $(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar $(OKHTTP_INTERMEDIATES)/javalib.jar $(OKHTTPTESTS_INTERMEDIATES)/javalib.jar $(OKHTTP_REPACKAGED_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)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik,\
 		cts/tests/core/libcore/dalvik/AndroidManifest.xml,\
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,dalvik,\
-		libcore/expectations)
+		$(TARGET_ARCH),libcore/expectations)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.com.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.com,\
 		cts/tests/core/libcore/com/AndroidManifest.xml,\
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,com,\
-		libcore/expectations)
+		$(TARGET_ARCH),libcore/expectations)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.conscrypt.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.conscrypt,\
 		cts/tests/core/libcore/conscrypt/AndroidManifest.xml,\
 		$(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar,,\
-		libcore/expectations)
+		$(TARGET_ARCH),libcore/expectations)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.sun.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.sun,\
 		cts/tests/core/libcore/sun/AndroidManifest.xml,\
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,sun,\
-		libcore/expectations)
+		$(TARGET_ARCH),libcore/expectations)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tests.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tests,\
 		cts/tests/core/libcore/tests/AndroidManifest.xml,\
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,tests,\
-		libcore/expectations)
+		$(TARGET_ARCH),libcore/expectations)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.org.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.org,\
 		cts/tests/core/libcore/org/AndroidManifest.xml,\
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,org,\
-		libcore/expectations)
+		$(TARGET_ARCH),libcore/expectations)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore,\
 		cts/tests/core/libcore/libcore/AndroidManifest.xml,\
 		$(CORETESTS_INTERMEDIATES)/javalib.jar,libcore,\
-		libcore/expectations)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(TARGET_ARCH),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)
+		$(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.beans,\
+		$(TARGET_ARCH),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)
-
+		$(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.logging,\
+		$(TARGET_ARCH),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)
+		$(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.prefs,\
+		$(TARGET_ARCH),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)
+		$(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.sql,\
+		$(TARGET_ARCH),libcore/expectations external/apache-harmony/Android.mk)
+
+$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.okhttp.xml: $(CTS_CORE_XMLS_DEPS)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.okhttp,\
+		cts/tests/core/libcore/okhttp/AndroidManifest.xml,\
+		$(OKHTTPTESTS_INTERMEDIATES)/javalib.jar,,\
+		$(TARGET_ARCH),libcore/expectations)
 
 # ----- Generate the test descriptions for the vm-tests-tf -----
 #
@@ -301,15 +325,16 @@
 CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)
 JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
 
-GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(VMTESTSTF_JAR):$(DDMLIB_JAR):$(TF_JAR)
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(VMTESTSTF_JAR):$(TF_JAR)
 
 $(CORE_VM_TEST_TF_DESC): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 # Please see big comment above on why this line depends on javalib.jar instead of classes.jar
-$(CORE_VM_TEST_TF_DESC): $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(HOST_OUT_JAVA_LIBRARIES)/junit.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(VMTESTSTF_JAR) $(DDMLIB_JAR) | $(ACP)
+$(CORE_VM_TEST_TF_DESC): $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(JUNIT_HOST_JAR) $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(VMTESTSTF_JAR) | $(ACP)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.vm-tests-tf,\
 		cts/tests/vm-tests-tf/AndroidManifest.xml,\
 		$(VMTESTSTF_JAR),"",\
+		$(TARGET_ARCH),\
 		libcore/expectations,\
 		cts/tools/vm-tests-tf/Android.mk)
 
@@ -339,15 +364,16 @@
 cts: $(INTERNAL_CTS_TARGET) adb
 $(call dist-for-goals,cts,$(INTERNAL_CTS_TARGET))
 
-define copy-testcase-apk
-
-$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(1))/package.apk \
-	$(PRIVATE_DIR)/repository/testcases/$(1).apk
-
-endef
 
 define copy-testcase
 
 $(hide) $(ACP) -fp $(1) $(PRIVATE_DIR)/repository/testcases/$(notdir $1)
 
 endef
+
+define copy-testcase-jar
+
+$(hide) $(ACP) -fp $(call intermediates-dir-for,JAVA_LIBRARIES,$(1))/javalib.jar \
+	$(PRIVATE_DIR)/repository/testcases/$(1).jar
+
+endef
diff --git a/core/tasks/factory_bundle.mk b/core/tasks/factory_bundle.mk
deleted file mode 100644
index 054a52a..0000000
--- a/core/tasks/factory_bundle.mk
+++ /dev/null
@@ -1,85 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifeq (,$(ONE_SHOT_MAKEFILE))
-ifneq ($(TARGET_BUILD_PDK),true)
-  TARGET_BUILD_FACTORY=true
-endif
-ifeq ($(TARGET_BUILD_FACTORY),true)
-
-# PRODUCT_FACTORY_RAMDISK_MODULES consists of "<module_name>:<install_path>[:<install_path>...]" tuples.
-# <install_path> is relative to the staging directory for the bundle.
-# 
-# Only host modules can be installed here. 
-# (It's possible to relax this, but it's not needed and kind of tricky.  We'll need to add
-# a better way of specifying the class. Really the answer is to stop having modules with
-# duplicate names)
-#
-# You can also add files with PRODUCT_COPY_FILES if necessary.
-#
-# For example:
-# PRODUCT_FACTORY_BUNDLE_MODULES := \
-#     adb:adb fastboot:fastboot
-requested_modules := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_FACTORY_BUNDLE_MODULES))
-
-root_dir := $(PRODUCT_OUT)/factory_bundle
-leaf := $(strip $(TARGET_PRODUCT))-factory_bundle-$(FILE_NAME_TAG)
-named_dir := $(PRODUCT_OUT)/$(leaf)
-tarball := $(PRODUCT_OUT)/$(leaf).tgz
-
-copied_files := \
-  $(foreach _fb_m, $(requested_modules), $(strip \
-    $(eval _fb_m_tuple := $(subst :, ,$(_fb_m))) \
-    $(eval _fb_m_name := $(word 1,$(_fb_m_tuple))) \
-    $(eval _fb_dests := $(wordlist 2,999,$(_fb_m_tuple))) \
-    $(eval _fb_m_built := $(filter $(HOST_OUT)/%, $(ALL_MODULES.$(_fb_m_name).BUILT))) \
-    $(if $(_fb_m_built),,$(error no built file in requested_modules for '$(_fb_m_built)'))\
-    $(foreach _fb_f,$(_fb_dests),$(eval $(call copy-one-file,$(_fb_m_built),$(root_dir)/$(_fb_f))))\
-    $(addprefix $(root_dir)/,$(_fb_dests)) \
-    )) \
-  $(filter $(root_dir)/%, $(ALL_DEFAULT_INSTALLED_MODULES))
-
-ifneq (,$(strip $(copied_files)))
-
-#
-# These files are made by magic so we need to explicitly include them
-#
-$(eval $(call copy-one-file,$(TARGET_OUT)/build.prop,$(root_dir)/build.prop))
-copied_files += $(root_dir)/build.prop
-
-$(eval $(call copy-one-file,$(PRODUCT_OUT)/factory_ramdisk.img,$(root_dir)/factory_ramdisk.img))
-copied_files += $(root_dir)/factory_ramdisk.img
-#
-# End magic
-#
-
-$(tarball): PRIVATE_ROOT_DIR := $(root_dir)
-$(tarball): PRIVATE_NAMED_DIR := $(named_dir)
-
-$(tarball): $(copied_files)
-	@echo "Tarball: $@"
-	$(hide) rm -rf $(PRIVATE_NAMED_DIR)
-	$(hide) ( cp -r $(PRIVATE_ROOT_DIR) $(PRIVATE_NAMED_DIR) \
-			&& tar cfz $@ -C $(dir $(PRIVATE_NAMED_DIR)) $(notdir $(PRIVATE_NAMED_DIR)) \
-			) && rm -rf $(PRIVATE_NAMED_DIR)
-
-INSTALLED_FACTORY_BUNDLE_TARGET := $(tarball)
-
-endif
-
-endif # TARGET_BUILD_PDK
-endif # ONE_SHOT_MAKEFILE
-
diff --git a/core/tasks/factory_ramdisk.mk b/core/tasks/factory_ramdisk.mk
deleted file mode 100644
index 00fcdde..0000000
--- a/core/tasks/factory_ramdisk.mk
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifeq (,$(ONE_SHOT_MAKEFILE))
-ifneq ($(TARGET_BUILD_PDK),true)
-  TARGET_BUILD_FACTORY=true
-endif
-ifeq ($(TARGET_BUILD_FACTORY),true)
-
-# PRODUCT_FACTORY_RAMDISK_MODULES consists of "<module_name>:<install_path>[:<install_path>...]" tuples.
-# <install_path> is relative to TARGET_FACTORY_RAMDISK_OUT.
-# We can have multiple <install_path>s because multiple modules may have the same name.
-# For example:
-# PRODUCT_FACTORY_RAMDISK_MODULES := \
-#     toolbox:system/bin/toolbox adbd:sbin/adbd adb:system/bin/adb
-factory_ramdisk_modules := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_FACTORY_RAMDISK_MODULES))
-ifneq (,$(factory_ramdisk_modules))
-
-# A module name may end up in multiple modules (so multiple built files)
-# with the same name.
-# This function selects the module built file based on the install path.
-# $(1): the dest install path
-# $(2): the module built files
-define install-one-factory-ramdisk-module
-$(eval _iofrm_suffix := $(suffix $(1))) \
-$(if $(_iofrm_suffix), \
-    $(eval _iofrm_pattern := %$(_iofrm_suffix)), \
-    $(eval _iofrm_pattern := %$(notdir $(1)))) \
-$(eval _iofrm_src := $(filter $(_iofrm_pattern),$(2))) \
-$(if $(filter 1,$(words $(_iofrm_src))), \
-    $(eval _fulldest := $(TARGET_FACTORY_RAMDISK_OUT)/$(1)) \
-    $(eval $(call copy-one-file,$(_iofrm_src),$(_fulldest))) \
-    $(eval INTERNAL_FACTORY_RAMDISK_EXTRA_MODULES_FILES += $(_fulldest)), \
-    $(error Error: Cannot find match in "$(2)" for "$(1)") \
-    )
-endef
-
-INTERNAL_FACTORY_RAMDISK_EXTRA_MODULES_FILES :=
-$(foreach m, $(factory_ramdisk_modules), \
-    $(eval _fr_m_tuple := $(subst :, ,$(m))) \
-    $(eval _fr_m_name := $(word 1,$(_fr_m_tuple))) \
-    $(eval _fr_dests := $(wordlist 2,999,$(_fr_m_tuple))) \
-    $(eval _fr_m_built := $(filter $(PRODUCT_OUT)/%, $(ALL_MODULES.$(_fr_m_name).BUILT))) \
-    $(foreach d,$(_fr_dests),$(call install-one-factory-ramdisk-module,$(d),$(_fr_m_built))) \
-    )
-endif
-
-# Files may also be installed via PRODUCT_COPY_FILES, PRODUCT_PACKAGES etc.
-INTERNAL_FACTORY_RAMDISK_FILES := $(filter $(TARGET_FACTORY_RAMDISK_OUT)/%, \
-    $(ALL_DEFAULT_INSTALLED_MODULES))
-
-ifneq (,$(INTERNAL_FACTORY_RAMDISK_EXTRA_MODULES_FILES)$(INTERNAL_FACTORY_RAMDISK_FILES))
-
-# These files are made by magic in build/core/Makefile so we need to explicitly include them
-$(eval $(call copy-one-file,$(TARGET_OUT)/build.prop,$(TARGET_FACTORY_RAMDISK_OUT)/system/build.prop))
-INTERNAL_FACTORY_RAMDISK_FILES += $(TARGET_FACTORY_RAMDISK_OUT)/system/build.prop
-
-BUILT_FACTORY_RAMDISK_FS := $(PRODUCT_OUT)/factory_ramdisk.gz
-BUILT_FACTORY_RAMDISK_TARGET := $(PRODUCT_OUT)/factory_ramdisk.img
-
-INSTALLED_FACTORY_RAMDISK_FS := $(BUILT_FACTORY_RAMDISK_FS)
-$(INSTALLED_FACTORY_RAMDISK_FS) : $(MKBOOTFS) \
-    $(INTERNAL_FACTORY_RAMDISK_EXTRA_MODULES_FILES) $(INTERNAL_FACTORY_RAMDISK_FILES) | $(MINIGZIP)
-	$(call pretty,"Target factory ram disk file system: $@")
-	$(hide) $(MKBOOTFS) $(TARGET_FACTORY_RAMDISK_OUT) | $(MINIGZIP) > $@
-
-TARGET_RAMDISK_KERNEL := $(INSTALLED_KERNEL_TARGET)
-INSTALLED_FACTORY_RAMDISK_TARGET := $(BUILT_FACTORY_RAMDISK_TARGET)
-ifneq (,$(BOARD_KERNEL_CMDLINE_FACTORY_BOOT))
-  RAMDISK_CMDLINE := --cmdline "$(BOARD_KERNEL_CMDLINE_FACTORY_BOOT)"
-else
-  RAMDISK_CMDLINE :=
-endif
-$(INSTALLED_FACTORY_RAMDISK_TARGET) : $(MKBOOTIMG) $(TARGET_RAMDISK_KERNEL) $(INSTALLED_FACTORY_RAMDISK_FS)
-	$(call pretty,"Target factory ram disk img format: $@")
-	$(MKBOOTIMG) --kernel $(TARGET_RAMDISK_KERNEL) --ramdisk $(INSTALLED_FACTORY_RAMDISK_FS) \
-            --base $(BOARD_KERNEL_BASE) $(BOARD_MKBOOTIMG_ARGS) $(RAMDISK_CMDLINE) --output $@
-
-endif
-
-endif # TARGET_BUILD_PDK
-endif # ONE_SHOT_MAKEFILE
diff --git a/core/tasks/oem_image.mk b/core/tasks/oem_image.mk
new file mode 100644
index 0000000..26b9aba
--- /dev/null
+++ b/core/tasks/oem_image.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# We build oem.img only if it's asked for.
+ifneq ($(filter $(MAKECMDGOALS),oem_image),)
+ifndef BOARD_OEMIMAGE_PARTITION_SIZE
+$(error BOARD_OEMIMAGE_PARTITION_SIZE is not set.)
+endif
+
+INTERNAL_OEMIMAGE_FILES := \
+    $(filter $(TARGET_OUT_OEM)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
+
+oemimage_intermediates := \
+    $(call intermediates-dir-for,PACKAGING,oem)
+BUILT_OEMIMAGE_TARGET := $(PRODUCT_OUT)/oem.img
+# We just build this directly to the install location.
+INSTALLED_OEMIMAGE_TARGET := $(BUILT_OEMIMAGE_TARGET)
+
+$(INSTALLED_OEMIMAGE_TARGET) : $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_OEMIMAGE_FILES)
+	$(call pretty,"Target oem fs image: $@")
+	@mkdir -p $(TARGET_OUT_OEM)
+	@mkdir -p $(oemimage_intermediates) && rm -rf $(oemimage_intermediates)/oem_image_info.txt
+	$(call generate-userimage-prop-dictionary, $(oemimage_intermediates)/oem_image_info.txt, skip_fsck=true)
+	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
+	  ./build/tools/releasetools/build_image.py \
+	  $(TARGET_OUT_OEM) $(oemimage_intermediates)/oem_image_info.txt $@
+	$(hide) $(call assert-max-image-size,$@,$(BOARD_OEMIMAGE_PARTITION_SIZE))
+
+.PHONY: oem_image
+oem_image : $(INSTALLED_OEMIMAGE_TARGET)
+$(call dist-for-goals, oem_image, $(INSTALLED_OEMIMAGE_TARGET))
+
+endif  # oem_image in $(MAKECMDGOALS)
diff --git a/core/tasks/product-graph.mk b/core/tasks/product-graph.mk
index fcec277..db2cf71 100644
--- a/core/tasks/product-graph.mk
+++ b/core/tasks/product-graph.mk
@@ -61,7 +61,7 @@
 $(hide) echo \"$(1)\" [ \
 label=\"$(dir $(1))\\n$(notdir $(1))\\n\\n$(subst $(close_parenthesis),,$(subst $(open_parethesis),,$(PRODUCTS.$(strip $(1)).PRODUCT_MODEL)))\\n$(PRODUCTS.$(strip $(1)).PRODUCT_DEVICE)\" \
 $(if $(filter $(1),$(PRIVATE_PRODUCTS_FILTER)), style=\"filled\" fillcolor=\"#FFFDB0\",) \
-fontcolor=\"darkblue\" href=\"products/$(1).html\" \
+colorscheme=\"svg\" fontcolor=\"darkblue\" href=\"products/$(1).html\" \
 ] >> $(2)
 
 endef
@@ -109,7 +109,6 @@
 	$(hide) echo 'PRODUCT_EXTRA_RECOVERY_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_EXTRA_RECOVERY_KEYS)' >> $$@
 	$(hide) echo 'PRODUCT_PACKAGE_OVERLAYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_PACKAGE_OVERLAYS)' >> $$@
 	$(hide) echo 'DEVICE_PACKAGE_OVERLAYS=$$(PRODUCTS.$(strip $(1)).DEVICE_PACKAGE_OVERLAYS)' >> $$@
-	$(hide) echo 'PRODUCT_TAGS=$$(PRODUCTS.$(strip $(1)).PRODUCT_TAGS)' >> $$@
 	$(hide) echo 'PRODUCT_SDK_ADDON_NAME=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_NAME)' >> $$@
 	$(hide) echo 'PRODUCT_SDK_ADDON_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_COPY_FILES)' >> $$@
 	$(hide) echo 'PRODUCT_SDK_ADDON_COPY_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_COPY_MODULES)' >> $$@
@@ -117,7 +116,6 @@
 	$(hide) echo 'PRODUCT_DEFAULT_WIFI_CHANNELS=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_WIFI_CHANNELS)' >> $$@
 	$(hide) echo 'PRODUCT_DEFAULT_DEV_CERTIFICATE=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_DEV_CERTIFICATE)' >> $$@
 	$(hide) echo 'PRODUCT_RESTRICT_VENDOR_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_RESTRICT_VENDOR_FILES)' >> $$@
-	$(hide) echo 'PRODUCT_FACTORY_RAMDISK_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_FACTORY_RAMDISK_MODULES)' >> $$@
 	$(hide) echo 'PRODUCT_VENDOR_KERNEL_HEADERS=$$(PRODUCTS.$(strip $(1)).PRODUCT_VENDOR_KERNEL_HEADERS)' >> $$@
 
 $(call product-debug-filename, $(p)): \
diff --git a/core/tasks/sdk-addon.mk b/core/tasks/sdk-addon.mk
index 5a24a00..5ac9b7d 100644
--- a/core/tasks/sdk-addon.mk
+++ b/core/tasks/sdk-addon.mk
@@ -18,11 +18,12 @@
 addon_name := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_NAME))
 ifneq ($(addon_name),)
 
-addon_dir_leaf := $(addon_name)-$(FILE_NAME_TAG)-$(INTERNAL_SDK_HOST_OS_NAME)
-
-intermediates := $(HOST_OUT_INTERMEDIATES)/SDK_ADDON/$(addon_name)_intermediates
-full_target := $(HOST_OUT_SDK_ADDON)/$(addon_dir_leaf).zip
-staging := $(intermediates)/$(addon_dir_leaf)
+addon_dir_leaf  := $(addon_name)-$(FILE_NAME_TAG)-$(INTERNAL_SDK_HOST_OS_NAME)
+addon_dir_img   := $(addon_dir_leaf)-img
+intermediates   := $(HOST_OUT_INTERMEDIATES)/SDK_ADDON/$(addon_name)_intermediates
+full_target     := $(HOST_OUT_SDK_ADDON)/$(addon_dir_leaf).zip
+full_target_img := $(HOST_OUT_SDK_ADDON)/$(addon_dir_img).zip
+staging         := $(intermediates)
 
 sdk_addon_deps :=
 files_to_copy :=
@@ -46,29 +47,54 @@
   $(eval _src := $(call stub-addon-jar-file,$(_src))) \
   $(if $(_src),,$(eval $(error Unknown or unlinkable module: $(call word-colon,1,$(cf)). Requested by $(INTERNAL_PRODUCT)))) \
   $(eval _dest := $(call word-colon,2,$(cf))) \
-  $(eval files_to_copy += $(_src):$(_dest)) \
+  $(eval files_to_copy += $(addon_dir_leaf):$(_src):$(_dest)) \
  )
 endif
 
 # Files that are copied directly into the sdk-addon
-files_to_copy += $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_COPY_FILES)
+ifneq ($(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_COPY_FILES)),)
+$(foreach cf,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_COPY_FILES), \
+  $(eval _src  := $(call word-colon,1,$(cf))) \
+  $(eval _dest := $(call word-colon,2,$(cf))) \
+  $(if $(findstring images/,$(_dest)), $(eval _root := $(addon_dir_img)), $(eval _root := $(addon_dir_leaf))) \
+  $(eval files_to_copy += $(_root):$(_src):$(_dest)) \
+ )
+endif
 
-# All SDK add-ons have these files
+# Files copied in the system-image directory
 files_to_copy += \
-        $(BUILT_SYSTEMIMAGE):images/$(TARGET_CPU_ABI)/system.img \
-        $(BUILT_USERDATAIMAGE_TARGET):images/$(TARGET_CPU_ABI)/userdata.img \
-        $(BUILT_RAMDISK_TARGET):images/$(TARGET_CPU_ABI)/ramdisk.img \
-        $(PRODUCT_OUT)/system/build.prop:images/$(TARGET_CPU_ABI)/build.prop \
-        $(target_notice_file_txt):images/$(TARGET_CPU_ABI)/NOTICE.txt
+	$(addon_dir_img):$(BUILT_SYSTEMIMAGE):images/$(TARGET_CPU_ABI)/system.img \
+	$(addon_dir_img):$(BUILT_USERDATAIMAGE_TARGET):images/$(TARGET_CPU_ABI)/userdata.img \
+	$(addon_dir_img):$(BUILT_RAMDISK_TARGET):images/$(TARGET_CPU_ABI)/ramdisk.img \
+	$(addon_dir_img):$(PRODUCT_OUT)/system/build.prop:images/$(TARGET_CPU_ABI)/build.prop \
+	$(addon_dir_img):$(target_notice_file_txt):images/$(TARGET_CPU_ABI)/NOTICE.txt \
+	$(addon_dir_img):$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_SYS_IMG_SOURCE_PROP):images/source.properties
 
 # Generate rules to copy the requested files
 $(foreach cf,$(files_to_copy), \
-  $(eval _src := $(call word-colon,1,$(cf))) \
-  $(eval _dest := $(call append-path,$(staging),$(call word-colon,2,$(cf)))) \
+  $(eval _root := $(call word-colon,1,$(cf))) \
+  $(eval _src  := $(call word-colon,2,$(cf))) \
+  $(eval _dest := $(call append-path,$(call append-path,$(staging),$(_root)),$(call word-colon,3,$(cf)))) \
   $(eval $(call copy-one-file,$(_src),$(_dest))) \
   $(eval sdk_addon_deps += $(_dest)) \
  )
 
+# The system-image source.properties is a template that we directly expand in-place
+addon_img_source_prop := $(call append-path,$(staging),$(addon_dir_img))/images/$(TARGET_CPU_ABI)/source.properties
+sdk_addon_deps += $(addon_img_source_prop)
+
+$(addon_img_source_prop): $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SDK_ADDON_SYS_IMG_SOURCE_PROP)
+	@echo Generate $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) sed \
+		-e 's/$${PLATFORM_VERSION}/$(PLATFORM_VERSION)/' \
+		-e 's/$${PLATFORM_SDK_VERSION}/$(PLATFORM_SDK_VERSION)/' \
+		-e 's/$${PLATFORM_VERSION_CODENAME}/$(subst REL,,$(PLATFORM_VERSION_CODENAME))/' \
+		-e 's/$${TARGET_ARCH}/$(TARGET_ARCH)/' \
+		-e 's/$${TARGET_CPU_ABI}/$(TARGET_CPU_ABI)/' \
+		$< > $@ && sed -i -e '/^AndroidVersion.CodeName=\s*$$/d' $@
+
+
 # We don't know about all of the docs files, so depend on the timestamps for
 # them, and record the directories, and the packaging rule will just copy the
 # whole thing.
@@ -76,7 +102,7 @@
 sdk_addon_deps += $(foreach dm, $(doc_modules), $(call doc-timestamp-for, $(dm)))
 $(full_target): PRIVATE_DOCS_DIRS := $(addprefix $(OUT_DOCS)/, $(doc_modules))
 
-$(full_target): PRIVATE_STAGING_DIR := $(staging)
+$(full_target): PRIVATE_STAGING_DIR := $(call append-path,$(staging),$(addon_dir_leaf))
 
 $(full_target): $(sdk_addon_deps) | $(ACP)
 	@echo Packaging SDK Addon: $@
@@ -85,16 +111,24 @@
 	    $(ACP) -r $$d $(PRIVATE_STAGING_DIR)/docs ;\
 	  done
 	$(hide) mkdir -p $(dir $@)
-	$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rq $$F * )
+	$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rq $$F $(notdir $(PRIVATE_STAGING_DIR)) )
+
+$(full_target_img): PRIVATE_STAGING_DIR := $(call append-path,$(staging),$(addon_dir_img))/images/$(TARGET_CPU_ABI)
+$(full_target_img): $(full_target) $(addon_img_source_prop)
+	@echo Packaging SDK Addon System-Image: $@
+	$(hide) mkdir -p $(dir $@)
+	$(hide) ( F=$$(pwd)/$@ ; cd $(PRIVATE_STAGING_DIR)/.. && zip -rq $$F $(notdir $(PRIVATE_STAGING_DIR)) )
+
 
 .PHONY: sdk_addon
-sdk_addon: $(full_target)
+sdk_addon: $(full_target) $(full_target_img)
 
 ifneq ($(sdk_repo_goal),)
 # If we're building the sdk_repo, keep the name of the addon zip
 # around so that development/build/tools/sdk_repo.mk can dist it
 # at the appropriate location.
-ADDON_SDK_ZIP := $(full_target)
+ADDON_SDK_ZIP        := $(full_target)
+ADDON_SDK_IMG_ZIP    := $(full_target_img)
 else
 # When not building an sdk_repo, just dist the addon zip file
 # as-is.
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index f7e04ed..bd9cf57 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -37,16 +37,26 @@
       $(eval my_copy_pairs += $(bui):$(my_staging_dir)/$(my_copy_dest)))\
   ))
 
+define copy-tests-in-batch
+$(hide) $(foreach p, $(1),\
+  $(eval pair := $(subst :,$(space),$(p)))\
+  mkdir -p $(dir $(word 2,$(pair)));\
+  cp -rf $(word 1,$(pair)) $(word 2,$(pair));)
+endef
+
 my_package_zip := $(my_staging_dir)/$(my_package_name).zip
 $(my_package_zip): PRIVATE_COPY_PAIRS := $(my_copy_pairs)
 $(my_package_zip): PRIVATE_PICKUP_FILES := $(my_pickup_files)
 $(my_package_zip) : $(my_built_modules)
 	@echo "Package $@"
 	@rm -rf $(dir $@) && mkdir -p $(dir $@)
-	$(hide) $(foreach p, $(PRIVATE_COPY_PAIRS), \
-	  $(eval pair := $(subst :,$(space),$(p)))\
-	  mkdir -p $(dir $(word 2,$(pair))); \
-	  cp -rf $(word 1,$(pair)) $(word 2,$(pair));)
-	$(hide) $(foreach f, $(PRIVATE_PICKUP_FILES), \
+	$(call copy-tests-in-batch,$(wordlist 1,200,$(PRIVATE_COPY_PAIRS)))
+	$(call copy-tests-in-batch,$(wordlist 201,400,$(PRIVATE_COPY_PAIRS)))
+	$(call copy-tests-in-batch,$(wordlist 401,600,$(PRIVATE_COPY_PAIRS)))
+	$(call copy-tests-in-batch,$(wordlist 601,800,$(PRIVATE_COPY_PAIRS)))
+	$(call copy-tests-in-batch,$(wordlist 801,1000,$(PRIVATE_COPY_PAIRS)))
+	$(call copy-tests-in-batch,$(wordlist 1001,1200,$(PRIVATE_COPY_PAIRS)))
+	$(call copy-tests-in-batch,$(wordlist 1201,9999,$(PRIVATE_COPY_PAIRS)))
+	$(hide) $(foreach f, $(PRIVATE_PICKUP_FILES),\
 	  cp -rf $(f) $(dir $@);)
 	$(hide) cd $(dir $@) && zip -rq $(notdir $@) *
diff --git a/core/tasks/vendor_module_check.mk b/core/tasks/vendor_module_check.mk
index 87d723c..d8e8ec7 100644
--- a/core/tasks/vendor_module_check.mk
+++ b/core/tasks/vendor_module_check.mk
@@ -18,19 +18,27 @@
 _vendor_owner_whitelist := \
         asus \
         audience \
+        atmel \
         broadcom \
         csr \
         elan \
         google \
+        htc \
         imgtec \
         invensense \
         intel \
         lge \
+        moto \
+        mtk \
         nvidia \
         nxp \
+        nxpsw \
         qcom \
+        qti \
         samsung \
         samsung_arm \
+        sony \
+        synaptics \
         ti \
         trusted_logic \
         widevine
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 32979af..f3b2297 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.43.43.43
+  PLATFORM_VERSION := 5.1.51
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -53,13 +53,18 @@
   # intermediate builds).  During development, this number remains at the
   # SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
   # the code-name of the new development work.
-  PLATFORM_SDK_VERSION := 19
+  PLATFORM_SDK_VERSION := 22
 endif
 
 ifeq "" "$(PLATFORM_VERSION_CODENAME)"
   # This is the current development code-name, if the build is not a final
   # release build.  If this is a final release build, it is simply "REL".
-  PLATFORM_VERSION_CODENAME := AOSP
+  PLATFORM_VERSION_CODENAME := REL
+
+  # This is all of the development codenames that are active.  Should be either
+  # the same as PLATFORM_VERSION_CODENAME or a comma-separated list of additional
+  # codenames after PLATFORM_VERSION_CODENAME.
+  PLATFORM_VERSION_ALL_CODENAMES := $(PLATFORM_VERSION_CODENAME)
 endif
 
 ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
diff --git a/envsetup.sh b/envsetup.sh
index 34b52e5..f93c07d 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -2,7 +2,7 @@
 cat <<EOF
 Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
 - lunch:   lunch <product_name>-<build_variant>
-- tapas:   tapas [<App1> <App2> ...] [arm|x86|mips|armv5] [eng|userdebug|user]
+- tapas:   tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
 - croot:   Changes directory to the top of the tree.
 - m:       Makes from the top of the tree.
 - mm:      Builds all of the modules in the current directory, but not their dependencies.
@@ -11,16 +11,25 @@
 - mma:     Builds all of the modules in the current directory, and their dependencies.
 - mmma:    Builds all of the modules in the supplied directories, and their dependencies.
 - cgrep:   Greps on all local C/C++ files.
+- ggrep:   Greps on all local Gradle files.
 - jgrep:   Greps on all local Java files.
 - resgrep: Greps on all local res/*.xml files.
+- mangrep: Greps on all local AndroidManifest.xml files.
+- sepgrep: Greps on all local sepolicy files.
+- sgrep:   Greps on all local source files.
 - godir:   Go to the directory containing a file.
 
+Environemnt options:
+- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
+                 ASAN_OPTIONS=detect_leaks=0 will be set by default until the
+                 build is leak-check clean.
+
 Look at the source to view more functions. The complete list is:
 EOF
     T=$(gettop)
     local A
     A=""
-    for i in `cat $T/build/envsetup.sh | sed -n "/^function /s/function \([a-z_]*\).*/\1/p" | sort`; do
+    for i in `cat $T/build/envsetup.sh | sed -n "/^[ \t]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
       A="$A $i"
     done
     echo $A
@@ -35,7 +44,7 @@
         return
     fi
     (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
-      make --no-print-directory -f build/core/config.mk dumpvar-abs-$1)
+      command make --no-print-directory -f build/core/config.mk dumpvar-abs-$1)
 }
 
 # Get the exact value of a build variable.
@@ -47,7 +56,7 @@
         return
     fi
     (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
-      make --no-print-directory -f build/core/config.mk dumpvar-$1)
+      command make --no-print-directory -f build/core/config.mk dumpvar-$1)
 }
 
 # check to see if the supplied product is one we can build
@@ -136,9 +145,7 @@
         arm64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin;
                toolchaindir2=arm/arm-linux-androideabi-$targetgccversion2/bin
             ;;
-        mips) toolchaindir=mips/mipsel-linux-android-$targetgccversion/bin
-            ;;
-        mips64) toolchaindir=mips/mips64el-linux-android-$targetgccversion/bin
+        mips|mips64) toolchaindir=mips/mips64el-linux-android-$targetgccversion/bin
             ;;
         *)
             echo "Can't find toolchain for unknown architecture: $ARCH"
@@ -231,6 +238,7 @@
     export ANDROID_BUILD_TOP=$(gettop)
     # With this environment variable new GCC can apply colors to warnings/errors
     export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
+    export ASAN_OPTIONS=detect_leaks=0
 }
 
 function set_sequence_number()
@@ -458,7 +466,6 @@
 add_lunch_combo aosp_mips64-eng
 add_lunch_combo aosp_x86-eng
 add_lunch_combo aosp_x86_64-eng
-add_lunch_combo vbox_x86-eng
 
 function print_lunch_menu()
 {
@@ -566,12 +573,13 @@
 complete -F _lunch lunch
 
 # Configures the build to build unbundled apps.
-# Run tapas with one ore more app names (from LOCAL_PACKAGE_NAME)
+# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
 function tapas()
 {
-    local arch=$(echo -n $(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5)$'))
-    local variant=$(echo -n $(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$'))
-    local apps=$(echo -n $(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5)$'))
+    local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)"
+    local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
+    local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
+    local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5|arm64|x86_64|mips64|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
 
     if [ $(echo $arch | wc -w) -gt 1 ]; then
         echo "tapas: Error: Multiple build archs supplied: $arch"
@@ -581,12 +589,19 @@
         echo "tapas: Error: Multiple build variants supplied: $variant"
         return
     fi
+    if [ $(echo $density | wc -w) -gt 1 ]; then
+        echo "tapas: Error: Multiple densities supplied: $density"
+        return
+    fi
 
     local product=full
     case $arch in
-      x86)   product=full_x86;;
-      mips)  product=full_mips;;
-      armv5) product=generic_armv5;;
+      x86)    product=full_x86;;
+      mips)   product=full_mips;;
+      armv5)  product=generic_armv5;;
+      arm64)  product=aosp_arm64;;
+      x86_64) product=aosp_x86_64;;
+      mips64)  product=aosp_mips64;;
     esac
     if [ -z "$variant" ]; then
         variant=eng
@@ -594,9 +609,13 @@
     if [ -z "$apps" ]; then
         apps=all
     fi
+    if [ -z "$density" ]; then
+        density=alldpi
+    fi
 
     export TARGET_PRODUCT=$product
     export TARGET_BUILD_VARIANT=$variant
+    export TARGET_BUILD_DENSITY=$density
     export TARGET_BUILD_TYPE=release
     export TARGET_BUILD_APPS=$apps
 
@@ -608,7 +627,8 @@
 {
     local TOPFILE=build/core/envsetup.mk
     if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
-        echo $TOP
+        # The following circumlocution ensures we remove symlinks from TOP.
+        (cd $TOP; PWD= /bin/pwd)
     else
         if [ -f $TOPFILE ] ; then
             # The following circumlocution (repeated below as well) ensures
@@ -881,6 +901,85 @@
     fi
 }
 
+# coredump_setup - enable core dumps globally for any process
+#                  that has the core-file-size limit set correctly
+#
+# NOTE: You must call also coredump_enable for a specific process
+#       if its core-file-size limit is not set already.
+# NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
+
+function coredump_setup()
+{
+	echo "Getting root...";
+	adb root;
+	adb wait-for-device;
+
+	echo "Remounting root parition read-write...";
+	adb shell mount -w -o remount -t rootfs rootfs;
+	sleep 1;
+	adb wait-for-device;
+	adb shell mkdir -p /cores;
+	adb shell mount -t tmpfs tmpfs /cores;
+	adb shell chmod 0777 /cores;
+
+	echo "Granting SELinux permission to dump in /cores...";
+	adb shell restorecon -R /cores;
+
+	echo "Set core pattern.";
+	adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
+
+	echo "Done."
+}
+
+# coredump_enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must have been called as well for a core
+#       dump to actually be generated.
+
+function coredump_enable()
+{
+	local PID=$1;
+	if [ -z "$PID" ]; then
+		printf "Expecting a PID!\n";
+		return;
+	fi;
+	echo "Setting core limit for $PID to infinite...";
+	adb shell prlimit $PID 4 -1 -1
+}
+
+# core - send SIGV and pull the core for process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump_setup must be called once per boot for core dumps to be
+#       enabled globally.
+
+function core()
+{
+	local PID=$1;
+
+	if [ -z "$PID" ]; then
+		printf "Expecting a PID!\n";
+		return;
+	fi;
+
+	local CORENAME=core.$PID;
+	local COREPATH=/cores/$CORENAME;
+	local SIG=SEGV;
+
+	coredump_enable $1;
+
+	local done=0;
+	while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
+		printf "\tSending SIG%s to %d...\n" $SIG $PID;
+		adb shell kill -$SIG $PID;
+		sleep 1;
+	done;
+
+	adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
+	echo "Done: core is under $COREPATH on device.";
+}
+
 # systemstack - dump the current stack trace of all threads in the system process
 # to the usual ANR traces file
 function systemstack()
@@ -936,18 +1035,6 @@
     fi
 }
 
-function gdbwrapper()
-{
-    local GDB_CMD="$1"
-    shift 1
-    $GDB_CMD -x "$@"
-}
-
-function get_symbols_directory()
-{
-    echo $(get_abs_build_var TARGET_OUT_UNSTRIPPED)
-}
-
 # Read the ELF header from /proc/$PID/exe to determine if the process is
 # 64-bit.
 function is64bit()
@@ -964,118 +1051,18 @@
     fi
 }
 
-# gdbclient now determines whether the user wants to debug a 32-bit or 64-bit
-# executable, set up the approriate gdbserver, then invokes the proper host
-# gdb.
-function gdbclient()
-{
-   local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT)
-   local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED)
-   local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)
-   local OUT_VENDOR_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_VENDOR_SHARED_LIBRARIES_UNSTRIPPED)
-   local OUT_EXE_SYMBOLS=$(get_symbols_directory)
-   local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS)
-   local ARCH=$(get_build_var TARGET_ARCH)
-   local GDB
-   case "$ARCH" in
-       arm) GDB=arm-linux-androideabi-gdb;;
-       arm64) GDB=arm-linux-androideabi-gdb; GDB64=aarch64-linux-android-gdb;;
-       mips) GDB=mipsel-linux-android-gdb;;
-       mips64) GDB=mipsel-linux-android-gdb;;
-       x86) GDB=x86_64-linux-android-gdb;;
-       x86_64) GDB=x86_64-linux-android-gdb;;
-       *) echo "Unknown arch $ARCH"; return 1;;
-   esac
-
-   if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then
-       local EXE="$1"
-       if [ "$EXE" ] ; then
-           EXE=$1
-           if [[ $EXE =~ ^[^/].* ]] ; then
-               EXE="system/bin/"$EXE
-           fi
-       else
-           EXE="app_process"
-       fi
-
-       local PORT="$2"
-       if [ "$PORT" ] ; then
-           PORT=$2
-       else
-           PORT=":5039"
-       fi
-
-       local PID="$3"
-       if [ "$PID" ] ; then
-           if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then
-               PID=`pid $3`
-               if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then
-                   # that likely didn't work because of returning multiple processes
-                   # try again, filtering by root processes (don't contain colon)
-                   PID=`adb shell ps | \grep $3 | \grep -v ":" | awk '{print $2}'`
-                   if [[ ! "$PID" =~ ^[0-9]+$ ]]
-                   then
-                       echo "Couldn't resolve '$3' to single PID"
-                       return 1
-                   else
-                       echo ""
-                       echo "WARNING: multiple processes matching '$3' observed, using root process"
-                       echo ""
-                   fi
-               fi
-           fi
-           adb forward "tcp$PORT" "tcp$PORT"
-           local USE64BIT="$(is64bit $PID)"
-           adb shell gdbserver$USE64BIT $PORT --attach $PID &
-           sleep 2
-       else
-               echo ""
-               echo "If you haven't done so already, do this first on the device:"
-               echo "    gdbserver $PORT /system/bin/$EXE"
-                   echo " or"
-               echo "    gdbserver $PORT --attach <PID>"
-               echo ""
-       fi
-
-       OUT_SO_SYMBOLS=$OUT_SO_SYMBOLS$USE64BIT
-
-       echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS"
-       echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx:$OUT_VENDOR_SO_SYMBOLS:$OUT_VENDOR_SO_SYMBOLS/hw:$OUT_VENDOR_SO_SYMBOLS/egl"
-       echo >>"$OUT_ROOT/gdbclient.cmds" "source $ANDROID_BUILD_TOP/development/scripts/gdb/dalvik.gdb"
-       echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT"
-       echo >>"$OUT_ROOT/gdbclient.cmds" ""
-
-       local WHICH_GDB=
-       # 64-bit exe found
-       if [ "$USE64BIT" != "" ] ; then
-           WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB64
-       # 32-bit exe / 32-bit platform
-       elif [ "$(get_build_var TARGET_2ND_ARCH)" = "" ]; then
-           WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB
-       # 32-bit exe / 64-bit platform
-       else
-           WHICH_GDB=$ANDROID_TOOLCHAIN_2ND_ARCH/$GDB
-       fi
-
-       gdbwrapper $WHICH_GDB "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE"
-  else
-       echo "Unable to determine build system output dir."
-   fi
-
-}
-
 case `uname -s` in
     Darwin)
         function sgrep()
         {
-            find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cpp|S|java|xml|sh|mk)' -print0 | xargs -0 grep --color -n "$@"
+            find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cc|cpp|S|java|xml|sh|mk|aidl)' -print0 | xargs -0 grep --color -n "$@"
         }
 
         ;;
     *)
         function sgrep()
         {
-            find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\|sh\|mk\)' -print0 | xargs -0 grep --color -n "$@"
+            find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cc\|cpp\|S\|java\|xml\|sh\|mk\|aidl\)' -print0 | xargs -0 grep --color -n "$@"
         }
         ;;
 esac
@@ -1085,6 +1072,11 @@
     get_build_var TARGET_ARCH
 }
 
+function ggrep()
+{
+    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" -print0 | xargs -0 grep --color -n "$@"
+}
+
 function jgrep()
 {
     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" -print0 | xargs -0 grep --color -n "$@"
@@ -1092,7 +1084,7 @@
 
 function cgrep()
 {
-    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' \) -print0 | xargs -0 grep --color -n "$@"
+    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -print0 | xargs -0 grep --color -n "$@"
 }
 
 function resgrep()
@@ -1220,9 +1212,7 @@
     fi
 
     # issue "am" command to cause the hprof dump
-    local sdcard=$(adb ${adbOptions} shell echo -n '$EXTERNAL_STORAGE')
-    local devFile=$sdcard/hprof-$targetPid
-    #local devFile=/data/local/hprof-$targetPid
+    local devFile=/data/local/tmp/hprof-$targetPid
     echo "Poking $targetPid and waiting for data..."
     echo "Storing data at $devFile"
     adb ${adbOptions} shell am dumpheap $targetPid $devFile
@@ -1392,7 +1382,7 @@
     \cd $T/$pathname
 }
 
-# Force JAVA_HOME to point to java 1.7 or java 1.6  if it isn't already set.
+# Force JAVA_HOME to point to java 1.7 if it isn't already set.
 #
 # Note that the MacOS path for java 1.7 includes a minor revision number (sigh).
 # For some reason, installing the JDK doesn't make it show up in the
@@ -1409,25 +1399,14 @@
     fi
 
     if [ ! "$JAVA_HOME" ]; then
-      if [ -n "$LEGACY_USE_JAVA6" ]; then
-        case `uname -s` in
-            Darwin)
-                export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
-                ;;
-            *)
-                export JAVA_HOME=/usr/lib/jvm/java-6-sun
-                ;;
-        esac
-      else
-        case `uname -s` in
-            Darwin)
-                export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
-                ;;
-            *)
-                export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
-                ;;
-        esac
-      fi
+      case `uname -s` in
+          Darwin)
+              export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
+              ;;
+          *)
+              export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
+              ;;
+      esac
 
       # Keep track of the fact that we set JAVA_HOME ourselves, so that
       # we can change it on the next envsetup.sh, if required.
@@ -1448,6 +1427,49 @@
     return $retval
 }
 
+function get_make_command()
+{
+  echo command make
+}
+
+function make()
+{
+    local start_time=$(date +"%s")
+    $(get_make_command) "$@"
+    local ret=$?
+    local end_time=$(date +"%s")
+    local tdiff=$(($end_time-$start_time))
+    local hours=$(($tdiff / 3600 ))
+    local mins=$((($tdiff % 3600) / 60))
+    local secs=$(($tdiff % 60))
+    local ncolors=$(tput colors 2>/dev/null)
+    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
+        color_failed="\e[0;31m"
+        color_success="\e[0;32m"
+        color_reset="\e[00m"
+    else
+        color_failed=""
+        color_success=""
+        color_reset=""
+    fi
+    echo
+    if [ $ret -eq 0 ] ; then
+        echo -n -e "${color_success}#### make completed successfully "
+    else
+        echo -n -e "${color_failed}#### make failed to build some targets "
+    fi
+    if [ $hours -gt 0 ] ; then
+        printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
+    elif [ $mins -gt 0 ] ; then
+        printf "(%02g:%02g (mm:ss))" $mins $secs
+    elif [ $secs -gt 0 ] ; then
+        printf "(%s seconds)" $secs
+    fi
+    echo -e " ####${color_reset}"
+    echo
+    return $ret
+}
+
 if [ "x$SHELL" != "x/bin/bash" ]; then
     case `ps -o command -p $$` in
         *bash*)
@@ -1459,8 +1481,8 @@
 fi
 
 # Execute the contents of any vendorsetup.sh files we can find.
-for f in `test -d device && find device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
-         `test -d vendor && find vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null`
+for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
+         `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null`
 do
     echo "including $f"
     . $f
diff --git a/libs/host/Android.mk b/libs/host/Android.mk
index c67afbb..cab878b 100644
--- a/libs/host/Android.mk
+++ b/libs/host/Android.mk
@@ -1,5 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_SRC_FILES:= \
     CopyFile.c
@@ -20,6 +21,8 @@
 # acp to install libhost.
 LOCAL_ACP_UNAVAILABLE:= true
 
+LOCAL_ADDRESS_SANITIZER := false
+
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 # Include toolchain prebuilt modules if they exist.
diff --git a/libs/host/CopyFile.c b/libs/host/CopyFile.c
index ca52565..855a565 100644
--- a/libs/host/CopyFile.c
+++ b/libs/host/CopyFile.c
@@ -28,8 +28,9 @@
 #  define  mkdir(path,mode)   _mkdir(path)
 #endif
 
-#ifndef HAVE_SYMLINKS
-#  define  lstat              stat
+#if defined(_WIN32)
+#  define S_ISLNK(s) 0
+#  define lstat stat
 #  ifndef EACCESS   /* seems to be missing from the Mingw headers */
 #    define  EACCESS            13
 #  endif
@@ -68,15 +69,13 @@
  */
 static bool isHiresMtime(const struct stat* pSrcStat)
 {
-#if HAVE_STAT_ST_MTIM
-#if defined(MACOSX_RSRC)
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+  return 0;
+#elif defined(MACOSX_RSRC)
     return pSrcStat->st_mtimespec.tv_nsec > 0;
 #else
     return pSrcStat->st_mtim.tv_nsec > 0;
 #endif
-#else
-    return 0;
-#endif
 }
 
 /*
@@ -339,7 +338,6 @@
 }
 
 
-#ifdef HAVE_SYMLINKS
 /*
  * Copy a symlink.  This only happens if we're in "no derefence" mode,
  * in which we copy the links rather than the files that are pointed at.
@@ -348,6 +346,9 @@
  * we want to throw it out and replace it.  If it's not a symlink, we
  * need to trash it so we can create one.
  */
+#if defined(_WIN32)
+extern int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options) __attribute__((error("no symlinks on Windows")));
+#else
 static int copySymlink(const char* src, const char* dst, const struct stat* pSrcStat, unsigned int options)
 {
     struct stat dstStat;
@@ -422,7 +423,7 @@
 
     return 0;
 }
-#endif /* HAVE_SYMLINKS */
+#endif
 
 /*
  * Copy the contents of one directory to another.  Both "src" and "dst"
@@ -618,10 +619,8 @@
         } else {
             retVal = copyDirectory(src, dst, &srcStat, options);
         }
-#ifdef HAVE_SYMLINKS
     } else if (S_ISLNK(srcStat.st_mode)) {
         retVal = copySymlink(src, dst, &srcStat, options);
-#endif		
     } else if (S_ISREG(srcStat.st_mode)) {
         retVal = copyRegular(src, dst, &srcStat, options);
     } else {
diff --git a/libs/host/list.java b/libs/host/list.java
deleted file mode 100644
index 30546e3..0000000
--- a/libs/host/list.java
+++ /dev/null
@@ -1,35 +0,0 @@
-import java.io.*;
-
-public class list {
-    private static char nibble(int c) {
-        return (char)(c < 10 ? ('0' + c) : ('a' + (c-10)));
-    }
-    public static void main(String[] argv)
-    {
-        ByteArrayOutputStream stream = new ByteArrayOutputStream(100);
-        OutputStreamWriter writer = null;
-        try {
-            writer = new OutputStreamWriter(stream, "utf-8");
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace(System.err);
-        }
-
-        int n = Integer.parseInt(argv[1], 16);
-        try {
-            writer.write(n);
-            writer.close();
-        } catch (IOException e) {
-            e.printStackTrace(System.err);
-        }
-
-        byte[] array = stream.toByteArray();
-
-        System.out.print("        case '" + argv[0] + "':   return \"");
-        for (int i=0; i<array.length; i++) {
-            int b = array[i];
-            System.out.print("\\x" + nibble((b >> 4) & 0x0f) + nibble(b & 0xf));
-        }
-        System.out.println("\";");
-    }
-}
-
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 62303d6..e06c985 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -82,8 +82,18 @@
         domain.te \
         file.te \
         file_contexts \
+        goldfish_setup.te \
+        goldfish_logcat.te \
+        property.te \
+        property_contexts \
+        qemu_props.te \
         qemud.te \
         rild.te \
         shell.te \
         surfaceflinger.te \
         system_server.te
+
+ifeq ($(TARGET_PRODUCT),sdk)
+  # include an expanded selection of fonts for the SDK.
+  EXTENDED_FONT_FOOTPRINT := true
+endif
diff --git a/target/board/generic/device.mk b/target/board/generic/device.mk
index fe64bcb..e56a4d1 100644
--- a/target/board/generic/device.mk
+++ b/target/board/generic/device.mk
@@ -25,10 +25,8 @@
 PRODUCT_COPY_FILES := \
     device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
     hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
-
-PRODUCT_PACKAGES := \
-    audio.primary.goldfish \
-    power.goldfish \
-    vibrator.goldfish
diff --git a/target/board/generic/sepolicy/device.te b/target/board/generic/sepolicy/device.te
index e4af13c..d129441 100644
--- a/target/board/generic/sepolicy/device.te
+++ b/target/board/generic/sepolicy/device.te
@@ -1 +1 @@
-type qemu_device, dev_type;
+type qemu_device, dev_type, mlstrustedobject;
diff --git a/target/board/generic/sepolicy/file_contexts b/target/board/generic/sepolicy/file_contexts
index f204cde..444a47f 100644
--- a/target/board/generic/sepolicy/file_contexts
+++ b/target/board/generic/sepolicy/file_contexts
@@ -1,4 +1,9 @@
+/dev/block/mtdblock0       u:object_r:system_block_device:s0
+/dev/block/mtdblock1       u:object_r:userdata_block_device:s0
+/dev/block/mtdblock2       u:object_r:cache_block_device:s0
 /dev/qemu_.*		u:object_r:qemu_device:s0
 /dev/socket/qemud	u:object_r:qemud_socket:s0
 /system/bin/qemud	u:object_r:qemud_exec:s0
 /sys/qemu_trace(/.*)?	--	u:object_r:sysfs_writable:s0
+/system/etc/init.goldfish.sh u:object_r:goldfish_setup_exec:s0
+/system/bin/qemu-props	     u:object_r:qemu_props_exec:s0
diff --git a/target/board/generic/sepolicy/goldfish_logcat.te b/target/board/generic/sepolicy/goldfish_logcat.te
new file mode 100644
index 0000000..a785355
--- /dev/null
+++ b/target/board/generic/sepolicy/goldfish_logcat.te
@@ -0,0 +1,10 @@
+# goldfish-logcat service:  runs logcat -Q
+type goldfish_logcat, domain;
+
+domain_auto_trans(init, logcat_exec, goldfish_logcat)
+
+# Read from logd.
+read_logd(goldfish_logcat)
+
+# Write to /dev/ttyS2
+allow goldfish_logcat serial_device:chr_file { write open };
diff --git a/target/board/generic/sepolicy/goldfish_setup.te b/target/board/generic/sepolicy/goldfish_setup.te
new file mode 100644
index 0000000..584731e
--- /dev/null
+++ b/target/board/generic/sepolicy/goldfish_setup.te
@@ -0,0 +1,18 @@
+# goldfish-setup service: runs init.goldfish.sh script
+type goldfish_setup, domain;
+type goldfish_setup_exec, exec_type, file_type;
+
+init_daemon_domain(goldfish_setup)
+
+# Inherit open file to shell (interpreter) for script.
+allow goldfish_setup shell_exec:file read;
+
+# Run ifconfig, route commands to configure interfaces and routes.
+allow goldfish_setup system_file:file execute_no_trans;
+allow goldfish_setup self:capability { net_admin net_raw };
+allow goldfish_setup self:udp_socket create_socket_perms;
+
+# Set net.eth0.dns*, debug.sf.nobootanimation
+unix_socket_connect(goldfish_setup, property, init)
+allow goldfish_setup system_prop:property_service set;
+allow goldfish_setup debug_prop:property_service set;
diff --git a/target/board/generic/sepolicy/property.te b/target/board/generic/sepolicy/property.te
new file mode 100644
index 0000000..b3d15f8
--- /dev/null
+++ b/target/board/generic/sepolicy/property.te
@@ -0,0 +1 @@
+type qemu_prop, property_type;
diff --git a/target/board/generic/sepolicy/property_contexts b/target/board/generic/sepolicy/property_contexts
new file mode 100644
index 0000000..5f741f8
--- /dev/null
+++ b/target/board/generic/sepolicy/property_contexts
@@ -0,0 +1 @@
+qemu.                   u:object_r:qemu_prop:s0
diff --git a/target/board/generic/sepolicy/qemu_props.te b/target/board/generic/sepolicy/qemu_props.te
new file mode 100644
index 0000000..05c7461
--- /dev/null
+++ b/target/board/generic/sepolicy/qemu_props.te
@@ -0,0 +1,9 @@
+# qemu-props service:  Sets system properties on boot.
+type qemu_props, domain;
+type qemu_props_exec, exec_type, file_type;
+
+init_daemon_domain(qemu_props)
+
+# Set properties.
+unix_socket_connect(qemu_props, property, init)
+allow qemu_props { qemu_prop dalvik_prop config_prop }:property_service set;
diff --git a/target/board/generic/sepolicy/qemud.te b/target/board/generic/sepolicy/qemud.te
index 4ff02ec..41f2065 100644
--- a/target/board/generic/sepolicy/qemud.te
+++ b/target/board/generic/sepolicy/qemud.te
@@ -3,4 +3,6 @@
 type qemud_exec, exec_type, file_type;
 
 init_daemon_domain(qemud)
-unconfined_domain(qemud)
+
+# Access /dev/ttyS1.
+allow qemud serial_device:chr_file rw_file_perms;
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 1493bd9..8afd5a8 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -22,11 +22,39 @@
 TARGET_CPU_ABI := arm64-v8a
 
 TARGET_2ND_ARCH := arm
-TARGET_2ND_ARCH_VARIANT := armv7-a-neon
-TARGET_2ND_CPU_VARIANT := cortex-a15
 TARGET_2ND_CPU_ABI := armeabi-v7a
 TARGET_2ND_CPU_ABI2 := armeabi
 
+ifneq ($(TARGET_BUILD_APPS)$(filter cts,$(MAKECMDGOALS)),)
+# DO NOT USE
+# DO NOT USE
+#
+# This architecture / CPU variant must NOT be used for any 64 bit
+# platform builds. It is the lowest common denominator required
+# to build an unbundled application or cts for all supported 32 and 64 bit
+# platforms.
+#
+# If you're building a 64 bit platform (and not an application) the
+# ARM-v8 specification allows you to assume NEON and all the features
+# available in a cortex-A15 CPU. You should be able to set :
+#
+# TARGET_2ND_ARCH_VARIANT := armv7-a-neon
+# TARGET_2ND_CPU_VARIANT := cortex-a15
+#
+# DO NOT USE
+# DO NOT USE
+TARGET_2ND_ARCH_VARIANT := armv7-a
+# DO NOT USE
+# DO NOT USE
+TARGET_2ND_CPU_VARIANT := generic
+# DO NOT USE
+# DO NOT USE
+else
+TARGET_2ND_ARCH_VARIANT := armv7-a-neon
+TARGET_2ND_CPU_VARIANT := cortex-a15
+endif
+
+
 TARGET_USES_64_BIT_BINDER := true
 
 # no hardware camera
@@ -48,10 +76,9 @@
 USE_OPENGL_RENDERER := true
 
 TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 786432000
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 943718400
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
-
diff --git a/target/board/generic_arm64/device.mk b/target/board/generic_arm64/device.mk
index 354fb2a..9647a4e 100644
--- a/target/board/generic_arm64/device.mk
+++ b/target/board/generic_arm64/device.mk
@@ -25,8 +25,11 @@
 PRODUCT_COPY_FILES := \
     device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
 
-PRODUCT_PACKAGES := \
-    audio.primary.goldfish \
-    vibrator.goldfish
+# Adjust the Dalvik heap to be appropriate for a tablet.
+$(call inherit-product-if-exists, frameworks/base/build/tablet-dalvik-heap.mk)
+$(call inherit-product-if-exists, frameworks/native/build/tablet-dalvik-heap.mk)
diff --git a/target/board/generic_armv5/BoardConfig.mk b/target/board/generic_armv5/BoardConfig.mk
index 95fb559..016937a 100644
--- a/target/board/generic_armv5/BoardConfig.mk
+++ b/target/board/generic_armv5/BoardConfig.mk
@@ -19,6 +19,5 @@
 TARGET_ARCH_VARIANT := armv5te
 TARGET_CPU_ABI := armeabi
 TARGET_CPU_ABI2 :=
-ARCH_ARM_HAVE_TLS_REGISTER := false
 
 WITH_DEXPREOPT := false
diff --git a/target/board/generic_mips/BoardConfig.mk b/target/board/generic_mips/BoardConfig.mk
index a319ad7..ff5a4e4 100644
--- a/target/board/generic_mips/BoardConfig.mk
+++ b/target/board/generic_mips/BoardConfig.mk
@@ -28,6 +28,9 @@
 endif
 TARGET_CPU_ABI  := mips
 
+# Make TARGET_CPU_VARIANT the same as TARGET_ARCH_VARIANT
+TARGET_CPU_VARIANT := $(TARGET_ARCH_VARIANT)
+
 HAVE_HTC_AUDIO_DRIVER := true
 BOARD_USES_GENERIC_AUDIO := true
 
@@ -50,7 +53,7 @@
 USE_OPENGL_RENDERER := true
 
 TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 786432000
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 838860800
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
@@ -64,6 +67,11 @@
         domain.te \
         file.te \
         file_contexts \
+        goldfish_setup.te \
+        goldfish_logcat.te \
+        property.te \
+        property_contexts \
+        qemu_props.te \
         qemud.te \
         rild.te \
         shell.te \
diff --git a/target/board/generic_mips/device.mk b/target/board/generic_mips/device.mk
index b182c4c..06a7d8a 100644
--- a/target/board/generic_mips/device.mk
+++ b/target/board/generic_mips/device.mk
@@ -25,11 +25,13 @@
 PRODUCT_COPY_FILES := \
     device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
     hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
 
 PRODUCT_PACKAGES := \
     audio.primary.goldfish \
     power.goldfish \
-    vibrator.goldfish \
-    libffi
+    vibrator.goldfish
diff --git a/target/board/generic_mips64/BoardConfig.mk b/target/board/generic_mips64/BoardConfig.mk
index 7452978..2097635 100644
--- a/target/board/generic_mips64/BoardConfig.mk
+++ b/target/board/generic_mips64/BoardConfig.mk
@@ -24,15 +24,23 @@
 
 TARGET_ARCH := mips64
 ifeq (,$(TARGET_ARCH_VARIANT))
-TARGET_ARCH_VARIANT := mips64r2
+TARGET_ARCH_VARIANT := mips64r6
 endif
 TARGET_CPU_ABI  := mips64
 
 TARGET_2ND_ARCH := mips
 ifeq (,$(TARGET_2ND_ARCH_VARIANT))
+ifeq ($(TARGET_ARCH_VARIANT),mips64r6)
+TARGET_2ND_ARCH_VARIANT :=  mips32r6
+else
 TARGET_2ND_ARCH_VARIANT :=  mips32r2-fp
 endif
-TARGET_CPU_ABI  := mips
+endif
+TARGET_2ND_CPU_ABI  := mips
+
+# Make TARGET_XXX_CPU_VARIANT the same as TARGET_XXX_ARCH_VARIANT
+TARGET_CPU_VARIANT := $(TARGET_ARCH_VARIANT)
+TARGET_2ND_CPU_VARIANT := $(TARGET_2ND_ARCH_VARIANT)
 
 # The emulator (qemu) uses the Goldfish devices
 HAVE_HTC_AUDIO_DRIVER := true
@@ -57,8 +65,8 @@
 USE_OPENGL_RENDERER := true
 
 TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 786432000
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1101004800
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 734003200
 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
diff --git a/target/board/generic_mips64/device.mk b/target/board/generic_mips64/device.mk
index 58fe976..66ec9db 100644
--- a/target/board/generic_mips64/device.mk
+++ b/target/board/generic_mips64/device.mk
@@ -25,10 +25,12 @@
 PRODUCT_COPY_FILES := \
     device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
     hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
 
 PRODUCT_PACKAGES := \
     audio.primary.goldfish \
-    power.goldfish \
-    libffi
+    power.goldfish
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 5d091f5..78b7590 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -53,6 +53,11 @@
         file_contexts \
         healthd.te \
         installd.te \
+        goldfish_setup.te \
+        goldfish_logcat.te \
+        property.te \
+        property_contexts \
+        qemu_props.te \
         qemud.te \
         rild.te \
         shell.te \
diff --git a/target/board/generic_x86/device.mk b/target/board/generic_x86/device.mk
index 089f584..b5b0faf 100644
--- a/target/board/generic_x86/device.mk
+++ b/target/board/generic_x86/device.mk
@@ -25,6 +25,9 @@
 PRODUCT_COPY_FILES := \
     device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
 
 PRODUCT_PACKAGES := \
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index c597f7d..295ee2b 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -41,7 +41,7 @@
 USE_OPENGL_RENDERER := true
 
 TARGET_USERIMAGES_USE_EXT4 := true
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 880803840 # 840M
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1073741824 # 1GB 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
diff --git a/target/board/generic_x86_64/device.mk b/target/board/generic_x86_64/device.mk
index 089f584..b5b0faf 100755
--- a/target/board/generic_x86_64/device.mk
+++ b/target/board/generic_x86_64/device.mk
@@ -25,6 +25,9 @@
 PRODUCT_COPY_FILES := \
     device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+    frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
     device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
 
 PRODUCT_PACKAGES := \
diff --git a/target/board/vbox_x86/AndroidBoard.mk b/target/board/vbox_x86/AndroidBoard.mk
deleted file mode 100644
index 8b13789..0000000
--- a/target/board/vbox_x86/AndroidBoard.mk
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/target/board/vbox_x86/BoardConfig.mk b/target/board/vbox_x86/BoardConfig.mk
deleted file mode 100644
index e5a1d3e..0000000
--- a/target/board/vbox_x86/BoardConfig.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# IA target for VitualBox
-#
-
-TARGET_ARCH=x86
-TARGET_COMPRESS_MODULE_SYMBOLS := false
-TARGET_NO_RECOVERY := true
-TARGET_HARDWARE_3D := false
-BOARD_USES_GENERIC_AUDIO := true
-USE_CAMERA_STUB := true
-TARGET_CPU_ABI := x86
-TARGET_USERIMAGES_USE_EXT4 := true
-TARGET_BOOTIMAGE_USE_EXT2 := true
-BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456
-BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
-
-# For VirtualBox and likely other emulators
-BOARD_INSTALLER_CMDLINE := init=/init console=ttyS0 console=tty0 vga=788 verbose
-BOARD_KERNEL_CMDLINE := init=/init qemu=1 console=tty0 vga=788 verbose androidboot.hardware=vbox_x86 androidboot.console=tty0 android.qemud=tty0
-TARGET_USE_DISKINSTALLER := true
-
-TARGET_DISK_LAYOUT_CONFIG := build/target/board/vbox_x86/disk_layout.conf
-BOARD_BOOTIMAGE_MAX_SIZE := 8388608
-BOARD_SYSLOADER_MAX_SIZE := 7340032
-BOARD_FLASH_BLOCK_SIZE := 512
-# 50M
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 52428800
-# 500M
-BOARD_INSTALLERIMAGE_PARTITION_SIZE := 524288000
-TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
-# Reserve 265M  for the system partition
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 268435456
-
-WITH_DEXPREOPT := false
-
-# The eth0 device should be started with dhcp on boot.
-# Useful for emulators that don't provide a wifi connection.
-NET_ETH0_STARTONBOOT := true
-
-ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.heapsize=32m
diff --git a/target/board/vbox_x86/README.txt b/target/board/vbox_x86/README.txt
deleted file mode 100644
index 568dc5f..0000000
--- a/target/board/vbox_x86/README.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-The "vbox_x86" product defines a non-hardware-specific target intended
-to run on the VirtualBox emulator.
-
-Most of the Android devices (networking, phones, sound, etc) do not work.
-
-ADB via ethernet works with this target. You can use 'adb install' to
-test applications that do not require network, phone or sound support.
-This emulation is useful because VirtualBox runs much faster then does the
-QEMU emulators (at least until a KVM enabled QEMU emulator is available).
diff --git a/target/board/vbox_x86/device.mk b/target/board/vbox_x86/device.mk
deleted file mode 100644
index a44a87f..0000000
--- a/target/board/vbox_x86/device.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2009 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 build configuration for the product aspects that
-# are specific to the emulator.
-
-LOCAL_PATH := $(call my-dir)
-
-PRODUCT_PROPERTY_OVERRIDES := \
-    ro.ril.hsxpa=1 \
-    ro.ril.gprsclass=10 \
-    ro.adb.qemud=1
-
-LOCAL_KERNEL := prebuilts/qemu-kernel/x86/kernel-vbox
-
-PRODUCT_COPY_FILES := \
-    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
-    device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
-    device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
-    build/target/board/vbox_x86/init.vbox_x86.rc:root/init.vbox_x86.rc \
-    $(LOCAL_KERNEL):kernel
-
-$(call inherit-product, frameworks/native/build/phone-xhdpi-1024-dalvik-heap.mk)
diff --git a/target/board/vbox_x86/disk_layout.conf b/target/board/vbox_x86/disk_layout.conf
deleted file mode 100644
index 12241ab..0000000
--- a/target/board/vbox_x86/disk_layout.conf
+++ /dev/null
@@ -1,76 +0,0 @@
-# Best to align all partion start/ends on a cylinder boundary (fdisk prefers it)
-# 512 bytes/sector
-# 63 sectors/track
-# 32 tracks/cylinder
-
-# LBAs are in 'k', so...
-# 1008 blocks (1k each) (1032192 bytes) / cylinder
-
-device {
-
-    path /dev/block/sda
-
-    scheme mbr
-
-    # bytes in a disk sector (== 1 LBA), must be a power of 2!
-    sector_size 512
-
-    # Start_lba should be on a cylindar boundary.
-    start_lba 63
-
-    # Autodetect disk size if == 0
-    num_lba 0
-
-    partitions {
-        # /dev/sdX1
-        sysloader {
-            active y
-            type linux
-            # 8 cyls in length... about 8M
-            len 8064
-        }
-
-        # /dev/sdX2
-        recovery {
-            active y
-            type linux
-            # 8 cyls in length... about 8M
-            len 8064
-        }
-
-        # /dev/sdX3
-        boot {
-            active y
-            type linux
-            # 8 cyls in length... about 8M
-            len 8064
-        }
-
-        # /dev/sdX4
-        # (extended partion begins)
-
-        # /dev/sdX5
-        cache {
-            type linux
-            len 512M
-        }
-
-        # /dev/sdX6
-        system {
-            type linux
-            len 512M
-        }
-
-        # /dev/sdX7
-        third_party {
-            type linux
-            len 512M
-        }
-
-        # /dev/sdX8
-        data {
-            type linux
-            len -1
-        }
-    }
-}
diff --git a/target/board/vbox_x86/init.vbox_x86.rc b/target/board/vbox_x86/init.vbox_x86.rc
deleted file mode 100644
index 15ca572..0000000
--- a/target/board/vbox_x86/init.vbox_x86.rc
+++ /dev/null
@@ -1,90 +0,0 @@
-on early-init
-    export EXTERNAL_STORAGE /mnt/sdcard
-    mkdir /mnt/sdcard 0000 system system
-    # for backwards compatibility
-    symlink /mnt/sdcard /sdcard
-
-on boot
-    setprop ARGH ARGH
-    setprop net.eth0.gw 10.0.2.2
-    setprop net.eth0.dns1 10.0.2.3
-    setprop net.gprs.local-ip 10.0.2.15
-    setprop ro.radio.use-ppp no
-    setprop ro.build.product generic
-    setprop ro.product.device generic
-
-# fake some battery state
-    setprop status.battery.state Slow
-    setprop status.battery.level 5
-    setprop status.battery.level_raw  50
-    setprop status.battery.level_scale 9
-
-# disable some daemons the emulator doesn't want
-    stop dund
-    stop akmd
-
-# start essential services
-    start qemud
-    start goldfish-logcat
-#   start goldfish-setup
-    start netcfg
-
-    setprop ro.setupwizard.mode EMULATOR
-
-on fs
-# mount sda (system) and sdb (data) partitions
-    mount ext4 /dev/block/sda6 /system
-    mount ext4 /dev/block/sda6 /system ro remount
-    mount ext4 /dev/block/sdb6 /data nosuid nodev
-    mount ext4 /dev/block/sdb7 /cache nosuid nodev
-
-# enable Google-specific location features,
-# like NetworkLocationProvider and LocationCollector
-    setprop ro.com.google.locationfeatures 1
-
-# For the emulator, which bypasses Setup Wizard, you can specify
-# account info for the device via these two properties.  Google
-# Login Service will insert these accounts into the database when
-# it is created (ie, after a data wipe).
-#
-#   setprop ro.config.hosted_account username@hosteddomain.org:password
-#   setprop ro.config.google_account username@gmail.com:password
-#
-# You MUST have a Google account on the device, and you MAY
-# additionally have a hosted account.  No other configuration is
-# supported, and arbitrary breakage may result if you specify
-# something else.
-
-service goldfish-setup /system/etc/init.goldfish.sh
-    user root
-    group root
-    oneshot
-
-# The qemu-props program is used to set various system
-# properties on boot. It must be run early during the boot
-# process to avoid race conditions with other daemons that
-# might read them (e.g. surface flinger), so define it in
-# class 'core'
-#
-service qemu-props /system/bin/qemu-props
-    class core
-    user root
-    group root
-    oneshot
-
-service qemud /system/bin/qemud
-    socket qemud    stream 666
-    oneshot
-
-# -Q is a special logcat option that forces the
-# program to check wether it runs on the emulator
-# if it does, it redirects its output to the device
-# named by the androidboot.console kernel option
-# if not, it simply exits immediately
-
-service goldfish-logcat /system/bin/logcat -Q
-    oneshot
-
-# Enable networking so that adb can connect
-service netcfg /system/bin/netcfg eth0 dhcp
-    oneshot
diff --git a/target/board/vbox_x86/system.prop b/target/board/vbox_x86/system.prop
deleted file mode 100644
index 137a0f9..0000000
--- a/target/board/vbox_x86/system.prop
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# system.prop for generic sdk
-#
-
-rild.libpath=/system/lib/libreference-ril.so
-rild.libargs=-d /dev/ttyS0
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index fc407d3..ac5902c 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -42,7 +42,8 @@
     $(LOCAL_DIR)/aosp_mips.mk \
     $(LOCAL_DIR)/full_mips.mk \
     $(LOCAL_DIR)/aosp_arm64.mk \
-    $(LOCAL_DIR)/aosp_mips64.mk
+    $(LOCAL_DIR)/aosp_mips64.mk \
+    $(LOCAL_DIR)/aosp_x86_64.mk
 else
 PRODUCT_MAKEFILES := \
     $(LOCAL_DIR)/core.mk \
@@ -59,9 +60,15 @@
     $(LOCAL_DIR)/aosp_mips64.mk \
     $(LOCAL_DIR)/aosp_x86_64.mk \
     $(LOCAL_DIR)/full_x86_64.mk \
-    $(LOCAL_DIR)/vbox_x86.mk \
+    $(LOCAL_DIR)/sdk_phone_armv7.mk \
+    $(LOCAL_DIR)/sdk_phone_x86.mk \
+    $(LOCAL_DIR)/sdk_phone_mips.mk \
+    $(LOCAL_DIR)/sdk_phone_arm64.mk \
+    $(LOCAL_DIR)/sdk_phone_x86_64.mk \
+    $(LOCAL_DIR)/sdk_phone_mips64.mk \
     $(LOCAL_DIR)/sdk.mk \
     $(LOCAL_DIR)/sdk_x86.mk \
     $(LOCAL_DIR)/sdk_mips.mk \
-    $(LOCAL_DIR)/large_emu_hw.mk
+    $(LOCAL_DIR)/sdk_arm64.mk \
+    $(LOCAL_DIR)/sdk_x86_64.mk
 endif
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index e119466..ea8ec06 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -23,8 +23,6 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/board/generic_arm64/device.mk)
 
-PRODUCT_RUNTIMES := runtime_libart_default
-
 include $(SRC_TARGET_DIR)/product/emulator.mk
 PRODUCT_NAME := aosp_arm64
 PRODUCT_DEVICE := generic_arm64
diff --git a/target/product/base.mk b/target/product/base.mk
index 8aa3bc0..0d052b5 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -18,6 +18,8 @@
 PRODUCT_PACKAGES += \
     20-dns.conf \
     95-configured \
+    appwidget \
+    appops \
     am \
     android.policy \
     android.test.runner \
@@ -30,8 +32,8 @@
     dhcpcd \
     dhcpcd-run-hooks \
     dnsmasq \
+    dpm \
     framework \
-    framework2 \
     fsck_msdos \
     ime \
     input \
@@ -41,24 +43,28 @@
     libandroid_servers \
     libaudioeffect_jni \
     libaudioflinger \
+    libaudiopolicyservice \
+    libaudiopolicymanager \
     libbundlewrapper \
     libcamera_client \
     libcameraservice \
     libdl \
+    libdrmclearkeyplugin \
     libeffectproxy \
     libeffects \
     libinput \
+    libinputflinger \
     libiprouteutil \
-    libjni_latinime \
     libjnigraphics \
     libldnhncr \
     libmedia \
     libmedia_jni \
     libmediaplayerservice \
     libmtp \
+    libnetd_client \
     libnetlink \
     libnetutils \
-    libpac \
+    libpdfium \
     libreference-ril \
     libreverbwrapper \
     libril \
@@ -67,6 +73,8 @@
     libskia \
     libsonivox \
     libsoundpool \
+    libsoundtrigger \
+    libsoundtriggerservice \
     libsqlite \
     libstagefright \
     libstagefright_amrnb_common \
@@ -79,6 +87,8 @@
     libutils \
     libvisualizer \
     libvorbisidec \
+    libmediandk \
+    libwifi-service \
     media \
     media_cmd \
     mediaserver \
@@ -95,7 +105,6 @@
     racoon \
     run-as \
     schedtest \
-    screenshot \
     sdcard \
     services \
     settings \
@@ -103,8 +112,16 @@
     tc \
     vdc \
     vold \
-    webview \
     wm
 
 
+PRODUCT_COPY_FILES := $(call add-to-product-copy-files-if-exists,\
+    frameworks/base/preloaded-classes:system/etc/preloaded-classes)
+
+# Note: it is acceptable to not have a compiled-classes file. In that case, all boot classpath
+#       classes will be compiled.
+PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
+    frameworks/base/compiled-classes:system/etc/compiled-classes)
+
+
 $(call inherit-product, $(SRC_TARGET_DIR)/product/embedded.mk)
diff --git a/target/product/core.mk b/target/product/core.mk
index c5ef2aa..519dbb8 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -15,22 +15,44 @@
 #
 
 # Base configuration for communication-oriented android devices
-# (phones, tablets, etc.).  If you want a change to apply to ALL
+# (phones, tablets, etc.).  If you want a change to apply to ALMOST ALL
 # devices (including non-phones and non-tablets), modify
-# core_minimal.mk instead.
+# core_minimal.mk instead. If you care about wearables, you need to modify
+# core_tiny.mk in addition to core_minimal.mk.
 
 PRODUCT_PACKAGES += \
     BasicDreams \
     Browser \
+    Calculator \
+    Calendar \
+    CalendarProvider \
+    CaptivePortalLogin \
+    CertInstaller \
     Contacts \
+    DeskClock \
     DocumentsUI \
     DownloadProviderUi \
+    Email \
+    Exchange2 \
     ExternalStorageProvider \
+    FusedLocation \
+    InputDevices \
     KeyChain \
+    Keyguard \
+    LatinIME \
+    Launcher2 \
+    ManagedProvisioning \
     PicoTts \
     PacProcessor \
+    libpac \
+    PrintSpooler \
     ProxyHandler \
+    QuickSearchBox \
+    Settings \
     SharedStorageBackup \
-    VpnDialogs
+    Telecom \
+    TeleService \
+    VpnDialogs \
+    MmsService
 
 $(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 529b5f2..6c29482 100644
--- a/target/product/core_base.mk
+++ b/target/product/core_base.mk
@@ -30,15 +30,12 @@
     libandroidfw \
     libaudiopreprocessing \
     libaudioutils \
-    libbcc \
     libfilterpack_imageproc \
     libgabi++ \
-    libkeystore \
     libmdnssd \
     libnfc_ndef \
     libpowermanager \
     libspeexresampler \
-    libstagefright_chromium_http \
     libstagefright_soft_aacdec \
     libstagefright_soft_aacenc \
     libstagefright_soft_amrdec \
@@ -49,9 +46,11 @@
     libstagefright_soft_gsmdec \
     libstagefright_soft_h264dec \
     libstagefright_soft_h264enc \
+    libstagefright_soft_hevcdec \
     libstagefright_soft_mp3dec \
     libstagefright_soft_mpeg4dec \
     libstagefright_soft_mpeg4enc \
+    libstagefright_soft_opusdec \
     libstagefright_soft_rawdec \
     libstagefright_soft_vorbisdec \
     libstagefright_soft_vpxdec \
@@ -59,26 +58,7 @@
     libvariablespeed \
     libwebrtc_audio_preprocessing \
     mdnsd \
-    mms-common \
     requestsync \
-    telephony-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.
-PRODUCT_BOOT_JARS := \
-    core-libart \
-    conscrypt \
-    okhttp \
-    core-junit \
-    bouncycastle \
-    ext \
-    framework \
-    framework2 \
-    telephony-common \
-    voip-common \
-    mms-common \
-    android.policy \
-    services \
-    apache-xml \
-    webviewchromium
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index ec51ea4..33b49a6 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -30,34 +30,54 @@
     PackageInstaller \
     SettingsProvider \
     Shell \
+    bcc \
     bu \
+    com.android.future.usb.accessory \
     com.android.location.provider \
     com.android.location.provider.xml \
     com.android.media.remotedisplay \
     com.android.media.remotedisplay.xml \
+    com.android.mediadrm.signer \
+    com.android.mediadrm.signer.xml \
     drmserver \
+    ethernet-service \
     framework-res \
     idmap \
     installd \
+    ims-common \
     ip \
     ip-up-vpn \
     ip6tables \
     iptables \
     keystore \
     keystore.default \
+    ld.mc \
+    libbcc \
     libOpenMAXAL \
     libOpenSLES \
     libdownmix \
     libdrmframework \
     libdrmframework_jni \
     libfilterfw \
+    libkeystore \
     libsqlite_jni \
     libwilhelm \
     logd \
     make_ext4fs \
+    e2fsck \
+    resize2fs \
+    mms-common \
     screencap \
     sensorservice \
-    uiautomator
+    telephony-common \
+    uiautomator \
+    uncrypt \
+    voip-common \
+    webview \
+    wifi-service
+
+PRODUCT_COPY_FILES += \
+    frameworks/native/data/etc/android.software.webview.xml:system/etc/permissions/android.software.webview.xml
 
 # The order of PRODUCT_BOOT_JARS matters.
 PRODUCT_BOOT_JARS := \
@@ -68,17 +88,23 @@
     bouncycastle \
     ext \
     framework \
-    framework2 \
+    telephony-common \
+    voip-common \
+    ims-common \
+    mms-common \
     android.policy \
-    services \
     apache-xml \
-    webviewchromium
 
-PRODUCT_RUNTIMES := runtime_libart_default
+# The order of PRODUCT_SYSTEM_SERVER_JARS matters.
+PRODUCT_SYSTEM_SERVER_JARS := \
+    services \
+    ethernet-service \
+    wifi-service
 
 PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
     ro.zygote=zygote32
 PRODUCT_COPY_FILES += \
     system/core/rootdir/init.zygote32.rc:root/init.zygote32.rc
 
+$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/base.mk)
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
new file mode 100644
index 0000000..39789d9
--- /dev/null
+++ b/target/product/core_tiny.mk
@@ -0,0 +1,119 @@
+#
+# 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 \
+    CalendarProvider \
+    ContactsProvider \
+    CertInstaller \
+    FusedLocation \
+    InputDevices
+
+PRODUCT_PACKAGES += \
+    clatd \
+    clatd.conf \
+    pppd
+
+PRODUCT_PACKAGES += \
+    audio.primary.default \
+    audio_policy.default \
+    local_time.default \
+    power.default
+
+PRODUCT_PACKAGES += \
+    local_time.default
+
+PRODUCT_PACKAGES += \
+    BackupRestoreConfirmation \
+    DefaultContainerService \
+    SettingsProvider \
+    Shell \
+    bcc \
+    bu \
+    com.android.location.provider \
+    com.android.location.provider.xml \
+    framework-res \
+    installd \
+    ims-common \
+    ip \
+    ip-up-vpn \
+    ip6tables \
+    iptables \
+    keystore \
+    keystore.default \
+    libOpenMAXAL \
+    libOpenSLES \
+    libdownmix \
+    libfilterfw \
+    libkeystore \
+    libsqlite_jni \
+    libwilhelm \
+    libdrmframework_jni \
+    libdrmframework \
+    make_ext4fs \
+    e2fsck \
+    resize2fs \
+    nullwebview \
+    screencap \
+    sensorservice \
+    uiautomator \
+    uncrypt \
+    telephony-common \
+    voip-common \
+    logd \
+    mms-common \
+    wifi-service
+
+# The order matters
+PRODUCT_BOOT_JARS := \
+    core-libart \
+    conscrypt \
+    okhttp \
+    core-junit \
+    bouncycastle \
+    ext \
+    framework \
+    telephony-common \
+    voip-common \
+    ims-common \
+    mms-common \
+    android.policy \
+    apache-xml \
+    nullwebview \
+
+# The order of PRODUCT_SYSTEM_SERVER_JARS matters.
+PRODUCT_SYSTEM_SERVER_JARS := \
+    services \
+    wifi-service
+
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+    ro.zygote=zygote32
+PRODUCT_COPY_FILES += \
+    system/core/rootdir/init.zygote32.rc:root/init.zygote32.rc
+
+PRODUCT_PROPERTY_OVERRIDES += \
+    ro.carrier=unknown
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
+$(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 cfac003..56a5f97 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -20,12 +20,13 @@
 PRODUCT_PACKAGES += \
     adb \
     adbd \
+    atrace \
     bootanimation \
     debuggerd \
-    debuggerd64 \
     dumpstate \
     dumpsys \
     gralloc.default \
+    grep \
     gzip \
     healthd \
     init \
@@ -48,6 +49,7 @@
     libm \
     libpixelflinger \
     libpower \
+    libsigchain \
     libstdc++ \
     libstlport \
     libsurfaceflinger \
@@ -56,7 +58,7 @@
     libui \
     libutils \
     linker \
-    linker64 \
+    lmkd \
     logcat \
     logwrapper \
     mkshrc \
@@ -66,7 +68,7 @@
     sh \
     surfaceflinger \
     toolbox \
-    libsigchain
+    toybox \
 
 # SELinux packages
 PRODUCT_PACKAGES += \
@@ -78,6 +80,10 @@
     selinux_version \
     service_contexts
 
+# Ensure that this property is always defined so that bionic_systrace.cpp
+# can rely on it being initially set by init.
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+    debug.atrace.tags.enableflags=0
 
 PRODUCT_COPY_FILES += \
     system/core/rootdir/init.usb.rc:root/init.usb.rc \
diff --git a/target/product/emulator.mk b/target/product/emulator.mk
index 62099df..3a8a4aa 100644
--- a/target/product/emulator.mk
+++ b/target/product/emulator.mk
@@ -41,11 +41,18 @@
     lights.goldfish \
     gps.goldfish \
     sensors.goldfish \
-    e2fsck
+    e2fsck \
+    audio.primary.goldfish \
+    vibrator.goldfish \
+    power.goldfish \
+    sensors.ranchu
 
 
 PRODUCT_COPY_FILES += \
     device/generic/goldfish/fstab.goldfish:root/fstab.goldfish \
     device/generic/goldfish/init.goldfish.rc:root/init.goldfish.rc \
     device/generic/goldfish/init.goldfish.sh:system/etc/init.goldfish.sh \
-    device/generic/goldfish/ueventd.goldfish.rc:root/ueventd.goldfish.rc
+    device/generic/goldfish/ueventd.goldfish.rc:root/ueventd.goldfish.rc \
+    device/generic/goldfish/init.ranchu.rc:root/init.ranchu.rc \
+    device/generic/goldfish/fstab.ranchu:root/fstab.ranchu \
+    device/generic/goldfish/ueventd.ranchu.rc:root/ueventd.ranchu.rc
diff --git a/target/product/full_base.mk b/target/product/full_base.mk
index 059697e..d8dad79 100644
--- a/target/product/full_base.mk
+++ b/target/product/full_base.mk
@@ -22,11 +22,9 @@
 PRODUCT_PACKAGES := \
     libfwdlockengine \
     OpenWnn \
-    PinyinIME \
     libWnnEngDic \
     libWnnJpnDic \
     libwnndict \
-    VideoEditor \
     WAPPushManager
 
 PRODUCT_PACKAGES += \
@@ -42,7 +40,6 @@
 
 # Additional settings used in all AOSP builds
 PRODUCT_PROPERTY_OVERRIDES := \
-    ro.com.android.dateformat=MM-dd-yyyy \
     ro.config.ringtone=Ring_Synth_04.ogg \
     ro.config.notification_sound=pixiedust.ogg
 
@@ -50,7 +47,7 @@
 PRODUCT_LOCALES := en_US
 
 # Include drawables for all densities
-PRODUCT_AAPT_CONFIG := normal hdpi xhdpi xxhdpi
+PRODUCT_AAPT_CONFIG := normal
 
 # Get some sounds
 $(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
diff --git a/target/product/full_base_telephony.mk b/target/product/full_base_telephony.mk
index f98e9a2..2fd2ce8 100644
--- a/target/product/full_base_telephony.mk
+++ b/target/product/full_base_telephony.mk
@@ -27,7 +27,8 @@
     ro.com.android.dataroaming=true
 
 PRODUCT_COPY_FILES := \
-    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml
+    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
+    frameworks/native/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony.mk)
diff --git a/target/product/full_mips64.mk b/target/product/full_mips64.mk
index 408e81c..e813e41 100644
--- a/target/product/full_mips64.mk
+++ b/target/product/full_mips64.mk
@@ -23,8 +23,6 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/board/generic_mips64/device.mk)
 
-PRODUCT_RUNTIMES := runtime_libart_default
-
 include $(SRC_TARGET_DIR)/product/emulator.mk
 
 # Overrides
diff --git a/target/product/full_x86_64.mk b/target/product/full_x86_64.mk
index d9c0c1e..051a86e 100755
--- a/target/product/full_x86_64.mk
+++ b/target/product/full_x86_64.mk
@@ -27,8 +27,6 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk)
 
-PRODUCT_RUNTIMES := runtime_libart_default
-
 include $(SRC_TARGET_DIR)/product/emulator.mk
 
 ifdef NET_ETH0_STARTONBOOT
diff --git a/target/product/generic_no_telephony.mk b/target/product/generic_no_telephony.mk
index 12797f4..dd18fab 100644
--- a/target/product/generic_no_telephony.mk
+++ b/target/product/generic_no_telephony.mk
@@ -17,37 +17,18 @@
 # 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 \
     WallpaperCropper
 
 PRODUCT_PACKAGES += \
-    bcc \
     clatd \
     clatd.conf \
     pppd \
@@ -68,9 +49,6 @@
     vibrator.default \
     power.default
 
-PRODUCT_PACKAGES += \
-    local_time.default
-
 PRODUCT_COPY_FILES := \
         frameworks/av/media/libeffects/data/audio_effects.conf:system/etc/audio_effects.conf
 
@@ -81,9 +59,10 @@
 $(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
 $(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
 $(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
+$(call inherit-product-if-exists, external/lohit-fonts/fonts.mk)
 $(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
 $(call inherit-product-if-exists, external/naver-fonts/fonts.mk)
-$(call inherit-product-if-exists, external/sil-fonts/fonts.mk)
 $(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
 $(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
diff --git a/target/product/languages_full.mk b/target/product/languages_full.mk
index 4cddc06..6d77cde 100644
--- a/target/product/languages_full.mk
+++ b/target/product/languages_full.mk
@@ -21,4 +21,4 @@
 
 # These are all the locales that have translations and are displayable
 # by TextView in this branch.
-PRODUCT_LOCALES := en_US en_IN fr_FR it_IT es_ES et_EE de_DE nl_NL cs_CZ pl_PL ja_JP zh_TW zh_CN zh_HK ru_RU ko_KR nb_NO es_US da_DK el_GR tr_TR pt_PT pt_BR rm_CH sv_SE bg_BG ca_ES en_GB fi_FI hi_IN hr_HR hu_HU in_ID iw_IL lt_LT lv_LV ro_RO sk_SK sl_SI sr_RS uk_UA vi_VN tl_PH ar_EG fa_IR th_TH sw_TZ ms_MY af_ZA zu_ZA am_ET hi_IN en_XA ar_XB fr_CA km_KH lo_LA ne_NP si_LK mn_MN hy_AM az_AZ ka_GE
+PRODUCT_LOCALES := en_US en_AU en_IN fr_FR it_IT es_ES et_EE de_DE nl_NL cs_CZ pl_PL ja_JP zh_TW zh_CN zh_HK ru_RU ko_KR nb_NO es_US da_DK el_GR tr_TR pt_PT pt_BR rm_CH sv_SE bg_BG ca_ES en_GB fi_FI hi_IN hr_HR hu_HU in_ID iw_IL lt_LT lv_LV ro_RO sk_SK sl_SI sr_RS uk_UA vi_VN tl_PH ar_EG fa_IR th_TH sw_TZ ms_MY af_ZA zu_ZA am_ET hi_IN en_XA ar_XB fr_CA km_KH lo_LA ne_NP si_LK mn_MN hy_AM az_AZ ka_GE my_MM mr_IN ml_IN is_IS mk_MK ky_KG eu_ES gl_ES bn_BD ta_IN kn_IN te_IN uz_UZ ur_PK kk_KZ
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/runtime_common.mk b/target/product/runtime_common.mk
deleted file mode 100644
index 9ae182a..0000000
--- a/target/product/runtime_common.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# 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.
-#
-
-# Common runtime modules for both Dalvik and ART
-
-PRODUCT_PACKAGES += \
-    apache-xml \
-    bouncycastle \
-    cacerts \
-    conscrypt \
-    core-junit \
-    dalvikvm \
-    dexdeps \
-    dexdump \
-    dexlist \
-    dmtracedump \
-    dx \
-    ext \
-    hprof-conv \
-    libcrypto \
-    libexpat \
-    libicui18n \
-    libicuuc \
-    libjavacore \
-    libnativehelper \
-    libssl \
-    libz \
-    okhttp
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index de4cf17..a35122b 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -17,9 +17,37 @@
 # Provides a functioning ART environment without Android frameworks
 
 PRODUCT_PACKAGES += \
-        core-libart \
-        libart \
-        dex2oat \
-        oatdump
+    apache-xml \
+    bouncycastle \
+    cacerts \
+    conscrypt \
+    core-junit \
+    core-libart \
+    dalvikvm \
+    dex2oat \
+    dexdeps \
+    dexdump \
+    dexlist \
+    dmtracedump \
+    dx \
+    ext \
+    hprof-conv \
+    libart \
+    libcrypto \
+    libexpat \
+    libicui18n \
+    libicuuc \
+    libjavacore \
+    libnativehelper \
+    libssl \
+    libz \
+    oatdump \
+    okhttp \
+    patchoat
 
-include $(SRC_TARGET_DIR)/product/runtime_common.mk
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+    dalvik.vm.image-dex2oat-Xms=64m \
+    dalvik.vm.image-dex2oat-Xmx=64m \
+    dalvik.vm.dex2oat-Xms=64m \
+    dalvik.vm.dex2oat-Xmx=512m \
+    ro.dalvik.vm.native.bridge=0 \
diff --git a/target/product/runtime_libart_default.mk b/target/product/runtime_libart_default.mk
deleted file mode 100644
index 2d4c793..0000000
--- a/target/product/runtime_libart_default.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# 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.
-#
-
-# Set ART as the default runtime environment
-
-DALVIK_VM_LIB := libart.so
-
-include $(SRC_TARGET_DIR)/product/runtime_libart.mk
diff --git a/target/product/runtime_libdvm.mk b/target/product/runtime_libdvm.mk
deleted file mode 100644
index 638d7d7..0000000
--- a/target/product/runtime_libdvm.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# 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.
-#
-
-# Provides a functioning Dalvik environment without Android frameworks
-
-PRODUCT_PACKAGES += \
-    core \
-    libdvm \
-    dexopt
-
-include $(SRC_TARGET_DIR)/product/runtime_common.mk
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 2962fd2..96d8cc9 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,171 +14,8 @@
 # limitations under the License.
 #
 
-PRODUCT_POLICY := android.policy_phone
-PRODUCT_PROPERTY_OVERRIDES :=
+# Don't modify this file - It's just an alias!
 
-PRODUCT_PACKAGES := \
-	Calculator \
-	DeskClock \
-	Email \
-	Exchange2 \
-	FusedLocation \
-	Gallery \
-	Keyguard \
-	Music \
-	Mms \
-	OpenWnn \
-	PrintSpooler \
-	libWnnEngDic \
-	libWnnJpnDic \
-	libwnndict \
-	TeleService \
-	PinyinIME \
-	Protips \
-	SoftKeyboard \
-	SystemUI \
-	Launcher2 \
-	Development \
-	DevelopmentSettings \
-	Fallback \
-	Settings \
-	SdkSetup \
-	CustomLocale \
-	sqlite3 \
-	InputDevices \
-	LatinIME \
-	CertInstaller \
-	LiveWallpapersPicker \
-	ApiDemos \
-	GestureBuilder \
-	CubeLiveWallpapers \
-	QuickSearchBox \
-	WidgetPreview \
-	librs_jni \
-	CalendarProvider \
-	Calendar \
-	SmokeTest \
-	SmokeTestApp \
-	EmulatorSmokeTests \
-	rild \
-	LegacyCamera \
-	Dialer
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_armv7.mk)
 
-
-
-# Define the host tools and libs that are parts of the SDK.
--include sdk/build/product_sdk.mk
--include development/build/product_sdk.mk
-
-# audio libraries.
-PRODUCT_PACKAGES += \
-	audio.primary.goldfish \
-	audio_policy.default \
-	local_time.default
-
-PRODUCT_PACKAGE_OVERLAYS := development/sdk_overlay
-
-PRODUCT_COPY_FILES := \
-	device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
-	frameworks/base/data/sounds/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
-	frameworks/base/data/sounds/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
-	frameworks/native/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml \
-	device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
-	device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
-	frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:system/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \
-	frameworks/native/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml \
-	frameworks/av/media/libeffects/data/audio_effects.conf:system/etc/audio_effects.conf \
-	hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
-
-include $(SRC_TARGET_DIR)/product/emulator.mk
-
-$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
-$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
-$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
-$(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
-$(call inherit-product-if-exists, external/naver-fonts/fonts.mk)
-$(call inherit-product-if-exists, external/sil-fonts/fonts.mk)
-$(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
-$(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
-
-# locale + densities. en_US is both first and in alphabetical order to
-# ensure this is the default locale.
-PRODUCT_LOCALES = \
-	en_US \
-	ldpi \
-	hdpi \
-	mdpi \
-	xhdpi \
-	ar_EG \
-	ar_IL \
-	bg_BG \
-	ca_ES \
-	cs_CZ \
-	da_DK \
-	de_AT \
-	de_CH \
-	de_DE \
-	de_LI \
-	el_GR \
-	en_AU \
-	en_CA \
-	en_GB \
-	en_IE \
-	en_IN \
-	en_NZ \
-	en_SG \
-	en_US \
-	en_ZA \
-	es_ES \
-	es_US \
-	fi_FI \
-	fr_BE \
-	fr_CA \
-	fr_CH \
-	fr_FR \
-	he_IL \
-	hi_IN \
-	hr_HR \
-	hu_HU \
-	id_ID \
-	it_CH \
-	it_IT \
-	ja_JP \
-	ko_KR \
-	lt_LT \
-	lv_LV \
-	nb_NO \
-	nl_BE \
-	nl_NL \
-	pl_PL \
-	pt_BR \
-	pt_PT \
-	ro_RO \
-	ru_RU \
-	sk_SK \
-	sl_SI \
-	sr_RS \
-	sv_SE \
-	th_TH \
-	tl_PH \
-	tr_TR \
-	uk_UA \
-	vi_VN \
-	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
diff --git a/target/board/generic_mips/Android.mk b/target/product/sdk_arm64.mk
similarity index 73%
rename from target/board/generic_mips/Android.mk
rename to target/product/sdk_arm64.mk
index abf8d57..8bb38f4 100644
--- a/target/board/generic_mips/Android.mk
+++ b/target/product/sdk_arm64.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2011 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,4 +14,8 @@
 # limitations under the License.
 #
 
-LOCAL_PATH := $(call my-dir)
+# Don't modify this file - It's just an alias!
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_arm64.mk)
+
+PRODUCT_NAME := sdk_arm64
diff --git a/target/product/sdk_base.mk b/target/product/sdk_base.mk
new file mode 100644
index 0000000..451c0b7
--- /dev/null
+++ b/target/product/sdk_base.mk
@@ -0,0 +1,158 @@
+#
+# 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.
+#
+
+PRODUCT_PROPERTY_OVERRIDES :=
+
+PRODUCT_PACKAGES := \
+	ApiDemos \
+	CubeLiveWallpapers \
+	CustomLocale \
+	Development \
+	DevelopmentSettings \
+	Dialer \
+	EmulatorSmokeTests \
+	Fallback \
+	Gallery \
+	GestureBuilder \
+	LegacyCamera \
+	librs_jni \
+	libwnndict \
+	libWnnEngDic \
+	libWnnJpnDic \
+	LiveWallpapersPicker \
+	Mms \
+	Music \
+	OpenWnn \
+	Protips \
+	rild \
+	SdkSetup \
+	SmokeTest \
+	SmokeTestApp \
+	SoftKeyboard \
+	sqlite3 \
+	SystemUI \
+	WidgetPreview
+
+# Define the host tools and libs that are parts of the SDK.
+-include sdk/build/product_sdk.mk
+-include development/build/product_sdk.mk
+
+# audio libraries.
+PRODUCT_PACKAGES += \
+	audio.primary.goldfish \
+	audio_policy.default \
+	local_time.default
+
+PRODUCT_PACKAGE_OVERLAYS := development/sdk_overlay
+
+PRODUCT_COPY_FILES := \
+	device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
+	frameworks/base/data/sounds/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	frameworks/base/data/sounds/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	frameworks/native/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml \
+	device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+	frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
+	frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
+	frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml \
+	device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml \
+	frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:system/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \
+	frameworks/native/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml \
+	frameworks/av/media/libeffects/data/audio_effects.conf:system/etc/audio_effects.conf \
+	hardware/libhardware_legacy/audio/audio_policy.conf:system/etc/audio_policy.conf
+
+include $(SRC_TARGET_DIR)/product/emulator.mk
+
+$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
+$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
+$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
+$(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
+$(call inherit-product-if-exists, external/naver-fonts/fonts.mk)
+$(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
+$(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
+
+# 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. en_US is both first and in alphabetical order to
+# ensure this is the default locale.
+PRODUCT_LOCALES := \
+	en_US \
+	ar_EG \
+	ar_IL \
+	bg_BG \
+	ca_ES \
+	cs_CZ \
+	da_DK \
+	de_AT \
+	de_CH \
+	de_DE \
+	de_LI \
+	el_GR \
+	en_AU \
+	en_CA \
+	en_GB \
+	en_IE \
+	en_IN \
+	en_NZ \
+	en_SG \
+	en_US \
+	en_ZA \
+	es_ES \
+	es_US \
+	fi_FI \
+	fr_BE \
+	fr_CA \
+	fr_CH \
+	fr_FR \
+	he_IL \
+	hi_IN \
+	hr_HR \
+	hu_HU \
+	id_ID \
+	it_CH \
+	it_IT \
+	ja_JP \
+	ko_KR \
+	lt_LT \
+	lv_LV \
+	nb_NO \
+	nl_BE \
+	nl_NL \
+	pl_PL \
+	pt_BR \
+	pt_PT \
+	ro_RO \
+	ru_RU \
+	sk_SK \
+	sl_SI \
+	sr_RS \
+	sv_SE \
+	th_TH \
+	tl_PH \
+	tr_TR \
+	uk_UA \
+	vi_VN \
+	zh_CN \
+	zh_TW
diff --git a/target/product/sdk_mips.mk b/target/product/sdk_mips.mk
index 2072400..366994a 100644
--- a/target/product/sdk_mips.mk
+++ b/target/product/sdk_mips.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,15 +14,8 @@
 # limitations under the License.
 #
 
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
+# Don't modify this file - It's just an alias!
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_mips.mk)
 
-# Overrides
-PRODUCT_BRAND := generic_mips
 PRODUCT_NAME := sdk_mips
-PRODUCT_DEVICE := generic_mips
-PRODUCT_MODEL := Android SDK for Mips
diff --git a/target/product/vbox_x86.mk b/target/product/sdk_phone_arm64.mk
similarity index 66%
copy from target/product/vbox_x86.mk
copy to target/product/sdk_phone_arm64.mk
index a7d1b65..a0cf6c1 100644
--- a/target/product/vbox_x86.mk
+++ b/target/product/sdk_phone_arm64.mk
@@ -18,19 +18,13 @@
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
-endif
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/vbox_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_arm64/device.mk)
 
-PRODUCT_PACKAGES += \
-       camera.vbox_x86 \
-       lights.vbox_x86 \
-       gps.vbox_x86 \
-       sensors.vbox_x86
-
-PRODUCT_NAME := vbox_x86
-PRODUCT_DEVICE := vbox_x86
-PRODUCT_MODEL := Full Android on x86 VirtualBox
+# Overrides
+PRODUCT_BRAND := generic_arm64
+PRODUCT_NAME := sdk_phone_arm64
+PRODUCT_DEVICE := generic_arm64
+PRODUCT_MODEL := Android SDK built for arm64
diff --git a/target/product/runtime_libdvm_default.mk b/target/product/sdk_phone_armv7.mk
similarity index 72%
copy from target/product/runtime_libdvm_default.mk
copy to target/product/sdk_phone_armv7.mk
index b581ce5..aeb4940 100644
--- a/target/product/runtime_libdvm_default.mk
+++ b/target/product/sdk_phone_armv7.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2013 The Android Open Source Project
+# 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.
@@ -14,8 +14,9 @@
 # limitations under the License.
 #
 
-# Set Dalvik as the default runtime environment
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
 
-DALVIK_VM_LIB := libdvm.so
-
-include $(SRC_TARGET_DIR)/product/runtime_libdvm.mk
+# Overrides
+PRODUCT_BRAND := generic
+PRODUCT_NAME := sdk_phone_armv7
+PRODUCT_DEVICE := generic
diff --git a/target/product/vbox_x86.mk b/target/product/sdk_phone_mips.mk
similarity index 62%
copy from target/product/vbox_x86.mk
copy to target/product/sdk_phone_mips.mk
index a7d1b65..818491f 100644
--- a/target/product/vbox_x86.mk
+++ b/target/product/sdk_phone_mips.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2012 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -18,19 +18,11 @@
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
-endif
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/vbox_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
 
-PRODUCT_PACKAGES += \
-       camera.vbox_x86 \
-       lights.vbox_x86 \
-       gps.vbox_x86 \
-       sensors.vbox_x86
-
-PRODUCT_NAME := vbox_x86
-PRODUCT_DEVICE := vbox_x86
-PRODUCT_MODEL := Full Android on x86 VirtualBox
+# Overrides
+PRODUCT_BRAND := generic_mips
+PRODUCT_NAME := sdk_phone_mips
+PRODUCT_DEVICE := generic_mips
+PRODUCT_MODEL := Android SDK for Mips
diff --git a/target/product/vbox_x86.mk b/target/product/sdk_phone_mips64.mk
similarity index 66%
copy from target/product/vbox_x86.mk
copy to target/product/sdk_phone_mips64.mk
index a7d1b65..afdb2a8 100644
--- a/target/product/vbox_x86.mk
+++ b/target/product/sdk_phone_mips64.mk
@@ -18,19 +18,12 @@
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
-endif
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/vbox_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
 
-PRODUCT_PACKAGES += \
-       camera.vbox_x86 \
-       lights.vbox_x86 \
-       gps.vbox_x86 \
-       sensors.vbox_x86
-
-PRODUCT_NAME := vbox_x86
-PRODUCT_DEVICE := vbox_x86
-PRODUCT_MODEL := Full Android on x86 VirtualBox
+# Overrides
+PRODUCT_BRAND := generic_mips64
+PRODUCT_NAME := sdk_phone_mips64
+PRODUCT_DEVICE := generic_mips64
+PRODUCT_MODEL := Android SDK built for mips64
diff --git a/target/product/vbox_x86.mk b/target/product/sdk_phone_x86.mk
similarity index 66%
copy from target/product/vbox_x86.mk
copy to target/product/sdk_phone_x86.mk
index a7d1b65..95c49ab 100644
--- a/target/product/vbox_x86.mk
+++ b/target/product/sdk_phone_x86.mk
@@ -18,19 +18,11 @@
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
-endif
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/vbox_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
 
-PRODUCT_PACKAGES += \
-       camera.vbox_x86 \
-       lights.vbox_x86 \
-       gps.vbox_x86 \
-       sensors.vbox_x86
-
-PRODUCT_NAME := vbox_x86
-PRODUCT_DEVICE := vbox_x86
-PRODUCT_MODEL := Full Android on x86 VirtualBox
+# Overrides
+PRODUCT_BRAND := generic_x86
+PRODUCT_NAME := sdk_phone_x86
+PRODUCT_DEVICE := generic_x86
+PRODUCT_MODEL := Android SDK built for x86
diff --git a/target/product/vbox_x86.mk b/target/product/sdk_phone_x86_64.mk
similarity index 66%
rename from target/product/vbox_x86.mk
rename to target/product/sdk_phone_x86_64.mk
index a7d1b65..69e37af 100644
--- a/target/product/vbox_x86.mk
+++ b/target/product/sdk_phone_x86_64.mk
@@ -18,19 +18,12 @@
 # Open-Source part of the tree. It's geared toward a US-centric
 # build quite specifically for the emulator, and might not be
 # entirely appropriate to inherit from for on-device configurations.
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
-endif
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
-$(call inherit-product, $(SRC_TARGET_DIR)/board/vbox_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_base.mk)
 
-PRODUCT_PACKAGES += \
-       camera.vbox_x86 \
-       lights.vbox_x86 \
-       gps.vbox_x86 \
-       sensors.vbox_x86
-
-PRODUCT_NAME := vbox_x86
-PRODUCT_DEVICE := vbox_x86
-PRODUCT_MODEL := Full Android on x86 VirtualBox
+# Overrides
+PRODUCT_BRAND := generic_x86_64
+PRODUCT_NAME := sdk_phone_x86_64
+PRODUCT_DEVICE := generic_x86_64
+PRODUCT_MODEL := Android SDK built for x86_64
diff --git a/target/product/sdk_x86.mk b/target/product/sdk_x86.mk
index 873d0c0..13ee57d 100644
--- a/target/product/sdk_x86.mk
+++ b/target/product/sdk_x86.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,15 +14,8 @@
 # limitations under the License.
 #
 
-# This is a build configuration for a full-featured build of the
-# Open-Source part of the tree. It's geared toward a US-centric
-# build quite specifically for the emulator, and might not be
-# entirely appropriate to inherit from for on-device configurations.
+# Don't modify this file - It's just an alias!
 
-include $(SRC_TARGET_DIR)/product/sdk.mk
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_x86.mk)
 
-# Overrides
-PRODUCT_BRAND := generic_x86
 PRODUCT_NAME := sdk_x86
-PRODUCT_DEVICE := generic_x86
-PRODUCT_MODEL := Android SDK built for x86
diff --git a/target/product/runtime_libdvm_default.mk b/target/product/sdk_x86_64.mk
similarity index 73%
rename from target/product/runtime_libdvm_default.mk
rename to target/product/sdk_x86_64.mk
index b581ce5..5f6553e 100644
--- a/target/product/runtime_libdvm_default.mk
+++ b/target/product/sdk_x86_64.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2013 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
 # limitations under the License.
 #
 
-# Set Dalvik as the default runtime environment
+# Don't modify this file - It's just an alias!
 
-DALVIK_VM_LIB := libdvm.so
+$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_x86_64.mk)
 
-include $(SRC_TARGET_DIR)/product/runtime_libdvm.mk
+PRODUCT_NAME := sdk_x86_64
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/target/product/security/verity.pk8 b/target/product/security/verity.pk8
new file mode 100644
index 0000000..bebf216
--- /dev/null
+++ b/target/product/security/verity.pk8
Binary files differ
diff --git a/target/product/security/verity.x509.pem b/target/product/security/verity.x509.pem
new file mode 100644
index 0000000..86399c3
--- /dev/null
+++ b/target/product/security/verity.x509.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAuWgAwIBAgIJAJcPmDkJqolJMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
+AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0xNDExMDYxOTA3NDBaFw00MjAzMjQxOTA3NDBaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAOjreE0vTVSRenuzO9vnaWfk0eQzYab0gqpi
+6xAzi6dmD+ugoEKJmbPiuE5Dwf21isZ9uhUUu0dQM46dK4ocKxMRrcnmGxydFn6o
+fs3ODJMXOkv2gKXL/FdbEPdDbxzdu8z3yk+W67udM/fW7WbaQ3DO0knu+izKak/3
+T41c5uoXmQ81UNtAzRGzGchNVXMmWuTGOkg6U+0I2Td7K8yvUMWhAWPPpKLtVH9r
+AL5TzjYNR92izdKcz3AjRsI3CTjtpiVABGeX0TcjRSuZB7K9EK56HV+OFNS6I1NP
+jdD7FIShyGlqqZdUOkAUZYanbpgeT5N7QL6uuqcGpoTOkalu6kkCAwEAAaNQME4w
+HQYDVR0OBBYEFH5DM/m7oArf4O3peeKO0ZIEkrQPMB8GA1UdIwQYMBaAFH5DM/m7
+oArf4O3peeKO0ZIEkrQPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
+AHO3NSvDE5jFvMehGGtS8BnFYdFKRIglDMc4niWSzhzOVYRH4WajxdtBWc5fx0ix
+NF/+hVKVhP6AIOQa+++sk+HIi7RvioPPbhjcsVlZe7cUEGrLSSveGouQyc+j0+m6
+JF84kszIl5GGNMTnx0XRPO+g8t6h5LWfnVydgZfpGRRg+WHewk1U2HlvTjIceb0N
+dcoJ8WKJAFWdcuE7VIm4w+vF/DYX/A2Oyzr2+QRhmYSv1cusgAeC1tvH4ap+J1Lg
+UnOu5Kh/FqPLLSwNVQp4Bu7b9QFfqK8Moj84bj88NqRGZgDyqzuTrFxn6FW7dmyA
+yttuAJAEAymk1mipd9+zp38=
+-----END CERTIFICATE-----
diff --git a/target/product/security/verity_key b/target/product/security/verity_key
new file mode 100644
index 0000000..31982d9
--- /dev/null
+++ b/target/product/security/verity_key
Binary files differ
diff --git a/target/product/verity.mk b/target/product/verity.mk
new file mode 100644
index 0000000..0361b64
--- /dev/null
+++ b/target/product/verity.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides dependencies necessary for verified boot
+
+PRODUCT_SUPPORTS_VERITY := true
+
+# The dev key is used to sign boot and recovery images, and the verity
+# metadata table. Actual product deliverables will be re-signed by hand.
+# We expect this file to exist with the suffixes ".x509.pem" and ".pk8".
+PRODUCT_VERITY_SIGNING_KEY := build/target/product/security/verity
+
+PRODUCT_PACKAGES += \
+        verity_key
diff --git a/tools/acp/Android.mk b/tools/acp/Android.mk
index 33c5567..2b41bc1 100644
--- a/tools/acp/Android.mk
+++ b/tools/acp/Android.mk
@@ -4,6 +4,7 @@
 
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_SRC_FILES := \
     acp.c
@@ -21,5 +22,7 @@
 LOCAL_C_INCLUDES := build/libs/host/include
 LOCAL_MODULE := acp
 LOCAL_ACP_UNAVAILABLE := true
+LOCAL_CXX_STL := none
+LOCAL_ADDRESS_SANITIZER := false
 
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/adbs b/tools/adbs
index a9bc7c2..a8f06c0 100755
--- a/tools/adbs
+++ b/tools/adbs
@@ -15,206 +15,30 @@
 # limitations under the License.
 
 import os
+import os.path
 import re
 import string
 import sys
 
-###############################################################################
-# match "#00 pc 0003f52e  /system/lib/libdvm.so" for example
-###############################################################################
-trace_line = re.compile("(.*)(\#[0-9]+) {1,2}(..) ([0-9a-f]{8})  ([^\r\n \t]*)")
-
-# returns a list containing the function name and the file/lineno
-def CallAddr2Line(lib, addr):
-  global symbols_dir
-  global addr2line_cmd
-  global cppfilt_cmd
-
-  if lib != "":
-    cmd = addr2line_cmd + \
-        " -f -e " + symbols_dir + lib + " 0x" + addr
-    stream = os.popen(cmd)
-    lines = stream.readlines()
-    list = map(string.strip, lines)
-  else:
-    list = []
-  if list != []:
-    # Name like "move_forward_type<JavaVMOption>" causes troubles
-    mangled_name = re.sub('<', '\<', list[0]);
-    mangled_name = re.sub('>', '\>', mangled_name);
-    cmd = cppfilt_cmd + " " + mangled_name
-    stream = os.popen(cmd)
-    list[0] = stream.readline()
-    stream.close()
-    list = map(string.strip, list)
-  else:
-    list = [ "(unknown)", "(unknown)" ]
-  return list
-
-
-###############################################################################
-# similar to CallAddr2Line, but using objdump to find out the name of the
-# containing function of the specified address
-###############################################################################
-def CallObjdump(lib, addr):
-  global objdump_cmd
-  global symbols_dir
-
-  unknown = "(unknown)"
-  uname = os.uname()[0]
-  if uname == "Darwin":
-    proc = os.uname()[-1]
-    if proc == "i386":
-      uname = "darwin-x86"
-    else:
-      uname = "darwin-ppc"
-  elif uname == "Linux":
-    uname = "linux-x86"
-  if lib != "":
-    next_addr = string.atoi(addr, 16) + 1
-    cmd = objdump_cmd \
-        + " -C -d --start-address=0x" + addr + " --stop-address=" \
-        + str(next_addr) \
-        + " " + symbols_dir + lib
-    stream = os.popen(cmd)
-    lines = stream.readlines()
-    map(string.strip, lines)
-    stream.close()
-  else:
-    return unknown
-
-  # output looks like
-  #
-  # file format elf32-littlearm
-  #
-  # Disassembly of section .text:
-  #
-  # 0000833c <func+0x4>:
-  #        833c:       701a            strb    r2, [r3, #0]
-  #
-  # we want to extract the "func" part
-  num_lines = len(lines)
-  if num_lines < 2:
-    return unknown
-  func_name = lines[num_lines-2]
-  func_regexp = re.compile("(^.*\<)(.*)(\+.*\>:$)")
-  components = func_regexp.match(func_name)
-  if components is None:
-    return unknown
-  return components.group(2)
-
-###############################################################################
-# determine the symbols directory in the local build
-###############################################################################
-def FindSymbolsDir():
-  global symbols_dir
-
-  try:
-    path = os.environ['ANDROID_PRODUCT_OUT'] + "/symbols"
-  except:
-    cmd = "CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core " \
-      + "SRC_TARGET_DIR=build/target make -f build/core/config.mk " \
-      + "dumpvar-abs-TARGET_OUT_UNSTRIPPED"
-    stream = os.popen(cmd)
-    str = stream.read()
-    stream.close()
-    path = str.strip()
-
-  if (not os.path.exists(path)):
-    print path + " not found!"
-    sys.exit(1)
-
-  symbols_dir = path
-
-###############################################################################
-# determine the path of binutils
-###############################################################################
-def SetupToolsPath():
-  global addr2line_cmd
-  global objdump_cmd
-  global cppfilt_cmd
-  global symbols_dir
-
-  uname = os.uname()[0]
-  if uname == "Darwin":
-    uname = "darwin-x86"
-  elif uname == "Linux":
-    uname = "linux-x86"
-  gcc_version = os.environ["TARGET_GCC_VERSION"]
-  prefix = "./prebuilts/gcc/" + uname + "/arm/arm-linux-androideabi-" + \
-           gcc_version + "/bin/"
-  addr2line_cmd = prefix + "arm-linux-androideabi-addr2line"
-
-  if (not os.path.exists(addr2line_cmd)):
-    try:
-      prefix = os.environ['ANDROID_BUILD_TOP'] + "/prebuilts/gcc/" + \
-               uname + "/arm/arm-linux-androideabi-" + gcc_version + "/bin/"
-    except:
-      prefix = "";
-
-    addr2line_cmd = prefix + "arm-linux-androideabi-addr2line"
-    if (not os.path.exists(addr2line_cmd)):
-      print addr2line_cmd + " not found!"
-      sys.exit(1)
-
-  objdump_cmd = prefix + "arm-linux-androideabi-objdump"
-  cppfilt_cmd = prefix + "arm-linux-androideabi-c++filt"
-
-###############################################################################
-# look up the function and file/line number for a raw stack trace line
-# groups[0]: log tag
-# groups[1]: stack level
-# groups[2]: "pc"
-# groups[3]: code address
-# groups[4]: library name
-###############################################################################
-def SymbolTranslation(groups):
-  lib_name = groups[4]
-  code_addr = groups[3]
-  caller = CallObjdump(lib_name, code_addr)
-  func_line_pair = CallAddr2Line(lib_name, code_addr)
-
-  # If a callee is inlined to the caller, objdump will see the caller's
-  # address but addr2line will report the callee's address. So the printed
-  # format is desgined to be "caller<-callee  file:line"
-  if (func_line_pair[0] != caller):
-    print groups[0] + groups[1] + " " + caller + "<-" + \
-          '  '.join(func_line_pair[:]) + " "
-  else:
-    print groups[0] + groups[1] + " " + '  '.join(func_line_pair[:]) + " "
-
-###############################################################################
+sys.path.insert(0, os.path.dirname(__file__) + "/../../development/scripts")
+import stack_core
+import symbol
 
 if __name__ == '__main__':
   # pass the options to adb
   adb_cmd  = "adb " + ' '.join(sys.argv[1:])
 
-  # setup addr2line_cmd and objdump_cmd
-  SetupToolsPath()
-
-  # setup the symbols directory
-  FindSymbolsDir()
+  # create tracer for line parsing
+  tracer = stack_core.TraceConverter()
 
   # invoke the adb command and filter its output
   stream = os.popen(adb_cmd)
   while (True):
     line = stream.readline()
-
-    # EOF reached
     if (line == ''):
       break
-
-    # remove the trailing \n
-    line = line.strip()
-
-    # see if this is a stack trace line
-    match = trace_line.match(line)
-    if (match):
-      groups = match.groups()
-      # translate raw address into symbols
-      SymbolTranslation(groups)
-    else:
-      print line
+    if(tracer.ProcessLine(line) == False):
+      print(line.strip())
       sys.stdout.flush()
 
   # adb itself aborts
diff --git a/tools/atree/atree.cpp b/tools/atree/atree.cpp
index 2ba284f..b134e01 100644
--- a/tools/atree/atree.cpp
+++ b/tools/atree/atree.cpp
@@ -90,6 +90,26 @@
     }
 }
 
+// Escape the filename so that it can be added to the makefile properly.
+static string
+escape_filename(const string name)
+{
+    ostringstream new_name;
+    for (string::const_iterator iter = name.begin(); iter != name.end(); ++iter)
+    {
+        switch (*iter)
+        {
+            case '$':
+                new_name << "$$";
+                break;
+            default:
+                new_name << *iter;
+                break;
+        }
+    }
+    return new_name.str();
+}
+
 int
 main(int argc, char* const* argv)
 {
@@ -324,7 +344,8 @@
             for (vector<FileRecord>::iterator it=files.begin();
                                 it!=files.end(); it++) {
                 if (!it->sourceIsDir) {
-                    fprintf(f, "%s \\\n", it->sourcePath.c_str());
+                    fprintf(f, "%s \\\n",
+                            escape_filename(it->sourcePath).c_str());
                 }
             }
             fprintf(f, "\n");
diff --git a/tools/atree/files.cpp b/tools/atree/files.cpp
index df3e987..d945f58 100644
--- a/tools/atree/files.cpp
+++ b/tools/atree/files.cpp
@@ -447,14 +447,7 @@
             continue;
         }
         string entry = path_append(path, ent->d_name);
-#ifdef HAVE_DIRENT_D_TYPE
-		bool is_directory = (ent->d_type == DT_DIR);
-#else
-	    // If dirent.d_type is missing, then use stat instead
-		struct stat stat_buf;
-		stat(entry.c_str(), &stat_buf);
-		bool is_directory = S_ISDIR(stat_buf.st_mode);
-#endif
+        bool is_directory = (ent->d_type == DT_DIR);
         add_more(entry, is_directory, rec, more);
         if (is_directory) {
             dirs.push_back(entry);
diff --git a/tools/atree/fs.cpp b/tools/atree/fs.cpp
index 9468cfd..6cd080e 100644
--- a/tools/atree/fs.cpp
+++ b/tools/atree/fs.cpp
@@ -63,14 +63,7 @@
             string full = path;
             full += '/';
             full += ent->d_name;
-#ifdef HAVE_DIRENT_D_TYPE
             bool is_directory = (ent->d_type == DT_DIR);
-#else
-            // If dirent.d_type is missing, then use stat instead
-            struct stat stat_buf;
-            stat(full.c_str(), &stat_buf);
-            bool is_directory = S_ISDIR(stat_buf.st_mode);
-#endif
             if (is_directory) {
                 dirs.push_back(full);
             } else {
diff --git a/tools/buildinfo.sh b/tools/buildinfo.sh
index 46a73f8..dcd9ab5 100755
--- a/tools/buildinfo.sh
+++ b/tools/buildinfo.sh
@@ -8,6 +8,7 @@
 echo "ro.build.version.incremental=$BUILD_NUMBER"
 echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION"
 echo "ro.build.version.codename=$PLATFORM_VERSION_CODENAME"
+echo "ro.build.version.all_codenames=$PLATFORM_VERSION_ALL_CODENAMES"
 echo "ro.build.version.release=$PLATFORM_VERSION"
 echo "ro.build.date=`date`"
 echo "ro.build.date.utc=`date +%s`"
@@ -15,6 +16,7 @@
 echo "ro.build.user=$USER"
 echo "ro.build.host=`hostname`"
 echo "ro.build.tags=$BUILD_VERSION_TAGS"
+echo "ro.build.flavor=$TARGET_BUILD_FLAVOR"
 echo "ro.product.model=$PRODUCT_MODEL"
 echo "ro.product.brand=$PRODUCT_BRAND"
 echo "ro.product.name=$PRODUCT_NAME"
@@ -34,11 +36,8 @@
 echo "ro.product.cpu.abilist64=$TARGET_CPU_ABI_LIST_64_BIT"
 
 echo "ro.product.manufacturer=$PRODUCT_MANUFACTURER"
-if [ -n "$PRODUCT_DEFAULT_LANGUAGE" ] ; then
-  echo "ro.product.locale.language=$PRODUCT_DEFAULT_LANGUAGE"
-fi
-if [ -n "$PRODUCT_DEFAULT_REGION" ] ; then
-  echo "ro.product.locale.region=$PRODUCT_DEFAULT_REGION"
+if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then
+  echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE"
 fi
 echo "ro.wifi.channels=$PRODUCT_DEFAULT_WIFI_CHANNELS"
 echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
@@ -46,9 +45,12 @@
 echo "# ro.build.product is obsolete; use ro.product.device"
 echo "ro.build.product=$TARGET_DEVICE"
 
-echo "# Do not try to parse ro.build.description or .fingerprint"
+echo "# Do not try to parse description, fingerprint, or thumbprint"
 echo "ro.build.description=$PRIVATE_BUILD_DESC"
 echo "ro.build.fingerprint=$BUILD_FINGERPRINT"
+if [ -n "$BUILD_THUMBPRINT" ] ; then
+  echo "ro.build.thumbprint=$BUILD_THUMBPRINT"
+fi
 echo "ro.build.characteristics=$TARGET_AAPT_CHARACTERISTICS"
 
 echo "# end build properties"
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/assets/images/android-partner-logo.png b/tools/droiddoc/templates-pdk/assets/images/android-partner-logo.png
new file mode 100644
index 0000000..dac0991
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/assets/images/android-partner-logo.png
Binary files differ
diff --git a/tools/droiddoc/templates-pdk/components/masthead.cs b/tools/droiddoc/templates-pdk/components/masthead.cs
index a581618..05437f3 100644
--- a/tools/droiddoc/templates-pdk/components/masthead.cs
+++ b/tools/droiddoc/templates-pdk/components/masthead.cs
@@ -2,8 +2,8 @@
 def:custom_masthead() ?>
   <div id="header">
       <div id="headerLeft">
-          <a href="<?cs var:toroot ?>guide/getting_started.html"><img
-              src="<?cs var:toroot ?>assets/images/open_source.png" alt="Android Open Source Project" /></a>
+          <a href="<?cs var:toroot ?>guide/index.html"><img
+              src="<?cs var:toroot ?>assets/images/android-partner-logo.png" alt="Android Platform Development Kit" /></a>
        
       </div>
       <div id="headerRight">
diff --git a/tools/droiddoc/templates-sac/assets/css/default.css b/tools/droiddoc/templates-sac/assets/css/default.css
index 0d9e601..c1a0c19 100644
--- a/tools/droiddoc/templates-sac/assets/css/default.css
+++ b/tools/droiddoc/templates-sac/assets/css/default.css
@@ -1016,12 +1016,13 @@
 }
 h1 {
     color:#333;
-    font-size: 22px;
-    margin: 20px 0 20px;
+    font-size: 34px;
+    margin: 36px 0 27px;
     padding:0 0 10px;
+    font-weight:300;
 }
 h1, h2 {
-    line-height: 32px;
+    line-height: 30px;
 }
 h1.short {
   margin-right:320px;
@@ -1030,35 +1031,41 @@
   margin-right:320px;
 }
 h1.super {
-    font-size: 37px;  
+    font-size: 37px;
 }
 h2 {
     color:#333;
-    font-size: 20px;
-    margin: 20px 0 20px;
+    font-size: 26px;
+    margin: 32px 0 20px;
     padding:0;
+    font-weight:300;
 }
 h3 {
     color:#333;
-    font-size: 18px;
+    font-size: 21px;
+    font-weight:400;
+    margin:21px 0 14px 0;
 }
 h3, h4 {
-    color:#333;
-    line-height: 20px;
-    margin: 10px 0;
+    line-height: 21px;
 }
 h4 {
-  font-size: 16px;
+  font-size: 18px;
+  margin: 12px 0;
+  font-weight:500;
 }
 h5 {
-  font-size: 14px;  
+  font-size: 14px;
 }
 h5, h6 {
   margin: 5px 0;
 }
 h6 {
-  font-size: 12px;  
+  font-size: 12px;
 }
+
+
+
 hr { /* applied to the bottom of h2 elements */
   height: 1px;
   margin: 5px 0 20px;
diff --git a/tools/droiddoc/templates-sac/assets/images/sac_logo.png b/tools/droiddoc/templates-sac/assets/images/sac_logo.png
index 54b9a4c..4ad113c 100644
--- a/tools/droiddoc/templates-sac/assets/images/sac_logo.png
+++ b/tools/droiddoc/templates-sac/assets/images/sac_logo.png
Binary files differ
diff --git a/tools/droiddoc/templates-sac/assets/images/sac_logo@2x.png b/tools/droiddoc/templates-sac/assets/images/sac_logo@2x.png
new file mode 100644
index 0000000..4040f3f
--- /dev/null
+++ b/tools/droiddoc/templates-sac/assets/images/sac_logo@2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sac/components/masthead.cs b/tools/droiddoc/templates-sac/components/masthead.cs
index fb9b71d..a8618c0 100644
--- a/tools/droiddoc/templates-sac/components/masthead.cs
+++ b/tools/droiddoc/templates-sac/components/masthead.cs
@@ -253,7 +253,9 @@
         <div class="wrap" id="header-wrap">
           <div class="col-3 saclogo">
           <a href="<?cs var:toroot ?>index.html">
-            <img src="<?cs var:toroot ?>assets/images/sac_logo.png" width="114" height="16" alt="Android Developers" />
+            <img src="<?cs var:toroot ?>assets/images/sac_logo.png"
+                srcset="<?cs var:toroot ?>assets/images/sac_logo@2x.png 2x"
+                width="123" height="25" alt="Android Developers" />
           </a>
           </div>
             <ul class="nav-x col-9">
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-dyn/assets/css/default.css b/tools/droiddoc/templates-sdk-dyn/assets/css/default.css
index 7515360..e26aec6 100644
--- a/tools/droiddoc/templates-sdk-dyn/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk-dyn/assets/css/default.css
@@ -98,7 +98,8 @@
 #devdoc-nav.fixed {
   position: fixed;
   margin:0;
-  top: 20px; }
+  top: 65px; /* sticky-header height + 20px gutter */
+}
 
 #devdoc-nav span.small {
   font-size:12px;
@@ -358,6 +359,19 @@
   #nav li span.tree-list-subtitle:after {
     content: '—';
   }
+  #nav li span.tree-list-subtitle.package {
+    padding-top:15px;
+    cursor:default;
+  }
+  #nav li span.tree-list-subtitle.package:before {
+    content: '';
+  }
+  #nav li span.tree-list-subtitle.package:after {
+    content: '';
+  }
+  #nav li ul.tree-list-children.classes {
+    padding-left:10px;
+  }
   #nav li ul {
     display:none;
     overflow: hidden;
@@ -1365,8 +1379,7 @@
   .training-nav-top, .training-nav-bottom,
   #doc-col .content-footer,
   .nav-x, .nav-y,
-  .paging-links,
-  a.totop {
+  .paging-links {
       display: none !important;
   }
 
@@ -1491,7 +1504,8 @@
 Header, Login, Nav-X, Search
 */
 #header {
-  padding: 2.2em 0 0.2em 0;
+  margin: 0;
+  padding: 0;
 }
 #header:before, #header:after {
   content: "";
@@ -1828,8 +1842,8 @@
 #qv-wrapper {
   float:right;
   clear:right;
-  margin:0 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
-  padding:0 0 20px;
+  margin:0 0 0 30px; /* negative top-margin to counter the content-header bottom margin */
+  padding:0 0 30px;
 }
 
 #tb-wrapper {
@@ -2871,26 +2885,6 @@
   margin:0 0 10px;
 }
 
-#devdoc-nav a.totop {
-  display:block;
-  top:0;
-  width:inherit;
-  background: transparent url(../images/styles/gototop.png) no-repeat scroll 50% 50%;
-  text-indent:-9999em;
-}
-#devdoc-nav a.totop {
-  position:fixed;
-  display:none;
-}
-#devdoc-nav a.totop:hover {
-  background-color:#33B5E5;
-}
-
-.content-footer a.totop {
-  text-transform:uppercase;
-  line-height:30px;
-}
-
 .expandable {
   height:34px;
   padding-left:20px;
@@ -3955,13 +3949,174 @@
   z-index:100;
 }
 
+
+
+
+
+/************ STICKY NAV BAR ******************/
+
+#header-wrapper {
+  background: #f9f9f9;
+  margin: 0 -10px 0 -10px;
+  padding: 31px 10px 0px 10px;
+  position: relative;
+}
+#header-wrapper #nav-x div.wrap {
+  max-width: 940px;
+  height: 38px;
+}
+#header-wrapper #nav-x ul.nav-x li {
+  margin-right: 36px !important;
+  margin-top: 5px;
+  margin-bottom: 0px;
+  height: 30px;
+}
+#header-wrapper #nav-x > div.wrap ul.nav-x li.active  {
+  color: #669900;
+  border-bottom: 3px solid #669900;
+}
+#header-wrapper #nav-x > div.wrap ul.nav-x li.active a {
+  color: #669900;
+}
+#header-wrapper #nav-x > div.wrap ul.nav-x a {
+  font-size: 14.5px;
+}
+#header-wrapper .developer-console-btn {
+  float: right;
+  background: #fefefe;
+  border-radius: 4px;
+  padding: 8px 14px;
+  box-shadow: 1px 1px 0px #7a7a7a;
+  font-size: 14px;
+  margin-top: -6px;
+  cursor: pointer;
+  color: #464646;
+  margin-right: 20px;
+}
+/* not currently used */
+#header-wrapper .shadow {
+  width: 1034px;
+  height: 4px;
+  position: absolute;
+  left: 50%;
+  margin-left: -517px;
+  bottom: -4px;
+  background-image: url(../images/header-shadow.png);
+}
+
+#context {
+  clear: both;
+  padding-top: 14px;
+}
+#context .breadcrumb {
+  float: left;
+  margin-bottom: 10px;
+}
+#context .util {
+  float: right;
+  margin-right: 20px;
+}
+
+.breadcrumb {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  position: relative;
+}
+.breadcrumb li {
+  float: left;
+  padding: 0 20px 0 0;
+  color: #000;
+  white-space: nowrap;
+}
+.breadcrumb li a {
+  color: #000;
+}
+.breadcrumb li:after {
+  content: url(../images/breadcrumb.png);
+  position: relative;
+  top: 1px;
+  left: 10px;
+  width: 5px;
+  height: 10px;
+}
+.breadcrumb li.current {
+  font-weight: 700;
+}
+.breadcrumb li.current:after {
+  display: none;
+}
+
+/* Sticky Nav overrides */
+.sticky-menu {
+  position: fixed;
+  width: 940px;
+  height: 0px;
+  z-index: 51;
+  top: 12px;
+}
+#sticky-header {
+  display: none;
+  padding: 0 10px;
+  position: fixed;
+  background: #f9f9f9;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  height: 45px;
+  box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.1);
+  border-bottom: 1px solid #a5c43a;
+  z-index: 50;
+}
+#sticky-header.design {
+  border-bottom: 1px solid #33b5e5;
+}
+#sticky-header.develop {
+  border-bottom: 1px solid #F80;
+}
+#sticky-header.distribute {
+  border-bottom: 1px solid #9C0;
+}
+#sticky-header.about {
+  border-bottom: 1px solid #9933CC;
+}
+#sticky-header > div {
+  overflow: hidden;
+  *zoom: 1;
+  width: 940px;
+  margin: 0 auto;
+  clear: both;
+  padding-top: 9px;
+}
+#sticky-header > div .logo {
+  float: left;
+  width: 26px;
+  height: 25px;
+  background: url(../images/dac_logo.png);
+  z-index: 52;
+  position: relative;
+}
+#sticky-header > div .top {
+  float: left;
+  width: 38px;
+  height: 38px;
+  position: relative;
+  background: url(../images/styles/gototop.png);
+  z-index: 52;
+}
+#sticky-header > div .breadcrumb {
+  float: left;
+  padding: 0 0 0 10px;
+  border-left: 1px solid #d2d2d2;
+  line-height: 24px;
+  font-size: 14px;
+  position: relative;
+  top: 0px;
+  z-index: 52;
 }
 
 
-
-
-
-
+}
 
 
 
@@ -4001,7 +4156,6 @@
 }
 
 .logo a {
-  width:123px;
   float:left;
 }
 
@@ -4013,6 +4167,17 @@
   padding-right:10px;
 }
 
+
+#header-wrap .logo.wear-logo {
+  width:220px;
+  margin:0;
+  padding:0;
+  margin-bottom:22px;
+}
+#header-wrap .logo.wear-logo img {
+  padding:0 0 0 10px;
+}
+
 .search {
   height:25px;
   margin-top: -3px;
@@ -4436,11 +4601,11 @@
 }
 
 #nav-x {
-  padding-top: 14px;
+  padding-top: 13px;
 }
 
 #nav-x .wrap {
-  min-height:34px;
+  min-height:32px;
 }
 
 #nav-x .wrap,
@@ -4782,53 +4947,6 @@
 
 
 
-/************ DISTRIBUTE HOMEPAGE ***************/
-
-.marquee {
-  width: 760px;
-}
-.marquee .main-img {
-  float: left;
-  margin-top: 20px;
-  width: 490px;
-}
-.marquee .copy {
-  width: 270px;
-  float: left;
-  margin-top: 30px;
-}
-.distribute-features {
-  margin: 0;
-}
-.distribute-features ul {
-  margin: 0;
-}
-.distribute-features ul li {
-  list-style: none;
-  float: left;
-  border-top: 1px solid #9C0;
-  width: 220px;
-  margin-right: 50px;
-}
-.distribute-features ul li.last {
-  margin-right: 0px;
-}
-
-.distribute-features .distribute-link li a {
-  color:red !important;
-}
-
-.distribute-features .distribute-link li a,
-.distribute-features .distribute-link li a:active {
-  color:#555 !important;
-}
-
-.distribute-features .distribute-link li a:hover,
-.distribute-features .distribute-link li a:hover * {
-  color:#7AA1B0 !important;
-}
-
-
 /************ DEVELOP TOPIC CONTAINERS ************/
 
 .landing-banner,
@@ -5006,3 +5124,1263 @@
 .fullpage #footer {
   margin-top: -40px;
 }
+
+/************ DISTRIBUTE PAGES ******************/
+
+/* Article page header line fix */
+.headerLine {
+  overflow: hidden;
+}
+.headerLine h1 {
+  float: left;
+  padding-right: 20px;
+  margin-bottom: 0px;
+  font-size: 20px;
+  color: #363636;
+}
+.headerLine hr {
+  overflow: hidden;
+  margin: 42px 0 0 0;
+}
+
+.article-detail #body-content {
+  padding-top: 10px;
+}
+
+/* A container for grid sets with uppercase h3 and rule */
+.dynamic-grid h3 {
+  font-size:14px;
+  line-height:21px;
+  color:#555;
+  text-transform:uppercase;
+  border-bottom:1px solid #CCC;
+  padding:8px 0 0 1px;
+  margin-bottom:10px;
+  clear:both;
+}
+
+.top-right-float {
+  float: right;
+}
+
+.clearfloat {
+  float: none;
+  clear: both;
+}
+
+.border-img {
+  border: 1px solid #CCC;
+}
+
+.center-img {
+  margin: auto;
+  text-align: center;
+}
+.center-img img {
+  margin-bottom: 15px;
+}
+
+.figure img, .border-img {
+  margin-bottom: 15px;
+}
+
+/************ RESOURCE CARDS ******************/
+
+/* Resource cards, 12, 13, 16-col */
+
+/* Basic card-styling with shadow */
+.resource-card {
+  border-radius: 1px;
+  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.14);
+  background: #fefefe;
+}
+
+/* Styling for background image including tinting and section icons in stacks */
+.card-bg {
+  display: block;
+  position: absolute;
+  vertical-align: top;
+  width: 100%;
+  left: 0;
+  top: 0;
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-image: url(../images/resource-card-default-android.jpg);
+}
+.card-bg:after {
+  content: "";
+  display: block;
+  height: 100%;
+  width: 100%;
+  opacity: 1;
+  background: rgba(0, 0, 0, 0.2);
+  -webkit-transition: opacity 0.5s;
+  -moz-transition: opacity 0.5s;
+  -o-transition: opacity 0.5s;
+  transition: opacity 0.5s;
+}
+.card-bg .card-section-icon {
+  position: absolute;
+  top: 50%;
+  width: 100%;
+  margin-top: -35px;
+  text-align: center;
+  padding-top: 65px;
+  z-index: 100;
+}
+.card-bg .card-section-icon .icon {
+  position: absolute;
+  left: 50%;
+  margin-left: -28px;
+  top: 0px;
+  width: 56px;
+  height: 56px;
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  background-image: url(../images/stack-icon.png);
+}
+.card-bg .card-section-icon .section {
+  text-transform: uppercase;
+  color: white;
+  font-size: 14px;
+}
+
+.card-info {
+  position: absolute;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  overflow: hidden;
+  background: #fefefe;
+  padding: 4px 12px 6px 12px;
+}
+.card-info .section {
+  text-transform: uppercase;
+  color: #898989;
+  font-size: 12px;
+  margin-bottom: 1px;
+}
+.card-info .title {
+  color: #363636;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding-bottom: 5px;
+  margin-bottom: -2px;
+  font-size: 16px;
+}
+.card-info .description {
+  overflow: hidden;
+}
+.card-info .description .text {
+  color: #464646;
+  font: 13px/15px Roboto Condensed;
+  overflow: hidden;
+  width:100%;
+}
+.card-info .description .util {
+  position: absolute;
+  right: 5px;
+  bottom: 70px; /*-2px;*/
+  opacity: 0;
+  -webkit-transition: opacity 0.5s;
+  -moz-transition: opacity 0.5s;
+  -o-transition: opacity 0.5s;
+  transition: opacity 0.5s;
+}
+.card-info.empty-desc .title {
+  white-space: normal;
+  overflow: visible;
+}
+.card-info.empty-desc .description {
+  display: none;
+}
+/* Truncate card summaries at bounding box and
+ * and apply ellipsis at lower right */
+.ellipsis {
+  overflow: hidden;
+  float:right;
+  line-height: 15px;
+  width:100%;
+}
+.resource-card-6x6 .card-info .description .teddddddxt {
+ float:left;
+  position:relative;
+  margin-left:0;
+}
+.ellipsis:before {
+  content:"";
+  float: left;
+  width: 5px;
+  height:100%;
+}
+.ellipsis > *:first-child.text {
+  float: right;
+  width: 100%  !important;
+  margin-left: -5px;
+}
+.ellipsis:after {
+  content: "\02026";
+  height:17px;
+  padding-bottom:4px;
+
+  box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+
+  float: right; position: relative;
+  top: -16px; left: 100%;
+  width: 4em; margin-left: -4em;
+  padding-right: 5px;
+
+  background: -webkit-gradient(linear, left top, right top,
+    from(rgba(255, 255, 255, 0)), to(white), color-stop(65%, white));
+  background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+  background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+  background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+  background: linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+}
+.ellipsis:after {
+  font-style: normal; color: #aaa;
+  font-size:13px;
+  text-align: right;
+}
+
+/* Flow Layout */
+.resource-flow-layout {
+  display: inline-block;
+}
+.resource-flow-layout .resource-card, .resource-flow-layout .resource-card-stack {
+  float: left;
+  position: relative;
+}
+.resource-flow-layout .resource-card-stack > .resource-card {
+  margin-right: 0px !important;
+}
+.resource-flow-layout:after {
+  content: ".";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+.resource-card:hover {
+  cursor: pointer;
+}
+.resource-card:hover .card-bg:after {
+  opacity: 0;
+}
+/* disabled to make way for fade/ellipsis truncation,
+   and the plusone moves up. 
+.resource-card:hover .card-info .description .text {
+  padding-right: 70px;
+} */
+.resource-card:hover .card-info .description .util {
+  opacity: 1;
+}
+
+/* Carousel Layout */
+/* Carousel styles for landing page */
+.resource-carousel-layout {
+  margin: 20px 0 20px 0;
+  position: relative;
+  overflow: hidden;
+}
+.resource-carousel-layout .slideshow-prev, .resource-carousel-layout .slideshow-next {
+  display: none;
+}
+.resource-carousel-layout .pagination {
+  bottom: 0px;
+}
+.resource-carousel-layout .frame li {
+  position: relative;
+}
+.resource-carousel-layout .frame li .card-bg {
+  height: 300px;
+}
+.resource-carousel-layout .frame li .card-info {
+  padding: 7px 15px 0px 15px;
+  top: 300px;
+}
+.resource-carousel-layout .frame li .card-info .section {
+  font-size: 13px;
+  margin-bottom: 7px;
+}
+.resource-carousel-layout .frame li .card-info .title {
+  font-size: 25px;
+  margin-bottom: 2px;
+}
+.resource-carousel-layout .frame li .card-info .description {
+  font-family: 15px/16px Roboto Condensed, sans-serif;
+}
+.resource-carousel-layout .frame li .card-info .description .text {
+  height: 40px;
+}
+.resource-carousel-layout .frame li .card-info .description .util {
+  bottom:97px;
+  right:4px;
+}
+
+/* Stack Layout */
+.resource-stack-layout {
+  display: inline-block;
+}
+.resource-stack-layout .resource-card-stack {
+  float: left;
+  position: relative;
+}
+.resource-stack-layout .resource-card {
+  margin-bottom: 20px;
+  display: block;
+  position: relative;
+}
+.resource-stack-layout .section-card-menu > .card-info .section, .resource-stack-layout .section-card > .card-info .title {
+  /*text-transform: uppercase;*/
+  color: #898989;
+  font-size: 17px;
+  line-height: 24px;
+  margin-bottom: 6px;
+}
+.resource-stack-layout .section-card {
+  height: 284px;
+}
+.resource-stack-layout .section-card > .card-bg {
+  height: 192px;
+}
+.resource-stack-layout .section-card > .card-info {
+  padding: 4px 12px 6px 12px;
+  top: 192px;
+}
+.resource-stack-layout .section-card > .card-info .section {
+  display: none;
+}
+.resource-stack-layout .section-card > .card-info .title {
+  font-size: 17px;
+  border-bottom: 1px solid #959595;
+  padding-bottom: 0px;
+}
+.resource-stack-layout .section-card > .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+.resource-stack-layout .section-card > .card-info .description .text {
+  height: 30px;
+}
+.resource-stack-layout .related-card {
+  height: 90px;
+}
+.resource-stack-layout .related-card > .card-bg {
+  left: 0;
+  top: 0;
+  width: 90px;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.resource-stack-layout .related-card > .card-info {
+  left: 90px;
+  padding: 4px 12px 4px 12px;
+}
+.resource-stack-layout .related-card > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+  display: none;
+}
+.resource-stack-layout .related-card > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+  overflow: visible;
+  text-overflow: ellipsis;
+}
+.resource-stack-layout .related-card > .card-info .title:after {
+  content: url(../images/link-out.png);
+  display: block;
+}
+.resource-stack-layout .related-card > .card-info .description {
+  display: none;
+}
+.resource-stack-layout .section-card-menu {
+  /* Flexible height */
+  display: block;
+  height: auto;
+  width: auto;
+}
+.resource-stack-layout .section-card-menu .card-bg {
+  height: 155px;
+  /* Flexible height */
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+}
+.resource-stack-layout .section-card-menu .card-info {
+  padding: 4px 12px 0px 12px;
+  /* Flexible height */
+  position: relative;
+  left: auto;
+  top: auto;
+  right: auto;
+  bottom: auto;
+}
+.resource-stack-layout .section-card-menu .card-info ul {
+  list-style: none;
+  margin: 0;
+}
+.resource-stack-layout .section-card-menu .card-info ul li {
+  list-style: none;
+  margin: 0;
+  padding: 15px 0;
+  border-top-width: 1px;
+  border-top-style: solid;
+  border-top-color: #959595;
+}
+.resource-stack-layout .section-card-menu .card-info ul li a, .resource-stack-layout .section-card-menu .card-info ul li a:focus, .resource-stack-layout .section-card-menu .card-info ul li a:link, .resource-stack-layout .section-card-menu .card-info ul li a:visited, .resource-stack-layout .section-card-menu .card-info ul li a:active, .resource-stack-layout .section-card-menu .card-info ul li a:hover {
+  color: #363636 !important;
+}
+.resource-stack-layout .section-card-menu .card-info ul li:first-child {
+  border-top: none;
+}
+.resource-stack-layout .section-card-menu .card-info ul li:hover .title:after {
+  opacity: 1;
+  -webkit-transition: opacity 0.5s;
+  -moz-transition: opacity 0.5s;
+  -o-transition: opacity 0.5s;
+  transition: opacity 0.5s;
+}
+.resource-stack-layout .section-card-menu .card-info ul li:hover .description {
+  max-height: 30px;
+  opacity: 1;
+  -webkit-transition: max-height 0.5s, opacity 1s;
+  -moz-transition: max-height 0.5s, opacity 1s;
+  -o-transition: max-height 0.5s, opacity 1s;
+  transition: max-height 0.5s, opacity 1s;
+}
+.resource-stack-layout .section-card-menu .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  position: relative;
+}
+.resource-stack-layout .section-card-menu .card-info .title:after {
+  background: url(../images/stack-arrow-right.png);
+  content: '';
+  opacity: 0;
+  -webkit-transition: opacity 0.25s;
+  -moz-transition: opacity 0.25s;
+  -o-transition: opacity 0.25s;
+  transition: opacity 0.25s;
+  position: absolute;
+  right: 0px;
+  top: 3px;
+  width: 10px;
+  height: 15px;
+}
+.resource-stack-layout .section-card-menu .card-info .title.more {
+  text-transform: uppercase;
+  color: #898989;
+  display: inline-block;
+}
+.resource-stack-layout .section-card-menu .card-info .title.more:after {
+  background: url(../images/stack-arrow-right.png);
+  content: '';
+  display: block;
+  position: absolute;
+  right: -20px;
+  top: 3px;
+  width: 10px;
+  height: 15px;
+}
+.resource-stack-layout .section-card-menu .card-info .description {
+  max-height: 0px;
+  opacity: 0;
+  overflow: hidden;
+  font-size: 13px;
+  line-height: 15px;
+  /* Hover off */
+  -webkit-transition: max-height 0.5s, opacity 0.5s;
+  -moz-transition: max-height 0.5s, opacity 0.5s;
+  -o-transition: max-height 0.5s, opacity 0.5s;
+  transition: max-height 0.5s, opacity 0.5s;
+}
+.resource-stack-layout .section-card-menu .card-info .description .text {
+  height: 30px;
+}
+.resource-stack-layout:after {
+  content: ".";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+/* Generate the flow layout styles for a 3-column 16-col span */
+.resource-flow-layout.col-16 {
+  margin: 0 -14px 0 0;
+  width: 954px;
+}
+.resource-flow-layout.col-16 .resource-card, .resource-flow-layout.col-16 .resource-card-stack {
+  margin: 0 14px 20px 0;
+}
+.resource-flow-layout.col-16 .resource-card-row-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-16 .resource-card-col-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-16 .resource-card-3x6 {
+  width: 145px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-3x12 {
+  width: 145px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-3x18 {
+  width: 145px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-6x6 {
+  width: 304px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-6x12 {
+  width: 304px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-6x18 {
+  width: 304px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-9x6 {
+  width: 463px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-9x12 {
+  width: 463px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-9x18 {
+  width: 463px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-12x6 {
+  width: 622px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-12x12 {
+  width: 622px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-12x18 {
+  width: 622px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-15x6 {
+  width: 781px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-15x12 {
+  width: 781px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-15x18 {
+  width: 781px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-18x6 {
+  width: 940px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-18x12 {
+  width: 940px;
+  height: 420px;
+}
+.resource-flow-layout.col-16 .resource-card-18x18 {
+  width: 940px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-3x2 {
+  width: 145px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-3x2x3 {
+  width: 145px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-3x3 {
+  width: 145px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-3x3x2 {
+  width: 145px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-6x2 {
+  width: 304px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-6x2x3 {
+  width: 304px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-6x3 {
+  width: 304px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-6x3x2 {
+  width: 304px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-9x2 {
+  width: 463px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-9x2x3 {
+  width: 463px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-9x3 {
+  width: 463px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-9x3x2 {
+  width: 463px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-12x2 {
+  width: 622px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-12x2x3 {
+  width: 622px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-12x3 {
+  width: 622px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-12x3x2 {
+  width: 622px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-15x2 {
+  width: 781px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-15x2x3 {
+  width: 781px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-15x3 {
+  width: 781px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-15x3x2 {
+  width: 781px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-18x2 {
+  width: 940px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-18x2x3 {
+  width: 940px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-18x3 {
+  width: 940px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-18x3x2 {
+  width: 940px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+
+/* Generate the flow layout styles for a 3-column 16-col span */
+.resource-flow-layout.col-12 {
+  margin: 0 -14px 0 0;
+  width: 714px;
+}
+
+.resource-flow-layout.col-12 .resource-card, .resource-flow-layout.col-12 .resource-card-stack {
+  margin: 0 14px 20px 0;
+}
+.resource-flow-layout.col-12 .resource-card-row-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-12 .resource-card-col-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-12 .resource-card-3x6 {
+  width: 105px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-3x12 {
+  width: 105px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-3x18 {
+  width: 105px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-6x6 {
+  width: 224px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-6x12 {
+  width: 224px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-6x18 {
+  width: 224px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-9x6 {
+  width: 343px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-9x12 {
+  width: 343px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-9x18 {
+  width: 343px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-12x6 {
+  width: 462px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-12x12 {
+  width: 462px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-12x18 {
+  width: 462px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-15x6 {
+  width: 581px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-15x12 {
+  width: 581px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-15x18 {
+  width: 581px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-18x6 {
+  width: 700px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-18x12 {
+  width: 700px;
+  height: 420px;
+}
+.resource-flow-layout.col-12 .resource-card-18x18 {
+  width: 700px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-3x2 {
+  width: 105px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-3x2x3 {
+  width: 105px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-3x3 {
+  width: 105px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-3x3x2 {
+  width: 105px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-6x2 {
+  width: 224px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-6x2x3 {
+  width: 224px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-6x3 {
+  width: 224px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-6x3x2 {
+  width: 224px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-9x2 {
+  width: 343px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-9x2x3 {
+  width: 343px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-9x3 {
+  width: 343px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-9x3x2 {
+  width: 343px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-12x2 {
+  width: 462px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-12x2x3 {
+  width: 462px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-12x3 {
+  width: 462px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-12x3x2 {
+  width: 462px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-15x2 {
+  width: 581px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-15x2x3 {
+  width: 581px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-15x3 {
+  width: 581px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-15x3x2 {
+  width: 581px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-18x2 {
+  width: 700px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-18x2x3 {
+  width: 700px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-18x3 {
+  width: 700px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-18x3x2 {
+  width: 700px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+
+/* Generate the flow layout styles for a 3-column 13-col span */
+
+.resource-flow-layout.col-13 {
+  margin: 0 -14px 0 0;
+  width: 774px;
+}
+.resource-flow-layout.col-13 .resource-card, .resource-flow-layout.col-13 .resource-card-stack {
+  margin: 0 14px 20px 0;
+}
+.resource-flow-layout.col-13 .resource-card-row-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-13 .resource-card-col-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-13 .resource-card-3x6 {
+  width: 115px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-3x12 {
+  width: 115px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-3x18 {
+  width: 115px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-6x6 {
+  width: 244px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-6x12 {
+  width: 244px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-6x18 {
+  width: 244px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-9x6 {
+  width: 373px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-9x12 {
+  width: 373px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-9x18 {
+  width: 373px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-12x6 {
+  width: 502px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-12x12 {
+  width: 502px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-12x18 {
+  width: 502px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-15x6 {
+  width: 631px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-15x12 {
+  width: 631px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-15x18 {
+  width: 631px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-18x6 {
+  width: 760px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-18x12 {
+  width: 760px;
+  height: 420px;
+}
+.resource-flow-layout.col-13 .resource-card-18x18 {
+  width: 760px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-3x2 {
+  width: 115px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-3x2x3 {
+  width: 115px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-3x3 {
+  width: 115px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-3x3x2 {
+  width: 115px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-6x2 {
+  width: 244px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-6x2x3 {
+  width: 244px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-6x3 {
+  width: 244px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-6x3x2 {
+  width: 244px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-9x2 {
+  width: 373px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-9x2x3 {
+  width: 373px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-9x3 {
+  width: 373px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-9x3x2 {
+  width: 373px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-12x2 {
+  width: 502px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-12x2x3 {
+  width: 502px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-12x3 {
+  width: 502px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-12x3x2 {
+  width: 502px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-15x2 {
+  width: 631px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-15x2x3 {
+  width: 631px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-15x3 {
+  width: 631px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-15x3x2 {
+  width: 631px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-18x2 {
+  width: 760px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-18x2x3 {
+  width: 760px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-18x3 {
+  width: 760px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-18x3x2 {
+  width: 760px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+
+/*
+  The following are styles for cards in the flowlayout above, styled by the number of rows they span
+*/
+/* Single row items, might be simpler to just apply a class */
+.resource-card-3x6 > .card-bg, .resource-card-6x6 > .card-bg, .resource-card-9x6 > .card-bg, .resource-card-12x6 > .card-bg, .resource-card-15x6 > .card-bg, .resource-card-18x6 > .card-bg {
+  height: 192px;
+}
+.resource-card-3x6 > .card-info, .resource-card-6x6 > .card-info, .resource-card-9x6 > .card-info, .resource-card-12x6 > .card-info, .resource-card-15x6 > .card-info, .resource-card-18x6 > .card-info {
+  padding: 4px 12px 6px 12px;
+  top: 192px;
+}
+.resource-card-3x6 > .card-info .section, .resource-card-6x6 > .card-info .section, .resource-card-9x6 > .card-info .section, .resource-card-12x6 > .card-info .section, .resource-card-15x6 > .card-info .section, .resource-card-18x6 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+}
+.resource-card-3x6 > .card-info .title, .resource-card-6x6 > .card-info .title, .resource-card-9x6 > .card-info .title, .resource-card-12x6 > .card-info .title, .resource-card-15x6 > .card-info .title, .resource-card-18x6 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+}
+.resource-card-3x6 > .card-info .description, .resource-card-6x6 > .card-info .description, .resource-card-9x6 > .card-info .description, .resource-card-12x6 > .card-info .description, .resource-card-15x6 > .card-info .description, .resource-card-18x6 > .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+.resource-card-3x6 > .card-info .description .text, .resource-card-6x6 > .card-info .description .text, .resource-card-9x6 > .card-info .description .text, .resource-card-12x6 > .card-info .description .text, .resource-card-15x6 > .card-info .description .text, .resource-card-18x6 > .card-info .description .text {
+  height: 30px;
+}
+
+/* Double row items */
+.resource-card-3x12 > .card-bg, .resource-card-6x12 > .card-bg, .resource-card-9x12 > .card-bg, .resource-card-12x12 > .card-bg, .resource-card-15x12 > .card-bg, .resource-card-18x12 > .card-bg {
+  height: 320px;
+}
+.resource-card-3x12 > .card-info, .resource-card-6x12 > .card-info, .resource-card-9x12 > .card-info, .resource-card-12x12 > .card-info, .resource-card-15x12 > .card-info, .resource-card-18x12 > .card-info {
+  padding: 4px 12px 6px 12px;
+  top: 320px;
+}
+.resource-card-3x12 > .card-info .section, .resource-card-6x12 > .card-info .section, .resource-card-9x12 > .card-info .section, .resource-card-12x12 > .card-info .section, .resource-card-15x12 > .card-info .section, .resource-card-18x12 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+}
+.resource-card-3x12 > .card-info .title, .resource-card-6x12 > .card-info .title, .resource-card-9x12 > .card-info .title, .resource-card-12x12 > .card-info .title, .resource-card-15x12 > .card-info .title, .resource-card-18x12 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+}
+.resource-card-3x12 > .card-info .description, .resource-card-6x12 > .card-info .description, .resource-card-9x12 > .card-info .description, .resource-card-12x12 > .card-info .description, .resource-card-15x12 > .card-info .description, .resource-card-18x12 > .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+
+/* 1/3 row items */
+.resource-card-3x2 > .card-bg, .resource-card-6x2 > .card-bg, .resource-card-9x2 > .card-bg, .resource-card-12x2 > .card-bg, .resource-card-15x2 > .card-bg, .resource-card-18x2 > .card-bg {
+  left: 0;
+  top: 0;
+  width: 90px;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.resource-card-3x2 > .card-info, .resource-card-6x2 > .card-info, .resource-card-9x2 > .card-info, .resource-card-12x2 > .card-info, .resource-card-15x2 > .card-info, .resource-card-18x2 > .card-info {
+  left: 90px;
+  padding: 4px 12px 4px 12px;
+  height: 80px;
+  overflow: hidden;
+}
+.resource-card-3x2 > .card-info .section, .resource-card-6x2 > .card-info .section, .resource-card-6x3 > .card-info .section, .resource-card-9x2 > .card-info .section, .resource-card-12x2 > .card-info .section, .resource-card-15x2 > .card-info .section, .resource-card-18x2 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+  /* display: none; */
+}
+.resource-card-3x2 > .card-info .title, .resource-card-6x2 > .card-info .title, .resource-card-9x2 > .card-info .title, .resource-card-12x2 > .card-info .title, .resource-card-15x2 > .card-info .title, .resource-card-18x2 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+  overflow: visible;
+  text-overflow: ellipsis;
+}
+.resource-card-3x2 > .card-info .title:after, .resource-card-6x2 > .card-info .title:after, .resource-card-9x2 > .card-info .title:after, .resource-card-12x2 > .card-info .title:after, .resource-card-15x2 > .card-info .title:after, .resource-card-18x2 > .card-info .title:after {
+  /* content: url(../images/link-out.png); */
+  display: block;
+}
+.resource-card-3x2 > .card-info .description, .resource-card-6x2 > .card-info .description, .resource-card-9x2 > .card-info .description, .resource-card-12x2 > .card-info .description, .resource-card-15x2 > .card-info .description, .resource-card-18x2 > .card-info .description {
+  display: none;
+}
+
+/* 1/2 row items */
+.resource-card-3x3 > .card-bg, .resource-card-6x3 > .card-bg, .resource-card-9x3 > .card-bg, .resource-card-12x3 > .card-bg, .resource-card-15x3 > .card-bg, .resource-card-18x3 > .card-bg {
+  left: 0;
+  top: 0;
+  width: 90px;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.resource-card-3x3 > .card-info, .resource-card-6x3 > .card-info, .resource-card-9x3 > .card-info, .resource-card-12x3 > .card-info, .resource-card-15x3 > .card-info, .resource-card-18x3 > .card-info {
+  left: 90px;
+  padding: 4px 12px 0px 12px;
+}
+.resource-card-3x3 > .card-info .section, .resource-card-6x3 > .card-info .section, .resource-card-9x3 > .card-info .section, .resource-card-12x3 > .card-info .section, .resource-card-15x3 > .card-info .section, .resource-card-18x3 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+  display: none;
+}
+.resource-card-3x3 > .card-info .title, .resource-card-6x3 > .card-info .title, .resource-card-9x3 > .card-info .title, .resource-card-12x3 > .card-info .title, .resource-card-15x3 > .card-info .title, .resource-card-18x3 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+  overflow: visible;
+}
+.resource-card-3x3 > .card-info .description .text, .resource-card-6x3 > .card-info .description .text, .resource-card-9x3 > .card-info .description .text, .resource-card-12x3 > .card-info .description .text, .resource-card-15x3 > .card-info .description .text, .resource-card-18x3 > .card-info .description .text {
+  font-size: 12px;
+  line-height: 15px;
+  padding-right: 0px !important;
+  height: 80px;
+}
+.resource-card-3x3 > .card-info .description .util, .resource-card-6x3 > .card-info .description .util, .resource-card-9x3 > .card-info .description .util, .resource-card-12x3 > .card-info .description .util, .resource-card-15x3 > .card-info .description .util, .resource-card-18x3 > .card-info .description .util {
+  display: none;
+}
+/* placement of plusone */
+.resource-card-6x12 > .card-info .description .util, .resource-card-9x12 > .card-info .description .util, .resource-card-12x12 > .card-info .description .util, .resource-card-15x12 > .card-info .description .util {
+  bottom:2px;
+}
+.resource-card-18x12 > .card-info .description .util {
+  bottom:2px;
+}
+/* Overrides for col-16 6x6 cards linking to local content on landing pages.
+   Suppresses "section" and puts the title above a hairline rule. */
+.landing .card-info .section, .resource-flow-layout.col-16.landing .resource-card-9x6 .card-info .section {
+  display:none;
+}
+.landing  .card-info .title {
+  color: #898989;
+  font-size: 17px;
+  line-height: 24px;
+  margin-bottom: 6px;
+  border-bottom: 1px solid #959595;
+  padding-bottom: 0px;
+}
+.landing .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+.landing .card-info .description .text {
+height:30px;
+}
+.landing .resource-card-6x6 > .card-info .description .util, .landing .resource-card-9x6 > .card-info .description .util {
+  bottom:2px;
+}
+/*
+  Generate a resource stack layout for a 3 column widget spanning 16 grid cols
+*/
+.resource-stack-layout.col-16 {
+  margin: 0 -14px 0 0;
+  width: 954px;
+}
+.resource-stack-layout.col-16 .resource-card-stack {
+  margin: 0 14px 0 0;
+  width: 304px;
+}
+
+/* Example of card menu tinting */
+.resource-widget[data-section=distribute\/tools] .section-card-menu
+.card-bg:after {
+  background: rgba(126, 55, 148, 0.4) !important;
+}
+.resource-widget[data-section=distribute\/tools] .section-card-menu
+.card-section-icon .icon {
+  background-color: #7e3794 !important;
+}
+.resource-widget[data-section=distribute\/tools] .section-card-menu
+.card-info ul li {
+  border-top-color: #7e3794 !important;
+}
+
+/* tinting for stacks */
+
+div.jd-descr > .resource-widget[data-section=distribute\/tools]
+.section-card-menu .card-info ul li {
+  border-top-color: #7e3794 !important;
+}
\ No newline at end of file
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/css/fullscreen.css b/tools/droiddoc/templates-sdk-dyn/assets/css/fullscreen.css
index 71cf65b..53d9a64 100644
--- a/tools/droiddoc/templates-sdk-dyn/assets/css/fullscreen.css
+++ b/tools/droiddoc/templates-sdk-dyn/assets/css/fullscreen.css
@@ -170,7 +170,7 @@
   max-width: 100%;
 }
 
-#nav-x .wrap,
+#header-wrapper #nav-x div.wrap,
 #searchResults.wrap {
     max-width:100%;
 }
@@ -184,7 +184,18 @@
   left:20px; /* !important ... for IE i think */
 }
 
+#sticky-header {
+  padding: 0 20px;
+}
 
+#sticky-header > div {
+  width: 100%;
+}
+
+.sticky-menu {
+  width:100%;
+  left:-20px;
+}
 
 
 }
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/images/breadcrumb.png b/tools/droiddoc/templates-sdk-dyn/assets/images/breadcrumb.png
new file mode 100644
index 0000000..407a318
--- /dev/null
+++ b/tools/droiddoc/templates-sdk-dyn/assets/images/breadcrumb.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/images/dac_logo@2x.png b/tools/droiddoc/templates-sdk-dyn/assets/images/dac_logo@2x.png
new file mode 100644
index 0000000..0f2784d
--- /dev/null
+++ b/tools/droiddoc/templates-sdk-dyn/assets/images/dac_logo@2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/images/link-out.png b/tools/droiddoc/templates-sdk-dyn/assets/images/link-out.png
new file mode 100644
index 0000000..aa55f9a
--- /dev/null
+++ b/tools/droiddoc/templates-sdk-dyn/assets/images/link-out.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/images/resource-card-default-android.jpg b/tools/droiddoc/templates-sdk-dyn/assets/images/resource-card-default-android.jpg
new file mode 100644
index 0000000..8050744
--- /dev/null
+++ b/tools/droiddoc/templates-sdk-dyn/assets/images/resource-card-default-android.jpg
Binary files differ
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/images/stack-arrow-right.png b/tools/droiddoc/templates-sdk-dyn/assets/images/stack-arrow-right.png
new file mode 100644
index 0000000..46d6a50
--- /dev/null
+++ b/tools/droiddoc/templates-sdk-dyn/assets/images/stack-arrow-right.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk-dyn/assets/js/docs.js b/tools/droiddoc/templates-sdk-dyn/assets/js/docs.js
index 6630bf9..e6befe3 100644
--- a/tools/droiddoc/templates-sdk-dyn/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk-dyn/assets/js/docs.js
@@ -167,10 +167,12 @@
   // highlight Design tab
   if ($("body").hasClass("design")) {
     $("#header li.design a").addClass("selected");
+    $("#sticky-header").addClass("design");
 
   // highlight Develop tab
   } else if ($("body").hasClass("develop") || $("body").hasClass("google")) {
     $("#header li.develop a").addClass("selected");
+    $("#sticky-header").addClass("develop");
     // In Develop docs, also highlight appropriate sub-tab
     var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
     if (rootDir == "training") {
@@ -195,12 +197,34 @@
   // highlight Distribute tab
   } else if ($("body").hasClass("distribute")) {
     $("#header li.distribute a").addClass("selected");
-  }
+    $("#sticky-header").addClass("distribute");
+
+    var baseFrag = pagePathOriginal.indexOf('/', 1) + 1;
+    var secondFrag = pagePathOriginal.substring(baseFrag, pagePathOriginal.indexOf('/', baseFrag));
+    if (secondFrag == "users") {
+      $("#nav-x li.users a").addClass("selected");
+    } else if (secondFrag == "engage") {
+      $("#nav-x li.engage a").addClass("selected");
+    } else if (secondFrag == "monetize") {
+      $("#nav-x li.monetize a").addClass("selected");
+    } else if (secondFrag == "tools") {
+      $("#nav-x li.disttools a").addClass("selected");
+    } else if (secondFrag == "stories") {
+      $("#nav-x li.stories a").addClass("selected");
+    } else if (secondFrag == "essentials") {
+      $("#nav-x li.essentials a").addClass("selected");
+    } else if (secondFrag == "googleplay") {
+      $("#nav-x li.googleplay a").addClass("selected");
+    }
+  } else if ($("body").hasClass("about")) {
+    $("#sticky-header").addClass("about");
+  } 
 
   // set global variable so we can highlight the sidenav a bit later (such as for google reference)
   // and highlight the sidenav
   mPagePath = pagePath;
   highlightSidenav();
+  buildBreadcrumbs();
 
   // set up prev/next links if they exist
   var $selNavLink = $('#nav').find('a[href="' + pagePath + '"]');
@@ -385,70 +409,6 @@
   });
 
 
-  // Set up fixed navbar
-  var prevScrollLeft = 0; // used to compare current position to previous position of horiz scroll
-  $(window).scroll(function(event) {
-    if ($('#side-nav').length == 0) return;
-    if (event.target.nodeName == "DIV") {
-      // Dump scroll event if the target is a DIV, because that means the event is coming
-      // from a scrollable div and so there's no need to make adjustments to our layout
-      return;
-    }
-    var scrollTop = $(window).scrollTop();
-    var headerHeight = $('#header').outerHeight();
-    var subheaderHeight = $('#nav-x').outerHeight();
-    var searchResultHeight = $('#searchResults').is(":visible") ?
-                             $('#searchResults').outerHeight() : 0;
-    var totalHeaderHeight = headerHeight + subheaderHeight + searchResultHeight;
-    // we set the navbar fixed when the scroll position is beyond the height of the site header...
-    var navBarShouldBeFixed = scrollTop > totalHeaderHeight;
-    // ... except if the document content is shorter than the sidenav height.
-    // (this is necessary to avoid crazy behavior on OSX Lion due to overscroll bouncing)
-    if ($("#doc-col").height() < $("#side-nav").height()) {
-      navBarShouldBeFixed = false;
-    }
-
-    var scrollLeft = $(window).scrollLeft();
-    // When the sidenav is fixed and user scrolls horizontally, reposition the sidenav to match
-    if (navBarIsFixed && (scrollLeft != prevScrollLeft)) {
-      updateSideNavPosition();
-      prevScrollLeft = scrollLeft;
-    }
-
-    // Don't continue if the header is sufficently far away
-    // (to avoid intensive resizing that slows scrolling)
-    if (navBarIsFixed && navBarShouldBeFixed) {
-      return;
-    }
-
-    if (navBarIsFixed != navBarShouldBeFixed) {
-      if (navBarShouldBeFixed) {
-        // make it fixed
-        var width = $('#devdoc-nav').width();
-        $('#devdoc-nav')
-            .addClass('fixed')
-            .css({'width':width+'px'})
-            .prependTo('#body-content');
-        // add neato "back to top" button
-        $('#devdoc-nav a.totop').css({'display':'block','width':$("#nav").innerWidth()+'px'});
-
-        // update the sidenaav position for side scrolling
-        updateSideNavPosition();
-      } else {
-        // make it static again
-        $('#devdoc-nav')
-            .removeClass('fixed')
-            .css({'width':'auto','margin':''})
-            .prependTo('#side-nav');
-        $('#devdoc-nav a.totop').hide();
-      }
-      navBarIsFixed = navBarShouldBeFixed;
-    }
-
-    resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
-  });
-
-
   var navBarLeftPos;
   if ($('#devdoc-nav').length) {
     setNavBarLeftPos();
@@ -593,6 +553,28 @@
   });
 }
 
+
+/** Create the list of breadcrumb links in the sticky header */
+function buildBreadcrumbs() {
+  var $breadcrumbUl =  $("#sticky-header ul.breadcrumb");
+  // Add the secondary horizontal nav item, if provided
+  var $selectedSecondNav = $("div#nav-x ul.nav-x a.selected").clone().removeClass("selected");
+  if ($selectedSecondNav.length) {
+    $breadcrumbUl.prepend($("<li>").append($selectedSecondNav))
+  }
+  // Add the primary horizontal nav
+  var $selectedFirstNav = $("div#header-wrap ul.nav-x a.selected").clone().removeClass("selected");
+  // If there's no header nav item, use the logo link and title from alt text
+  if ($selectedFirstNav.length < 1) {
+    $selectedFirstNav = $("<a>")
+        .attr('href', $("div#header .logo a").attr('href'))
+        .text($("div#header .logo img").attr('alt'));
+  }
+  $breadcrumbUl.prepend($("<li>").append($selectedFirstNav));
+}
+
+
+
 /** Highlight the current page in sidenav, expanding children as appropriate */
 function highlightSidenav() {
   // if something is already highlighted, undo it. This is for dynamic navigation (Samples index)
@@ -705,9 +687,8 @@
   // Then figure out based on scroll position whether the header is visible
   var windowHeight = $window.height();
   var scrollTop = $window.scrollTop();
-  var headerHeight = $('#header').outerHeight();
-  var subheaderHeight = $('#nav-x').outerHeight();
-  var headerVisible = (scrollTop < (headerHeight + subheaderHeight));
+  var headerHeight = $('#header-wrapper').outerHeight();
+  var headerVisible = scrollTop < stickyTop;
 
   // get the height of space between nav and top of window.
   // Could be either margin or top position, depending on whether the nav is fixed.
@@ -717,7 +698,7 @@
   // Depending on whether the header is visible, set the side nav's height.
   if (headerVisible) {
     // The sidenav height grows as the header goes off screen
-    navHeight = windowHeight - (headerHeight + subheaderHeight - scrollTop) - topMargin;
+    navHeight = windowHeight - (headerHeight - scrollTop) - topMargin;
   } else {
     // Once header is off screen, the nav height is almost full window height
     navHeight = windowHeight - topMargin;
@@ -905,8 +886,115 @@
 
 
 
+var stickyTop;
+/* Sets the vertical scoll position at which the sticky bar should appear.
+   This method is called to reset the position when search results appear or hide */
+function setStickyTop() {
+  stickyTop = $('#header-wrapper').outerHeight() - $('#sticky-header').outerHeight();
+}
 
 
+/* 
+ * Displays sticky nav bar on pages when dac header scrolls out of view 
+ */
+(function() {
+  $(document).ready(function() {
+
+    setStickyTop();
+    var sticky = false;
+    var hiding = false;
+    var $stickyEl = $('#sticky-header');
+    var $menuEl = $('.menu-container');
+
+    var prevScrollLeft = 0; // used to compare current position to previous position of horiz scroll
+
+    $(window).scroll(function() {
+      // Exit if there's no sidenav
+      if ($('#side-nav').length == 0) return;
+      // Exit if the mouse target is a DIV, because that means the event is coming
+      // from a scrollable div and so there's no need to make adjustments to our layout
+      if (event.target.nodeName == "DIV") {
+        return;
+      }
+
+
+      var top = $(window).scrollTop();
+      // we set the navbar fixed when the scroll position is beyond the height of the site header...
+      var shouldBeSticky = top >= stickyTop;
+      // ... except if the document content is shorter than the sidenav height.
+      // (this is necessary to avoid crazy behavior on OSX Lion due to overscroll bouncing)
+      if ($("#doc-col").height() < $("#side-nav").height()) {
+        shouldBeSticky = false;
+      }
+
+      // Don't continue if the header is sufficently far away
+      // (to avoid intensive resizing that slows scrolling)
+      if (sticky && shouldBeSticky) {
+        return;
+      }
+
+      // Account for horizontal scroll
+      var scrollLeft = $(window).scrollLeft();
+      // When the sidenav is fixed and user scrolls horizontally, reposition the sidenav to match
+      if (navBarIsFixed && (scrollLeft != prevScrollLeft)) {
+        updateSideNavPosition();
+        prevScrollLeft = scrollLeft;
+      }
+
+      // If sticky header visible and position is now near top, hide sticky
+      if (sticky && !shouldBeSticky) {
+        sticky = false;
+        hiding = true;
+        // make the sidenav static again
+        $('#devdoc-nav')
+            .removeClass('fixed')
+            .css({'width':'auto','margin':''})
+            .prependTo('#side-nav');
+        // delay hide the sticky
+        $menuEl.removeClass('sticky-menu');
+        $stickyEl.fadeOut(250);
+        hiding = false;
+
+        // update the sidenaav position for side scrolling
+        updateSideNavPosition();
+      } else if (!sticky && shouldBeSticky) {
+        sticky = true;
+        $stickyEl.fadeIn(10);
+        $menuEl.addClass('sticky-menu');
+
+        // make the sidenav fixed
+        var width = $('#devdoc-nav').width();
+        $('#devdoc-nav')
+            .addClass('fixed')
+            .css({'width':width+'px'})
+            .prependTo('#body-content');
+
+        // update the sidenaav position for side scrolling
+        updateSideNavPosition();
+
+      } else if (hiding && top < 15) {
+        $menuEl.removeClass('sticky-menu');
+        $stickyEl.hide();
+        hiding = false;
+      }
+
+      resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
+    });
+
+    // Stack hover states
+    $('.section-card-menu').each(function(index, el) {
+      var height = $(el).height();
+      $(el).css({height:height+'px', position:'relative'});
+      var $cardInfo = $(el).find('.card-info');
+
+      $cardInfo.css({position: 'absolute', bottom:'0px', left:'0px', right:'0px', overflow:'visible'});
+    });
+
+    resizeNav();  // must resize once loading is finished
+  });
+
+})();
+
 
 
 
@@ -1724,6 +1812,7 @@
             $('.suggest-card').hide();
             if ($("#searchResults").is(":hidden") && (search.value != "")) {
               // if results aren't showing (and text not empty), return true to allow search to execute
+              $('body,html').animate({scrollTop:0}, '500', 'swing');
               return true;
             } else {
               // otherwise, results are already showing, so allow ajax to auto refresh the results
@@ -2278,13 +2367,13 @@
   var query = document.getElementById('search_autocomplete').value;
   location.hash = 'q=' + query;
   loadSearchResults();
-  $("#searchResults").slideDown('slow');
+  $("#searchResults").slideDown('slow', setStickyTop);
   return false;
 }
 
 
 function hideResults() {
-  $("#searchResults").slideUp();
+  $("#searchResults").slideUp('fast', setStickyTop);
   $(".search .close").addClass("hide");
   location.hash = '';
 
@@ -2401,7 +2490,7 @@
     return;
   } else {
     // first time loading search results for this page
-    $('#searchResults').slideDown('slow');
+    $('#searchResults').slideDown('slow', setStickyTop);
     $(".search .close").removeClass("hide");
     loadSearchResults();
   }
@@ -2409,19 +2498,22 @@
 
 // when an event on the browser history occurs (back, forward, load) requery hash and do search
 $(window).hashchange( function(){
-  // Exit if the hash isn't a search query or there's an error in the query
+  // If the hash isn't a search query or there's an error in the query,
+  // then adjust the scroll position to account for sticky header, then exit.
   if ((location.hash.indexOf("q=") == -1) || (query == "undefined")) {
     // If the results pane is open, close it.
     if (!$("#searchResults").is(":hidden")) {
       hideResults();
     }
+    // Adjust the scroll position to account for sticky header
+    $(window).scrollTop($(window).scrollTop() - 60);
     return;
   }
 
   // Otherwise, we have a search to do
   var query = decodeURI(getQuery(location.hash));
   searchControl.execute(query);
-  $('#searchResults').slideDown('slow');
+  $('#searchResults').slideDown('slow', setStickyTop);
   $("#search_autocomplete").focus();
   $(".search .close").removeClass("hide");
 
@@ -3233,3 +3325,560 @@
   $("#samples").append($ul);
 
 }
+
+
+
+/* ########################################################## */
+/* ###################  RESOURCE CARDS  ##################### */
+/* ########################################################## */
+
+/** Handle resource queries, collections, and grids (sections). Requires
+    jd_tag_helpers.js and the *_unified_data.js to be loaded. */
+
+(function() {
+  // Prevent the same resource from being loaded more than once per page.
+  var addedPageResources = {};
+
+  $(document).ready(function() {
+    $('.resource-widget').each(function() {
+      initResourceWidget(this);
+    });
+
+    /* Pass the line height to ellipsisfade() to adjust the height of the
+    text container to show the max number of lines possible, without
+    showing lines that are cut off. This works with the css ellipsis
+    classes to fade last text line and apply an ellipsis char. */
+
+    //card text currently uses 15px line height. 
+    var lineHeight = 15;
+    $('.card-info .text').ellipsisfade(lineHeight);
+  });
+
+  /*
+    Three types of resource layouts:
+    Flow - Uses a fixed row-height flow using float left style.
+    Carousel - Single card slideshow all same dimension absolute.
+    Stack - Uses fixed columns and flexible element height.
+  */
+  function initResourceWidget(widget) {
+    var $widget = $(widget);
+    var isFlow = $widget.hasClass('resource-flow-layout'),
+        isCarousel = $widget.hasClass('resource-carousel-layout'),
+        isStack = $widget.hasClass('resource-stack-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 = {
+      cardSizes: ($widget.data('cardsizes') || '').split(','),
+      maxResults: parseInt($widget.data('maxresults') || '100', 10),
+      itemsPerPage: $widget.data('itemsperpage'),
+      sortOrder: $widget.data('sortorder'),
+      query: $widget.data('query'),
+      section: $widget.data('section'),
+      sizeCols: sizeCols
+    };
+
+    // run the search for the set of resources to show
+
+    var resources = buildResourceList(opts);
+
+    if (isFlow) {
+      drawResourcesFlowWidget($widget, opts, resources);
+    } else if (isCarousel) {
+      drawResourcesCarouselWidget($widget, opts, resources);
+    } else if (isStack) {
+      var sections = buildSectionList(opts);
+      opts['numStacks'] = $widget.data('numstacks');
+      drawResourcesStackWidget($widget, opts, resources, sections);
+    }
+  }
+
+  /* Initializes a Resource Carousel Widget */
+  function drawResourcesCarouselWidget($widget, opts, resources) {
+    $widget.empty();
+    var plusone = true; //always show plusone on carousel
+
+    $widget.addClass('resource-card slideshow-container')
+      .append($('<a>').addClass('slideshow-prev').text('Prev'))
+      .append($('<a>').addClass('slideshow-next').text('Next'));
+
+    var css = { 'width': $widget.width() + 'px',
+                'height': $widget.height() + 'px' };
+
+    var $ul = $('<ul>');
+
+    for (var i = 0; i < resources.length; ++i) {
+      //keep url clean for matching and offline mode handling
+      var urlPrefix = resources[i].url.indexOf("//") > -1 ? "" : toRoot;
+      var $card = $('<a>')
+        .attr('href', urlPrefix + resources[i].url)
+        .decorateResourceCard(resources[i],plusone);
+
+      $('<li>').css(css)
+          .append($card)
+          .appendTo($ul);
+    }
+
+    $('<div>').addClass('frame')
+      .append($ul)
+      .appendTo($widget);
+
+    $widget.dacSlideshow({
+      auto: true,
+      btnPrev: '.slideshow-prev',
+      btnNext: '.slideshow-next'
+    });
+  };
+
+  /* Initializes a Resource Card Stack Widget (column-based layout) */
+  function drawResourcesStackWidget($widget, opts, resources, sections) {
+    // Don't empty widget, grab all items inside since they will be the first
+    // items stacked, followed by the resource query
+    var plusone = true; //by default show plusone on section cards
+    var cards = $widget.find('.resource-card').detach().toArray();
+    var numStacks = opts.numStacks || 1;
+    var $stacks = [];
+    var urlString;
+
+    for (var i = 0; i < numStacks; ++i) {
+      $stacks[i] = $('<div>').addClass('resource-card-stack')
+          .appendTo($widget);
+    }
+
+    var sectionResources = [];
+
+    // Extract any subsections that are actually resource cards
+    for (var i = 0; i < sections.length; ++i) {
+      if (!sections[i].sections || !sections[i].sections.length) {
+        //keep url clean for matching and offline mode handling
+        urlPrefix = sections[i].url.indexOf("//") > -1 ? "" : toRoot;
+        // Render it as a resource card
+
+        sectionResources.push(
+          $('<a>')
+            .addClass('resource-card section-card')
+            .attr('href', urlPrefix + sections[i].resource.url)
+            .decorateResourceCard(sections[i].resource,plusone)[0]
+        );
+
+      } else {
+        cards.push(
+          $('<div>')
+            .addClass('resource-card section-card-menu')
+            .decorateResourceSection(sections[i],plusone)[0]
+        );
+      }
+    }
+
+    cards = cards.concat(sectionResources);
+
+    for (var i = 0; i < resources.length; ++i) {
+      //keep url clean for matching and offline mode handling
+      urlPrefix = resources[i].url.indexOf("//") > -1 ? "" : toRoot;
+      var $card = $('<a>')
+          .addClass('resource-card related-card')
+          .attr('href', urlPrefix + resources[i].url)
+          .decorateResourceCard(resources[i],plusone);
+
+      cards.push($card[0]);
+    }
+
+    for (var i = 0; i < cards.length; ++i) {
+      // Find the stack with the shortest height, but give preference to
+      // left to right order.
+      var minHeight = $stacks[0].height();
+      var minIndex = 0;
+
+      for (var j = 1; j < numStacks; ++j) {
+        var height = $stacks[j].height();
+        if (height < minHeight - 45) {
+          minHeight = height;
+          minIndex = j;
+        }
+      }
+
+      $stacks[minIndex].append($(cards[i]));
+    }
+
+  };
+
+  /* Initializes a flow widget, see distribute.scss for generating accompanying css */
+  function drawResourcesFlowWidget($widget, opts, resources) {
+    $widget.empty();
+    var cardSizes = opts.cardSizes || ['6x6'];
+    var i = 0, j = 0;
+    var plusone = true; // by default show plusone on resource cards
+
+    while (i < resources.length) {
+      var cardSize = cardSizes[j++ % cardSizes.length];
+      cardSize = cardSize.replace(/^\s+|\s+$/,'');
+      console.log("cardsize is " + cardSize);
+      // Some card sizes do not get a plusone button, such as where space is constrained
+      // or for cards commonly embedded in docs (to improve overall page speed).
+      plusone = !((cardSize == "6x2") || (cardSize == "6x3") ||
+                  (cardSize == "9x2") || (cardSize == "9x3") ||
+                  (cardSize == "12x2") || (cardSize == "12x3"));
+
+      // A stack has a third dimension which is the number of stacked items
+      var isStack = cardSize.match(/(\d+)x(\d+)x(\d+)/);
+      var stackCount = 0;
+      var $stackDiv = null;
+
+      if (isStack) {
+        // Create a stack container which should have the dimensions defined
+        // by the product of the items inside.
+        $stackDiv = $('<div>').addClass('resource-card-stack resource-card-' + isStack[1]
+            + 'x' + isStack[2] * isStack[3]) .appendTo($widget);
+      }
+
+      // Build each stack item or just a single item
+      do {
+        var resource = resources[i];
+        //keep url clean for matching and offline mode handling
+        urlPrefix = resource.url.indexOf("//") > -1 ? "" : toRoot;
+        var $card = $('<a>')
+            .addClass('resource-card resource-card-' + cardSize + ' resource-card-' + resource.type)
+            .attr('href', urlPrefix + resource.url);
+
+        if (isStack) {
+          $card.addClass('resource-card-' + isStack[1] + 'x' + isStack[2]);
+          if (++stackCount == parseInt(isStack[3])) {
+            $card.addClass('resource-card-row-stack-last');
+            stackCount = 0;
+          }
+        } else {
+          stackCount = 0;
+        }
+
+        $card.decorateResourceCard(resource,plusone)
+          .appendTo($stackDiv || $widget);
+
+      } while (++i < resources.length && stackCount > 0);
+    }
+  }
+
+  /* Build a site map of resources using a section as a root. */
+  function buildSectionList(opts) {
+    if (opts.section && SECTION_BY_ID[opts.section]) {
+      return SECTION_BY_ID[opts.section].sections || [];
+    }
+    return [];
+  }
+
+  function buildResourceList(opts) {
+    var maxResults = opts.maxResults || 100;
+
+    var query = opts.query || '';
+    var expressions = parseResourceQuery(query);
+    var addedResourceIndices = {};
+    var results = [];
+
+    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;
+        case 'collection':
+          var urls = RESOURCE_COLLECTIONS[firstClause.value].resources || [];
+          resources = urls.map(function(url){ return ALL_RESOURCES_BY_URL[url]; });
+          break;
+        case 'section':
+          var urls = SITE_MAP[firstClause.value].sections || [];
+          resources = urls.map(function(url){ return ALL_RESOURCES_BY_URL[url]; });
+          break;
+      }
+      // console.log(firstClause.attr + ':' + firstClause.value);
+      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(addedResourceIndices));
+      }
+
+      // add to list of already added indices
+      for (var j = 0; j < resources.length; j++) {
+        // console.log(resources[j].title);
+        addedResourceIndices[resources[j].index] = 1;
+      }
+
+      // concat to final results list
+      results = results.concat(resources);
+    }
+
+    if (opts.sortOrder && results.length) {
+      var attr = opts.sortOrder;
+
+      if (opts.sortOrder == 'random') {
+        var i = results.length, j, temp;
+        while (--i) {
+          j = Math.floor(Math.random() * (i + 1));
+          temp = results[i];
+          results[i] = results[j];
+          results[j] = temp;
+        }
+      } else {
+        var desc = attr.charAt(0) == '-';
+        if (desc) {
+          attr = attr.substring(1);
+        }
+        results = results.sort(function(x,y) {
+          return (desc ? -1 : 1) * (parseInt(x[attr], 10) - parseInt(y[attr], 10));
+        });
+      }
+    }
+
+    results = results.filter(getResourceNotAlreadyAddedFilter(addedPageResources));
+    results = results.slice(0, maxResults);
+
+    for (var j = 0; j < results.length; ++j) {
+      addedPageResources[results[j].index] = 1;
+    }
+
+    return results;
+  }
+
+
+  function getResourceNotAlreadyAddedFilter(addedResourceIndices) {
+    return function(resource) {
+      return !addedResourceIndices[resource.index];
+    };
+  }
+
+
+  function getResourceMatchesClausesFilter(clauses) {
+    return function(resource) {
+      return doesResourceMatchClauses(resource, 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 clauses[i].negative;
+      }
+    }
+    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+|\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+|\s+$/g,'');
+        }
+
+        clauses.push(clause);
+      }
+
+      if (!clauses.length) {
+        continue;
+      }
+
+      expressions.push(clauses);
+    }
+
+    return expressions;
+  }
+})();
+
+(function($) {
+  /* Simple jquery function to create dom for a standard resource card */
+  $.fn.decorateResourceCard = function(resource,plusone) {
+    var section = resource.group || resource.type;
+    var imgUrl;
+    if (resource.image) {
+      //keep url clean for matching and offline mode handling
+      var urlPrefix = resource.image.indexOf("//") > -1 ? "" : toRoot;
+      imgUrl = urlPrefix + resource.image;
+    }
+    //add linkout logic here. check url or type, assign a class, map to css :after
+    $('<div>')
+        .addClass('card-bg')
+        .css('background-image', 'url(' + (imgUrl || toRoot + 'assets/images/resource-card-default-android.jpg') + ')')
+      .appendTo(this);
+    if (!plusone) {
+      $('<div>').addClass('card-info' + (!resource.summary ? ' empty-desc' : ''))
+        .append($('<div>').addClass('section').text(section))
+        .append($('<div>').addClass('title').html(resource.title))
+        .append($('<div>').addClass('description ellipsis')
+            .append($('<div>').addClass('text').html(resource.summary))
+          .append($('<div>').addClass('util')))
+          .appendTo(this);
+    } else {
+      $('<div>').addClass('card-info' + (!resource.summary ? ' empty-desc' : ''))
+        .append($('<div>').addClass('section').text(section))
+        .append($('<div>').addClass('title').html(resource.title))
+        .append($('<div>').addClass('description ellipsis')
+            .append($('<div>').addClass('text').html(resource.summary))
+          .append($('<div>').addClass('util')
+            .append($('<div>').addClass('g-plusone')
+              .attr('data-size', 'small')
+              .attr('data-align', 'right')
+              .attr('data-href', resource.url))))
+            .appendTo(this);
+    }
+
+    return this;
+  };
+
+  /* Simple jquery function to create dom for a resource section card (menu) */
+  $.fn.decorateResourceSection = function(section,plusone) {
+    var resource = section.resource;
+    //keep url clean for matching and offline mode handling
+    var urlPrefix = resource.image.indexOf("//") > -1 ? "" : toRoot;
+    var $base = $('<a>')
+        .addClass('card-bg')
+        .attr('href', resource.url)
+        .append($('<div>').addClass('card-section-icon')
+          .append($('<div>').addClass('icon'))
+          .append($('<div>').addClass('section').html(resource.title)))
+      .appendTo(this);
+
+    var $cardInfo = $('<div>').addClass('card-info').appendTo(this);
+
+    if (section.sections && section.sections.length) {
+      // Recurse the section sub-tree to find a resource image.
+      var stack = [section];
+
+      while (stack.length) {
+        if (stack[0].resource.image) {
+          $base.css('background-image', 'url(' + urlPrefix + stack[0].resource.image + ')');
+          break;
+        }
+
+        if (stack[0].sections) {
+          stack = stack.concat(stack[0].sections);
+        }
+
+        stack.shift();
+      }
+
+      var $ul = $('<ul>')
+        .appendTo($cardInfo);
+
+      var max = section.sections.length > 3 ? 3 : section.sections.length;
+
+      for (var i = 0; i < max; ++i) {
+
+        var subResource = section.sections[i];
+        if (!plusone) {
+          $('<li>')
+            .append($('<a>').attr('href', subResource.url)
+              .append($('<div>').addClass('title').html(subResource.title))
+              .append($('<div>').addClass('description ellipsis')
+                .append($('<div>').addClass('text').html(subResource.summary))
+                .append($('<div>').addClass('util'))))
+          .appendTo($ul);
+        } else {
+          $('<li>')
+            .append($('<a>').attr('href', subResource.url)
+              .append($('<div>').addClass('title').html(subResource.title))
+              .append($('<div>').addClass('description ellipsis')
+                .append($('<div>').addClass('text').html(subResource.summary))
+                .append($('<div>').addClass('util')
+                  .append($('<div>').addClass('g-plusone')
+                    .attr('data-size', 'small')
+                    .attr('data-align', 'right')
+                    .attr('data-href', resource.url)))))
+          .appendTo($ul);
+        }
+      }
+
+      // Add a more row
+      if (max < section.sections.length) {
+        $('<li>')
+          .append($('<a>').attr('href', resource.url)
+            .append($('<div>')
+              .addClass('title')
+              .text('More')))
+        .appendTo($ul);
+      }
+    } else {
+      // No sub-resources, just render description?
+    }
+
+    return this;
+  };
+})(jQuery);
+/* Calculate the vertical area remaining */
+(function($) {
+    $.fn.ellipsisfade= function(lineHeight) {
+        this.each(function() {
+            // get element text
+            var $this = $(this);
+            var remainingHeight = $this.parent().parent().height();
+            $this.parent().siblings().each(function ()
+            {
+              var h = $(this).height();
+              remainingHeight = remainingHeight - h;
+            });
+
+            adjustedRemainingHeight = ((remainingHeight)/lineHeight>>0)*lineHeight
+            $this.parent().css({'height': adjustedRemainingHeight});
+            $this.css({'height': "auto"});
+        });
+
+        return this;
+    };
+}) (jQuery);
diff --git a/tools/droiddoc/templates-sdk-dyn/components/masthead.cs b/tools/droiddoc/templates-sdk-dyn/components/masthead.cs
index 47639bb..d0ff64d 100644
--- a/tools/droiddoc/templates-sdk-dyn/components/masthead.cs
+++ b/tools/droiddoc/templates-sdk-dyn/components/masthead.cs
@@ -1,225 +1,131 @@
 <?cs def:custom_masthead() ?>
+<?cs if:wear ?>
+  <?cs call:wear_masthead() ?>
+<?cs else ?>
 <a name="top"></a>
-<?cs if:!devsite ?><?cs # leave out the global header for devsite; it's in devsite template ?>
-    <!-- Header -->
+<?cs if:!devsite ?><?cs # leave out the global header for devsite; it is in devsite template ?>
+  <!-- Header -->
+  <div id="header-wrapper">
     <div id="header">
-        <div class="wrap" id="header-wrap">
-          <div class="col-3 logo">
+      <div class="wrap" id="header-wrap">
+        <div class="col-3 logo">
           <a href="<?cs var:toroot ?>index.html">
-            <img src="<?cs var:toroot ?>assets/images/dac_logo.png" width="123" height="25" alt="Android Developers" />
+            <img src="<?cs var:toroot ?>assets/images/dac_logo.png"
+                srcset="<?cs var:toroot ?>assets/images/dac_logo@2x.png 2x"
+                width="123" height="25" alt="Android Developers" />
           </a>
           <div class="btn-quicknav" id="btn-quicknav">
-          	<a href="#" class="arrow-inactive">Quicknav</a>
-			      <a href="#" class="arrow-active">Quicknav</a>
+            <a href="#" class="arrow-inactive">Quicknav</a>
+            <a href="#" class="arrow-active">Quicknav</a>
           </div>
-          </div>
-            <ul class="nav-x col-9">
-                <li class="design">
-                  <a href="<?cs var:toroot ?>design/index.html"
-                  zh-tw-lang="設計"
-                  zh-cn-lang="设计"
-                  ru-lang="Проектирование"
-                  ko-lang="디자인"
-                  ja-lang="設計"
-                  es-lang="Diseñar"               
-                  >Design</a></li>
-                <li class="develop"><a href="<?cs var:toroot ?>develop/index.html"
-                  zh-tw-lang="開發"
-                  zh-cn-lang="开发"
-                  ru-lang="Разработка"
-                  ko-lang="개발"
-                  ja-lang="開発"
-                  es-lang="Desarrollar"               
-                  >Develop</a></li>
-                <li class="distribute last"><a href="<?cs var:toroot ?>distribute/index.html"
-                  zh-tw-lang="發佈"
-                  zh-cn-lang="分发"
-                  ru-lang="Распространение"
-                  ko-lang="배포"
-                  ja-lang="配布"
-                  es-lang="Distribuir"               
-                  >Distribute</a></li>
-            </ul>
-            
-            <!-- New Search -->
-            <div class="menu-container">
-            <div class="moremenu">
-    <div id="more-btn"></div>
-  </div>
-  <div class="morehover" id="moremenu">
-    <div class="top"></div>
-    <div class="mid">
-      <div class="header">Links</div>
-      <ul>
-        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
-        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
-        <li><a href="<?cs var:toroot ?>about/index.html">About Android</a></li>
-      </ul>
-      <div class="header">Android Sites</div>
-      <ul>
-        <li><a href="http://www.android.com">Android.com</a></li>
-        <li class="active"><a>Android Developers</a></li>
-        <li><a href="http://source.android.com">Android Open Source Project</a></li>
-      </ul>
-      
-      <?cs # Include language switcher only in online docs ?>
-      <?cs if:android.whichdoc == "online" ?>
-        <div class="header">Language</div>
-          <div id="language" class="locales">
-            <select name="language" onChange="changeLangPref(this.value, true)">
-                <option value="en">English</option>
-                <option value="es">Español</option>
-                <option value="ja">日本語</option>
-                <option value="ko">한국어</option>
-                <option value="ru">Русский</option>
-                <option value="zh-cn">中文 (中国)</option>
-                <option value="zh-tw">中文 (台灣)</option>
-            </select>
-          </div>
-        <script type="text/javascript">
-          <!--
-          loadLangPref();
-            //-->
-        </script>
-      <?cs /if ?>
-      <?cs # End of lang switcher ?>
-
-
-      <br class="clearfix" />
-    </div>
-    <div class="bottom"></div>
-  </div>
-  <div class="search" id="search-container">
-    <div class="search-inner">
-      <div id="search-btn"></div>
-      <div class="left"></div>
-      <form onsubmit="return submit_search()">
-        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '<?cs var:toroot ?>')" 
-onkeyup="return search_changed(event, false, '<?cs var:toroot ?>')" />
-      </form>
-      <div class="right"></div>
-        <a class="close hide">close</a>
-        <div class="left"></div>
-        <div class="right"></div>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper reference">
-    <div class="suggest-card reference no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper docs">
-    <div class="suggest-card dummy no-display">&nbsp;</div>
-    <div class="suggest-card develop no-display">
-      <ul class="search_filtered">
-      </ul>
-      <div class="child-card guides no-display">
-      </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">
-      </ul>
-    </div>
-    <div class="suggest-card distribute no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  </div>
-  <!-- /New Search>
-          
-          
-          <!-- Expanded quicknav -->
-           <div id="quicknav" class="col-9">
-                <ul>
-                    <li class="design">
-                      <ul>
-                        <li><a href="<?cs var:toroot ?>design/index.html">Get Started</a></li>
-                        <li><a href="<?cs var:toroot ?>design/style/index.html">Style</a></li>
-                        <li><a href="<?cs var:toroot ?>design/patterns/index.html">Patterns</a></li>
-                        <li><a href="<?cs var:toroot ?>design/building-blocks/index.html">Building Blocks</a></li>
-                        <li><a href="<?cs var:toroot ?>design/downloads/index.html">Downloads</a></li>
-                        <li><a href="<?cs var:toroot ?>design/videos/index.html">Videos</a></li>
-                      </ul>
-                    </li>
-                    <li class="develop">
-                      <ul>
-                        <li><a href="<?cs var:toroot ?>training/index.html"
-                          zh-tw-lang="訓練課程"
-                          zh-cn-lang="培训"
-                          ru-lang="Курсы"
-                          ko-lang="교육"
-                          ja-lang="トレーニング"
-                          es-lang="Capacitación"               
-                          >Training</a></li>
-                        <li><a href="<?cs var:toroot ?>guide/index.html"
-                          zh-tw-lang="API 指南"
-                          zh-cn-lang="API 指南"
-                          ru-lang="Руководства по API"
-                          ko-lang="API 가이드"
-                          ja-lang="API ガイド"
-                          es-lang="Guías de la API"               
-                          >API Guides</a></li>
-                        <li><a href="<?cs var:toroot ?>reference/packages.html"
-                          zh-tw-lang="參考資源"
-                          zh-cn-lang="参考"
-                          ru-lang="Справочник"
-                          ko-lang="참조문서"
-                          ja-lang="リファレンス"
-                          es-lang="Referencia"               
-                          >Reference</a></li>
-                        <li><a href="<?cs var:toroot ?>tools/index.html"
-                          zh-tw-lang="相關工具"
-                          zh-cn-lang="工具"
-                          ru-lang="Инструменты"
-                          ko-lang="도구"
-                          ja-lang="ツール"
-                          es-lang="Herramientas"               
-                          >Tools</a>
-                          <ul><li><a href="<?cs var:toroot ?>sdk/index.html">Get the SDK</a></li></ul>
-                        </li>
-                        <li><a href="<?cs var:toroot ?>google/index.html">Google Services</a>
-                        </li>
-                        <?cs if:android.hasSamples ?>
-                          <li><a href="<?cs var:toroot ?>samples/index.html">Samples</a>
-                          </li>
-                        <?cs /if ?>
-                      </ul>
-                    </li>
-                    <li class="distribute last">
-                      <ul>
-                        <li><a href="<?cs var:toroot ?>distribute/index.html">Google Play</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/publish/index.html">Publishing</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/promote/index.html">Promoting</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/quality/index.html">App Quality</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/index.html">Spotlight</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/open.html">Open Distribution</a></li>
-                      </ul>
-                    </li>
-                </ul>
-          </div>
-          <!-- /Expanded quicknav -->
         </div>
-    </div>
-    <!-- /Header -->
-    
-    
-  <div id="searchResults" class="wrap" style="display:none;">
-          <h2 id="searchTitle">Results</h2>
-          <div id="leftSearchControl" class="search-control">Loading...</div>
-  </div>
-    
-    
+        <ul class="nav-x col-9">
+            <li class="design">
+              <a href="<?cs var:toroot ?>design/index.html"
+              zh-tw-lang="設計"
+              zh-cn-lang="设计"
+              ru-lang="Проектирование"
+              ko-lang="디자인"
+              ja-lang="設計"
+              es-lang="Diseñar"
+              >Design</a></li>
+            <li class="develop"><a href="<?cs var:toroot ?>develop/index.html"
+              zh-tw-lang="開發"
+              zh-cn-lang="开发"
+              ru-lang="Разработка"
+              ko-lang="개발"
+              ja-lang="開発"
+              es-lang="Desarrollar"
+              >Develop</a></li>
+            <li class="distribute last"><a href="<?cs var:toroot ?>distribute/<?cs
+              if:android.whichdoc == "offline" ?>googleplay/<?cs /if ?>index.html"
+              zh-tw-lang="發佈"
+              zh-cn-lang="分发"
+              ru-lang="Распространение"
+              ko-lang="배포"
+              ja-lang="配布"
+              es-lang="Distribuir"
+              >Distribute</a></li>
+        </ul>
+
+
+        <?cs # ADD SEARCH AND MENU ?>
+        <?cs call:header_search_widget() ?>
+
+
+        <!-- Expanded quicknav -->
+        <div id="quicknav" class="col-9">
+          <ul>
+            <li class="design">
+              <ul>
+                <li><a href="<?cs var:toroot ?>design/index.html">Get Started</a></li>
+                <li><a href="<?cs var:toroot ?>design/style/index.html">Style</a></li>
+                <li><a href="<?cs var:toroot ?>design/patterns/index.html">Patterns</a></li>
+                <li><a href="<?cs var:toroot ?>design/building-blocks/index.html">Building Blocks</a></li>
+                <li><a href="<?cs var:toroot ?>design/downloads/index.html">Downloads</a></li>
+                <li><a href="<?cs var:toroot ?>design/videos/index.html">Videos</a></li>
+              </ul>
+            </li>
+            <li class="develop">
+              <ul>
+                <li><a href="<?cs var:toroot ?>training/index.html"
+                  zh-tw-lang="訓練課程"
+                  zh-cn-lang="培训"
+                  ru-lang="Курсы"
+                  ko-lang="교육"
+                  ja-lang="トレーニング"
+                  es-lang="Capacitación"
+                  >Training</a></li>
+                <li><a href="<?cs var:toroot ?>guide/index.html"
+                  zh-tw-lang="API 指南"
+                  zh-cn-lang="API 指南"
+                  ru-lang="Руководства по API"
+                  ko-lang="API 가이드"
+                  ja-lang="API ガイド"
+                  es-lang="Guías de la API"
+                  >API Guides</a></li>
+                <li><a href="<?cs var:toroot ?>reference/packages.html"
+                  zh-tw-lang="參考資源"
+                  zh-cn-lang="参考"
+                  ru-lang="Справочник"
+                  ko-lang="참조문서"
+                  ja-lang="リファレンス"
+                  es-lang="Referencia"
+                  >Reference</a></li>
+                <li><a href="<?cs var:toroot ?>tools/index.html"
+                  zh-tw-lang="相關工具"
+                  zh-cn-lang="工具"
+                  ru-lang="Инструменты"
+                  ko-lang="도구"
+                  ja-lang="ツール"
+                  es-lang="Herramientas"
+                  >Tools</a>
+                  <ul><li><a href="<?cs var:toroot ?>sdk/index.html">Get the SDK</a></li></ul>
+                </li>
+                <li><a href="<?cs var:toroot ?>google/index.html">Google Services</a>
+                </li>
+                <?cs if:android.hasSamples ?>
+                  <li><a href="<?cs var:toroot ?>samples/index.html">Samples</a>
+                  </li>
+                <?cs /if ?>
+              </ul>
+            </li>
+            <li class="distribute last">
+              <ul>
+                <li><a href="<?cs var:toroot ?>distribute/googleplay/index.html">Google Play</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/essentials/index.html">Essentials</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/users/index.html">Get Users</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/engage/index.html">Engage &amp; Retain</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/monetize/index.html">Monetize</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/tools/index.html">Tools &amp; Reference</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/stories/index.html">Developer Stories</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div><!-- /Expanded quicknav -->
+      </div><!-- end header-wrap.wrap -->
+    </div><!-- end header -->
+
   <?cs if:training || guide || reference || tools || develop || google || samples ?>
     <!-- Secondary x-nav -->
     <div id="nav-x">
@@ -231,7 +137,7 @@
                   ru-lang="Курсы"
                   ko-lang="교육"
                   ja-lang="トレーニング"
-                  es-lang="Capacitación"               
+                  es-lang="Capacitación"
                   >Training</a></li>
                 <li class="guide"><a href="<?cs var:toroot ?>guide/index.html"
                   zh-tw-lang="API 指南"
@@ -239,7 +145,7 @@
                   ru-lang="Руководства по API"
                   ko-lang="API 가이드"
                   ja-lang="API ガイド"
-                  es-lang="Guías de la API"               
+                  es-lang="Guías de la API"
                   >API Guides</a></li>
                 <li class="reference"><a href="<?cs var:toroot ?>reference/packages.html"
                   zh-tw-lang="參考資源"
@@ -247,7 +153,7 @@
                   ru-lang="Справочник"
                   ko-lang="참조문서"
                   ja-lang="リファレンス"
-                  es-lang="Referencia"               
+                  es-lang="Referencia"
                   >Reference</a></li>
                 <li class="tools"><a href="<?cs var:toroot ?>tools/index.html"
                   zh-tw-lang="相關工具"
@@ -267,13 +173,98 @@
                 <?cs /if ?>
             </ul>
         </div>
-        
     </div>
     <!-- /Sendondary x-nav -->
+
+  <?cs elif:distribute || googleplay || essentials || users || engage || monetize || disttools || stories ?>
+    <!-- Secondary distribute x-nav -->
+    <div id="nav-x">
+        <div class="wrap">
+            <ul class="nav-x distribute">
+                <li class="googleplay"><a href="<?cs var:toroot ?>distribute/googleplay/index.html"
+                  >Google Play</a></li>
+                <li class="essentials"><a href="<?cs var:toroot ?>distribute/essentials/index.html"
+                  >Essentials</a></li>
+                <li class="users"><a href="<?cs var:toroot ?>distribute/users/index.html"
+                  >Get Users</a></li>
+                <li class="engage"><a href="<?cs var:toroot ?>distribute/engage/index.html"
+                  >Engage &amp; Retain</a></li>
+                <li class="monetize"><a href="<?cs var:toroot ?>distribute/monetize/index.html"
+                  >Monetize</a>
+                </li>
+                <li class="disttools"><a href="<?cs var:toroot ?>distribute/tools/index.html"
+                  >Tools</a>
+                </li>
+                <li class="stories"><a href="<?cs var:toroot ?>distribute/stories/index.html"
+                  >Stories</a>
+                </li>
+            </ul>
+            <a href="https://play.google.com/apps/publish/" class="developer-console-btn">Developer Console</a>
+        </div> <!-- /Secondary distribute x-nav -->
+    </div>
   <?cs /if ?>
 
-<?cs /if ?>
-<?cs # end if/else !devsite ?>
+    <div id="searchResults" class="wrap" style="display:none;">
+      <h2 id="searchTitle">Results</h2>
+      <div id="leftSearchControl" class="search-control">Loading...</div>
+    </div>
+  </div> <!--end header-wrapper -->
 
-  <?cs 
+  <div id="sticky-header">
+    <div>
+      <a class="logo" href="#top"></a>
+      <a class="top" href="#top"></a>
+      <ul class="breadcrumb">
+        <?cs # More <li> elements added here with javascript ?>
+        <?cs if:!section.landing ?><li class="current"><?cs var:page.title ?></li><?cs
+        /if ?>
+      </ul>
+    </div>
+  </div>
+
+<?cs /if ?><?cs # end if/else !devsite ?>
+<?cs /if ?><?cs # end if/else wear ?><?cs
+/def ?>
+
+<?cs def:wear_masthead() ?>
+<a name="top"></a>
+
+<!-- Header -->
+<div id="header-wrapper">
+  <div id="header">
+    <div class="wrap" id="header-wrap">
+      <div class="col_3 logo wear-logo">
+        <a href="<?cs var:toroot ?>wear/index.html">
+          <img src="<?cs var:toroot ?>wear/images/android-wear.png" height="16" alt="Android Wear" />
+        </a>
+      </div>
+      <div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+
+      <?cs # ADD SEARCH AND MENU ?>
+      <?cs call:header_search_widget() ?>
+
+    </div><!-- end header-wrap -->
+  </div><!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+</div> <!--end header-wrapper -->
+
+<div id="sticky-header">
+  <div>
+    <a class="logo" href="#top"></a>
+    <a class="top" href="#top"></a>
+    <ul class="breadcrumb">
+      <?cs # More <li> elements added here with javascript ?>
+      <?cs if:!section.landing ?><li class="current"><?cs var:page.title ?></li><?cs
+      /if ?>
+    </ul>
+  </div>
+</div>
+
+  <?cs
 /def ?>
diff --git a/tools/droiddoc/templates-sdk-dyn/customizations.cs b/tools/droiddoc/templates-sdk-dyn/customizations.cs
index ed57f1c..27822d5 100644
--- a/tools/droiddoc/templates-sdk-dyn/customizations.cs
+++ b/tools/droiddoc/templates-sdk-dyn/customizations.cs
@@ -7,7 +7,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs 
         include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
@@ -15,33 +14,16 @@
 
       </div>
     </div> <!-- end side-nav -->
-<?cs /def ?>
-<?cs 
-def:resources_tab_nav() ?>
+<?cs /def ?><?cs
+
+def:no_nav() ?>
   <div class="wrap clearfix" id="body-content">
-    <a
-    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
-      <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+<?cs /def ?><?cs
 
-<?cs 
-        include:"../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
-
-
-      </div>
-    </div> <!-- end side-nav -->
-    <script>
-      $(document).ready(function() {
-        scrollIntoView("devdoc-nav");
-        });
-    </script>
-<?cs /def ?>
-<?cs
 def:tools_nav() ?>
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 <?cs 
         include:"../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
         
@@ -59,7 +41,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 
 <?cs 
@@ -73,14 +54,110 @@
         scrollIntoView("devdoc-nav");
         });
     </script>
-<?cs /def ?>
-<?cs 
+<?cs /def ?><?cs
+
+def:googleplay_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/googleplay/googleplay_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:essentials_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/essentials/essentials_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:users_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/users/users_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:engage_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/engage/engage_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:monetize_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/monetize/monetize_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:disttools_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/tools/disttools_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:stories_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/stories/stories_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
 def:guide_nav() ?>
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
 
 <?cs 
         include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
@@ -99,7 +176,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 
 <?cs
@@ -119,7 +195,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/distribute/distribute_toc.cs" ?>
@@ -139,7 +214,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
@@ -159,7 +233,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
@@ -183,7 +256,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
@@ -198,6 +270,26 @@
     </script>
 <?cs /def ?>
 
+
+<?cs
+def:wear_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+
+<?cs
+        include:"../../../../frameworks/base/docs/html/wear/wear_toc.cs" ?>
+
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?>
+
 <?cs # The default side navigation for the reference docs ?><?cs 
 def:default_left_nav() ?>
 <?cs if:reference.gcm || reference.gms ?>
@@ -206,8 +298,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav">
-
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
       <div id="api-nav-header">
         <div id="api-level-toggle">
           <label for="apiLevelCheckbox" class="disabled"
@@ -308,10 +398,111 @@
     <?cs 
 /def ?>
 
+
+<?cs
+def:header_search_widget() ?>
+<div class="menu-container">
+  <div class="moremenu">
+    <div id="more-btn"></div>
+  </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/" target="_googleplay">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="<?cs var:toroot ?>about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+
+      <?cs # Include language switcher only in online docs ?>
+      <?cs if:android.whichdoc == "online" ?>
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      <?cs /if ?>
+      <?cs # End of lang switcher ?>
+      <br class="clearfix" />
+    </div><!-- end 'mid' -->
+    <div class="bottom"></div>
+  </div><!-- end 'moremenu' -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+          onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+          onkeydown="return search_changed(event, true, '<?cs var:toroot ?>')"
+          onkeyup="return search_changed(event, false, '<?cs var:toroot ?>')" />
+      </form>
+      <div class="right"></div>
+      <a class="close hide">close</a>
+      <div class="left"></div>
+      <div class="right"></div>
+    </div><!-- end search-inner -->
+  </div><!-- end search-container -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </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">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+</div><!-- end menu-container (search and menu widget) -->
+<?cs /def ?>
+
+
+
 <?cs 
 def:custom_left_nav() ?><?cs
-  if:fullpage ?><?cs 
-    call:fullpage() ?><?cs 
+  if:fullpage ?><?cs
+    call:fullpage() ?><?cs
+  elif:nonavpage ?><?cs
+    call:no_nav() ?><?cs
   elif:guide ?><?cs 
     call:guide_nav() ?><?cs 
   elif:design ?><?cs
@@ -324,15 +515,31 @@
     call:google_nav() ?><?cs 
   elif:samples ?><?cs
     call:samples_nav() ?><?cs
-  elif:more ?><?cs 
-    call:dist_more_nav() ?><?cs
   elif:distribute ?><?cs 
-    call:distribute_nav() ?><?cs 
-  elif:about ?><?cs 
-    call:about_nav() ?><?cs 
-  else ?><?cs 
-    call:default_left_nav() ?> <?cs 
-  /if ?><?cs 
+    if:googleplay ?><?cs
+      call:googleplay_nav() ?><?cs
+    elif:essentials ?><?cs
+      call:essentials_nav() ?><?cs
+    elif:users ?><?cs
+      call:users_nav() ?><?cs
+    elif:engage ?><?cs
+      call:engage_nav() ?><?cs
+    elif:monetize ?><?cs
+      call:monetize_nav() ?><?cs
+    elif:disttools ?><?cs
+      call:disttools_nav() ?><?cs
+    elif:stories ?><?cs
+      call:stories_nav() ?><?cs
+    /if ?><?cs
+  elif:about ?><?cs
+    call:about_nav() ?><?cs
+  elif:distribute ?><?cs
+    call:distribute_nav() ?><?cs
+  elif:wear ?><?cs
+    call:wear_nav() ?><?cs
+  else ?><?cs
+    call:default_left_nav() ?> <?cs
+  /if ?><?cs
 /def ?>
 
 <?cs # appears at the bottom of every page ?><?cs 
diff --git a/tools/droiddoc/templates-sdk-dyn/docpage.cs b/tools/droiddoc/templates-sdk-dyn/docpage.cs
index ea462c9..7eae405 100644
--- a/tools/droiddoc/templates-sdk-dyn/docpage.cs
+++ b/tools/droiddoc/templates-sdk-dyn/docpage.cs
@@ -2,19 +2,36 @@
 <?cs include:"macros.cs" ?>
 <html<?cs if:devsite ?> devsite<?cs /if ?>>
 <?cs include:"head_tag.cs" ?>
-<body class="gc-documentation <?cs if:(google || reference.gms || reference.gcm) ?>google<?cs /if ?>
-  <?cs if:(guide||develop||training||reference||tools||sdk||samples) ?>develop<?cs if:guide ?> guide<?cs /if ?><?cs if:samples ?> samples<?cs /if ?><?cs
+<body class="gc-documentation 
+
+<?cs
+if:(google || reference.gms || reference.gcm) ?>google<?cs /if ?><?cs
+  if:(guide||develop||training||reference||tools||sdk||samples) ?>develop<?cs
+    if:guide ?> guide<?cs /if ?><?cs
+    if:samples ?> samples<?cs /if ?><?cs
+  elif:(distribute||googleplay||essentials||users||engage||monetize||disttools||stories)
+    ?>distribute<?cs
+    if:googleplay ?> googleplay<?cs /if ?><?cs
+    if:essentials ?> essentials<?cs /if ?><?cs
+    if:users ?> users<?cs /if ?><?cs
+    if:engage ?> engage<?cs /if ?><?cs
+    if:monetize ?> monetize<?cs /if ?><?cs
+    if:disttools ?> disttools<?cs /if ?><?cs
+    if:stories ?> stories<?cs /if ?><?cs
   elif:about ?>about<?cs
   elif:design ?>design<?cs
-  elif:distribute ?>distribute<?cs
-  /if ?><?cs
-  if:page.trainingcourse ?> trainingcourse<?cs /if ?>" itemscope itemtype="http://schema.org/Article">
-<?cs include:"header.cs" ?>
+/if ?><?cs
+if:page.trainingcourse ?> trainingcourse<?cs
+/if ?>" itemscope itemtype="http://schema.org/Article"><?cs
+include:"header.cs" ?>
 
-<div <?cs if:fullpage
-?>class="fullpage"<?cs elif:design||tools||about||sdk||distribute
-?>class="col-13" id="doc-col"<?cs else
-?>class="col-12" id="doc-col"<?cs /if ?> >
+<div <?cs
+  if:fullpage
+    ?>class="fullpage"<?cs
+  elif:(design||tools||about||sdk||googleplay||essentials||users||monetize||disttools) && !nonavpage
+    ?>class="col-13" id="doc-col"<?cs
+  elif:!nonavpage
+    ?>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 ?>
   <?cs if:header.hide ?>
@@ -74,6 +91,7 @@
     <?cs /if ?><?cs # end if training ?>
   </div>
   <?cs /if ?>
+
 <?cs elif:samplesProjectIndex ?>
   <div id="api-info-block">
   <div class="sum-details-links">
@@ -83,7 +101,10 @@
   </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">
@@ -181,8 +202,6 @@
 <?cs include:"footer.cs" ?>
 </div><!-- end doc-content -->
 
-<?cs include:"trailer.cs" ?>
-
 <!-- Start of Tag -->
 <script type="text/javascript">
 var axel = Math.random() + "";
@@ -193,6 +212,15 @@
 <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 -->
+
+
+<?cs include:"trailer.cs" ?>
+  <script src="https://developer.android.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 ?>jd_extras.js" type="text/javascript"></script>
+  <script src="<?cs var:toroot ?>jd_collections.js" type="text/javascript"></script>
+  <script src="<?cs var:toroot ?>jd_tag_helpers.js" type="text/javascript"></script>
+
 </body>
 </html>
 
diff --git a/tools/droiddoc/templates-sdk-dyn/head_tag.cs b/tools/droiddoc/templates-sdk-dyn/head_tag.cs
index 54de169..732118f 100644
--- a/tools/droiddoc/templates-sdk-dyn/head_tag.cs
+++ b/tools/droiddoc/templates-sdk-dyn/head_tag.cs
@@ -15,13 +15,13 @@
 ?><?cs
   # END if/else devsite ?>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
+<meta name="viewport" content="width=<?cs
+  if:page.viewport_width ?><?cs
+    var:page.viewport_width ?><?cs
+  else ?>device-width<?cs /if ?>" />
 <?cs
   if:page.metaDescription ?>
 <meta name="Description" content="<?cs var:page.metaDescription ?>"><?cs
-  /if ?><?cs
-  if:page.customHeadTag ?>
-<?cs var:page.customHeadTag ?><?cs
   /if ?>
 <link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>favicon.ico" />
 <title><?cs 
@@ -31,10 +31,16 @@
 
 <!-- STYLESHEETS -->
 <link rel="stylesheet"
-href="<?cs if:android.whichdoc != 'online' ?>http:<?cs /if ?>//fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+href="<?cs
+if:android.whichdoc != 'online' ?>http:<?cs
+/if ?>//fonts.googleapis.com/css?family=Roboto+Condensed">
+<link rel="stylesheet" href="<?cs
+if:android.whichdoc != 'online' ?>http:<?cs
+/if ?>//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold"
+  title="roboto">
 <link href="<?cs var:toroot ?>assets/css/default.css" rel="stylesheet" type="text/css">
 
-<?cs if:reference && !(reference.gms || reference.gcm) ?>
+<?cs if:reference && !(reference.gms || reference.gcm || wear) ?>
 <!-- FULLSCREEN STYLESHEET -->
 <link href="<?cs var:toroot ?>assets/css/fullscreen.css" rel="stylesheet" class="fullscreen"
 type="text/css">
@@ -47,7 +53,10 @@
   ?><script src="<?cs var:toroot ?>_static/js/android_3p-bundle.js" type="text/javascript"></script><?cs
 else
   ?><script src="<?cs var:toroot ?>assets/js/android_3p-bundle.js" type="text/javascript"></script><?cs
-/if ?>
+/if ?><?cs
+  if:page.customHeadTag ?>
+<?cs var:page.customHeadTag ?><?cs
+  /if ?>
 <script type="text/javascript">
   var toRoot = "<?cs var:toroot ?>";
   var metaTags = [<?cs var:meta.tags ?>];
@@ -66,4 +75,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-sdk-dyn/sample.cs b/tools/droiddoc/templates-sdk-dyn/sample.cs
index 684e284..c6f28f8 100644
--- a/tools/droiddoc/templates-sdk-dyn/sample.cs
+++ b/tools/droiddoc/templates-sdk-dyn/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 -->
diff --git a/tools/droiddoc/templates-sdk-dyn/sdkpage.cs b/tools/droiddoc/templates-sdk-dyn/sdkpage.cs
index d98146a..95f6596 100644
--- a/tools/droiddoc/templates-sdk-dyn/sdkpage.cs
+++ b/tools/droiddoc/templates-sdk-dyn/sdkpage.cs
@@ -11,7 +11,7 @@
 <?cs else ?>
   <?cs include:"head_tag.cs" ?>
 <?cs /if ?>
-<body class="gc-documentation 
+<body class="gc-documentation
   <?cs if:(guide||develop||training||reference||tools||sdk) ?>develop<?cs
   elif:design ?>design<?cs
   elif:distribute ?>distribute<?cs
@@ -107,7 +107,7 @@
     </td>
     <td><?cs var:ndk.win64_bytes ?></td>
     <td><?cs var:ndk.win64_checksum ?></td>
-  </tr> 
+  </tr>
  <!--  <tr>
     <td>
   <a onClick="return onDownload(this)"
@@ -199,12 +199,12 @@
     <td><?cs var:ndk.debug_info_checksum ?></td>
   </tr>
   </table>
-  
+
   <?cs ########  HERE IS THE JD DOC CONTENT ######### ?>
   <?cs call:tag_list(root.descr) ?>
 
 
-  
+
 <script>
   function onDownload(link) {
 
@@ -229,13 +229,13 @@
   function onDownloadNdkForRealz(link) {
     if ($("input#agree").is(':checked')) {
       $("#tos").fadeOut('slow');
-      
+
       $('html, body').animate({
           scrollTop: $("#Installing").offset().top
         }, 800, function() {
           $("#Installing").click();
       });
-     
+
       return true;
     } else {
       $("label#agreeLabel").parent().stop().animate({color: "#258AAF"}, 200,
@@ -254,7 +254,7 @@
 </script>
 
   <?cs else ?>
-<?cs # end if NDK ... 
+<?cs # end if NDK ...
 #
 #
 #
@@ -281,11 +281,11 @@
 <h4><a href='' class="expandable"
   onclick="toggleExpandable(this,'.pax');hideExpandable('.myide,.reqs');return false;"
   >DOWNLOAD FOR OTHER PLATFORMS</a></h4>
-  
-  
+
+
 <div class="pax col-13 online" style="display:none;margin:0;">
 
-  
+
 <p class="table-caption"><strong>ADT Bundle</strong></p>
   <table class="download">
     <tr>
@@ -298,7 +298,7 @@
     <td>Windows 32-bit</td>
     <td>
   <a onClick="return onDownload(this)" id="win-bundle32"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.win32_bundle_download ?>"><?cs var:sdk.win32_bundle_download ?></a>
+     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.win32_bundle_download ?>"><?cs var:sdk.win32_bundle_download ?></a>
     </td>
     <td><?cs var:sdk.win32_bundle_bytes ?> bytes</td>
     <td><?cs var:sdk.win32_bundle_checksum ?></td>
@@ -307,7 +307,7 @@
     <td>Windows 64-bit</td>
     <td>
   <a onClick="return onDownload(this)" id="win-bundle64"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.win64_bundle_download ?>"><?cs var:sdk.win64_bundle_download ?></a>
+     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.win64_bundle_download ?>"><?cs var:sdk.win64_bundle_download ?></a>
     </td>
     <td><?cs var:sdk.win64_bundle_bytes ?> bytes</td>
     <td><?cs var:sdk.win64_bundle_checksum ?></td>
@@ -316,7 +316,7 @@
     <td><nobr>Mac OS X 64-bit</nobr></td>
     <td>
   <a onClick="return onDownload(this)" id="mac-bundle64"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.mac64_bundle_download ?>"><?cs var:sdk.mac64_bundle_download ?></a>
+     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.mac64_bundle_download ?>"><?cs var:sdk.mac64_bundle_download ?></a>
     </td>
     <td><?cs var:sdk.mac64_bundle_bytes ?> bytes</td>
     <td><?cs var:sdk.mac64_bundle_checksum ?></td>
@@ -325,7 +325,7 @@
     <td>Linux 32-bit</td>
     <td>
   <a onClick="return onDownload(this)" id="linux-bundle32"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.linux32_bundle_download ?>"><?cs var:sdk.linux32_bundle_download ?></a>
+     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.linux32_bundle_download ?>"><?cs var:sdk.linux32_bundle_download ?></a>
     </td>
     <td><?cs var:sdk.linux32_bundle_bytes ?> bytes</td>
     <td><?cs var:sdk.linux32_bundle_checksum ?></td>
@@ -334,7 +334,7 @@
     <td>Linux 64-bit</td>
     <td>
   <a onClick="return onDownload(this)" id="linux-bundle64"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.linux64_bundle_download ?>"><?cs var:sdk.linux64_bundle_download ?></a>
+     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.linux64_bundle_download ?>"><?cs var:sdk.linux64_bundle_download ?></a>
     </td>
     <td><?cs var:sdk.linux64_bundle_bytes ?> bytes</td>
     <td><?cs var:sdk.linux64_bundle_checksum ?></td>
@@ -396,10 +396,10 @@
 
 
 </div><!-- end col-13 for lower-half content -->
-  
-  
-  
-  
+
+
+
+
 <script>
   if (location.hash == "#Requirements") {
     $('.reqs').show();
@@ -440,17 +440,17 @@
   } else {
     $('.pax').show();
   }
-  
-  
+
+
   function onDownload(link, button, bundle) {
-  
+
     /* set text for download button */
     if (button) {
       $("#downloadForRealz").html($(link).text());
     } else {
       $("#downloadForRealz").html("Download " + $(link).text());
     }
-    
+
     /* if it's a bundle, show the 32/64-bit picker */
     if (bundle) {
       $("#downloadForRealz").attr('bundle','true');
@@ -482,7 +482,7 @@
   function onAgreeChecked() {
     /* verify that the TOS is agreed and a bit version is chosen */
     if ($("input#agree").is(":checked") && $("#bitpicker input:checked").length) {
-      
+
       /* if downloading the bundle */
       if ($("#downloadForRealz").attr('bundle')) {
         /* construct the name of the link we want based on the bit version */
@@ -490,7 +490,7 @@
         /* set the real url for download */
         $("a#downloadForRealz").attr("href", $(linkId).attr("href"));
       }
-      
+
       /* reveal the download button */
       $("a#downloadForRealz").removeClass('disabled');
     } else {
@@ -536,29 +536,29 @@
       <p>Welcome developers! We are pleased to provide you with a preview SDK for the upcoming
     Android 3.0 release, to give you a head-start on developing applications for it.
     </p>
-    
+
       <p>See the <a
     href="<?cs var:toroot ?>sdk/preview/start.html">Getting Started</a> document for more information
     about how to set up the preview SDK and get started.</p>
     <style type="text/css">
     .non-preview { display:none; }
     </style>
-    
+
     <?cs else ?><?cs # it's normal offline docs ?>
-      
+
       <?cs ########  HERE IS THE JD DOC CONTENT FOR OFFLINE ######### ?>
       <?cs call:tag_list(root.descr) ?>
       <style type="text/css">
         body .offline { display:block; }
         body .online { display:none; }
-      </style>      
+      </style>
       <script>
         $('.reqs').show();
       </script>
     <?cs /if ?>
-    
+
   <?cs /if ?> <?cs # end if/else online ?>
-  
+
 <?cs /if ?> <?cs # end if/else NDK ?>
 
 <?cs /if ?> <?cs # end if/else redirect ?>
diff --git a/tools/droiddoc/templates-sdk/assets/css/default.css b/tools/droiddoc/templates-sdk/assets/css/default.css
index aa30c8a..f411d93 100644
--- a/tools/droiddoc/templates-sdk/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk/assets/css/default.css
@@ -98,7 +98,8 @@
 #devdoc-nav.fixed {
   position: fixed;
   margin:0;
-  top: 20px; }
+  top: 65px; /* sticky-header height + 20px gutter */
+}
 
 #devdoc-nav span.small {
   font-size:12px;
@@ -157,12 +158,6 @@
 .layout-content-row {
   display: inline-block;
   margin-bottom: 10px; }
-  .layout-content-row:after {
-    content: ".";
-    display: block;
-    height: 0;
-    clear: both;
-    visibility: hidden; }
   * html .layout-content-row {
     height: 1px; }
 
@@ -429,20 +424,19 @@
 /* content header */
 .content-header {
   height: 30px;
-  margin:20px 0 25px;
-  padding:0 0 10px;}
+  margin:36px 0 23px;  /* same as h1 */
+  padding:0 0 10px;}  /* same as h1 */
 .content-header.just-links {
   margin-bottom:0;
   padding-bottom:0;}
 
 .content-header h1 {
-  color:#000;
   margin:0;
-  border-bottom:0;
   padding:0;
+  width: 700px;
 }
 .content-header > div:first-child {
-  height:55px; /* set fixed height for the header div to ensure the
+  height:1px; /* set fixed height for the header div to ensure the
                   next/prev links align with toc on training classes */
 }
 
@@ -450,7 +444,7 @@
   border-top: 1px solid #ccc;
   margin-top: 10px;
   padding-top:10px;
-  height: 30px; }
+  width:100%; }
 
 .content-footer .col-9 {
   margin-left:0;
@@ -461,20 +455,33 @@
 .content-footer.wrap {
   width:940px;
 }
+.content-footer .plus-container {
+  margin:5px 0 0;
+  text-align:right;
+  float:right;
+}
 
+a.back-link {
+    text-decoration: none;
+    text-transform: uppercase;
+}
+
+.content-header .paging-links {
+  margin-top:-25px;
+}
 .paging-links {
-  position: relative; }
+  position: relative;
+  height:30px; }
   .paging-links a {
     position: absolute; }
   .paging-links a,
   .training-nav-top a {
-    font-size: 14px;
-    line-height: 30px;
     color: #555555;
     text-decoration: none;
     text-transform: uppercase; }
     .paging-links .prev-page-link:before,
-    .training-nav-top .prev-page-link:before {
+    .training-nav-top .prev-page-link:before,
+    a.back-link:before {
       content: '';
       background: transparent url(../images/styles/disclosure_left.png) no-repeat scroll 50% 50%;
       width: 10px;
@@ -488,7 +495,7 @@
     .paging-links .prev-page-link {
       left: -15px; }
     .paging-links .next-page-link {
-      right: 0px; }
+      right: 0; }
     .next-page-link:after,
     .start-class-link:after,
     .start-course-link:after,
@@ -505,6 +512,9 @@
     .next-page-link.inline:after {
       content: none; }
 
+  .content-footer .paging-links .next-page-link {
+    left:0;
+  }
 
   .training-nav-top a {
     display:block;
@@ -543,7 +553,6 @@
 
   .paging-links a.start-class-link {
     width:100%;
-    text-align:right;
   }
 
   /* list of classes on course landing page */
@@ -622,19 +631,6 @@
     display:none !important;
   }
 
-  .content-footer.next-class {
-    display:block;
-    border:0;
-    margin-top:0;
-    padding-top:0;
-  }
-
-  .content-footer.next-class a.next-class-link {
-    display:block;
-    float:right;
-    text-transform:uppercase;
-  }
-
 
 
   /* inner-doc tabs w/ title */
@@ -712,6 +708,7 @@
     color: #33b5e5;
     border-bottom-color: #33b5e5; } }
 
+h1:target,
 h2:target,
 h3:target {
     -webkit-animation-name: glowheader;
@@ -893,7 +890,7 @@
   .framed-nexus4-port-216 img {
     width: 216px;
     height: 360px; }
-    
+
 .framed-nexus5-port-span-5 {
   background: transparent url(../images/styles/device_nexus5_blank_port_span5.png) no-repeat
   scroll top left;
@@ -928,6 +925,47 @@
   height: 384px;
 }
 
+/* wear device frames */
+
+.framed-wear-square {
+  background: transparent url(../images/styles/device_wear_square.png) no-repeat scroll top left;
+  background-size: 302px 302px;
+  height:222px;
+  width:222px;
+  padding:40px;
+  overflow:hidden;
+}
+
+.framed-wear-square-small {
+  background: transparent url(../images/styles/device_wear_square_small.png) no-repeat scroll top left;
+  background-size: 169px 200px;
+  height:147px;
+  width:147px;
+  padding:27px 11px;
+  overflow:hidden;
+}
+
+#jd-content
+.framed-wear-square img {
+  height:222px;
+  width: 222px;
+  padding:0;
+  margin:0;
+}
+
+#jd-content
+.framed-wear-square-small img {
+  height:147px;
+  width: 147px;
+  padding:0;
+  margin:0;
+}
+
+
+
+
+
+
 /* landing page disclosures */
 .landing-page-link {
   text-decoration: none;
@@ -1101,12 +1139,13 @@
 }
 h1 {
     color:#333;
-    font-size: 22px;
-    margin: 20px 0 20px;
+    font-size: 34px;
+    margin: 36px 0 27px;
     padding:0 0 10px;
+    font-weight:300;
 }
 h1, h2 {
-    line-height: 32px;
+    line-height: 30px;
 }
 h1.short {
   margin-right:320px;
@@ -1119,21 +1158,24 @@
 }
 h2 {
     color:#333;
-    font-size: 20px;
-    margin: 20px 0 20px;
+    font-size: 26px;
+    margin: 32px 0 20px;
     padding:0;
+    font-weight:300;
 }
 h3 {
     color:#333;
-    font-size: 18px;
+    font-size: 21px;
+    font-weight:400;
+    margin:21px 0 14px 0;
 }
 h3, h4 {
-    color:#333;
-    line-height: 20px;
-    margin: 10px 0;
+    line-height: 21px;
 }
 h4 {
-  font-size: 16px;
+  font-size: 18px;
+  margin: 12px 0;
+  font-weight:500;
 }
 h5 {
   font-size: 14px;
@@ -1146,7 +1188,7 @@
 }
 hr { /* applied to the bottom of h2 elements */
   height: 1px;
-  margin: 5px 0 20px;
+  margin: 3px 0 12px;
   border: 0;
   background: #ccc;
 }
@@ -1207,7 +1249,7 @@
 legend {
     display: none;
 }
-a:link, a:visited {
+a:link, a:visited, .link-color {
   color: #258aaf;
   text-decoration: none;
 }
@@ -1215,6 +1257,13 @@
   color: #33B5E5;
   text-decoration: none;
 }
+a.white {
+  color: #fff;
+  text-decoration:underline;
+}
+a.white:hover, a.white:active {
+  color: #ccc !important;
+}
 strong, b {
   font-weight:bold;
   color: #222;
@@ -1248,6 +1297,7 @@
 tr:first-of-type th:first-of-type:empty {
     visibility: hidden;
 }
+
 /* --------------------------------------------------------------------------
 Footer
 */
@@ -1378,8 +1428,7 @@
   .training-nav-top, .training-nav-bottom,
   #doc-col .content-footer,
   .nav-x, .nav-y,
-  .paging-links,
-  a.totop {
+  .paging-links {
       display: none !important;
   }
 
@@ -1504,7 +1553,8 @@
 Header, Login, Nav-X, Search
 */
 #header {
-  padding: 2.2em 0 0.2em 0;
+  margin: 0;
+  padding: 0;
 }
 #header:before, #header:after {
   content: "";
@@ -1522,6 +1572,9 @@
     color: #333;
     font-size: 16px;
 }
+.about a.selected {
+    color: #9933CC;
+}
 .design a.selected {
     color: #33b5e5;
 }
@@ -1833,6 +1886,11 @@
   margin:0 0 0 20px;
 }
 
+.training-nav-top {
+  position:relative;
+  top:73px;
+}
+
 .training-nav-bottom {
   padding:0 0 20px;
 }
@@ -1841,12 +1899,12 @@
 #qv-wrapper {
   float:right;
   clear:right;
-  margin:0 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
-  padding:0 0 20px;
+  margin:6px 0 0 30px; /* negative top-margin to counter the content-header bottom margin */
+  padding:0 0 30px;
 }
 
 #tb-wrapper {
-  margin:-29px 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
+  margin:51px 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
 }
 
 #tb,
@@ -1930,6 +1988,10 @@
   margin:0 15px 10px 35px;
 }
 
+#tb p {
+  margin:0 15px 10px;
+}
+
 #qv ol {
   list-style:none;
   margin:0 15px 15px;
@@ -1958,28 +2020,12 @@
 
 /* related resources blocks in checklists */
 
-.rel-resources {
-  margin:10px 0px;
-  border:1px solid #ccc;
-  background-color:rgba(0, 0, 0, 0.027451);
-  border:1px solid #ccc;
-  font-size:13px;
-  color:#6f6f6f;
-}
+/* related resources sections that have dynamic content */
 
-.rel-resources ul {
-padding: .5em 1em 0 1em;
-}
 
-.rel-resources a {
-font-weight:500;
-}
 
-.rel-resources h3 {
-  margin:4px 15px 0px 15px;
-  font-size:13px;
-  font-weight:600;
-  text-transform:uppercase;
+h3.rel-resources {
+margin:1.25em auto;
 }
 
 /* --------------------------------------------------------------------------
@@ -2359,6 +2405,13 @@
 #doc-col {
   margin-right:0;
 }
+
+/* Uncomment this for preview release watermark
+#doc-col {
+  background: url('../images/preview.png') repeat;
+}
+*/
+
 #doc-content-container {
   margin-left: 291px
 }
@@ -2724,19 +2777,22 @@
   width:100%;
 }
 #butterbar {
-  width:940px;
+  width:100%;
   margin:0 auto;
 }
 #butterbar-message {
-  background-color:#f80;
-  float:right;
-  font-size:12px;
-  font-weight:bold;
-  padding:0 10px;
-  border-radius: 0 0 5px 5px;
+  background-color:rgba(255, 187, 51, .4);
+  font-size:13px;
+  padding: 5px 0;
+  text-align:center;
 }
-#butterbar-message a {color:#fff !important}
-#butterbar-message a:hover {text-decoration:underline;}
+a#butterbar-message {
+  cursor:pointer;
+  display:block;
+}
+a#butterbar-message:hover {
+  text-decoration:underline;
+}
 
 /* --------------------------------------------------------------------------
 Misc
@@ -2760,7 +2816,7 @@
 .caption {
   margin: 0.5em 0 2em 0;
   color: #000;
-  font-size: 11.5px; 
+  font-size: 11.5px;
 }
 
 .nolist, .nolist ul, .nolist ol {
@@ -2884,26 +2940,6 @@
   margin:0 0 10px;
 }
 
-#devdoc-nav a.totop {
-  display:block;
-  top:0;
-  width:inherit;
-  background: transparent url(../images/styles/gototop.png) no-repeat scroll 50% 50%;
-  text-indent:-9999em;
-}
-#devdoc-nav a.totop {
-  position:fixed;
-  display:none;
-}
-#devdoc-nav a.totop:hover {
-  background-color:#33B5E5;
-}
-
-.content-footer a.totop {
-  text-transform:uppercase;
-  line-height:30px;
-}
-
 .expandable {
   height:34px;
   padding-left:20px;
@@ -3013,6 +3049,34 @@
 }
 
 
+/* for IDE instruction toggle (Studio/Eclipse/Other) */
+select.ide {
+  background: transparent;
+  border: 1px solid #bbb;
+  border-left: 0;
+  border-right: 0;
+  margin: 10px 0;
+  padding: 10px 0;
+  color:#666;
+}
+select.ide,
+select.ide option {
+  font-family: inherit;
+  font-size:16px;
+  font-weight:500;
+}
+/* hide all except studio by default */
+.select-ide.eclipse,
+.select-ide.other {
+  display:none;
+}
+/* ... unless studio also includes one of the others */
+.select-ide.studio.eclipse,
+.select-ide.studio.other {
+  display:none;
+}
+
+
 /* -----------------------------------------------
 good/bad example containers
 */
@@ -3091,6 +3155,7 @@
   -webkit-box-shadow:-5px 5px 10px #ccc;
 }
 
+div#langMessage,
 div#naMessage {
   display:none;
   width:555px;
@@ -3098,6 +3163,8 @@
   margin:0 auto;
 }
 
+
+div#langMessage>div,
 div#naMessage div {
   z-index:99;
   width:450px;
@@ -3111,12 +3178,16 @@
   -webkit-box-shadow:-10px 10px 40px #888;
 }
 /* IE6 can't position fixed */
+* html div#langMessage>div,
 * html div#naMessage div { position:absolute; }
 
 div#naMessage strong {
   font-size:1.1em;
 }
 
+div#langMessage .lang {
+  display:none;
+}
 
 /* --------------------------------------------------------------------------
 Slideshow Controls & Next/Prev
@@ -3365,28 +3436,37 @@
 }
 
 #jd-header {
-  padding: 0 0 5px;
-  margin: 20px 0 10px;
-  font-size:13px;
+  padding: 0 0 12px;
+  margin: 20px 0 12px;
+  font-size:12px;
+  padding-bottom:12px;
   border-bottom:solid 1px #ccc;
 }
 
 #jd-header h1 {
   margin:0;
-  padding:0;
+  padding:0 0 6px 0;
 }
 
+/* not sure if this is needed in the ref docs, disabling for now
+.jd-descr h2 {
+  margin:16px 0;
+}
+*/
+
 /* page-top-right container for reference pages (holds
 links to summary tables) */
 #api-info-block {
-  font-size:13px;
+  font-size:12px;
   margin:20px 0 0;
   padding:0 10px 6px;
   font-weight:normal;
   float:right;
   text-align:right;
   color:#999;
-  max-width:70%;
+  max-width:80%;
+  font-size: 12px;
+  line-height:14px;
 }
 
 #api-info-block div.api-level {
@@ -3403,7 +3483,8 @@
   border-spacing:0;
   margin:0;
   padding:0;
-  font-size:13px;
+  font-size:12px;
+  line-height:14px;
   background-color:transparent;
 }
 .jd-inheritance-table tr td {
@@ -3968,13 +4049,183 @@
   z-index:100;
 }
 
+
+
+
+
+/************ STICKY NAV BAR ******************/
+
+#header-wrapper {
+  background: #f9f9f9;
+  margin: 0 -10px 0 -10px;
+  padding: 31px 10px 0px 10px;
+  position: relative;
+}
+#header-wrapper #nav-x div.wrap {
+  max-width: 940px;
+  height: 38px;
+}
+#header-wrapper #nav-x ul.nav-x li {
+  margin-right: 31px !important;
+  margin-top: 5px;
+  margin-bottom: 0px;
+  height: 30px;
+}
+#header-wrapper #nav-x > div.wrap ul.nav-x li.active  {
+  color: #669900;
+  border-bottom: 3px solid #669900;
+}
+#header-wrapper #nav-x > div.wrap ul.nav-x li.active a {
+  color: #669900;
+}
+#header-wrapper #nav-x > div.wrap ul.nav-x a {
+  font-size: 14.5px;
+}
+#header-wrapper .developer-console-btn {
+  float: right;
+  background: #fefefe;
+  border-radius: 4px;
+  padding: 8px 14px;
+  box-shadow: 1px 1px 0px #7a7a7a;
+  font-size: 14px;
+  margin-top: -6px;
+  cursor: pointer;
+  color: #464646;
+  margin-right: 20px;
+}
+/* not currently used */
+#header-wrapper .shadow {
+  width: 1034px;
+  height: 4px;
+  position: absolute;
+  left: 50%;
+  margin-left: -517px;
+  bottom: -4px;
+  background-image: url(../images/header-shadow.png);
+}
+
+#context {
+  clear: both;
+  padding-top: 14px;
+}
+#context .breadcrumb {
+  float: left;
+  margin-bottom: 10px;
+}
+#context .util {
+  float: right;
+  margin-right: 20px;
+}
+
+.breadcrumb {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  position: relative;
+}
+.breadcrumb li {
+  float: left;
+  padding: 0 20px 0 0;
+  color: #000;
+  white-space: nowrap;
+}
+.breadcrumb li a {
+  color: #000;
+}
+.breadcrumb li:after {
+  content: url(../images/breadcrumb.png);
+  position: relative;
+  top: 1px;
+  left: 10px;
+  width: 5px;
+  height: 10px;
+}
+.breadcrumb li.current {
+  font-weight: 700;
+}
+.breadcrumb li.current:after {
+  display: none;
+}
+
+/* Sticky Nav overrides */
+.sticky-menu {
+  position: fixed;
+  width: 940px;
+  height: 0px;
+  z-index: 51;
+  top: 12px;
+}
+#sticky-header {
+  display: none;
+  padding: 0 10px;
+  position: fixed;
+  background: #f9f9f9;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  height: 45px;
+  box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.1);
+  border-bottom: 1px solid #a5c43a;
+  z-index: 50;
+}
+#sticky-header.design {
+  border-bottom: 1px solid #33b5e5;
+}
+#sticky-header.develop {
+  border-bottom: 1px solid #F80;
+}
+#sticky-header.distribute {
+  border-bottom: 1px solid #9C0;
+}
+#sticky-header.about {
+  border-bottom: 1px solid #9933CC;
+}
+#sticky-header > div {
+  overflow: hidden;
+  *zoom: 1;
+  width: 940px;
+  margin: 0 auto;
+  clear: both;
+  padding-top: 9px;
+}
+#sticky-header > div .logo {
+  float: left;
+  width: 26px;
+  height: 25px;
+  background: url(../images/dac_logo.png);
+  background-image: -webkit-image-set(url(../images/dac_logo.png) 1x, url(../images/dac_logo@2x.png) 2x);
+  z-index: 52;
+  position: relative;
+}
+#sticky-header > div .top {
+  float: left;
+  width: 38px;
+  height: 38px;
+  position: relative;
+  background: url(../images/styles/gototop.png);
+  z-index: 52;
+}
+#sticky-header > div .breadcrumb {
+  float: left;
+  padding: 0 0 0 10px;
+  border-left: 1px solid #d2d2d2;
+  line-height: 24px;
+  font-size: 14px;
+  position: relative;
+  top: 0px;
+  z-index: 52;
+}
+
+/* offset the <a name=""> tags to account for sticky nav */
+body.reference a[name] {
+  visibility: hidden;
+  display: block;
+  position: relative;
+  top: -56px;
 }
 
 
-
-
-
-
+}
 
 
 
@@ -4014,7 +4265,6 @@
 }
 
 .logo a {
-  width:123px;
   float:left;
 }
 
@@ -4027,11 +4277,13 @@
 }
 
 
-#header .logo-wear {
+#header-wrap .logo.landing-logo {
   width:220px;
   margin:0;
+  padding:0;
+  margin-bottom:22px;
 }
-#header .logo-wear img {
+#header-wrap .logo.landing-logo img {
   padding:0 0 0 10px;
 }
 
@@ -4103,7 +4355,7 @@
 #quicknav {
  float:none;
  clear:both;
- margin-left:180px;
+ margin-left:0;
  margin-top:-30px;
  display:none;
  overflow:hidden;
@@ -4118,6 +4370,10 @@
   padding:0;
 }
 
+#quicknav ul li.about {
+  border-top:1px solid #9933CC;
+}
+
 #quicknav ul li.design {
   border-top:1px solid #33b5e5;
 }
@@ -4168,7 +4424,7 @@
 }
 
 #header-wrap.quicknav {
-  height:196px;
+  height:216px;
 
 }
 
@@ -4447,7 +4703,9 @@
 }
 
 
-
+#landing h1 {
+  margin:17px 0 20px 0 !important;
+}
 
 a.download-sdk {
     float:right;
@@ -4458,11 +4716,11 @@
 }
 
 #nav-x {
-  padding-top: 14px;
+  padding-top: 13px;
 }
 
 #nav-x .wrap {
-  min-height:34px;
+  min-height:32px;
 }
 
 #nav-x .wrap,
@@ -4618,14 +4876,14 @@
 
 /* Slideshow */
 .slideshow-develop {
-  height: 300px;
+  height: 316px;
   width: 940px;
   position: relative;
   overflow:hidden;
 }
 .slideshow-develop .frame {
   width: 940px;
-  height: 300px;
+  height: 316px;
 }
 .slideshow-develop img.play {
   max-width:350px;
@@ -4657,6 +4915,7 @@
   padding:0;
   margin-bottom:10px;
   border:none;
+  font-size:24px;
 }
 .slideshow-develop .item {
   height: 300px;
@@ -4804,53 +5063,6 @@
 
 
 
-/************ DISTRIBUTE HOMEPAGE ***************/
-
-.marquee {
-  width: 760px;
-}
-.marquee .main-img {
-  float: left;
-  margin-top: 20px;
-  width: 490px;
-}
-.marquee .copy {
-  width: 270px;
-  float: left;
-  margin-top: 30px;
-}
-.distribute-features {
-  margin: 0;
-}
-.distribute-features ul {
-  margin: 0;
-}
-.distribute-features ul li {
-  list-style: none;
-  float: left;
-  border-top: 1px solid #9C0;
-  width: 220px;
-  margin-right: 50px;
-}
-.distribute-features ul li.last {
-  margin-right: 0px;
-}
-
-.distribute-features .distribute-link li a {
-  color:red !important;
-}
-
-.distribute-features .distribute-link li a,
-.distribute-features .distribute-link li a:active {
-  color:#555 !important;
-}
-
-.distribute-features .distribute-link li a:hover,
-.distribute-features .distribute-link li a:hover * {
-  color:#7AA1B0 !important;
-}
-
-
 /************ DEVELOP TOPIC CONTAINERS ************/
 
 .landing-banner,
@@ -4876,7 +5088,8 @@
   margin-bottom:0;
 }
 .landing-banner h1 {
-  margin-top:0;
+  margin-top:16px;
+  padding-bottom:24px;
 }
 .landing-docs,
 .landing-banner {
@@ -5028,3 +5241,2200 @@
 .fullpage #footer {
   margin-top: -40px;
 }
+
+/************ DISTRIBUTE PAGES ******************/
+
+.article-detail #body-content {
+  padding-top: 10px;
+}
+
+/* A container for grid sets with uppercase h3 and rule */
+.dynamic-grid h3 {
+  font-size:14px;
+  line-height:21px;
+  color:#555;
+  text-transform:uppercase;
+  border-bottom:1px solid #CCC;
+  padding:8px 0 0 1px;
+  margin-bottom:14px;
+  clear:both;
+}
+
+.top-right-float {
+  float: right;
+}
+
+.clearfloat {
+  float: none;
+  clear: both;
+}
+
+.border-img {
+  border: 1px solid #CCC;
+}
+
+.center-img {
+  margin: auto;
+  text-align: center;
+}
+.center-img img {
+  margin-bottom: 15px;
+}
+
+.figure img, .border-img {
+  margin-bottom: 15px;
+}
+
+/************ RESOURCE CARDS ******************/
+
+/* Resource cards, 12, 13, 16-col */
+
+/* Basic card-styling with shadow */
+.resource-card {
+  border-radius: 1px;
+  box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.12);
+  background: #fefefe;
+}
+
+/* Styling for background image including tinting and section icons in stacks */
+.card-bg {
+  display: block;
+  position: absolute;
+  vertical-align: top;
+  width: 100%;
+  left: 0;
+  top: 0;
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-image: url(../images/resource-card-default-android.jpg);
+}
+.card-bg:after {
+  content: "";
+  display: block;
+  height: 100%;
+  width: 100%;
+  opacity: 1;
+  background: rgba(0, 0, 0, 0.2);
+  -webkit-transition: opacity 0.5s;
+  -moz-transition: opacity 0.5s;
+  -o-transition: opacity 0.5s;
+  transition: opacity 0.5s;
+}
+.static .card-bg:after {
+  display:none;
+}
+.card-bg .card-section-icon {
+  position: absolute;
+  top: 50%;
+  width: 100%;
+  margin-top: -35px;
+  text-align: center;
+  padding-top: 65px;
+  z-index: 100;
+}
+.card-bg .card-section-icon .icon {
+  position: absolute;
+  left: 50%;
+  margin-left: -28px;
+  top: 0px;
+  width: 56px;
+  height: 56px;
+  background-repeat: no-repeat;
+  background-position: 50% 50%;
+  background-image: url(../images/stack-icon.png);
+}
+.card-bg .card-section-icon .section {
+  text-transform: uppercase;
+  color: white;
+  font-size: 14px;
+}
+
+.card-info {
+  position: absolute;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  overflow: hidden;
+  background: #fefefe;
+  padding: 4px 12px 6px 12px;
+}
+.card-info .section {
+  text-transform: uppercase;
+  color: #898989;
+  font-size: 12px;
+  margin-bottom: 1px;
+}
+.card-info .title {
+  color: #363636;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  padding-bottom: 5px;
+  margin-bottom: -2px;
+  font-size: 16px;
+}
+.card-info .description {
+  overflow: hidden;
+}
+.card-info .description .text {
+  color: #464646;
+  font: 13px/15px Roboto Condensed;
+  overflow: hidden;
+  width:100%;
+}
+.card-info .description .util {
+  position: absolute;
+  right: 5px;
+  bottom: 70px; /*-2px;*/
+  opacity: 0;
+  -webkit-transition: opacity 0.5s;
+  -moz-transition: opacity 0.5s;
+  -o-transition: opacity 0.5s;
+  transition: opacity 0.5s;
+}
+.card-info.empty-desc .title {
+  white-space: normal;
+  overflow: visible;
+}
+.card-info.empty-desc .description {
+  display: none;
+}
+/* Truncate card summaries at bounding box and
+ * and apply ellipsis at lower right */
+.ellipsis {
+  overflow: hidden;
+  float:right;
+  line-height: 15px;
+  width:100%;
+}
+.resource-card-6x6 .card-info .description .teddddddxt {
+ float:left;
+  position:relative;
+  margin-left:0;
+}
+.ellipsis:before {
+  content:"";
+  float: left;
+  width: 5px;
+  height:100%;
+}
+.ellipsis > *:first-child.text {
+  float: right;
+  width: 100%  !important;
+  margin-left: -5px;
+}
+.ellipsis:after {
+  content: "\02026";
+  height:17px;
+  padding-bottom:4px;
+
+  box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+
+  float: right; position: relative;
+  top: -16px; left: 100%;
+  width: 4em; margin-left: -4em;
+  padding-right: 5px;
+
+  background: -webkit-gradient(linear, left top, right top,
+    from(rgba(255, 255, 255, 0)), to(white), color-stop(65%, white));
+  background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+  background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+  background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+  background: linear-gradient(to right, rgba(255, 255, 255, 0), white 65%, white);
+}
+.ellipsis:after {
+  font-style: normal; color: #aaa;
+  font-size:13px;
+  text-align: right;
+}
+
+/* Flow Layout */
+.resource-flow-layout {
+  display: inline-block;
+}
+.resource-flow-layout .resource-card, .resource-flow-layout .resource-card-stack {
+  float: left;
+  position: relative;
+}
+.resource-flow-layout .resource-card-stack > .resource-card {
+  margin-right: 0px !important;
+}
+.resource-flow-layout:after {
+  content: ".";
+  display: block;
+  height: 0;
+  position:relative;
+  clear: both;
+  visibility: hidden;
+}
+.resource-card:hover {
+  cursor: pointer;
+}
+.static .resource-card:hover {
+  cursor: auto;
+}
+.resource-card:hover .card-bg:after {
+  opacity: 0;
+}
+/* disabled to make way for fade/ellipsis truncation,
+   and the plusone moves up.
+.resource-card:hover .card-info .description .text {
+  padding-right: 70px;
+} */
+.resource-card:hover .card-info .description .util {
+  opacity: 1;
+}
+
+/* Carousel Layout */
+/* Carousel styles for landing page */
+.resource-carousel-layout {
+  margin: 20px 0 20px 0;
+  position: relative;
+  overflow: hidden;
+}
+.resource-carousel-layout .slideshow-prev, .resource-carousel-layout .slideshow-next {
+  display: none;
+}
+.resource-carousel-layout .pagination {
+  bottom: 0px;
+}
+.resource-carousel-layout .frame li {
+  position: relative;
+}
+.resource-carousel-layout .frame li .card-bg {
+  height: 300px;
+}
+.resource-carousel-layout .frame li .card-info {
+  padding: 7px 15px 0px 15px;
+  top: 300px;
+}
+.resource-carousel-layout .frame li .card-info .section {
+  font-size: 13px;
+  margin-bottom: 7px;
+}
+.resource-carousel-layout .frame li .card-info .title {
+  font-size: 25px;
+  margin-bottom: 2px;
+}
+.resource-carousel-layout .frame li .card-info .description {
+  font-family: 15px/16px Roboto Condensed, sans-serif;
+}
+.resource-carousel-layout .frame li .card-info .description .text {
+  height: 40px;
+}
+.resource-carousel-layout .frame li .card-info .description .util {
+  bottom:97px;
+  right:4px;
+}
+
+/* Stack Layout */
+.resource-stack-layout {
+  display: inline-block;
+}
+.resource-stack-layout .resource-card-stack {
+  float: left;
+  position: relative;
+}
+.resource-stack-layout .resource-card {
+  margin-bottom: 20px;
+  display: block;
+  position: relative;
+}
+.resource-stack-layout .section-card-menu > .card-info .section, .resource-stack-layout .section-card > .card-info .title {
+  /*text-transform: uppercase;*/
+  color: #898989;
+  font-size: 17px;
+  line-height: 24px;
+  margin-bottom: 6px;
+}
+.resource-stack-layout .section-card {
+  height: 284px;
+}
+.resource-stack-layout .section-card > .card-bg {
+  height: 192px;
+}
+.resource-stack-layout .section-card > .card-info {
+  padding: 4px 12px 6px 12px;
+  top: 192px;
+}
+.resource-stack-layout .section-card > .card-info .section {
+  display: none;
+}
+.resource-stack-layout .section-card > .card-info .title {
+  font-size: 17px;
+  border-bottom: 1px solid #959595;
+  padding-bottom: 0px;
+}
+.resource-stack-layout .section-card > .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+.resource-stack-layout .section-card > .card-info .description .text {
+  height: 30px;
+}
+.resource-stack-layout .related-card {
+  height: 90px;
+}
+.resource-stack-layout .related-card > .card-bg {
+  left: 0;
+  top: 0;
+  width: 90px;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.resource-stack-layout .related-card > .card-info {
+  left: 90px;
+  padding: 4px 12px 4px 12px;
+}
+.resource-stack-layout .related-card > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+  display: none;
+}
+.resource-stack-layout .related-card > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+  overflow: visible;
+  text-overflow: ellipsis;
+}
+.resource-stack-layout .related-card > .card-info .title:after {
+  content: url(../images/link-out.png);
+  display: block;
+}
+.resource-stack-layout .related-card > .card-info .description {
+  display: none;
+}
+.resource-stack-layout .section-card-menu {
+  /* Flexible height */
+  display: block;
+  height: auto;
+  width: auto;
+}
+.resource-stack-layout .section-card-menu .card-bg {
+  height: 155px;
+  /* Flexible height */
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+}
+.resource-stack-layout .section-card-menu .card-info {
+  padding: 4px 12px 0px 12px;
+  /* Flexible height */
+  position: relative;
+  left: auto;
+  top: auto;
+  right: auto;
+  bottom: auto;
+}
+.resource-stack-layout .section-card-menu .card-info ul {
+  list-style: none;
+  margin: 0;
+}
+.resource-stack-layout .section-card-menu .card-info ul li {
+  list-style: none;
+  margin: 0;
+  padding: 15px 0;
+  border-top-width: 1px;
+  border-top-style: solid;
+  border-top-color: #959595;
+}
+.resource-stack-layout .section-card-menu .card-info ul li a, .resource-stack-layout .section-card-menu .card-info ul li a:focus, .resource-stack-layout .section-card-menu .card-info ul li a:link, .resource-stack-layout .section-card-menu .card-info ul li a:visited, .resource-stack-layout .section-card-menu .card-info ul li a:active, .resource-stack-layout .section-card-menu .card-info ul li a:hover {
+  color: #363636 !important;
+}
+.resource-stack-layout .section-card-menu .card-info ul li:first-child {
+  border-top: none;
+}
+.resource-stack-layout .section-card-menu .card-info ul li:hover .title:after {
+  opacity: 1;
+  -webkit-transition: opacity 0.5s;
+  -moz-transition: opacity 0.5s;
+  -o-transition: opacity 0.5s;
+  transition: opacity 0.5s;
+}
+.resource-stack-layout .section-card-menu .card-info ul li:hover .description {
+  max-height: 30px;
+  opacity: 1;
+  -webkit-transition: max-height 0.5s, opacity 1s;
+  -moz-transition: max-height 0.5s, opacity 1s;
+  -o-transition: max-height 0.5s, opacity 1s;
+  transition: max-height 0.5s, opacity 1s;
+}
+.resource-stack-layout .section-card-menu .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  position: relative;
+}
+.resource-stack-layout .section-card-menu .card-info .title:after {
+  background: url(../images/stack-arrow-right.png);
+  content: '';
+  opacity: 0;
+  -webkit-transition: opacity 0.25s;
+  -moz-transition: opacity 0.25s;
+  -o-transition: opacity 0.25s;
+  transition: opacity 0.25s;
+  position: absolute;
+  right: 0px;
+  top: 3px;
+  width: 10px;
+  height: 15px;
+}
+.resource-stack-layout .section-card-menu .card-info .title.more {
+  text-transform: uppercase;
+  color: #898989;
+  display: inline-block;
+}
+.resource-stack-layout .section-card-menu .card-info .title.more:after {
+  background: url(../images/stack-arrow-right.png);
+  content: '';
+  display: block;
+  position: absolute;
+  right: -20px;
+  top: 3px;
+  width: 10px;
+  height: 15px;
+}
+.resource-stack-layout .section-card-menu .card-info .description {
+  max-height: 0px;
+  opacity: 0;
+  overflow: hidden;
+  font-size: 13px;
+  line-height: 15px;
+  /* Hover off */
+  -webkit-transition: max-height 0.5s, opacity 0.5s;
+  -moz-transition: max-height 0.5s, opacity 0.5s;
+  -o-transition: max-height 0.5s, opacity 0.5s;
+  transition: max-height 0.5s, opacity 0.5s;
+}
+.resource-stack-layout .section-card-menu .card-info .description .text {
+  height: 30px;
+}
+.resource-stack-layout:after {
+  content: ".";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+/* Generate the flow layout styles for a 3-column 16-col span */
+.resource-flow-layout.col-16 {
+  margin: 0 -14px 0 0;
+  width: 954px;
+}
+.resource-flow-layout.col-16 .resource-card, .resource-flow-layout.col-16 .resource-card-stack {
+  margin: 0 14px 20px 0;
+}
+.resource-flow-layout.col-16 .resource-card-row-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-16 .resource-card-col-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-16 .resource-card-3x6 {
+  width: 145px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-3x12 {
+  width: 145px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-3x18 {
+  width: 145px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-6x6 {
+  width: 304px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-6x12 {
+  width: 304px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-6x18 {
+  width: 304px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-9x6 {
+  width: 463px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-9x12 {
+  width: 463px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-9x18 {
+  width: 463px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-12x6 {
+  width: 622px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-12x12 {
+  width: 622px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-12x18 {
+  width: 622px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-15x6 {
+  width: 781px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-15x12 {
+  width: 781px;
+  height: 588px;
+}
+.resource-flow-layout.col-16 .resource-card-15x18 {
+  width: 781px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-18x6 {
+  width: 940px;
+  height: 284px;
+}
+.resource-flow-layout.col-16 .resource-card-18x12 {
+  width: 940px;
+  height: 420px;
+}
+.resource-flow-layout.col-16 .resource-card-18x18 {
+  width: 940px;
+  height: 892px;
+}
+.resource-flow-layout.col-16 .resource-card-3x2 {
+  width: 145px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-3x2x3 {
+  width: 145px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-3x3 {
+  width: 145px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-3x3x2 {
+  width: 145px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-6x2 {
+  width: 304px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-6x2x3 {
+  width: 304px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-6x3 {
+  width: 304px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-6x3x2 {
+  width: 304px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-9x2 {
+  width: 463px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-9x2x3 {
+  width: 463px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-9x3 {
+  width: 463px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-9x3x2 {
+  width: 463px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-12x2 {
+  width: 622px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-12x2x3 {
+  width: 622px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-12x3 {
+  width: 622px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-12x3x2 {
+  width: 622px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-15x2 {
+  width: 781px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-15x2x3 {
+  width: 781px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-15x3 {
+  width: 781px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-15x3x2 {
+  width: 781px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-16 .resource-card-18x2 {
+  width: 940px;
+  height: 95px;
+}
+.resource-flow-layout.col-16 .resource-card-18x2x3 {
+  width: 940px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-16 .resource-card-18x3 {
+  width: 940px;
+  height: 142px;
+}
+.resource-flow-layout.col-16 .resource-card-18x3x2 {
+  width: 940px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+
+/* Generate the flow layout styles for a 3-column 16-col span */
+.resource-flow-layout.col-12 {
+  margin: 0 -14px 0 0;
+  width: 714px;
+}
+
+.resource-flow-layout.col-12 .resource-card, .resource-flow-layout.col-12 .resource-card-stack {
+  margin: 0 14px 20px 0;
+}
+.resource-flow-layout.col-12 .resource-card-row-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-12 .resource-card-col-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-12 .resource-card-3x6 {
+  width: 105px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-3x12 {
+  width: 105px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-3x18 {
+  width: 105px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-6x6 {
+  width: 224px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-6x12 {
+  width: 224px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-6x18 {
+  width: 224px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-9x6 {
+  width: 343px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-9x12 {
+  width: 343px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-9x18 {
+  width: 343px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-12x6 {
+  width: 462px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-12x12 {
+  width: 462px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-12x18 {
+  width: 462px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-15x6 {
+  width: 581px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-15x12 {
+  width: 581px;
+  height: 588px;
+}
+.resource-flow-layout.col-12 .resource-card-15x18 {
+  width: 581px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-18x6 {
+  width: 700px;
+  height: 284px;
+}
+.resource-flow-layout.col-12 .resource-card-18x12 {
+  width: 700px;
+  height: 420px;
+}
+.resource-flow-layout.col-12 .resource-card-18x18 {
+  width: 700px;
+  height: 892px;
+}
+.resource-flow-layout.col-12 .resource-card-3x2 {
+  width: 105px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-3x2x3 {
+  width: 105px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-3x3 {
+  width: 105px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-3x3x2 {
+  width: 105px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-6x2 {
+  width: 224px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-6x2x3 {
+  width: 224px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-6x3 {
+  width: 224px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-6x3x2 {
+  width: 224px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-9x2 {
+  width: 343px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-9x2x3 {
+  width: 343px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-9x3 {
+  width: 343px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-9x3x2 {
+  width: 343px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-12x2 {
+  width: 462px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-12x2x3 {
+  width: 462px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-12x3 {
+  width: 462px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-12x3x2 {
+  width: 462px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-15x2 {
+  width: 581px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-15x2x3 {
+  width: 581px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-15x3 {
+  width: 581px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-15x3x2 {
+  width: 581px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-12 .resource-card-18x2 {
+  width: 700px;
+  height: 95px;
+}
+.resource-flow-layout.col-12 .resource-card-18x2x3 {
+  width: 700px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-12 .resource-card-18x3 {
+  width: 700px;
+  height: 142px;
+}
+.resource-flow-layout.col-12 .resource-card-18x3x2 {
+  width: 700px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+
+/* Generate the flow layout styles for a 3-column 13-col span */
+
+.resource-flow-layout.col-13 {
+  margin: 0 -14px 0 0;
+  width: 774px;
+}
+.resource-flow-layout.col-13 .resource-card, .resource-flow-layout.col-13 .resource-card-stack {
+  margin: 0 14px 20px 0;
+}
+.resource-flow-layout.col-13 .resource-card-row-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-13 .resource-card-col-stack-last {
+  margin-bottom: 0px !important;
+}
+.resource-flow-layout.col-13 .resource-card-3x6 {
+  width: 115px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-3x12 {
+  width: 115px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-3x18 {
+  width: 115px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-6x6 {
+  width: 244px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-6x12 {
+  width: 244px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-6x18 {
+  width: 244px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-9x6 {
+  width: 373px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-9x12 {
+  width: 373px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-9x18 {
+  width: 373px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-12x6 {
+  width: 502px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-12x12 {
+  width: 502px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-12x18 {
+  width: 502px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-15x6 {
+  width: 631px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-15x12 {
+  width: 631px;
+  height: 588px;
+}
+.resource-flow-layout.col-13 .resource-card-15x18 {
+  width: 631px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-18x6 {
+  width: 760px;
+  height: 284px;
+}
+.resource-flow-layout.col-13 .resource-card-18x12 {
+  width: 760px;
+  height: 420px;
+}
+.resource-flow-layout.col-13 .resource-card-18x18 {
+  width: 760px;
+  height: 892px;
+}
+.resource-flow-layout.col-13 .resource-card-3x2 {
+  width: 115px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-3x2x3 {
+  width: 115px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-3x3 {
+  width: 115px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-3x3x2 {
+  width: 115px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-6x2 {
+  width: 244px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-6x2x3 {
+  width: 244px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-6x3 {
+  width: 244px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-6x3x2 {
+  width: 244px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-9x2 {
+  width: 373px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-9x2x3 {
+  width: 373px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-9x3 {
+  width: 373px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-9x3x2 {
+  width: 373px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-12x2 {
+  width: 502px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-12x2x3 {
+  width: 502px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-12x3 {
+  width: 502px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-12x3x2 {
+  width: 502px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-15x2 {
+  width: 631px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-15x2x3 {
+  width: 631px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-15x3 {
+  width: 631px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-15x3x2 {
+  width: 631px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+.resource-flow-layout.col-13 .resource-card-18x2 {
+  width: 760px;
+  height: 95px;
+}
+.resource-flow-layout.col-13 .resource-card-18x2x3 {
+  width: 760px;
+  height: 90px;
+  margin-bottom: 7px;
+}
+.resource-flow-layout.col-13 .resource-card-18x3 {
+  width: 760px;
+  height: 142px;
+}
+.resource-flow-layout.col-13 .resource-card-18x3x2 {
+  width: 760px;
+  height: 138px;
+  margin-bottom: 8px;
+}
+
+/*
+  The following are styles for cards in the flowlayout above, styled by the number of rows they span
+*/
+/* Single row items, might be simpler to just apply a class */
+.resource-card-3x6 > .card-bg, .resource-card-6x6 > .card-bg, .resource-card-9x6 > .card-bg, .resource-card-12x6 > .card-bg, .resource-card-15x6 > .card-bg, .resource-card-18x6 > .card-bg {
+  height: 192px;
+}
+.resource-card-3x6 > .card-info, .resource-card-6x6 > .card-info, .resource-card-9x6 > .card-info, .resource-card-12x6 > .card-info, .resource-card-15x6 > .card-info, .resource-card-18x6 > .card-info {
+  padding: 4px 12px 6px 12px;
+  top: 192px;
+}
+.resource-card-3x6 > .card-info .section, .resource-card-6x6 > .card-info .section, .resource-card-9x6 > .card-info .section, .resource-card-12x6 > .card-info .section, .resource-card-15x6 > .card-info .section, .resource-card-18x6 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+}
+.resource-card-3x6 > .card-info .title, .resource-card-6x6 > .card-info .title, .resource-card-9x6 > .card-info .title, .resource-card-12x6 > .card-info .title, .resource-card-15x6 > .card-info .title, .resource-card-18x6 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+}
+.resource-card-3x6 > .card-info .description, .resource-card-6x6 > .card-info .description, .resource-card-9x6 > .card-info .description, .resource-card-12x6 > .card-info .description, .resource-card-15x6 > .card-info .description, .resource-card-18x6 > .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+.resource-card-3x6 > .card-info .description .text, .resource-card-6x6 > .card-info .description .text, .resource-card-9x6 > .card-info .description .text, .resource-card-12x6 > .card-info .description .text, .resource-card-15x6 > .card-info .description .text, .resource-card-18x6 > .card-info .description .text {
+  height: 30px;
+}
+
+/* Double row items */
+.resource-card-3x12 > .card-bg, .resource-card-6x12 > .card-bg, .resource-card-9x12 > .card-bg, .resource-card-12x12 > .card-bg, .resource-card-15x12 > .card-bg, .resource-card-18x12 > .card-bg {
+  height: 320px;
+}
+.resource-card-3x12 > .card-info, .resource-card-6x12 > .card-info, .resource-card-9x12 > .card-info, .resource-card-12x12 > .card-info, .resource-card-15x12 > .card-info, .resource-card-18x12 > .card-info {
+  padding: 4px 12px 6px 12px;
+  top: 320px;
+}
+.resource-card-3x12 > .card-info .section, .resource-card-6x12 > .card-info .section, .resource-card-9x12 > .card-info .section, .resource-card-12x12 > .card-info .section, .resource-card-15x12 > .card-info .section, .resource-card-18x12 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+}
+.resource-card-3x12 > .card-info .title, .resource-card-6x12 > .card-info .title, .resource-card-9x12 > .card-info .title, .resource-card-12x12 > .card-info .title, .resource-card-15x12 > .card-info .title, .resource-card-18x12 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+}
+.resource-card-3x12 > .card-info .description, .resource-card-6x12 > .card-info .description, .resource-card-9x12 > .card-info .description, .resource-card-12x12 > .card-info .description, .resource-card-15x12 > .card-info .description, .resource-card-18x12 > .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+
+/* 1/3 row items */
+.resource-card-3x2 > .card-bg, .resource-card-6x2 > .card-bg, .resource-card-9x2 > .card-bg, .resource-card-12x2 > .card-bg, .resource-card-15x2 > .card-bg, .resource-card-18x2 > .card-bg {
+  left: 0;
+  top: 0;
+  width: 90px;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.resource-card-3x2 > .card-info, .resource-card-6x2 > .card-info, .resource-card-9x2 > .card-info, .resource-card-12x2 > .card-info, .resource-card-15x2 > .card-info, .resource-card-18x2 > .card-info {
+  left: 90px;
+  padding: 4px 12px 4px 12px;
+  height: 80px;
+  overflow: hidden;
+}
+.resource-card-3x2 > .card-info .section, .resource-card-6x2 > .card-info .section, .resource-card-6x3 > .card-info .section, .resource-card-9x2 > .card-info .section, .resource-card-12x2 > .card-info .section, .resource-card-15x2 > .card-info .section, .resource-card-18x2 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+  /* display: none; */
+}
+.resource-card-3x2 > .card-info .title, .resource-card-6x2 > .card-info .title, .resource-card-9x2 > .card-info .title, .resource-card-12x2 > .card-info .title, .resource-card-15x2 > .card-info .title, .resource-card-18x2 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+  overflow: visible;
+  text-overflow: ellipsis;
+}
+.resource-card-3x2 > .card-info .title:after, .resource-card-6x2 > .card-info .title:after, .resource-card-9x2 > .card-info .title:after, .resource-card-12x2 > .card-info .title:after, .resource-card-15x2 > .card-info .title:after, .resource-card-18x2 > .card-info .title:after {
+  /* content: url(../images/link-out.png); */
+  display: block;
+}
+.resource-card-3x2 > .card-info .description, .resource-card-6x2 > .card-info .description, .resource-card-9x2 > .card-info .description, .resource-card-12x2 > .card-info .description, .resource-card-15x2 > .card-info .description, .resource-card-18x2 > .card-info .description {
+  display: none;
+}
+
+
+/* Override to show the description instead of the content section */
+.no-section .resource-card-3x2 > .card-info .section,
+.no-section .resource-card-6x2 > .card-info .section {
+  display: none;
+}
+.no-section .resource-card-3x2 > .card-info .description,
+.no-section .resource-card-6x2 > .card-info .description {
+  display: block;
+}
+
+/* 1/2 row items */
+.resource-card-3x3 > .card-bg, .resource-card-6x3 > .card-bg, .resource-card-9x3 > .card-bg, .resource-card-12x3 > .card-bg, .resource-card-15x3 > .card-bg, .resource-card-18x3 > .card-bg {
+  left: 0;
+  top: 0;
+  width: 90px;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.resource-card-3x3 > .card-info, .resource-card-6x3 > .card-info, .resource-card-9x3 > .card-info, .resource-card-12x3 > .card-info, .resource-card-15x3 > .card-info, .resource-card-18x3 > .card-info {
+  left: 90px;
+  padding: 4px 12px 0px 12px;
+}
+.resource-card-3x3 > .card-info .section, .resource-card-6x3 > .card-info .section, .resource-card-9x3 > .card-info .section, .resource-card-12x3 > .card-info .section, .resource-card-15x3 > .card-info .section, .resource-card-18x3 > .card-info .section {
+  font-size: 12px;
+  margin-bottom: 1px;
+  display: none;
+}
+.resource-card-3x3 > .card-info .title, .resource-card-6x3 > .card-info .title, .resource-card-9x3 > .card-info .title, .resource-card-12x3 > .card-info .title, .resource-card-15x3 > .card-info .title, .resource-card-18x3 > .card-info .title {
+  font-size: 16px;
+  margin-bottom: -2px;
+  white-space: normal;
+  overflow: visible;
+}
+.resource-card-3x3 > .card-info .description .text, .resource-card-6x3 > .card-info .description .text, .resource-card-9x3 > .card-info .description .text, .resource-card-12x3 > .card-info .description .text, .resource-card-15x3 > .card-info .description .text, .resource-card-18x3 > .card-info .description .text {
+  font-size: 12px;
+  line-height: 15px;
+  padding-right: 0px !important;
+  height: 80px;
+}
+.resource-card-3x3 > .card-info .description .util, .resource-card-6x3 > .card-info .description .util, .resource-card-9x3 > .card-info .description .util, .resource-card-12x3 > .card-info .description .util, .resource-card-15x3 > .card-info .description .util, .resource-card-18x3 > .card-info .description .util {
+  display: none;
+}
+/* placement of plusone */
+.resource-card-6x12 > .card-info .description .util, .resource-card-9x12 > .card-info .description .util, .resource-card-12x12 > .card-info .description .util, .resource-card-15x12 > .card-info .description .util {
+  bottom:2px;
+}
+.resource-card-18x12 > .card-info .description .util {
+  bottom:2px;
+}
+/* Overrides for col-16 6x6 cards linking to local content on landing pages.
+   Suppresses "section" and puts the title above a hairline rule. */
+.landing .card-info .section, .resource-flow-layout.col-16.landing .resource-card-9x6 .card-info .section {
+  display:none;
+}
+.landing  .card-info .title {
+  color: #898989;
+  font-size: 17px;
+  line-height: 24px;
+  margin-bottom: 6px;
+  border-bottom: 1px solid #959595;
+  padding-bottom: 0px;
+}
+.landing .card-info .description {
+  font-size: 13px;
+  line-height: 15px;
+}
+.landing .card-info .description .text {
+height:30px;
+}
+.landing .resource-card-6x6 > .card-info .description .util, .landing .resource-card-9x6 > .card-info .description .util {
+  bottom:2px;
+}
+/*
+  Generate a resource stack layout for a 3 column widget spanning 16 grid cols
+*/
+.resource-stack-layout.col-16 {
+  margin: 0 -14px 0 0;
+  width: 954px;
+}
+.resource-stack-layout.col-16 .resource-card-stack {
+  margin: 0 14px 0 0;
+  width: 304px;
+}
+
+/* Example of card menu tinting */
+.resource-widget[data-section=distribute\/tools] .section-card-menu
+.card-bg:after {
+  background: rgba(126, 55, 148, 0.4) !important;
+}
+.resource-widget[data-section=distribute\/tools] .section-card-menu
+.card-section-icon .icon {
+  background-color: #7e3794 !important;
+}
+.resource-widget[data-section=distribute\/tools] .section-card-menu
+.card-info ul li {
+  border-top-color: #7e3794 !important;
+}
+
+/* tinting for stacks */
+
+div.jd-descr > .resource-widget[data-section=distribute\/tools]
+.section-card-menu .card-info ul li {
+  border-top-color: #7e3794 !important;
+}
+
+
+
+/**
+ * UTILITIES
+ */
+
+
+.border-box {
+  box-sizing: border-box;
+}
+
+.vertical-center-outer {
+  display: table;
+  height: 100%;
+  width: 100%;
+}
+
+.vertical-center-inner {
+  display: table-cell;
+  vertical-align: middle;
+}
+
+/**
+ * TYPE STYLES
+ */
+
+.landing-h1 {
+  font-weight: 100;
+  font-size: 60px;
+  line-height: 78px;
+  text-align: center;
+  letter-spacing: -1px;
+}
+
+.landing-pre-h1 {
+  font-weight: 400;
+  font-size: 28px;
+  color: #93B73F;
+  line-height: 36px;
+  text-align: center;
+  letter-spacing: -1px;
+  text-transform: uppercase;
+
+}
+
+.landing-h1.hero {
+  text-align: left;
+}
+
+.landing-h2 {
+  font-weight: 300;
+  font-size: 42px;
+  line-height: 64px;
+  text-align: center;
+}
+
+.landing-subhead {
+  color: #999999;
+  font-size: 20px;
+  line-height: 28px;
+  font-weight:300;
+  text-align: center;
+}
+.landing-subhead.hero {
+  text-align: left;
+  color: white;
+}
+
+.landing-hero-description {
+  text-align: left;
+  margin: 1em 0;
+}
+
+.landing-hero-description p {
+  font-weight: 300;
+  margin: 0;
+  font-size: 18px;
+  line-height: 24px;
+}
+
+.landing-body .landing-small {
+  font-size: 14px;
+  line-height: 19px;
+}
+
+.landing-body.landing-align-center {
+  text-align: center;
+}
+
+.landing-align-left {
+  text-align: left;
+}
+
+/**
+ * LAYOUT
+ */
+
+#body-content,
+.fullpage,
+#jd-content,
+.jd-descr,
+.landing-body-content {
+  height: 100%;
+}
+
+.landing-section {
+  padding: 80px 10px 80px;
+  width: 100%;
+  margin-left: -10px;
+  text-rendering: optimizeLegibility;
+}
+
+#extending-android-to-wearables {
+  padding-top: 30px;
+}
+
+.landing-short-section {
+  padding: 40px 10px 28px;
+}
+
+.landing-gray-background {
+  background-color: #e9e9e9;
+}
+
+.landing-white-background {
+  background-color: white;
+}
+
+.landing-red-background {
+  color: white;
+  background-color: hsl(8, 70%, 54%);
+}
+
+.landing-subhead-red {
+  color: hsl(8, 71%, 84%);
+  text-align: left;
+}
+
+.landing-subhead-red p {
+  margin-top: 20px;
+}
+
+.landing-hero-container {
+  height: 100%;
+}
+
+
+.preview-hero {
+  height: calc(100% - 110px);
+  min-height: 504px;
+  margin-top: -5px;
+  padding-top: 0;
+  padding-bottom: 0;
+  background-image: url(../../preview/images/hero.jpg);
+  background-size: cover;
+  background-position: right center;
+  color: white;
+  position: relative;
+  overflow: hidden;
+}
+
+.wear-hero {
+  height: calc(100% - 110px);
+  min-height: 504px;
+  margin-top: -5px;
+  padding-top: 0;
+  padding-bottom: 0;
+  background-image: url(../../wear/images/hero.jpg);
+  background-size: cover;
+  background-position: top center;
+  color: white;
+  position: relative;
+  overflow: hidden;
+}
+
+.tv-hero {
+  height: calc(100% - 110px);
+  min-height: 504px;
+  margin-top: -5px;
+  padding-top: 0;
+  padding-bottom: 0;
+  background-image: url(../../tv/images/hero.jpg);
+  background-size: cover;
+  background-position: right center;
+  color: white;
+  position: relative;
+  overflow: hidden;
+}
+
+.auto-hero {
+  height: calc(100% - 110px);
+  min-height: 504px;
+  margin-top: -5px;
+  padding-top: 0;
+  padding-bottom: 0;
+  background-image: url(../../auto/images/hero.jpg);
+  background-size: cover;
+  background-position: right center;
+  color: white;
+  position: relative;
+  overflow: hidden;
+}
+
+.landing-hero-scrim {
+  background: black;
+  opacity: .2;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  margin-left: -10px;
+}
+
+.landing-hero-wrap {
+  margin: 0 auto;
+  width: 940px;
+  clear: both;
+  height: 100%;
+  position: relative;
+}
+
+.landing-section-header {
+  margin-bottom: 40px;
+}
+
+.landing-hero-wrap .landing-section-header {
+  margin-bottom: 16px;
+}
+
+.landing-body {
+  font-size: 18px;
+  line-height: 24px;
+}
+
+.landing-button {
+  white-space: nowrap;
+  display: inline-block;
+  padding: 16px 32px;
+  font-size: 18px;
+  font-weight: 500;
+  line-height: 24px;
+  cursor: pointer;
+  color: white;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+       -o-user-select: none;
+  user-select: none;
+  -webkit-transition: .2s background-color ease-in-out;
+     -moz-transition: .2s background-color ease-in-out;
+       -o-transition: .2s background-color ease-in-out;
+  transition: .2s background-color ease-in-out;
+}
+
+.landing-primary {
+  background-color: hsl(8, 70%, 44%);
+  color: #f8f8f8;
+}
+
+.landing-button.landing-primary:hover {
+  background-color: hsl(8, 70%, 36%);
+}
+
+.landing-button.landing-primary:active {
+  background-color: hsl(8, 70%, 30%);
+}
+
+.landing-button.landing-secondary {
+  background-color: #2faddb;
+}
+
+.landing-button.landing-secondary:hover {
+  background-color: #09c;
+}
+
+.landing-button.landing-secondary:active {
+  background-color: #3990ab;
+}
+
+a.landing-button,
+a.landing-button:hover,
+a.landing-button:visited {
+  color: white !important;
+}
+
+.landing-video-link {
+  white-space: nowrap;
+  display: inline-block;
+  padding: 16px 32px 16px 82px;
+  font-size: 18px;
+  font-weight: 400;
+  line-height: 24px;
+  cursor: pointer;
+  color: hsla(0, 0%, 100%, .8);
+  -webkit-user-select: none;
+     -moz-user-select: none;
+       -o-user-select: none;
+  user-select: none;
+  -webkit-transition: .2s color ease-in-out;
+     -moz-transition: .2s color ease-in-out;
+       -o-transition: .2s color ease-in-out;
+  transition: .2s color ease-in-out;
+}
+
+.landing-video-link:before {
+  height: 64px;
+  width: 64px;
+  display: inline-block;
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAFuklEQVR42u2dXWgcVRSAV9LWtBBTTZVWUhNqEQtq1QeroDRKFRFsROqTYPuo+JCiIoJKFC0USqlUfCiowRcfrBgVUUElefAPkW5T8aeaGn9aRbFsjP0x2cx8PuRMvFxmdjeb2Z17Z8+B85DsZPbO+eaec3/OPSkABdXsVI2gABSAqgJQAKoKQAGoKgAFoKoAFICqAlAAqgpAAai6DqDRAiwDeoFtwB7gPaAInABKwKToCWAMeB/YDdwJrAWWNLh9+QMAXABsBQ4A3wFTwAxQBmaBAAhjNJDPy3L938BXwAvArUCHAkh+kCXAVcA+YBw4bRg7MngtkgTlDPA98CywHmhTAP8/xCbgVeAvMZZpwDQllN7xB/AysKGlAQAXAvuBkzW85UVgCBgENlfQQbmuWAXELPAnsAvoaikAQBtwh/j3coLhS2LIfqCzzu/plL8fkvvFgZiR4L2lHrfkHQBgpQTFUwmGnwC212v0KjC2y/3jQPwDPA+05xYAcBHwubx1YZzhC02QBBBRbxgBzssdAOBy4JgRZE0ZTPuNr7FHDCbEhqNAd24AAN0yUbID7QSwsZChABut3hANXY8Bq70HIMb/Ocb4w81+66v0hmGrN0QQ1ngLQJYRvpWHMWWo4KDIaMnuCcVKgdlZAGL8t2J8vpPGrwChDLyWBMFlAA8D0z4ZvwKEs8D93gCQEc9Jy/jFgkdizaRDGUSs8wXAu1bQLQE9ngHosWbPAXDQeQAypT9rBd3+gociyxi2K9riLABZUj5iuZ6RgsciM2OzFxw2A7JrAO6VwGtKTwpG+Anoy9AVmb3gDHCPcwCAFcChRox6jPu9CazMeFQUAKNRL3AJwE2yopjq228BQPZ/d2bcCyaBTa4BeNGa8Q6naIA4GQWubiKEYWvBbp8zAGQt5VfL/fQ3GEAkTzXDLVkjokA2k5a7AuA2GaLNj/tTfvhq0pQgbcwLQtlQusYVALtlzSR191MjADNI9zbJDZWBR10BMGr5/4GMADQ0SAMDlht62xUAxy0AmzMEEMnhtIO0ZF2YAH5wITd0hQw/5wE04M1bjDyXZpC2hqMlYGnWAHqBf40APOEYgChI35VSWyasWfGqrAH0WVkOIw4CSC1IG2tDoSy7XJE1gPs8ArDoIG0BmJGk30wBDHgGYFFBOgbAtqwB7GxxAHerC8rOBU0Dt2gQzjYIb8gawDor+6HVhqFdrkzEwhabiAVOTMSkUb+06FLEUVfWgj5q0cW4g64AeNo66ZLlcnTDNmesBN4y8KArAG6QU42ttCEzBVzpCoAO4EfLDeV5SzIEvgHaXdqUP2BlQud1Ux55zj2uZUX02cPRnKalRLmu17qYmPWF5YbymJgVAh8Ay5wCII3ZEZOYm6fURGT2u9X43Mnk3CDHybmfmRVYXExPv9nKEcpLejqSC3SjdY2TBzTesHqB7wc0onTEV2KucxLApXKkJy9HlAI5anuJFwCkYQ/EuCJfD+mdBnYkXOssgHY53un7MdVZ4CVgqVcADAhjMafkfTioHc14P04yvvMApIEXy5F/+7S8y6UKolPyR4BVVf7Wi2IdawwIPhTrmAW+rmZ8bwBIQ7vloXwoVzNWS6UUrwAYy9YfOlqwKZDkgneA5Qu4l3cly84F9sqGhislywLmaozuYoGFXr0DII1ukxP1hxJ6QzR7HqLxRfumZaRzXZ3f4XXZyi7gCeB3kqsnzs+kSb9s5XHgMeD8RTxDLgq3rmeuYuFvNYCoR8wqujNi+L3UWBcu9wAMt3QZ8LiMlk5RuU50teq6kcEDgTolveIRYHUQBOek1O5cFu/ukLz7/ZJgNSm+OirebWpgaPS7slxfAr4EngGuX8jopqUBxGzyrAVuB54EXgc+lV4yLhO8cfn5E+ZqUD8kBu9sQvv0Hzj4rmoEBaAAVBWAAlBVAApAVQEoAFUFoABUFYACUFUACkC1CfofXVRJocowZVYAAAAASUVORK5CYII=);
+  background-size: contain;
+  position: absolute;
+  content: "";
+  opacity: .7;
+  margin-top: -19px;
+  margin-left: -64px;
+  -webkit-transition: .2s opacity ease-in-out;
+     -moz-transition: .2s opacity ease-in-out;
+       -o-transition: .2s opacity ease-in-out;
+  transition: .2s opacity ease-in-out;
+}
+
+.landing-video-link:hover {
+  color: hsla(0, 0%, 100%, 1);
+}
+
+.landing-video-link:hover:before {
+  opacity: 1;
+}
+
+.landing-social-image {
+  float: left;
+  margin-right: 14px;
+  height: 64px;
+  width: 64px;
+}
+
+.landing-social-copy {
+  padding-left: 78px;
+}
+
+.landing-scroll-down-affordance {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  text-align: center;
+  z-index: 10;
+}
+
+.landing-down-arrow {
+  padding: 24px;
+  display: inline-block;
+  opacity: .5;
+  -webkit-transition: .2s opacity ease-in-out;
+     -moz-transition: .2s opacity ease-in-out;
+       -o-transition: .2s opacity ease-in-out;
+  transition: .2s opacity ease-in-out;
+
+  -webkit-animation-name: pulse-opacity;
+  -webkit-animation-duration: 4s;
+}
+
+.landing-down-arrow:hover {
+  opacity: 1;
+}
+
+.landing-down-arrow img {
+  height: 28px;
+  width: 28px;
+  margin: 0 auto;
+  display: block;
+}
+
+.landing-divider {
+  display: inline-block;
+  height: 2px;
+  background-color: white;
+  position: relative;
+  margin: 10px 0;
+}
+
+/* 3 CLOLUMN LAYOUT */
+
+.landing-breakout {
+  margin-top: 40px;
+  margin-bottom: 40px;
+}
+
+.landing-breakout img {
+  margin-bottom: 20px;
+}
+
+.landing-partners img {
+  margin-bottom: 20px;
+}
+
+.landing-breakout p {
+  padding: 0 23px;
+}
+
+.landing-breakout.landing-partners img {
+  margin-bottom: 20px;
+}
+
+.col-3-wide {
+  display: inline;
+  float: left;
+  margin-left: 10px;
+  margin-right: 10px;
+}
+
+.col-3-wide {
+  width: 302px;
+}
+
+/**
+ * ANIMATION
+ */
+
+@-webkit-keyframes pulse-opacity {
+  0% {
+    opacity: .5;
+  }
+  20% {
+    opacity: .5;
+  }
+  40% {
+    opacity: 1;
+  }
+  60% {
+    opacity: .5;
+  }
+  80% {
+    opacity: 1;
+  }
+  100% {
+    opacity: .5;
+  }
+}
+
+
+
+/**
+ * VIDEO
+ */
+
+#video-container {
+  display:none;
+  position:fixed;
+  top:0;
+  left:0;
+  width:100%;
+  height:100%;
+  background-color:rgba(0,0,0,0.8);
+  z-index:9999;
+}
+
+#video-frame {
+  width:940px;
+  height:100%;
+  margin:72px auto;
+  display:none;
+  position:relative;
+}
+
+.video-close {
+  cursor: pointer;
+  position: absolute;
+  right: -49px;
+  top: -49px;
+  pointer-events: all;
+}
+
+#icon-video-close {
+  background-image: url("../images/close-white.png");
+  background-image: -webkit-image-set(url(../images/close-white.png) 1x, url(../images/close-white_2x.png) 2x);
+  background-repeat: no-repeat;
+  background-position: 0 0;
+  background-size: 36px 36px;
+  height: 36px;
+  width: 36px;
+  display:block;
+}
+
+#icon-video-close:hover {
+  background-image: url("../images/close-grey.png");
+  background-image: -webkit-image-set(url(../images/close-grey.png) 1x, url(../images/close-grey_2x.png) 2x);
+}
+
+/* Preload the hover images */
+a.video-shadowbox-button.white:after {
+  display:none;
+  content:url("../images/close-grey.png") url("../images/close-grey_2x.png");
+}
+
+a.video-shadowbox-button.white {
+  background-image: url("../images/play-circle-white.png");
+  background-image: -webkit-image-set(url(../images/play-circle-white.png) 1x, url(../images/play-circle-white_2x.png) 2x);
+  background-size: 36px 36px;
+  background-repeat: no-repeat;
+  background-position: right;
+  padding: 16px 42px 16px 8px;
+  font-size: 18px;
+  font-weight: 500;
+  line-height: 24px;
+  color: #fff;
+  text-decoration:none;
+}
+
+a.video-shadowbox-button.white:hover {
+  color:#bababa !important;
+  background-image: url("../images/play-circle-grey.png");
+  background-image: -webkit-image-set(url(../images/play-circle-grey.png) 1x, url(../images/play-circle-grey_2x.png) 2x);
+}
+
+/* Preload the hover images */
+a.video-shadowbox-button.white:after {
+  display:none;
+  content:url("../images/play-circle-grey.png") url("../images/play-circle-grey_2x.png");
+}
+
+/******************
+Styles for d.a.c/index:
+*******************/
+
+
+
+/* Generic full screen carousel styling to be used across pages. */
+.fullscreen-carousel {
+  margin: 0 -10px;
+  width: 100%;
+  overflow: hidden;
+  position: relative;
+}
+
+.fullscreen-carousel-content {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  display: table; /* For vertical centering */
+}
+
+.fullscreen-carousel .vcenter {
+  display: table-cell;
+  vertical-align: middle;
+  position: relative;
+}
+
+.fullscreen-carousel .vcenter > div {
+  margin: 10px auto;
+}
+
+/* Styles for the full-bleed hero image type. */
+.fullscreen-carousel .hero, .fullscreen-carousel .hero h1 {
+  color: #fff;
+}
+
+.fullscreen-carousel .hero h1 {
+  font-weight: 300;
+  font-size: 60px;
+  line-height: 68px;
+  letter-spacing: -1px;
+  margin-top: 0;
+}
+
+.fullscreen-carousel .hero p {
+  font-weight: 300;
+  font-size: 18px;
+  line-height: 24px;
+  -webkit-font-smoothing: antialiased;
+}
+
+.fullscreen-carousel .hero .hero-bg {
+  background-size: cover;
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  left: 0px;
+  top: 0px;
+}
+
+
+/* Full screen carousel styling for the resource flow layout type of content */
+.fullscreen-carousel .resource-flow-layout:after {
+  height: 0; /* Dont know why this is set at 10 in default.css */
+}
+
+.fullscreen-carousel .resource-flow-layout {
+  margin-bottom: 20px;
+}
+
+
+
+/* Generic Tab carousel styling to be used across multiple pages. */
+
+.tab-carousel .tab-nav {
+  list-style: none;
+  position: relative;
+  text-align: center;
+}
+
+.tab-carousel .tab-nav li {
+  display: inline-block;
+  font-size: 22px;
+  font-weight: 400;
+  line-height: 50px;
+  list-style: none;
+  margin: 0;
+  padding: 0 25px;
+  position: relative;
+}
+
+.tab-carousel .tab-nav li a,
+.tab-carousel .tab-nav li a:hover {
+  color: #333 !important;
+  padding: 10px 10px 13px 10px;
+  position: relative;
+  z-index: 1000;
+}
+
+.tab-carousel .tab-nav li:after {
+  background: #ddd;
+  bottom: 0;
+  content: '';
+  height: 4px;
+  left: 0;
+  position: absolute;
+  width: 100%;
+  z-index: 0;
+}
+
+.tab-carousel .tab-nav .highlight {
+  position: absolute;
+  height: 4px;
+  width: 100px;
+  bottom: 0;
+  background: #33b5e5;
+}
+
+.tab-carousel .tab-carousel-content {
+  position: relative;
+  overflow: hidden;
+  white-space: nowrap;
+}
+
+.tab-carousel .tab-carousel-content [data-tab] {
+  display: inline-block;
+  white-space: normal;
+}
+
+
+
+/*
+  Resource styling for the tab carousel. The tab carousel contains either
+  a 3 column layout of resources or a single full-width resource. The
+  latter has the 18x12 class applied to it and can be styled differently
+  that way.
+*/
+
+.tab-carousel .resource .image {
+  width: 100%;
+  height: 250px;
+  background-repeat: no-repeat;
+  background-size: contain;
+  background-position: 50% 50%;
+}
+
+.tab-carousel .resource .info .title {
+  font-size: 18px;
+  line-height: 24px;
+}
+
+.tab-carousel .resource .info .summary,
+.tab-carousel .resource .info .cta {
+  line-height: 24px;
+  font-size: 16px;
+}
+
+.tab-carousel .resource-card-18x12 {
+  position: relative;
+  padding-left: 450px;
+  box-sizing: border-box;
+  display: table-cell;
+  vertical-align: middle;
+}
+
+.tab-carousel .resource-card-18x12 .image {
+  position: absolute;
+  width: 420px;
+  height: 100%;
+  left: 0;
+  top: 0;
+}
+
+.tab-carousel .resource-card-18x12 .info {
+  display: inline-block;
+}
+
+.tab-carousel .resource-card-18x12 .info .title {
+  margin-bottom: 26px;
+}
+
+
+
+
+
+/*
+   Styles for the entity link used in the actions bar and in the cta of
+   the resources that appear in the tab carousel.
+*/
+.actions-bar a:after,
+.resource .cta:after {
+  content: '›';
+  font-weight: 400;
+  font-size: 22px;
+  left: 5px;
+  line-height: 1;
+  position: relative;
+  top: 1px;
+  transition: left 190ms ease-out;
+}
+
+.actions-bar a:hover:after,
+.resource .cta:hover:after {
+  left: 10px;
+}
+
+
+
+
+/*
+  Styles for the actions bar.
+*/
+.actions-bar {
+  background: #9acd00;
+  margin: 0 -10px;
+  text-align: center;
+}
+
+.actions-bar .actions {
+  padding: 30px 0 30px;
+  text-align: justify;
+  font-size: 0.1px;
+  line-height: 0.1px;
+  margin: 0 10px 0 0;
+}
+
+.actions-bar .actions:after {
+  content: '';
+  width: 100%;
+  display: inline-block;
+}
+
+.actions-bar .actions > div {
+  display: inline-block;
+}
+
+.actions-bar a {
+  font-size: 21px;
+  line-height: 27px;
+  color: #fff;
+  font-weight: 300;
+  -webkit-font-smoothing: antialiased;
+}
+
+.actions-bar a:after {
+  top: 0px;
+  font-size: 22px;
+}
+
+.actions-bar a:hover {
+  color: #fff !important;
+}
+
+
+
+
+
+/*
+  Specific styles for new home page layout of the carousels.
+*/
+
+/* Big blue button */
+a.home-new-cta-btn,
+.home-new-carousel-1 .resource-card-18x6 .cta {
+  white-space: nowrap;
+  display: inline-block;
+  padding: 14px 32px;
+  font-size: 18px;
+  font-weight: 500;
+  line-height: 24px;
+  cursor: pointer;
+  background: #33b5e6;
+  border-radius: 4px;
+  margin-top: 20px;
+  color: #fff;
+  transition: 0.2s background-color ease-in-out;
+}
+
+.home-new-carousel-1 .resource-card-18x6 .cta:after {
+  display: none; /* Hide the entity for this button */
+}
+
+a.home-new-cta-btn:hover,
+.home-new-carousel-1 .resource-card-18x6 .cta:hover {
+  color: #fff !important;
+  background: #2d9fca;
+}
+
+.home-new-carousel-1 .resource-card-18x6 .cta {
+  position: absolute;
+  bottom: 20px;
+  left: 16px;
+}
+
+/* Fullscreen carousel. */
+.home-new-carousel-1 {
+  max-height: 700px; /* Set max height so doesn't get too long */
+}
+
+.home-new-carousel-1 .fullscreen-carousel-content {
+  min-height: 450px;  /* Set min height for all content */
+}
+
+.home-new-carousel-1 .hero {
+  background: #000;
+}
+
+.home-new-carousel-1 .hero-bg {
+  background-image: url(/home-new/images/hero.jpg);
+  background-position: right center;
+  opacity: 0.85;
+}
+
+/*
+  Styling for special top card of full screen layout resource layout.
+  We need to specifically style the 18x6 card to adjust its size and layout,
+  since it's not a standard card, not sure if this is unique to the home page
+  layout or should be namespaced within the fullscreen-carousel container.
+*/
+.home-new-carousel-1 .resource-flow-layout.col-16 .resource-card-18x6 {
+  height: 320px;
+  background-color:#F9F9F9;
+  border-radius: 0px;
+  box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
+
+}
+
+.home-new-carousel-1 .resource-card-18x6 .card-bg {
+  width: 636px;
+  height: 100%;
+}
+
+.home-new-carousel-1 .resource-card-18x6 .card-info {
+  right: 0px;
+  left: 636px;
+  height: 100%;
+  top: 0px;
+  padding: 15px 22px;
+}
+
+.home-new-carousel-1 .resource-card-18x6 .card-info .util {
+  display: none;
+}
+
+.home-new-carousel-1 .resource-card-18x6 .card-info .title {
+  font-size: 20px;
+  font-weight: 500;
+  margin-top: 15px;
+  margin-bottom: 15px;
+}
+
+.home-new-carousel-1 .resource-card-18x6 .card-info .text {
+  font-size: 15px;
+  line-height: 21px;
+}
+
+
+/* Tabbed carousel. */
+.home-new-carousel-2 {
+  margin: 35px auto 100px auto;
+}
+
+.home-new-carousel-2 h1 {
+  font-size: 47px;
+  font-weight: 100;
+  line-height: 54px;
+  text-align: center;
+}
+
+.annotation-message {
+    display: block;
+    font-style: italic;
+    color: #F80;
+}
+
+
+
+/* Helpouts widget */
+.resource-card-6x2.helpouts-card {
+  width: 255px;
+  height: 40px;
+  position:absolute;
+  z-index:999;
+  top:-8px;
+  right:1px;
+}
+
+.resource-card-6x2.helpouts-card > .card-info {
+  left:35px;
+  height:35px;
+  padding:4px 8px 4px 0;
+}
+
+.resource-card-6x2.helpouts-card > .card-info .helpouts-description {
+  display:block;
+  overflow:visible;
+  font-size:12px;
+  line-height:12px;
+  text-align:right;
+  color:#666;
+}
+
+.helpouts-description .link-color {
+  text-transform: uppercase;
+}
+
+.resource-card-6x2 > .card-bg.helpouts-card-bg {
+  width:35px;
+  height:35px;
+  margin:2px 0 0 0;
+  background-image: url(../images/styles/helpouts-logo-35_2x.png);
+  background-image: -webkit-image-set(url(../images/styles/helpouts-logo-35.png) 1x, url(../images/styles/helpouts-logo-35_2x.png) 2x);
+}
+
+.resource-card-6x2 > .card-bg.helpouts-card-bg:after {
+  display:none;
+}
diff --git a/tools/droiddoc/templates-sdk/assets/css/fullscreen.css b/tools/droiddoc/templates-sdk/assets/css/fullscreen.css
index 71cf65b..7912e34 100644
--- a/tools/droiddoc/templates-sdk/assets/css/fullscreen.css
+++ b/tools/droiddoc/templates-sdk/assets/css/fullscreen.css
@@ -170,7 +170,7 @@
   max-width: 100%;
 }
 
-#nav-x .wrap,
+#header-wrapper #nav-x div.wrap,
 #searchResults.wrap {
     max-width:100%;
 }
@@ -184,9 +184,17 @@
   left:20px; /* !important ... for IE i think */
 }
 
+#sticky-header {
+  padding: 0 20px;
+}
 
+#sticky-header > div {
+  width: 100%;
+}
 
-
+.sticky-menu {
+  width:100%;
+  left:-20px;
 }
 
 .col-right {
diff --git a/tools/droiddoc/templates-sdk/assets/images/android.png b/tools/droiddoc/templates-sdk/assets/images/android.png
new file mode 100644
index 0000000..4040f3f
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/android.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/breadcrumb.png b/tools/droiddoc/templates-sdk/assets/images/breadcrumb.png
new file mode 100644
index 0000000..407a318
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/breadcrumb.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/close-grey.png b/tools/droiddoc/templates-sdk/assets/images/close-grey.png
new file mode 100644
index 0000000..1b0d7f1
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/close-grey.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/close-grey_2x.png b/tools/droiddoc/templates-sdk/assets/images/close-grey_2x.png
new file mode 100644
index 0000000..1355507
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/close-grey_2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/close-white.png b/tools/droiddoc/templates-sdk/assets/images/close-white.png
new file mode 100644
index 0000000..ef02018
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/close-white.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/close-white_2x.png b/tools/droiddoc/templates-sdk/assets/images/close-white_2x.png
new file mode 100644
index 0000000..9b9c41d
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/close-white_2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/dac_logo@2x.png b/tools/droiddoc/templates-sdk/assets/images/dac_logo@2x.png
new file mode 100644
index 0000000..0f2784d
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/dac_logo@2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/link-out.png b/tools/droiddoc/templates-sdk/assets/images/link-out.png
new file mode 100644
index 0000000..aa55f9a
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/link-out.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/play-circle-grey.png b/tools/droiddoc/templates-sdk/assets/images/play-circle-grey.png
new file mode 100644
index 0000000..5e7e7ba
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/play-circle-grey.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/play-circle-grey_2x.png b/tools/droiddoc/templates-sdk/assets/images/play-circle-grey_2x.png
new file mode 100644
index 0000000..3e01635
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/play-circle-grey_2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/play-circle-white.png b/tools/droiddoc/templates-sdk/assets/images/play-circle-white.png
new file mode 100644
index 0000000..017d846
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/play-circle-white.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/play-circle-white_2x.png b/tools/droiddoc/templates-sdk/assets/images/play-circle-white_2x.png
new file mode 100644
index 0000000..e48c1fd
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/play-circle-white_2x.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/preview.png b/tools/droiddoc/templates-sdk/assets/images/preview.png
new file mode 100644
index 0000000..e5856db
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/preview.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/resource-card-default-android.jpg b/tools/droiddoc/templates-sdk/assets/images/resource-card-default-android.jpg
new file mode 100644
index 0000000..8050744
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/resource-card-default-android.jpg
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/stack-arrow-right.png b/tools/droiddoc/templates-sdk/assets/images/stack-arrow-right.png
new file mode 100644
index 0000000..46d6a50
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/stack-arrow-right.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/device_wear_square.png b/tools/droiddoc/templates-sdk/assets/images/styles/device_wear_square.png
new file mode 100644
index 0000000..077a7e6
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/device_wear_square.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/device_wear_square_small.png b/tools/droiddoc/templates-sdk/assets/images/styles/device_wear_square_small.png
new file mode 100644
index 0000000..e7e1540
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/device_wear_square_small.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/helpouts-logo-35.png b/tools/droiddoc/templates-sdk/assets/images/styles/helpouts-logo-35.png
new file mode 100644
index 0000000..3c2dc1a
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/helpouts-logo-35.png
Binary files differ
diff --git a/tools/droiddoc/templates-sdk/assets/images/styles/helpouts-logo-35_2x.png b/tools/droiddoc/templates-sdk/assets/images/styles/helpouts-logo-35_2x.png
new file mode 100644
index 0000000..e34be2e
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/images/styles/helpouts-logo-35_2x.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 6630bf9..7f4be4e 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -19,9 +19,19 @@
 
 /******  ON LOAD SET UP STUFF *********/
 
-var navBarIsFixed = false;
 $(document).ready(function() {
 
+  // show lang dialog if the URL includes /intl/
+  //if (location.pathname.substring(0,6) == "/intl/") {
+  //  var lang = location.pathname.split('/')[2];
+   // if (lang != getLangPref()) {
+   //   $("#langMessage a.yes").attr("onclick","changeLangPref('" + lang
+   //       + "', true); $('#langMessage').hide(); return false;");
+  //    $("#langMessage .lang." + lang).show();
+   //   $("#langMessage").show();
+   // }
+  //}
+
   // load json file for JD doc search suggestions
   $.getScript(toRoot + 'jd_lists_unified.js');
   // load json file for Android API search suggestions
@@ -64,7 +74,12 @@
   $('.scroll-pane').jScrollPane( {verticalGutter:0} );
 
   // add HRs below all H2s (except for a few other h2 variants)
-  $('h2').not('#qv h2').not('#tb h2').not('.sidebox h2').not('#devdoc-nav h2').not('h2.norule').css({marginBottom:0}).after('<hr/>');
+  $('h2').not('#qv h2')
+         .not('#tb h2')
+         .not('.sidebox h2')
+         .not('#devdoc-nav h2')
+         .not('h2.norule').css({marginBottom:0})
+         .after('<hr/>');
 
   // set up the search close button
   $('.search .close').click(function() {
@@ -167,10 +182,24 @@
   // highlight Design tab
   if ($("body").hasClass("design")) {
     $("#header li.design a").addClass("selected");
+    $("#sticky-header").addClass("design");
 
+  // highlight About tabs
+  } else if ($("body").hasClass("about")) {
+    var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
+    if (rootDir == "about") {
+      $("#nav-x li.about a").addClass("selected");
+    } else if (rootDir == "wear") {
+      $("#nav-x li.wear a").addClass("selected");
+    } else if (rootDir == "tv") {
+      $("#nav-x li.tv a").addClass("selected");
+    } else if (rootDir == "auto") {
+      $("#nav-x li.auto a").addClass("selected");
+    }
   // highlight Develop tab
   } else if ($("body").hasClass("develop") || $("body").hasClass("google")) {
     $("#header li.develop a").addClass("selected");
+    $("#sticky-header").addClass("develop");
     // In Develop docs, also highlight appropriate sub-tab
     var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
     if (rootDir == "training") {
@@ -195,12 +224,36 @@
   // highlight Distribute tab
   } else if ($("body").hasClass("distribute")) {
     $("#header li.distribute a").addClass("selected");
+    $("#sticky-header").addClass("distribute");
+
+    var baseFrag = pagePathOriginal.indexOf('/', 1) + 1;
+    var secondFrag = pagePathOriginal.substring(baseFrag, pagePathOriginal.indexOf('/', baseFrag));
+    if (secondFrag == "users") {
+      $("#nav-x li.users a").addClass("selected");
+    } else if (secondFrag == "engage") {
+      $("#nav-x li.engage a").addClass("selected");
+    } else if (secondFrag == "monetize") {
+      $("#nav-x li.monetize a").addClass("selected");
+    } else if (secondFrag == "analyze") {
+      $("#nav-x li.analyze a").addClass("selected");
+    } else if (secondFrag == "tools") {
+      $("#nav-x li.disttools a").addClass("selected");
+    } else if (secondFrag == "stories") {
+      $("#nav-x li.stories a").addClass("selected");
+    } else if (secondFrag == "essentials") {
+      $("#nav-x li.essentials a").addClass("selected");
+    } else if (secondFrag == "googleplay") {
+      $("#nav-x li.googleplay a").addClass("selected");
+    }
+  } else if ($("body").hasClass("about")) {
+    $("#sticky-header").addClass("about");
   }
 
   // set global variable so we can highlight the sidenav a bit later (such as for google reference)
   // and highlight the sidenav
   mPagePath = pagePath;
   highlightSidenav();
+  buildBreadcrumbs();
 
   // set up prev/next links if they exist
   var $selNavLink = $('#nav').find('a[href="' + pagePath + '"]');
@@ -215,7 +268,7 @@
     var crossBoundaries = ($("body.design").length > 0) || ($("body.guide").length > 0) ? true :
 false; // navigate across topic boundaries only in design docs
     if ($prevListItem.length) {
-      if ($prevListItem.hasClass('nav-section')) {
+      if ($prevListItem.hasClass('nav-section') || crossBoundaries) {
         // jump to last topic of previous section
         $prevLink = $prevListItem.find('a:last');
       } else if (!$selListItem.hasClass('nav-section')) {
@@ -238,7 +291,6 @@
     // set up next links
     var $nextLink = [];
     var startClass = false;
-    var training = $(".next-class-link").length; // decides whether to provide "next class" link
     var isCrossingBoundary = false;
 
     if ($selListItem.hasClass('nav-section') && $selListItem.children('div.empty').length == 0) {
@@ -265,13 +317,15 @@
       if ($nextLink.length == 0) {
         isCrossingBoundary = true;
         // no more topics in this section, jump to the first topic in the next section
-        $nextLink = $selListItem.parents('li:eq(0)').next('li.nav-section').find('a:eq(0)');
+        $nextLink = $selListItem.parents('li:eq(0)').next('li').find('a:eq(0)');
         if (!$nextLink.length) {  // Go up another layer to look for next page (lesson > class > course)
           $nextLink = $selListItem.parents('li:eq(1)').next('li.nav-section').find('a:eq(0)');
           if ($nextLink.length == 0) {
             // if that doesn't work, we're at the end of the list, so disable NEXT link
             $('.next-page-link').attr('href','').addClass("disabled")
                                 .click(function() { return false; });
+            // and completely hide the one in the footer
+            $('.content-footer .next-page-link').hide();
           }
         }
       }
@@ -290,13 +344,19 @@
       $('.next-page-link').attr('href','')
                           .removeClass("hide").addClass("disabled")
                           .click(function() { return false; });
+      // and completely hide the one in the footer
+      $('.content-footer .next-page-link').hide();
       if ($nextLink.length) {
         $('.next-class-link').attr('href',$nextLink.attr('href'))
-                             .removeClass("hide").append($nextLink.html());
+                             .removeClass("hide")
+                             .append(": " + $nextLink.html());
         $('.next-class-link').find('.new').empty();
       }
     } else {
-      $('.next-page-link').attr('href', $nextLink.attr('href')).removeClass("hide");
+      $('.next-page-link').attr('href', $nextLink.attr('href'))
+                          .removeClass("hide");
+      // for the footer link, also add the next page title
+      $('.content-footer .next-page-link').append(": " + $nextLink.html());
     }
 
     if (!startClass && $prevLink.length) {
@@ -308,14 +368,6 @@
       }
     }
 
-    // If this is a training 'article', there should be no prev/next nav
-    // ... if the grandparent is the "nav" ... and it has no child list items...
-    if (training && $selListItem.parents('ul').eq(1).is('[id="nav"]') &&
-        !$selListItem.find('li').length) {
-      $('.next-page-link,.prev-page-link').attr('href','').addClass("disabled")
-                          .click(function() { return false; });
-    }
-
   }
 
 
@@ -323,7 +375,20 @@
   // Set up the course landing pages for Training with class names and descriptions
   if ($('body.trainingcourse').length) {
     var $classLinks = $selListItem.find('ul li a').not('#nav .nav-section .nav-section ul a');
-    var $classDescriptions = $classLinks.attr('description');
+
+    // create an array for all the class descriptions
+    var $classDescriptions = new Array($classLinks.length);
+    var lang = getLangPref();
+    $classLinks.each(function(index) {
+      var langDescr = $(this).attr(lang + "-description");
+      if (typeof langDescr !== 'undefined' && langDescr !== false) {
+        // if there's a class description in the selected language, use that
+        $classDescriptions[index] = langDescr;
+      } else {
+        // otherwise, use the default english description
+        $classDescriptions[index] = $(this).attr("description");
+      }
+    });
 
     var $olClasses  = $('<ol class="class-list"></ol>');
     var $liClass;
@@ -335,7 +400,7 @@
     $classLinks.each(function(index) {
       $liClass  = $('<li></li>');
       $h2Title  = $('<a class="title" href="'+$(this).attr('href')+'"><h2>' + $(this).html()+'</h2><span></span></a>');
-      $pSummary = $('<p class="description">' + $(this).attr('description') + '</p>');
+      $pSummary = $('<p class="description">' + $classDescriptions[index] + '</p>');
 
       $olLessons  = $('<ol class="lesson-list"></ol>');
 
@@ -374,7 +439,7 @@
     var stylesheet = $('link[rel="stylesheet"][class="fullscreen"]');
     setNavBarLeftPos(); // do this even if sidenav isn't fixed because it could become fixed
     // make sidenav behave when resizing the window and side-scolling is a concern
-    if (navBarIsFixed) {
+    if (sticky) {
       if ((stylesheet.attr("disabled") == "disabled") || stylesheet.length == 0) {
         updateSideNavPosition();
       } else {
@@ -385,70 +450,6 @@
   });
 
 
-  // Set up fixed navbar
-  var prevScrollLeft = 0; // used to compare current position to previous position of horiz scroll
-  $(window).scroll(function(event) {
-    if ($('#side-nav').length == 0) return;
-    if (event.target.nodeName == "DIV") {
-      // Dump scroll event if the target is a DIV, because that means the event is coming
-      // from a scrollable div and so there's no need to make adjustments to our layout
-      return;
-    }
-    var scrollTop = $(window).scrollTop();
-    var headerHeight = $('#header').outerHeight();
-    var subheaderHeight = $('#nav-x').outerHeight();
-    var searchResultHeight = $('#searchResults').is(":visible") ?
-                             $('#searchResults').outerHeight() : 0;
-    var totalHeaderHeight = headerHeight + subheaderHeight + searchResultHeight;
-    // we set the navbar fixed when the scroll position is beyond the height of the site header...
-    var navBarShouldBeFixed = scrollTop > totalHeaderHeight;
-    // ... except if the document content is shorter than the sidenav height.
-    // (this is necessary to avoid crazy behavior on OSX Lion due to overscroll bouncing)
-    if ($("#doc-col").height() < $("#side-nav").height()) {
-      navBarShouldBeFixed = false;
-    }
-
-    var scrollLeft = $(window).scrollLeft();
-    // When the sidenav is fixed and user scrolls horizontally, reposition the sidenav to match
-    if (navBarIsFixed && (scrollLeft != prevScrollLeft)) {
-      updateSideNavPosition();
-      prevScrollLeft = scrollLeft;
-    }
-
-    // Don't continue if the header is sufficently far away
-    // (to avoid intensive resizing that slows scrolling)
-    if (navBarIsFixed && navBarShouldBeFixed) {
-      return;
-    }
-
-    if (navBarIsFixed != navBarShouldBeFixed) {
-      if (navBarShouldBeFixed) {
-        // make it fixed
-        var width = $('#devdoc-nav').width();
-        $('#devdoc-nav')
-            .addClass('fixed')
-            .css({'width':width+'px'})
-            .prependTo('#body-content');
-        // add neato "back to top" button
-        $('#devdoc-nav a.totop').css({'display':'block','width':$("#nav").innerWidth()+'px'});
-
-        // update the sidenaav position for side scrolling
-        updateSideNavPosition();
-      } else {
-        // make it static again
-        $('#devdoc-nav')
-            .removeClass('fixed')
-            .css({'width':'auto','margin':''})
-            .prependTo('#side-nav');
-        $('#devdoc-nav a.totop').hide();
-      }
-      navBarIsFixed = navBarShouldBeFixed;
-    }
-
-    resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
-  });
-
-
   var navBarLeftPos;
   if ($('#devdoc-nav').length) {
     setNavBarLeftPos();
@@ -522,7 +523,11 @@
     }
   }
 
+  // Resize once loading is finished
   resizeNav();
+  // Check if there's an anchor that we need to scroll into view.
+  // A delay is needed, because some browsers do not immediately scroll down to the anchor
+  window.setTimeout(offsetScrollForSticky, 100);
 
   /* init the language selector based on user cookie for lang */
   loadLangPref();
@@ -555,10 +560,147 @@
     cookiePath = "distribute_";
   }
 
+
+  /* setup shadowbox for any videos that want it */
+  var $videoLinks = $("a.video-shadowbox-button, a.notice-developers-video");
+  if ($videoLinks.length) {
+    // if there's at least one, add the shadowbox HTML to the body
+    $('body').prepend(
+'<div id="video-container">'+
+  '<div id="video-frame">'+
+    '<div class="video-close">'+
+      '<span id="icon-video-close" onclick="closeVideo()">&nbsp;</span>'+
+    '</div>'+
+    '<div id="youTubePlayer"></div>'+
+  '</div>'+
+'</div>');
+
+    // loads the IFrame Player API code asynchronously.
+    $.getScript("https://www.youtube.com/iframe_api");
+
+    $videoLinks.each(function() {
+      var videoId = $(this).attr('href').split('?v=')[1];
+      $(this).click(function(event) {
+        event.preventDefault();
+        startYouTubePlayer(videoId);
+      });
+    });
+  }
 });
 // END of the onload event
 
 
+var youTubePlayer;
+function onYouTubeIframeAPIReady() {
+}
+
+/* Returns the height the shadowbox video should be. It's based on the current
+   height of the "video-frame" element, which is 100% height for the window.
+   Then minus the margin so the video isn't actually the full window height. */
+function getVideoHeight() {
+  var frameHeight = $("#video-frame").height();
+  var marginTop = $("#video-frame").css('margin-top').split('px')[0];
+  return frameHeight - (marginTop * 2);
+}
+
+var mPlayerPaused = false;
+
+function startYouTubePlayer(videoId) {
+  $("#video-container").show();
+  $("#video-frame").show();
+  mPlayerPaused = false;
+
+  // compute the size of the player so it's centered in window
+  var maxWidth = 940;  // the width of the web site content
+  var videoAspect = .5625; // based on 1280x720 resolution
+  var maxHeight = maxWidth * videoAspect;
+  var videoHeight = getVideoHeight();
+  var videoWidth = videoHeight / videoAspect;
+  if (videoWidth > maxWidth) {
+    videoWidth = maxWidth;
+    videoHeight = maxHeight;
+  }
+  $("#video-frame").css('width', videoWidth);
+
+  // check if we've already created this player
+  if (youTubePlayer == null) {
+    // check if there's a start time specified
+    var idAndHash = videoId.split("#");
+    var startTime = 0;
+    if (idAndHash.length > 1) {
+      startTime = idAndHash[1].split("t=")[1] != undefined ? idAndHash[1].split("t=")[1] : 0;
+    }
+    // enable localized player
+    var lang = getLangPref();
+    var captionsOn = lang == 'en' ? 0 : 1;
+
+    youTubePlayer = new YT.Player('youTubePlayer', {
+      height: videoHeight,
+      width: videoWidth,
+      videoId: idAndHash[0],
+      playerVars: {start: startTime, hl: lang, cc_load_policy: captionsOn},
+      events: {
+        'onReady': onPlayerReady,
+        'onStateChange': onPlayerStateChange
+      }
+    });
+  } else {
+    // reset the size in case the user adjusted the window since last play
+    youTubePlayer.setSize(videoWidth, videoHeight);
+    // if a video different from the one already playing was requested, cue it up
+    if (videoId != youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0]) {
+      youTubePlayer.cueVideoById(videoId);
+    }
+    youTubePlayer.playVideo();
+  }
+}
+
+function onPlayerReady(event) {
+  event.target.playVideo();
+  mPlayerPaused = false;
+}
+
+function closeVideo() {
+  try {
+    youTubePlayer.pauseVideo();
+  } catch(e) {
+  }
+  $("#video-container").fadeOut(200);
+}
+
+/* Track youtube playback for analytics */
+function onPlayerStateChange(event) {
+    // Video starts, send the video ID
+    if (event.data == YT.PlayerState.PLAYING) {
+      if (mPlayerPaused) {
+        ga('send', 'event', 'Videos', 'Resume',
+            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0]);
+      } else {
+        // track the start playing event so we know from which page the video was selected
+        ga('send', 'event', 'Videos', 'Start: ' +
+            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
+            'on: ' + document.location.href);
+      }
+      mPlayerPaused = false;
+    }
+    // Video paused, send video ID and video elapsed time
+    if (event.data == YT.PlayerState.PAUSED) {
+      ga('send', 'event', 'Videos', 'Paused',
+            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
+            youTubePlayer.getCurrentTime());
+      mPlayerPaused = true;
+    }
+    // Video finished, send video ID and video elapsed time
+    if (event.data == YT.PlayerState.ENDED) {
+      ga('send', 'event', 'Videos', 'Finished',
+            youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
+            youTubePlayer.getCurrentTime());
+      mPlayerPaused = true;
+    }
+}
+
+
+
 function initExpandableNavItems(rootTag) {
   $(rootTag + ' li.nav-section .nav-section-header').click(function() {
     var section = $(this).closest('li.nav-section');
@@ -593,6 +735,28 @@
   });
 }
 
+
+/** Create the list of breadcrumb links in the sticky header */
+function buildBreadcrumbs() {
+  var $breadcrumbUl =  $("#sticky-header ul.breadcrumb");
+  // Add the secondary horizontal nav item, if provided
+  var $selectedSecondNav = $("div#nav-x ul.nav-x a.selected").clone().removeClass("selected");
+  if ($selectedSecondNav.length) {
+    $breadcrumbUl.prepend($("<li>").append($selectedSecondNav))
+  }
+  // Add the primary horizontal nav
+  var $selectedFirstNav = $("div#header-wrap ul.nav-x a.selected").clone().removeClass("selected");
+  // If there's no header nav item, use the logo link and title from alt text
+  if ($selectedFirstNav.length < 1) {
+    $selectedFirstNav = $("<a>")
+        .attr('href', $("div#header .logo a").attr('href'))
+        .text($("div#header .logo img").attr('alt'));
+  }
+  $breadcrumbUl.prepend($("<li>").append($selectedFirstNav));
+}
+
+
+
 /** Highlight the current page in sidenav, expanding children as appropriate */
 function highlightSidenav() {
   // if something is already highlighted, undo it. This is for dynamic navigation (Samples index)
@@ -644,7 +808,7 @@
     setTimeout(updateSidenavFixedWidth,delay); // need to wait a moment for css to switch
     enabled = false;
   }
-  writeCookie("fullscreen", enabled, null, null);
+  writeCookie("fullscreen", enabled, null);
   setNavBarLeftPos();
   resizeNav(delay);
   updateSideNavPosition();
@@ -705,9 +869,8 @@
   // Then figure out based on scroll position whether the header is visible
   var windowHeight = $window.height();
   var scrollTop = $window.scrollTop();
-  var headerHeight = $('#header').outerHeight();
-  var subheaderHeight = $('#nav-x').outerHeight();
-  var headerVisible = (scrollTop < (headerHeight + subheaderHeight));
+  var headerHeight = $('#header-wrapper').outerHeight();
+  var headerVisible = scrollTop < stickyTop;
 
   // get the height of space between nav and top of window.
   // Could be either margin or top position, depending on whether the nav is fixed.
@@ -717,7 +880,7 @@
   // Depending on whether the header is visible, set the side nav's height.
   if (headerVisible) {
     // The sidenav height grows as the header goes off screen
-    navHeight = windowHeight - (headerHeight + subheaderHeight - scrollTop) - topMargin;
+    navHeight = windowHeight - (headerHeight - scrollTop) - topMargin;
   } else {
     // Once header is off screen, the nav height is almost full window height
     navHeight = windowHeight - topMargin;
@@ -806,7 +969,7 @@
 function saveNavPanels() {
   var basePath = getBaseUri(location.pathname);
   var section = basePath.substring(1,basePath.indexOf("/",1));
-  writeCookie("height", resizePackagesNav.css("height"), section, null);
+  writeCookie("height", resizePackagesNav.css("height"), section);
 }
 
 
@@ -887,25 +1050,123 @@
   return 0;
 }
 
-function writeCookie(cookie, val, section, expiration) {
+function writeCookie(cookie, val, section) {
   if (val==undefined) return;
   section = section == null ? "_" : "_"+section+"_";
-  if (expiration == null) {
-    var date = new Date();
-    date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
-    expiration = date.toGMTString();
-  }
+  var age = 2*365*24*60*60; // set max-age to 2 years
   var cookieValue = cookie_namespace + section + cookie + "=" + val
-                    + "; expires=" + expiration+"; path=/";
+                    + "; max-age=" + age +"; path=/";
   document.cookie = cookieValue;
 }
 
 /* #########     END COOKIES!     ########## */
 
 
+var sticky = false;
+var stickyTop;
+var prevScrollLeft = 0; // used to compare current position to previous position of horiz scroll
+/* Sets the vertical scoll position at which the sticky bar should appear.
+   This method is called to reset the position when search results appear or hide */
+function setStickyTop() {
+  stickyTop = $('#header-wrapper').outerHeight() - $('#sticky-header').outerHeight();
+}
 
+/*
+ * Displays sticky nav bar on pages when dac header scrolls out of view
+ */
+$(window).scroll(function(event) {
 
+  setStickyTop();
+  var hiding = false;
+  var $stickyEl = $('#sticky-header');
+  var $menuEl = $('.menu-container');
+  // Exit if there's no sidenav
+  if ($('#side-nav').length == 0) return;
+  // Exit if the mouse target is a DIV, because that means the event is coming
+  // from a scrollable div and so there's no need to make adjustments to our layout
+  if ($(event.target).nodeName == "DIV") {
+    return;
+  }
 
+  var top = $(window).scrollTop();
+  // we set the navbar fixed when the scroll position is beyond the height of the site header...
+  var shouldBeSticky = top >= stickyTop;
+  // ... except if the document content is shorter than the sidenav height.
+  // (this is necessary to avoid crazy behavior on OSX Lion due to overscroll bouncing)
+  if ($("#doc-col").height() < $("#side-nav").height()) {
+    shouldBeSticky = false;
+  }
+  // Account for horizontal scroll
+  var scrollLeft = $(window).scrollLeft();
+  // When the sidenav is fixed and user scrolls horizontally, reposition the sidenav to match
+  if (sticky && (scrollLeft != prevScrollLeft)) {
+    updateSideNavPosition();
+    prevScrollLeft = scrollLeft;
+  }
+
+  // Don't continue if the header is sufficently far away
+  // (to avoid intensive resizing that slows scrolling)
+  if (sticky == shouldBeSticky) {
+    return;
+  }
+
+  // If sticky header visible and position is now near top, hide sticky
+  if (sticky && !shouldBeSticky) {
+    sticky = false;
+    hiding = true;
+    // make the sidenav static again
+    $('#devdoc-nav')
+        .removeClass('fixed')
+        .css({'width':'auto','margin':''})
+        .prependTo('#side-nav');
+    // delay hide the sticky
+    $menuEl.removeClass('sticky-menu');
+    $stickyEl.fadeOut(250);
+    hiding = false;
+
+    // update the sidenaav position for side scrolling
+    updateSideNavPosition();
+  } else if (!sticky && shouldBeSticky) {
+    sticky = true;
+    $stickyEl.fadeIn(10);
+    $menuEl.addClass('sticky-menu');
+
+    // make the sidenav fixed
+    var width = $('#devdoc-nav').width();
+    $('#devdoc-nav')
+        .addClass('fixed')
+        .css({'width':width+'px'})
+        .prependTo('#body-content');
+
+    // update the sidenaav position for side scrolling
+    updateSideNavPosition();
+
+  } else if (hiding && top < 15) {
+    $menuEl.removeClass('sticky-menu');
+    $stickyEl.hide();
+    hiding = false;
+  }
+  resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
+});
+
+/*
+ * Manages secion card states and nav resize to conclude loading
+ */
+(function() {
+  $(document).ready(function() {
+
+    // Stack hover states
+    $('.section-card-menu').each(function(index, el) {
+      var height = $(el).height();
+      $(el).css({height:height+'px', position:'relative'});
+      var $cardInfo = $(el).find('.card-info');
+
+      $cardInfo.css({position: 'absolute', bottom:'0px', left:'0px', right:'0px', overflow:'visible'});
+    });
+
+  });
+
+})();
 
 
 
@@ -972,8 +1233,16 @@
 }
 
 
+/* Call this to add listeners to a <select> element for Studio/Eclipse/Other docs */
+function setupIdeDocToggle() {
+  $( "select.ide" ).change(function() {
+    var selected = $(this).find("option:selected").attr("value");
+    $(".select-ide").hide();
+    $(".select-ide."+selected).show();
 
-
+    $("select.ide").val(selected);
+  });
+}
 
 
 
@@ -1026,9 +1295,7 @@
     nav_pref = NAV_PREF_TREE;
     init_default_navtree(toRoot);
   }
-  var date = new Date();
-  date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
-  writeCookie("nav", nav_pref, "reference", date.toGMTString());
+  writeCookie("nav", nav_pref, "reference");
 
   $("#nav-panels").toggle();
   $("#panel-link").toggle();
@@ -1096,11 +1363,7 @@
 }
 
 function changeLangPref(lang, submit) {
-  var date = new Date();
-  expires = date.toGMTString(date.setTime(date.getTime()+(10*365*24*60*60*1000)));
-  // keep this for 50 years
-  //alert("expires: " + expires)
-  writeCookie("pref_lang", lang, null, expires);
+  writeCookie("pref_lang", lang, null);
 
   //  #######  TODO:  Remove this condition once we're stable on devsite #######
   //  This condition is only needed if we still need to support legacy GAE server
@@ -1519,8 +1782,8 @@
 
 function onSuggestionClick(link) {
   // When user clicks a suggested document, track it
-  _gaq.push(['_trackEvent', 'Suggestion Click', 'clicked: ' + $(link).text(),
-            'from: ' + $("#search_autocomplete").val()]);
+  ga('send', 'event', 'Suggestion Click', 'clicked: ' + $(link).attr('href'),
+                'query: ' + $("#search_autocomplete").val().toLowerCase());
 }
 
 function set_item_selected($li, selected)
@@ -1724,6 +1987,7 @@
             $('.suggest-card').hide();
             if ($("#searchResults").is(":hidden") && (search.value != "")) {
               // if results aren't showing (and text not empty), return true to allow search to execute
+              $('body,html').animate({scrollTop:0}, '500', 'swing');
               return true;
             } else {
               // otherwise, results are already showing, so allow ajax to auto refresh the results
@@ -1736,8 +2000,12 @@
             return false;
         }
     }
-    // Stop here if Google results are showing
+    // If Google results are showing, return true to allow ajax search to execute
     else if ($("#searchResults").is(":visible")) {
+        // Also, if search_results is scrolled out of view, scroll to top to make results visible
+        if ((sticky ) && (search.value != "")) {
+          $('body,html').animate({scrollTop:0}, '500', 'swing');
+        }
         return true;
     }
     // 38 UP ARROW
@@ -1860,7 +2128,7 @@
 
 
         // Search for matching JD docs
-        if (text.length >= 3) {
+        if (text.length >= 2) {
           // Regex to match only the beginning of a word
           var textRegex = new RegExp("\\b" + text.toLowerCase(), "g");
 
@@ -2278,13 +2546,13 @@
   var query = document.getElementById('search_autocomplete').value;
   location.hash = 'q=' + query;
   loadSearchResults();
-  $("#searchResults").slideDown('slow');
+  $("#searchResults").slideDown('slow', setStickyTop);
   return false;
 }
 
 
 function hideResults() {
-  $("#searchResults").slideUp();
+  $("#searchResults").slideUp('fast', setStickyTop);
   $(".search .close").addClass("hide");
   location.hash = '';
 
@@ -2401,27 +2669,50 @@
     return;
   } else {
     // first time loading search results for this page
-    $('#searchResults').slideDown('slow');
+    $('#searchResults').slideDown('slow', setStickyTop);
     $(".search .close").removeClass("hide");
     loadSearchResults();
   }
 }, true);
 
+/* Adjust the scroll position to account for sticky header, only if the hash matches an id.
+   This does not handle <a name=""> tags. Some CSS fixes those, but only for reference docs. */
+function offsetScrollForSticky() {
+  // Ignore if there's no search bar (some special pages have no header)
+  if ($("#search-container").length < 1) return;
+
+  var hash = escape(location.hash.substr(1));
+  var $matchingElement = $("#"+hash);
+  // Sanity check that there's an element with that ID on the page
+  if ($matchingElement.length) {
+    // If the position of the target element is near the top of the page (<20px, where we expect it
+    // to be because we need to move it down 60px to become in view), then move it down 60px
+    if (Math.abs($matchingElement.offset().top - $(window).scrollTop()) < 20) {
+      $(window).scrollTop($(window).scrollTop() - 60);
+    }
+  }
+}
+
 // when an event on the browser history occurs (back, forward, load) requery hash and do search
 $(window).hashchange( function(){
-  // Exit if the hash isn't a search query or there's an error in the query
+  // Ignore if there's no search bar (some special pages have no header)
+  if ($("#search-container").length < 1) return;
+
+  // If the hash isn't a search query or there's an error in the query,
+  // then adjust the scroll position to account for sticky header, then exit.
   if ((location.hash.indexOf("q=") == -1) || (query == "undefined")) {
     // If the results pane is open, close it.
     if (!$("#searchResults").is(":hidden")) {
       hideResults();
     }
+    offsetScrollForSticky();
     return;
   }
 
   // Otherwise, we have a search to do
   var query = decodeURI(getQuery(location.hash));
   searchControl.execute(query);
-  $('#searchResults').slideDown('slow');
+  $('#searchResults').slideDown('slow', setStickyTop);
   $("#search_autocomplete").focus();
   $(".search .close").removeClass("hide");
 
@@ -2465,8 +2756,8 @@
   $("#searchResults a.gs-title").each(function(index, link) {
     // When user clicks enter for Google search results, track it
     $(link).click(function() {
-      _gaq.push(['_trackEvent', 'Google Click', 'clicked: ' + $(this).text(),
-                'from: ' + $("#search_autocomplete").val()]);
+      ga('send', 'event', 'Google Click', 'clicked: ' + $(this).attr('href'),
+                'query: ' + $("#search_autocomplete").val().toLowerCase());
     });
   });
 }
@@ -2529,7 +2820,7 @@
   }
 
 function updateSidenavFixedWidth() {
-  if (!navBarIsFixed) return;
+  if (!sticky) return;
   $('#devdoc-nav').css({
     'width' : $('#side-nav').css('width'),
     'margin' : $('#side-nav').css('margin')
@@ -2540,7 +2831,7 @@
 }
 
 function updateSidenavFullscreenWidth() {
-  if (!navBarIsFixed) return;
+  if (!sticky) return;
   $('#devdoc-nav').css({
     'width' : $('#side-nav').css('width'),
     'margin' : $('#side-nav').css('margin')
@@ -2581,10 +2872,7 @@
   selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
   toggleVisisbleApis(selectedLevel, "body");
 
-  var date = new Date();
-  date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
-  var expiration = date.toGMTString();
-  writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration);
+  writeCookie(API_LEVEL_COOKIE, selectedLevel, null);
 
   if (selectedLevel < minLevel) {
     var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
@@ -3233,3 +3521,836 @@
   $("#samples").append($ul);
 
 }
+
+
+
+/* ########################################################## */
+/* ###################  RESOURCE CARDS  ##################### */
+/* ########################################################## */
+
+/** Handle resource queries, collections, and grids (sections). Requires
+    jd_tag_helpers.js and the *_unified_data.js to be loaded. */
+
+(function() {
+  // Prevent the same resource from being loaded more than once per page.
+  var addedPageResources = {};
+
+  $(document).ready(function() {
+    $('.resource-widget').each(function() {
+      initResourceWidget(this);
+    });
+
+    /* Pass the line height to ellipsisfade() to adjust the height of the
+    text container to show the max number of lines possible, without
+    showing lines that are cut off. This works with the css ellipsis
+    classes to fade last text line and apply an ellipsis char. */
+
+    //card text currently uses 15px line height.
+    var lineHeight = 15;
+    $('.card-info .text').ellipsisfade(lineHeight);
+  });
+
+  /*
+    Three types of resource layouts:
+    Flow - Uses a fixed row-height flow using float left style.
+    Carousel - Single card slideshow all same dimension absolute.
+    Stack - Uses fixed columns and flexible element height.
+  */
+  function initResourceWidget(widget) {
+    var $widget = $(widget);
+    var isFlow = $widget.hasClass('resource-flow-layout'),
+        isCarousel = $widget.hasClass('resource-carousel-layout'),
+        isStack = $widget.hasClass('resource-stack-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 = {
+      cardSizes: ($widget.data('cardsizes') || '').split(','),
+      maxResults: parseInt($widget.data('maxresults') || '100', 10),
+      itemsPerPage: $widget.data('itemsperpage'),
+      sortOrder: $widget.data('sortorder'),
+      query: $widget.data('query'),
+      section: $widget.data('section'),
+      sizeCols: sizeCols,
+      /* Added by LFL 6/6/14 */
+      resourceStyle: $widget.data('resourcestyle') || 'card',
+      stackSort: $widget.data('stacksort') || 'true'
+    };
+
+    // run the search for the set of resources to show
+
+    var resources = buildResourceList(opts);
+
+    if (isFlow) {
+      drawResourcesFlowWidget($widget, opts, resources);
+    } else if (isCarousel) {
+      drawResourcesCarouselWidget($widget, opts, resources);
+    } else if (isStack) {
+      /* Looks like this got removed and is not used, so repurposing for the
+          homepage style layout.
+          Modified by LFL 6/6/14
+      */
+      //var sections = buildSectionList(opts);
+      opts['numStacks'] = $widget.data('numstacks');
+      drawResourcesStackWidget($widget, opts, resources/*, sections*/);
+    }
+  }
+
+  /* Initializes a Resource Carousel Widget */
+  function drawResourcesCarouselWidget($widget, opts, resources) {
+    $widget.empty();
+    var plusone = true; //always show plusone on carousel
+
+    $widget.addClass('resource-card slideshow-container')
+      .append($('<a>').addClass('slideshow-prev').text('Prev'))
+      .append($('<a>').addClass('slideshow-next').text('Next'));
+
+    var css = { 'width': $widget.width() + 'px',
+                'height': $widget.height() + 'px' };
+
+    var $ul = $('<ul>');
+
+    for (var i = 0; i < resources.length; ++i) {
+      var $card = $('<a>')
+        .attr('href', cleanUrl(resources[i].url))
+        .decorateResourceCard(resources[i],plusone);
+
+      $('<li>').css(css)
+          .append($card)
+          .appendTo($ul);
+    }
+
+    $('<div>').addClass('frame')
+      .append($ul)
+      .appendTo($widget);
+
+    $widget.dacSlideshow({
+      auto: true,
+      btnPrev: '.slideshow-prev',
+      btnNext: '.slideshow-next'
+    });
+  };
+
+  /* Initializes a Resource Card Stack Widget (column-based layout)
+     Modified by LFL 6/6/14
+   */
+  function drawResourcesStackWidget($widget, opts, resources, sections) {
+    // Don't empty widget, grab all items inside since they will be the first
+    // items stacked, followed by the resource query
+    var plusone = true; //by default show plusone on section cards
+    var cards = $widget.find('.resource-card').detach().toArray();
+    var numStacks = opts.numStacks || 1;
+    var $stacks = [];
+    var urlString;
+
+    for (var i = 0; i < numStacks; ++i) {
+      $stacks[i] = $('<div>').addClass('resource-card-stack')
+          .appendTo($widget);
+    }
+
+    var sectionResources = [];
+
+    // Extract any subsections that are actually resource cards
+    if (sections) {
+      for (var i = 0; i < sections.length; ++i) {
+        if (!sections[i].sections || !sections[i].sections.length) {
+          // Render it as a resource card
+          sectionResources.push(
+            $('<a>')
+              .addClass('resource-card section-card')
+              .attr('href', cleanUrl(sections[i].resource.url))
+              .decorateResourceCard(sections[i].resource,plusone)[0]
+          );
+
+        } else {
+          cards.push(
+            $('<div>')
+              .addClass('resource-card section-card-menu')
+              .decorateResourceSection(sections[i],plusone)[0]
+          );
+        }
+      }
+    }
+
+    cards = cards.concat(sectionResources);
+
+    for (var i = 0; i < resources.length; ++i) {
+      var $card = createResourceElement(resources[i], opts);
+
+      if (opts.resourceStyle.indexOf('related') > -1) {
+        $card.addClass('related-card');
+      }
+
+      cards.push($card[0]);
+    }
+
+    if (opts.stackSort != 'false') {
+      for (var i = 0; i < cards.length; ++i) {
+        // Find the stack with the shortest height, but give preference to
+        // left to right order.
+        var minHeight = $stacks[0].height();
+        var minIndex = 0;
+
+        for (var j = 1; j < numStacks; ++j) {
+          var height = $stacks[j].height();
+          if (height < minHeight - 45) {
+            minHeight = height;
+            minIndex = j;
+          }
+        }
+
+        $stacks[minIndex].append($(cards[i]));
+      }
+    }
+
+  };
+
+  /*
+    Create a resource card using the given resource object and a list of html
+     configured options. Returns a jquery object containing the element.
+  */
+  function createResourceElement(resource, opts, plusone) {
+    var $el;
+
+    // The difference here is that generic cards are not entirely clickable
+    // so its a div instead of an a tag, also the generic one is not given
+    // the resource-card class so it appears with a transparent background
+    // and can be styled in whatever way the css setup.
+    if (opts.resourceStyle == 'generic') {
+      $el = $('<div>')
+        .addClass('resource')
+        .attr('href', cleanUrl(resource.url))
+        .decorateResource(resource, opts);
+    } else {
+      var cls = 'resource resource-card';
+
+      $el = $('<a>')
+        .addClass(cls)
+        .attr('href', cleanUrl(resource.url))
+        .decorateResourceCard(resource, plusone);
+    }
+
+    return $el;
+  }
+
+  /* Initializes a flow widget, see distribute.scss for generating accompanying css */
+  function drawResourcesFlowWidget($widget, opts, resources) {
+    $widget.empty();
+    var cardSizes = opts.cardSizes || ['6x6'];
+    var i = 0, j = 0;
+    var plusone = true; // by default show plusone on resource cards
+
+    while (i < resources.length) {
+      var cardSize = cardSizes[j++ % cardSizes.length];
+      cardSize = cardSize.replace(/^\s+|\s+$/,'');
+      // Some card sizes do not get a plusone button, such as where space is constrained
+      // or for cards commonly embedded in docs (to improve overall page speed).
+      plusone = !((cardSize == "6x2") || (cardSize == "6x3") ||
+                  (cardSize == "9x2") || (cardSize == "9x3") ||
+                  (cardSize == "12x2") || (cardSize == "12x3"));
+
+      // A stack has a third dimension which is the number of stacked items
+      var isStack = cardSize.match(/(\d+)x(\d+)x(\d+)/);
+      var stackCount = 0;
+      var $stackDiv = null;
+
+      if (isStack) {
+        // Create a stack container which should have the dimensions defined
+        // by the product of the items inside.
+        $stackDiv = $('<div>').addClass('resource-card-stack resource-card-' + isStack[1]
+            + 'x' + isStack[2] * isStack[3]) .appendTo($widget);
+      }
+
+      // Build each stack item or just a single item
+      do {
+        var resource = resources[i];
+
+        var $card = createResourceElement(resources[i], opts, plusone);
+
+        $card.addClass('resource-card-' + cardSize +
+          ' resource-card-' + resource.type);
+
+        if (isStack) {
+          $card.addClass('resource-card-' + isStack[1] + 'x' + isStack[2]);
+          if (++stackCount == parseInt(isStack[3])) {
+            $card.addClass('resource-card-row-stack-last');
+            stackCount = 0;
+          }
+        } else {
+          stackCount = 0;
+        }
+
+        $card.appendTo($stackDiv || $widget);
+
+      } while (++i < resources.length && stackCount > 0);
+    }
+  }
+
+  /* Build a site map of resources using a section as a root. */
+  function buildSectionList(opts) {
+    if (opts.section && SECTION_BY_ID[opts.section]) {
+      return SECTION_BY_ID[opts.section].sections || [];
+    }
+    return [];
+  }
+
+  function buildResourceList(opts) {
+    var maxResults = opts.maxResults || 100;
+
+    var query = opts.query || '';
+    var expressions = parseResourceQuery(query);
+    var addedResourceIndices = {};
+    var results = [];
+
+    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;
+        case 'collection':
+          var urls = RESOURCE_COLLECTIONS[firstClause.value].resources || [];
+          resources = urls.map(function(url){ return ALL_RESOURCES_BY_URL[url]; });
+          break;
+        case 'section':
+          var urls = SITE_MAP[firstClause.value].sections || [];
+          resources = urls.map(function(url){ return ALL_RESOURCES_BY_URL[url]; });
+          break;
+      }
+      // console.log(firstClause.attr + ':' + firstClause.value);
+      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(addedResourceIndices));
+      }
+
+      // add to list of already added indices
+      for (var j = 0; j < resources.length; j++) {
+        // console.log(resources[j].title);
+        addedResourceIndices[resources[j].index] = 1;
+      }
+
+      // concat to final results list
+      results = results.concat(resources);
+    }
+
+    if (opts.sortOrder && results.length) {
+      var attr = opts.sortOrder;
+
+      if (opts.sortOrder == 'random') {
+        var i = results.length, j, temp;
+        while (--i) {
+          j = Math.floor(Math.random() * (i + 1));
+          temp = results[i];
+          results[i] = results[j];
+          results[j] = temp;
+        }
+      } else {
+        var desc = attr.charAt(0) == '-';
+        if (desc) {
+          attr = attr.substring(1);
+        }
+        results = results.sort(function(x,y) {
+          return (desc ? -1 : 1) * (parseInt(x[attr], 10) - parseInt(y[attr], 10));
+        });
+      }
+    }
+
+    results = results.filter(getResourceNotAlreadyAddedFilter(addedPageResources));
+    results = results.slice(0, maxResults);
+
+    for (var j = 0; j < results.length; ++j) {
+      addedPageResources[results[j].index] = 1;
+    }
+
+    return results;
+  }
+
+
+  function getResourceNotAlreadyAddedFilter(addedResourceIndices) {
+    return function(resource) {
+      return !addedResourceIndices[resource.index];
+    };
+  }
+
+
+  function getResourceMatchesClausesFilter(clauses) {
+    return function(resource) {
+      return doesResourceMatchClauses(resource, 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 clauses[i].negative;
+      }
+    }
+    return true;
+  }
+
+  function cleanUrl(url)
+  {
+    if (url && url.indexOf('//') === -1) {
+      url = toRoot + url;
+    }
+
+    return url;
+  }
+
+
+  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+|\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+|\s+$/g,'');
+        }
+
+        clauses.push(clause);
+      }
+
+      if (!clauses.length) {
+        continue;
+      }
+
+      expressions.push(clauses);
+    }
+
+    return expressions;
+  }
+})();
+
+(function($) {
+
+  /*
+    Utility method for creating dom for the description area of a card.
+    Used in decorateResourceCard and decorateResource.
+  */
+  function buildResourceCardDescription(resource, plusone) {
+    var $description = $('<div>').addClass('description ellipsis');
+
+    $description.append($('<div>').addClass('text').html(resource.summary));
+
+    if (resource.cta) {
+      $description.append($('<a>').addClass('cta').html(resource.cta));
+    }
+
+    if (plusone) {
+      var plusurl = resource.url.indexOf("//") > -1 ? resource.url :
+        "//developer.android.com/" + resource.url;
+
+      $description.append($('<div>').addClass('util')
+        .append($('<div>').addClass('g-plusone')
+          .attr('data-size', 'small')
+          .attr('data-align', 'right')
+          .attr('data-href', plusurl)));
+    }
+
+    return $description;
+  }
+
+
+  /* Simple jquery function to create dom for a standard resource card */
+  $.fn.decorateResourceCard = function(resource,plusone) {
+    var section = resource.group || resource.type;
+    var imgUrl = resource.image ||
+      'assets/images/resource-card-default-android.jpg';
+
+    if (imgUrl.indexOf('//') === -1) {
+      imgUrl = toRoot + imgUrl;
+    }
+
+    $('<div>').addClass('card-bg')
+      .css('background-image', 'url(' + (imgUrl || toRoot +
+        'assets/images/resource-card-default-android.jpg') + ')')
+      .appendTo(this);
+
+    $('<div>').addClass('card-info' + (!resource.summary ? ' empty-desc' : ''))
+      .append($('<div>').addClass('section').text(section))
+      .append($('<div>').addClass('title').html(resource.title))
+      .append(buildResourceCardDescription(resource, plusone))
+      .appendTo(this);
+
+    return this;
+  };
+
+  /* Simple jquery function to create dom for a resource section card (menu) */
+  $.fn.decorateResourceSection = function(section,plusone) {
+    var resource = section.resource;
+    //keep url clean for matching and offline mode handling
+    var urlPrefix = resource.image.indexOf("//") > -1 ? "" : toRoot;
+    var $base = $('<a>')
+        .addClass('card-bg')
+        .attr('href', resource.url)
+        .append($('<div>').addClass('card-section-icon')
+          .append($('<div>').addClass('icon'))
+          .append($('<div>').addClass('section').html(resource.title)))
+      .appendTo(this);
+
+    var $cardInfo = $('<div>').addClass('card-info').appendTo(this);
+
+    if (section.sections && section.sections.length) {
+      // Recurse the section sub-tree to find a resource image.
+      var stack = [section];
+
+      while (stack.length) {
+        if (stack[0].resource.image) {
+          $base.css('background-image', 'url(' + urlPrefix + stack[0].resource.image + ')');
+          break;
+        }
+
+        if (stack[0].sections) {
+          stack = stack.concat(stack[0].sections);
+        }
+
+        stack.shift();
+      }
+
+      var $ul = $('<ul>')
+        .appendTo($cardInfo);
+
+      var max = section.sections.length > 3 ? 3 : section.sections.length;
+
+      for (var i = 0; i < max; ++i) {
+
+        var subResource = section.sections[i];
+        if (!plusone) {
+          $('<li>')
+            .append($('<a>').attr('href', subResource.url)
+              .append($('<div>').addClass('title').html(subResource.title))
+              .append($('<div>').addClass('description ellipsis')
+                .append($('<div>').addClass('text').html(subResource.summary))
+                .append($('<div>').addClass('util'))))
+          .appendTo($ul);
+        } else {
+          $('<li>')
+            .append($('<a>').attr('href', subResource.url)
+              .append($('<div>').addClass('title').html(subResource.title))
+              .append($('<div>').addClass('description ellipsis')
+                .append($('<div>').addClass('text').html(subResource.summary))
+                .append($('<div>').addClass('util')
+                  .append($('<div>').addClass('g-plusone')
+                    .attr('data-size', 'small')
+                    .attr('data-align', 'right')
+                    .attr('data-href', resource.url)))))
+          .appendTo($ul);
+        }
+      }
+
+      // Add a more row
+      if (max < section.sections.length) {
+        $('<li>')
+          .append($('<a>').attr('href', resource.url)
+            .append($('<div>')
+              .addClass('title')
+              .text('More')))
+        .appendTo($ul);
+      }
+    } else {
+      // No sub-resources, just render description?
+    }
+
+    return this;
+  };
+
+
+
+
+  /* Render other types of resource styles that are not cards. */
+  $.fn.decorateResource = function(resource, opts) {
+    var imgUrl = resource.image ||
+      'assets/images/resource-card-default-android.jpg';
+    var linkUrl = resource.url;
+
+    if (imgUrl.indexOf('//') === -1) {
+      imgUrl = toRoot + imgUrl;
+    }
+
+    if (linkUrl && linkUrl.indexOf('//') === -1) {
+      linkUrl = toRoot + linkUrl;
+    }
+
+    $(this).append(
+      $('<div>').addClass('image')
+        .css('background-image', 'url(' + imgUrl + ')'),
+      $('<div>').addClass('info').append(
+        $('<h4>').addClass('title').html(resource.title),
+        $('<p>').addClass('summary').html(resource.summary),
+        $('<a>').attr('href', linkUrl).addClass('cta').html('Learn More')
+      )
+    );
+
+    return this;
+  };
+})(jQuery);
+
+
+/* Calculate the vertical area remaining */
+(function($) {
+    $.fn.ellipsisfade= function(lineHeight) {
+        this.each(function() {
+            // get element text
+            var $this = $(this);
+            var remainingHeight = $this.parent().parent().height();
+            $this.parent().siblings().each(function ()
+            {
+              if ($(this).is(":visible")) {
+                var h = $(this).height();
+                remainingHeight = remainingHeight - h;
+              }
+            });
+
+            adjustedRemainingHeight = ((remainingHeight)/lineHeight>>0)*lineHeight
+            $this.parent().css({'height': adjustedRemainingHeight});
+            $this.css({'height': "auto"});
+        });
+
+        return this;
+    };
+}) (jQuery);
+
+/*
+  Fullscreen Carousel
+
+  The following allows for an area at the top of the page that takes over the
+  entire browser height except for its top offset and an optional bottom
+  padding specified as a data attribute.
+
+  HTML:
+
+  <div class="fullscreen-carousel">
+    <div class="fullscreen-carousel-content">
+      <!-- content here -->
+    </div>
+    <div class="fullscreen-carousel-content">
+      <!-- content here -->
+    </div>
+
+    etc ...
+
+  </div>
+
+  Control over how the carousel takes over the screen can mostly be defined in
+  a css file. Setting min-height on the .fullscreen-carousel-content elements
+  will prevent them from shrinking to far vertically when the browser is very
+  short, and setting max-height on the .fullscreen-carousel itself will prevent
+  the area from becoming to long in the case that the browser is stretched very
+  tall.
+
+  There is limited functionality for having multiple sections since that request
+  was removed, but it is possible to add .next-arrow and .prev-arrow elements to
+  scroll between multiple content areas.
+*/
+
+(function() {
+  $(document).ready(function() {
+    $('.fullscreen-carousel').each(function() {
+      initWidget(this);
+    });
+  });
+
+  function initWidget(widget) {
+    var $widget = $(widget);
+
+    var topOffset = $widget.offset().top;
+    var padBottom = parseInt($widget.data('paddingbottom')) || 0;
+    var maxHeight = 0;
+    var minHeight = 0;
+    var $content = $widget.find('.fullscreen-carousel-content');
+    var $nextArrow = $widget.find('.next-arrow');
+    var $prevArrow = $widget.find('.prev-arrow');
+    var $curSection = $($content[0]);
+
+    if ($content.length <= 1) {
+      $nextArrow.hide();
+      $prevArrow.hide();
+    } else {
+      $nextArrow.click(function() {
+        var index = ($content.index($curSection) + 1);
+        $curSection.hide();
+        $curSection = $($content[index >= $content.length ? 0 : index]);
+        $curSection.show();
+      });
+
+      $prevArrow.click(function() {
+        var index = ($content.index($curSection) - 1);
+        $curSection.hide();
+        $curSection = $($content[index < 0 ? $content.length - 1 : 0]);
+        $curSection.show();
+      });
+    }
+
+    // Just hide all content sections except first.
+    $content.each(function(index) {
+      if ($(this).height() > minHeight) minHeight = $(this).height();
+      $(this).css({position: 'absolute',  display: index > 0 ? 'none' : ''});
+    });
+
+    // Register for changes to window size, and trigger.
+    $(window).resize(resizeWidget);
+    resizeWidget();
+
+    function resizeWidget() {
+      var height = $(window).height() - topOffset - padBottom;
+      $widget.width($(window).width());
+      $widget.height(height < minHeight ? minHeight :
+        (maxHeight && height > maxHeight ? maxHeight : height));
+    }
+  }
+})();
+
+
+
+
+
+/*
+  Tab Carousel
+
+  The following allows tab widgets to be installed via the html below. Each
+  tab content section should have a data-tab attribute matching one of the
+  nav items'. Also each tab content section should have a width matching the
+  tab carousel.
+
+  HTML:
+
+  <div class="tab-carousel">
+    <ul class="tab-nav">
+      <li><a href="#" data-tab="handsets">Handsets</a>
+      <li><a href="#" data-tab="wearable">Wearable</a>
+      <li><a href="#" data-tab="tv">TV</a>
+    </ul>
+
+    <div class="tab-carousel-content">
+      <div data-tab="handsets">
+        <!--Full width content here-->
+      </div>
+
+      <div data-tab="wearable">
+        <!--Full width content here-->
+      </div>
+
+      <div data-tab="tv">
+        <!--Full width content here-->
+      </div>
+    </div>
+  </div>
+
+*/
+(function() {
+  $(document).ready(function() {
+    $('.tab-carousel').each(function() {
+      initWidget(this);
+    });
+  });
+
+  function initWidget(widget) {
+    var $widget = $(widget);
+    var $nav = $widget.find('.tab-nav');
+    var $anchors = $nav.find('[data-tab]');
+    var $li = $nav.find('li');
+    var $contentContainer = $widget.find('.tab-carousel-content');
+    var $tabs = $contentContainer.find('[data-tab]');
+    var $curTab = $($tabs[0]); // Current tab is first tab.
+    var width = $widget.width();
+
+    // Setup nav interactivity.
+    $anchors.click(function(evt) {
+      evt.preventDefault();
+      var query = '[data-tab=' + $(this).data('tab') + ']';
+      transitionWidget($tabs.filter(query));
+    });
+
+    // Add highlight for navigation on first item.
+    var $highlight = $('<div>').addClass('highlight')
+      .css({left:$li.position().left + 'px', width:$li.outerWidth() + 'px'})
+      .appendTo($nav);
+
+    // Store height since we will change contents to absolute.
+    $contentContainer.height($contentContainer.height());
+
+    // Absolutely position tabs so they're ready for transition.
+    $tabs.each(function(index) {
+      $(this).css({position: 'absolute', left: index > 0 ? width + 'px' : '0'});
+    });
+
+    function transitionWidget($toTab) {
+      if (!$curTab.is($toTab)) {
+        var curIndex = $tabs.index($curTab[0]);
+        var toIndex = $tabs.index($toTab[0]);
+        var dir = toIndex > curIndex ? 1 : -1;
+
+        // Animate content sections.
+        $toTab.css({left:(width * dir) + 'px'});
+        $curTab.animate({left:(width * -dir) + 'px'});
+        $toTab.animate({left:'0'});
+
+        // Animate navigation highlight.
+        $highlight.animate({left:$($li[toIndex]).position().left + 'px',
+          width:$($li[toIndex]).outerWidth() + 'px'})
+
+        // Store new current section.
+        $curTab = $toTab;
+      }
+    }
+  }
+})();
diff --git a/tools/droiddoc/templates-sdk/class.cs b/tools/droiddoc/templates-sdk/class.cs
index 0461af6..7aa99f9 100644
--- a/tools/droiddoc/templates-sdk/class.cs
+++ b/tools/droiddoc/templates-sdk/class.cs
@@ -1,9 +1,12 @@
 <?cs include:"doctype.cs" ?>
 <?cs include:"macros.cs" ?>
+<?cs include:"macros_override.cs" ?>
 <html<?cs if:devsite ?> devsite<?cs /if ?>>
 <?cs include:"head_tag.cs" ?>
 <body class="gc-documentation <?cs if:(reference.gms || reference.gcm) ?>google<?cs /if ?>
   <?cs if:(guide||develop||training||reference||tools||sdk) ?>develop<?cs
+    if:reference ?> reference<?cs
+    /if ?><?cs
   elif:design ?>design<?cs
   elif:distribute ?>distribute<?cs
   /if ?>" itemscope itemtype="http://schema.org/Article">
@@ -123,6 +126,7 @@
   <?cs /if ?>
   <?cs set:colspan = colspan-1 ?>
 <?cs /each ?>
+<?cs call:show_annotations_list(class) ?>
 
 </div><!-- end header -->
 
@@ -193,7 +197,10 @@
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><?cs call:cond_link(method.name, toroot, method.href, included) ?></span>(<?cs call:parameter_list(method.params) ?>)</nobr>
         <?cs if:subcount(method.shortDescr) || subcount(method.deprecated) ?>
-        <div class="jd-descrdiv"><?cs call:short_descr(method) ?></div>
+        <div class="jd-descrdiv">
+          <?cs call:short_descr(method) ?>
+          <?cs call:show_annotations_list(method) ?>
+        </div>
   <?cs /if ?>
   </td></tr>
 <?cs set:count = count + #1 ?>
@@ -210,7 +217,10 @@
           <?cs var:field.final ?>
           <?cs call:type_link(field.type) ?></nobr></td>
           <td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, included) ?></td>
-          <td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
+          <td class="jd-descrcol" width="100%">
+            <?cs call:short_descr(field) ?>
+            <?cs call:show_annotations_list(field) ?>
+          </td>
       </tr>
       <?cs set:count = count + #1 ?>
     <?cs /each ?>
@@ -222,7 +232,10 @@
     <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
         <td class="jd-typecol"><?cs call:type_link(field.type) ?></td>
         <td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, included) ?></td>
-        <td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
+        <td class="jd-descrcol" width="100%">
+          <?cs call:short_descr(field) ?>
+          <?cs call:show_annotations_list(field) ?>
+        </td>
     </tr>
     <?cs set:count = count + #1 ?>
     <?cs /each ?>
@@ -242,7 +255,10 @@
             <?cs call:cond_link(m.name, toroot, m.href, included) ?>
             <?cs /each ?>
         </td>
-        <td class="jd-descrcol" width="100%"><?cs call:short_descr(attr) ?>&nbsp;</td>
+        <td class="jd-descrcol" width="100%">
+          <?cs call:short_descr(attr) ?>&nbsp;
+          <?cs call:show_annotations_list(attr) ?>
+        </td>
     </tr>
     <?cs set:count = count + #1 ?>
     <?cs /each ?>
@@ -259,7 +275,10 @@
         <?cs var:cl.abstract ?>
         <?cs var:cl.kind ?></nobr></td>
       <td class="jd-linkcol"><?cs call:type_link(cl.type) ?></td>
-      <td class="jd-descrcol" width="100%"><?cs call:short_descr(cl) ?>&nbsp;</td>
+      <td class="jd-descrcol" width="100%">
+        <?cs call:short_descr(cl) ?>&nbsp;
+        <?cs call:show_annotations_list(cl) ?>
+      </td>
     </tr>
     <?cs set:count = count + #1 ?>
     <?cs /each ?>
@@ -335,7 +354,10 @@
     <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
         <td class="jd-descrcol"><?cs call:type_link(field.type) ?>&nbsp;</td>
         <td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, cl.included) ?>&nbsp;</td>
-        <td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?>&nbsp;</td>
+        <td class="jd-descrcol" width="100%">
+          <?cs call:short_descr(field) ?>&nbsp;
+          <?cs call:show_annotations_list(field) ?>
+        </td>
     </tr>
     <?cs set:count = count + #1 ?>
     <?cs /each ?>
@@ -504,6 +526,7 @@
         <?cs call:federated_refs(field) ?>
       </div>
     <div class="jd-details-descr">
+      <?cs call:show_annotations_list(field) ?>
       <?cs call:description(field) ?>
     <?cs if:subcount(field.constantValue) ?>
         <div class="jd-tagdata">
@@ -546,6 +569,7 @@
         <?cs call:federated_refs(method) ?>
       </div>
     <div class="jd-details-descr">
+      <?cs call:show_annotations_list(method) ?>
       <?cs call:description(method) ?>
     </div>
 </div>
@@ -560,6 +584,7 @@
     <h4 class="jd-details-title"><?cs var:attr.name ?>
     </h4>
     <div class="jd-details-descr">
+        <?cs call:show_annotations_list(attr) ?>
         <?cs call:description(attr) ?>
 
         <div class="jd-tagdata">
diff --git a/tools/droiddoc/templates-sdk/classes.cs b/tools/droiddoc/templates-sdk/classes.cs
index 6769f47..405892d 100644
--- a/tools/droiddoc/templates-sdk/classes.cs
+++ b/tools/droiddoc/templates-sdk/classes.cs
@@ -1,9 +1,12 @@
 <?cs include:"doctype.cs" ?>
 <?cs include:"macros.cs" ?>
+<?cs include:"macros_override.cs" ?>
 <html<?cs if:devsite ?> devsite<?cs /if ?>>
 <?cs include:"head_tag.cs" ?>
 <body class="gc-documentation <?cs if:(reference.gms || reference.gcm) ?>google<?cs /if ?>
   <?cs if:(guide||develop||training||reference||tools||sdk) ?>develop<?cs
+    if:reference ?> reference<?cs
+    /if ?><?cs
   elif:design ?>design<?cs
   elif:distribute ?>distribute<?cs
   /if ?>" itemscope itemtype="http://schema.org/Article">
@@ -30,7 +33,10 @@
     <?cs each:cl = letter ?>
         <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:cl.since ?>" >
             <td class="jd-linkcol"><?cs call:type_link(cl.type) ?></td>
-            <td class="jd-descrcol" width="100%"><?cs call:short_descr(cl) ?>&nbsp;</td>
+            <td class="jd-descrcol" width="100%">
+              <?cs call:short_descr(cl) ?>&nbsp;
+              <?cs call:show_annotations_list(cl) ?>
+            </td>
         </tr>
     <?cs set:count = count + #1 ?>
     <?cs /each ?>
diff --git a/tools/droiddoc/templates-sdk/components/masthead.cs b/tools/droiddoc/templates-sdk/components/masthead.cs
index 47639bb..c09dc02 100644
--- a/tools/droiddoc/templates-sdk/components/masthead.cs
+++ b/tools/droiddoc/templates-sdk/components/masthead.cs
@@ -1,229 +1,228 @@
 <?cs def:custom_masthead() ?>
+<?cs if:preview ?>
+  <?cs call:preview_masthead() ?>
+<?cs else ?>
 <a name="top"></a>
-<?cs if:!devsite ?><?cs # leave out the global header for devsite; it's in devsite template ?>
-    <!-- Header -->
-    <div id="header">
-        <div class="wrap" id="header-wrap">
-          <div class="col-3 logo">
+
+<!-- dialog to prompt lang pref change when loaded from hardcoded URL 
+<div id="langMessage" style="display:none">
+  <div>
+    <div class="lang en">
+      <p>You requested a page in English, would you like to proceed with this language setting?</p>
+    </div>
+    <div class="lang es">
+      <p>You requested a page in Spanish (Español), would you like to proceed with this language setting?</p>
+    </div>
+    <div class="lang ja">
+      <p>You requested a page in Japanese (日本語), would you like to proceed with this language setting?</p>
+    </div>
+    <div class="lang ko">
+      <p>You requested a page in Korean (한국어), would you like to proceed with this language setting?</p>
+    </div>
+    <div class="lang ru">
+      <p>You requested a page in Russian (Русский), would you like to proceed with this language setting?</p>
+    </div>
+    <div class="lang zh-cn">
+      <p>You requested a page in Simplified Chinese (简体中文), would you like to proceed with this language setting?</p>
+    </div>
+    <div class="lang zh-tw">
+      <p>You requested a page in Traditional Chinese (繁體中文), would you like to proceed with this language setting?</p>
+    </div>
+    <a href="#" class="button yes" onclick="return false;">
+      <span class="lang en">Yes</span>
+      <span class="lang es">Sí</span>
+      <span class="lang ja">Yes</span>
+      <span class="lang ko">Yes</span>
+      <span class="lang ru">Yes</span>
+      <span class="lang zh-cn">是的</span>
+      <span class="lang zh-tw">没有</span>
+    </a>
+    <a href="#" class="button" onclick="$('#langMessage').hide();return false;">
+      <span class="lang en">No</span>
+      <span class="lang es">No</span>
+      <span class="lang ja">No</span>
+      <span class="lang ko">No</span>
+      <span class="lang ru">No</span>
+      <span class="lang zh-cn">没有</span>
+      <span class="lang zh-tw">没有</span>
+    </a>
+  </div>
+</div> -->
+
+<?cs if:!devsite ?><?cs # leave out the global header for devsite; it is in devsite template ?>
+  <!-- Header -->
+  <div id="header-wrapper">
+    <div id="header"><?cs call:butter_bar() ?>
+      <div class="wrap" id="header-wrap">
+        <div class="col-3 logo">
           <a href="<?cs var:toroot ?>index.html">
-            <img src="<?cs var:toroot ?>assets/images/dac_logo.png" width="123" height="25" alt="Android Developers" />
+            <img src="<?cs var:toroot ?>assets/images/dac_logo.png"
+                srcset="<?cs var:toroot ?>assets/images/dac_logo@2x.png 2x"
+                width="123" height="25" alt="Android Developers" />
           </a>
           <div class="btn-quicknav" id="btn-quicknav">
-          	<a href="#" class="arrow-inactive">Quicknav</a>
-			      <a href="#" class="arrow-active">Quicknav</a>
+            <a href="#" class="arrow-inactive">Quicknav</a>
+            <a href="#" class="arrow-active">Quicknav</a>
           </div>
-          </div>
-            <ul class="nav-x col-9">
-                <li class="design">
-                  <a href="<?cs var:toroot ?>design/index.html"
-                  zh-tw-lang="設計"
-                  zh-cn-lang="设计"
-                  ru-lang="Проектирование"
-                  ko-lang="디자인"
-                  ja-lang="設計"
-                  es-lang="Diseñar"               
-                  >Design</a></li>
-                <li class="develop"><a href="<?cs var:toroot ?>develop/index.html"
-                  zh-tw-lang="開發"
-                  zh-cn-lang="开发"
-                  ru-lang="Разработка"
-                  ko-lang="개발"
-                  ja-lang="開発"
-                  es-lang="Desarrollar"               
-                  >Develop</a></li>
-                <li class="distribute last"><a href="<?cs var:toroot ?>distribute/index.html"
-                  zh-tw-lang="發佈"
-                  zh-cn-lang="分发"
-                  ru-lang="Распространение"
-                  ko-lang="배포"
-                  ja-lang="配布"
-                  es-lang="Distribuir"               
-                  >Distribute</a></li>
-            </ul>
-            
-            <!-- New Search -->
-            <div class="menu-container">
-            <div class="moremenu">
-    <div id="more-btn"></div>
-  </div>
-  <div class="morehover" id="moremenu">
-    <div class="top"></div>
-    <div class="mid">
-      <div class="header">Links</div>
-      <ul>
-        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
-        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
-        <li><a href="<?cs var:toroot ?>about/index.html">About Android</a></li>
-      </ul>
-      <div class="header">Android Sites</div>
-      <ul>
-        <li><a href="http://www.android.com">Android.com</a></li>
-        <li class="active"><a>Android Developers</a></li>
-        <li><a href="http://source.android.com">Android Open Source Project</a></li>
-      </ul>
-      
-      <?cs # Include language switcher only in online docs ?>
-      <?cs if:android.whichdoc == "online" ?>
-        <div class="header">Language</div>
-          <div id="language" class="locales">
-            <select name="language" onChange="changeLangPref(this.value, true)">
-                <option value="en">English</option>
-                <option value="es">Español</option>
-                <option value="ja">日本語</option>
-                <option value="ko">한국어</option>
-                <option value="ru">Русский</option>
-                <option value="zh-cn">中文 (中国)</option>
-                <option value="zh-tw">中文 (台灣)</option>
-            </select>
-          </div>
-        <script type="text/javascript">
-          <!--
-          loadLangPref();
-            //-->
-        </script>
-      <?cs /if ?>
-      <?cs # End of lang switcher ?>
-
-
-      <br class="clearfix" />
-    </div>
-    <div class="bottom"></div>
-  </div>
-  <div class="search" id="search-container">
-    <div class="search-inner">
-      <div id="search-btn"></div>
-      <div class="left"></div>
-      <form onsubmit="return submit_search()">
-        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
-onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
-onkeydown="return search_changed(event, true, '<?cs var:toroot ?>')" 
-onkeyup="return search_changed(event, false, '<?cs var:toroot ?>')" />
-      </form>
-      <div class="right"></div>
-        <a class="close hide">close</a>
-        <div class="left"></div>
-        <div class="right"></div>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper reference">
-    <div class="suggest-card reference no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  <div class="search_filtered_wrapper docs">
-    <div class="suggest-card dummy no-display">&nbsp;</div>
-    <div class="suggest-card develop no-display">
-      <ul class="search_filtered">
-      </ul>
-      <div class="child-card guides no-display">
-      </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">
-      </ul>
-    </div>
-    <div class="suggest-card distribute no-display">
-      <ul class="search_filtered">
-      </ul>
-    </div>
-  </div>
-
-  </div>
-  <!-- /New Search>
-          
-          
-          <!-- Expanded quicknav -->
-           <div id="quicknav" class="col-9">
-                <ul>
-                    <li class="design">
-                      <ul>
-                        <li><a href="<?cs var:toroot ?>design/index.html">Get Started</a></li>
-                        <li><a href="<?cs var:toroot ?>design/style/index.html">Style</a></li>
-                        <li><a href="<?cs var:toroot ?>design/patterns/index.html">Patterns</a></li>
-                        <li><a href="<?cs var:toroot ?>design/building-blocks/index.html">Building Blocks</a></li>
-                        <li><a href="<?cs var:toroot ?>design/downloads/index.html">Downloads</a></li>
-                        <li><a href="<?cs var:toroot ?>design/videos/index.html">Videos</a></li>
-                      </ul>
-                    </li>
-                    <li class="develop">
-                      <ul>
-                        <li><a href="<?cs var:toroot ?>training/index.html"
-                          zh-tw-lang="訓練課程"
-                          zh-cn-lang="培训"
-                          ru-lang="Курсы"
-                          ko-lang="교육"
-                          ja-lang="トレーニング"
-                          es-lang="Capacitación"               
-                          >Training</a></li>
-                        <li><a href="<?cs var:toroot ?>guide/index.html"
-                          zh-tw-lang="API 指南"
-                          zh-cn-lang="API 指南"
-                          ru-lang="Руководства по API"
-                          ko-lang="API 가이드"
-                          ja-lang="API ガイド"
-                          es-lang="Guías de la API"               
-                          >API Guides</a></li>
-                        <li><a href="<?cs var:toroot ?>reference/packages.html"
-                          zh-tw-lang="參考資源"
-                          zh-cn-lang="参考"
-                          ru-lang="Справочник"
-                          ko-lang="참조문서"
-                          ja-lang="リファレンス"
-                          es-lang="Referencia"               
-                          >Reference</a></li>
-                        <li><a href="<?cs var:toroot ?>tools/index.html"
-                          zh-tw-lang="相關工具"
-                          zh-cn-lang="工具"
-                          ru-lang="Инструменты"
-                          ko-lang="도구"
-                          ja-lang="ツール"
-                          es-lang="Herramientas"               
-                          >Tools</a>
-                          <ul><li><a href="<?cs var:toroot ?>sdk/index.html">Get the SDK</a></li></ul>
-                        </li>
-                        <li><a href="<?cs var:toroot ?>google/index.html">Google Services</a>
-                        </li>
-                        <?cs if:android.hasSamples ?>
-                          <li><a href="<?cs var:toroot ?>samples/index.html">Samples</a>
-                          </li>
-                        <?cs /if ?>
-                      </ul>
-                    </li>
-                    <li class="distribute last">
-                      <ul>
-                        <li><a href="<?cs var:toroot ?>distribute/index.html">Google Play</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/publish/index.html">Publishing</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/promote/index.html">Promoting</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/quality/index.html">App Quality</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/googleplay/spotlight/index.html">Spotlight</a></li>
-                        <li><a href="<?cs var:toroot ?>distribute/open.html">Open Distribution</a></li>
-                      </ul>
-                    </li>
-                </ul>
-          </div>
-          <!-- /Expanded quicknav -->
         </div>
-    </div>
-    <!-- /Header -->
-    
-    
-  <div id="searchResults" class="wrap" style="display:none;">
-          <h2 id="searchTitle">Results</h2>
-          <div id="leftSearchControl" class="search-control">Loading...</div>
-  </div>
-    
-    
-  <?cs if:training || guide || reference || tools || develop || google || samples ?>
+        <ul class="nav-x col-9">
+            <li class="design">
+              <a href="<?cs var:toroot ?>design/index.html"
+              zh-tw-lang="設計"
+              zh-cn-lang="设计"
+              ru-lang="Проектирование"
+              ko-lang="디자인"
+              ja-lang="設計"
+              es-lang="Diseñar"
+              >Design</a></li>
+            <li class="develop"><a href="<?cs var:toroot ?>develop/index.html"
+              zh-tw-lang="開發"
+              zh-cn-lang="开发"
+              ru-lang="Разработка"
+              ko-lang="개발"
+              ja-lang="開発"
+              es-lang="Desarrollar"
+              >Develop</a></li>
+            <li class="distribute last"><a href="<?cs var:toroot ?>distribute/<?cs
+              if:android.whichdoc == "offline" ?>googleplay/<?cs /if ?>index.html"
+              zh-tw-lang="發佈"
+              zh-cn-lang="分发"
+              ru-lang="Распространение"
+              ko-lang="배포"
+              ja-lang="配布"
+              es-lang="Distribuir"
+              >Distribute</a></li>
+        </ul>
+
+
+        <?cs # ADD SEARCH AND MENU ?>
+        <?cs call:header_search_widget() ?>
+
+
+        <!-- Expanded quicknav -->
+        <div id="quicknav" class="col-13">
+          <ul>
+            <li class="about">
+              <ul>
+                <li><a href="<?cs var:toroot ?>about/index.html">About</a></li>
+                <li><a href="<?cs var:toroot ?>wear/index.html">Wear</a></li>
+                <li><a href="<?cs var:toroot ?>tv/index.html">TV</a></li>
+                <li><a href="<?cs var:toroot ?>auto/index.html">Auto</a></li>
+              </ul>
+            </li>
+            <li class="design">
+              <ul>
+                <li><a href="<?cs var:toroot ?>design/index.html">Get Started</a></li>
+                <li><a href="<?cs var:toroot ?>design/devices.html">Devices</a></li>
+                <li><a href="<?cs var:toroot ?>design/style/index.html">Style</a></li>
+                <li><a href="<?cs var:toroot ?>design/patterns/index.html">Patterns</a></li>
+                <li><a href="<?cs var:toroot ?>design/building-blocks/index.html">Building Blocks</a></li>
+                <li><a href="<?cs var:toroot ?>design/downloads/index.html">Downloads</a></li>
+                <li><a href="<?cs var:toroot ?>design/videos/index.html">Videos</a></li>
+              </ul>
+            </li>
+            <li class="develop">
+              <ul>
+                <li><a href="<?cs var:toroot ?>training/index.html"
+                  zh-tw-lang="訓練課程"
+                  zh-cn-lang="培训"
+                  ru-lang="Курсы"
+                  ko-lang="교육"
+                  ja-lang="トレーニング"
+                  es-lang="Capacitación"
+                  >Training</a></li>
+                <li><a href="<?cs var:toroot ?>guide/index.html"
+                  zh-tw-lang="API 指南"
+                  zh-cn-lang="API 指南"
+                  ru-lang="Руководства по API"
+                  ko-lang="API 가이드"
+                  ja-lang="API ガイド"
+                  es-lang="Guías de la API"
+                  >API Guides</a></li>
+                <li><a href="<?cs var:toroot ?>reference/packages.html"
+                  zh-tw-lang="參考資源"
+                  zh-cn-lang="参考"
+                  ru-lang="Справочник"
+                  ko-lang="참조문서"
+                  ja-lang="リファレンス"
+                  es-lang="Referencia"
+                  >Reference</a></li>
+                <li><a href="<?cs var:toroot ?>sdk/index.html"
+                  zh-tw-lang="相關工具"
+                  zh-cn-lang="工具"
+                  ru-lang="Инструменты"
+                  ko-lang="도구"
+                  ja-lang="ツール"
+                  es-lang="Herramientas"
+                  >Tools</a>
+                </li>
+                <li><a href="<?cs var:toroot ?>google/index.html">Google Services</a>
+                </li>
+                <?cs if:android.hasSamples ?>
+                  <li><a href="<?cs var:toroot ?>samples/index.html">Samples</a>
+                  </li>
+                <?cs /if ?>
+              </ul>
+            </li>
+            <li class="distribute last">
+              <ul>
+                <li><a href="<?cs var:toroot ?>distribute/googleplay/index.html">Google Play</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/essentials/index.html">Essentials</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/users/index.html">Get Users</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/engage/index.html">Engage &amp; Retain</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/monetize/index.html">Monetize</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/analyze/index.html">Analyze</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/tools/index.html">Tools &amp; Reference</a></li>
+                <li><a href="<?cs var:toroot ?>distribute/stories/index.html">Developer Stories</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div><!-- /Expanded quicknav -->
+      </div><!-- end header-wrap.wrap -->
+    </div><!-- end header -->
+
+  <?cs if:about || wear || tv || auto ?>
     <!-- Secondary x-nav -->
     <div id="nav-x">
         <div class="wrap">
+            <ul class="nav-x col-9 about" style="width:100%">
+                <li class="about"><a href="<?cs var:toroot ?>about/index.html"
+                  >About</a></li>
+                <li class="wear"><a href="<?cs var:toroot ?>wear/index.html"
+                  >Wear</a></li>
+                <li class="tv"><a href="<?cs var:toroot ?>tv/index.html"
+                  >TV</a></li>
+                <li class="auto"><a href="<?cs var:toroot ?>auto/index.html"
+                  >Auto</a></li>
+            </ul>
+        </div>
+    </div>
+    <!-- /Sendondary x-nav ABOUT -->
+
+
+
+  <?cs elif:training || guide || reference || tools || develop || google || samples ?>
+    <!-- Secondary x-nav -->
+    <div id="nav-x">
+        <div class="wrap" style="position:relative;z-index:1">
+
+        <?cs if:reference ?>
+        <?cs # HIDE HELPOUTS RECRUIT BANNER
+            <a id="helpoutsLink" class="resource resource-card resource-card-6x2x3 resource-card-6x2 helpouts-card" 
+              href="http://helpouts.google.com/partner/landing/provider/googledevelopers?utm_source=dac&utm_medium=banner&utm_campaign=android_provider_banner3" target="_blank">
+              <div class="card-bg helpouts-card-bg"></div>
+              <div class="card-info">
+                <div class="helpouts-description">
+                  <div class="text">Help Android Wear and TV developers<br/>
+                    <span id="helpoutsLinkText" class="link-color" 
+                    style="display:block;padding-top:5px;text-align:right">Learn more</span>
+                  </div>
+                </div>
+              </div>
+            </a>
+        # END HIDE HELPOUTS ?>
+        <?cs /if ?>
+
             <ul class="nav-x col-9 develop" style="width:100%">
                 <li class="training"><a href="<?cs var:toroot ?>training/index.html"
                   zh-tw-lang="訓練課程"
@@ -231,7 +230,7 @@
                   ru-lang="Курсы"
                   ko-lang="교육"
                   ja-lang="トレーニング"
-                  es-lang="Capacitación"               
+                  es-lang="Capacitación"
                   >Training</a></li>
                 <li class="guide"><a href="<?cs var:toroot ?>guide/index.html"
                   zh-tw-lang="API 指南"
@@ -239,7 +238,7 @@
                   ru-lang="Руководства по API"
                   ko-lang="API 가이드"
                   ja-lang="API ガイド"
-                  es-lang="Guías de la API"               
+                  es-lang="Guías de la API"
                   >API Guides</a></li>
                 <li class="reference"><a href="<?cs var:toroot ?>reference/packages.html"
                   zh-tw-lang="參考資源"
@@ -247,9 +246,9 @@
                   ru-lang="Справочник"
                   ko-lang="참조문서"
                   ja-lang="リファレンス"
-                  es-lang="Referencia"               
+                  es-lang="Referencia"
                   >Reference</a></li>
-                <li class="tools"><a href="<?cs var:toroot ?>tools/index.html"
+                <li class="tools"><a href="<?cs var:toroot ?>sdk/index.html"
                   zh-tw-lang="相關工具"
                   zh-cn-lang="工具"
                   ru-lang="Инструменты"
@@ -267,13 +266,123 @@
                 <?cs /if ?>
             </ul>
         </div>
-        
     </div>
-    <!-- /Sendondary x-nav -->
+    <!-- /Sendondary x-nav DEVELOP -->
+
+  <?cs elif:distribute || googleplay || essentials || users || engage || monetize || analyze ||  disttools || stories ?>
+    <!-- Secondary distribute x-nav -->
+    <div id="nav-x">
+        <div class="wrap">
+            <ul class="nav-x distribute">
+                <li class="googleplay"><a href="<?cs var:toroot ?>distribute/googleplay/index.html"
+                  >Google Play</a></li>
+                <li class="essentials"><a href="<?cs var:toroot ?>distribute/essentials/index.html"
+                  >Essentials</a></li>
+                <li class="users"><a href="<?cs var:toroot ?>distribute/users/index.html"
+                  >Get Users</a></li>
+                <li class="engage"><a href="<?cs var:toroot ?>distribute/engage/index.html"
+                  >Engage &amp; Retain</a></li>
+                <li class="monetize"><a href="<?cs var:toroot ?>distribute/monetize/index.html"
+                  >Monetize</a>
+                </li>
+                <li class="analyze"><a href="<?cs var:toroot ?>distribute/analyze/index.html"
+                  >Analyze</a>
+                </li>
+                <li class="disttools"><a href="<?cs var:toroot ?>distribute/tools/index.html"
+                  >Tools</a>
+                </li>
+                <li class="stories"><a href="<?cs var:toroot ?>distribute/stories/index.html"
+                  >Stories</a>
+                </li>
+            </ul>
+            <a href="https://play.google.com/apps/publish/" class="developer-console-btn">Developer Console</a>
+        </div> <!-- /Secondary distribute x-nav -->
+    </div>
+    <!-- /Sendondary x-nav DISTRIBUTE -->
   <?cs /if ?>
 
-<?cs /if ?>
-<?cs # end if/else !devsite ?>
+    <div id="searchResults" class="wrap" style="display:none;">
+      <h2 id="searchTitle">Results</h2>
+      <div id="leftSearchControl" class="search-control">Loading...</div>
+    </div>
+  </div> <!--end header-wrapper -->
 
-  <?cs 
+  <div id="sticky-header">
+    <div>
+      <a class="logo" href="#top"></a>
+      <a class="top" href="#top"></a>
+      <ul class="breadcrumb">
+        <?cs # More <li> elements added here with javascript ?>
+        <?cs if:!section.landing ?><li class="current"><?cs var:page.title ?></li><?cs
+        /if ?>
+      </ul>
+    </div>
+  </div>
+
+<?cs /if ?><?cs # end if/else !devsite ?>
+<?cs /if ?><?cs # end if/else preview ?><?cs
 /def ?>
+
+<?cs def:preview_masthead() ?>
+<a name="top"></a>
+
+
+<!-- Header -->
+<div id="header-wrapper">
+  <div id="header"><?cs call:butter_bar() ?>
+    <div class="wrap" id="header-wrap">
+      <div class="col_3 logo landing-logo" style="width:240px">
+        <a href="<?cs var:toroot ?>preview/index.html">
+          <img src="<?cs var:toroot ?>assets/images/android.png" height="25" alt="Android"
+            style="margin:-3px 0 0" />
+        </a>
+      </div>
+      <div class="col-8" style="margin:0"><h1 style="margin: 4px 0 0 0px;padding:0;line-height:16px;
+color:#666;font-weight:100;font-size:27px;">L Developer Preview</h1></div>
+
+      <?cs # ADD SEARCH AND MENU ?>
+      <?cs call:header_search_widget() ?>
+
+    </div><!-- end header-wrap -->
+  </div><!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+</div> <!--end header-wrapper -->
+
+<div id="sticky-header">
+  <div>
+    <a class="logo" href="#top"></a>
+    <a class="top" href="#top"></a>
+    <ul class="breadcrumb">
+      <?cs # More <li> elements added here with javascript ?>
+      <?cs if:!section.landing ?><li class="current"><?cs var:page.title ?></li><?cs
+      /if ?>
+    </ul>
+  </div>
+</div>
+
+  <?cs
+/def ?>
+
+
+<?cs # (UN)COMMENT THE INSIDE OF THIS METHOD TO TOGGLE VISIBILITY ?>
+<?cs def:butter_bar() ?>
+
+<?cs # HIDE THE BUTTER BAR
+
+    <div style="height:20px"><!-- spacer to bump header down --></div>
+    <div id="butterbar-wrapper">
+      <div id="butterbar">
+        <a href="http://googleblog.blogspot.com/" id="butterbar-message">
+          The Android 5.0 SDK will be available on October 17th!
+        </a>
+      </div>
+    </div>
+
+?>    
+
+<?cs /def ?>
diff --git a/tools/droiddoc/templates-sdk/customizations.cs b/tools/droiddoc/templates-sdk/customizations.cs
index ed57f1c..c8c88cc 100644
--- a/tools/droiddoc/templates-sdk/customizations.cs
+++ b/tools/droiddoc/templates-sdk/customizations.cs
@@ -7,7 +7,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs 
         include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
@@ -15,33 +14,16 @@
 
       </div>
     </div> <!-- end side-nav -->
-<?cs /def ?>
-<?cs 
-def:resources_tab_nav() ?>
+<?cs /def ?><?cs
+
+def:no_nav() ?>
   <div class="wrap clearfix" id="body-content">
-    <a
-    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
-      <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+<?cs /def ?><?cs
 
-<?cs 
-        include:"../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
-
-
-      </div>
-    </div> <!-- end side-nav -->
-    <script>
-      $(document).ready(function() {
-        scrollIntoView("devdoc-nav");
-        });
-    </script>
-<?cs /def ?>
-<?cs
 def:tools_nav() ?>
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 <?cs 
         include:"../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
         
@@ -59,7 +41,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 
 <?cs 
@@ -73,14 +54,124 @@
         scrollIntoView("devdoc-nav");
         });
     </script>
-<?cs /def ?>
-<?cs 
+<?cs /def ?><?cs
+
+def:googleplay_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/googleplay/googleplay_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:essentials_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/essentials/essentials_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:users_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/users/users_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:engage_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/engage/engage_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:analyze_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/analyze/analyze_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:monetize_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/monetize/monetize_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:disttools_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/tools/disttools_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
+def:stories_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<?cs include:"../../../../frameworks/base/docs/html/distribute/stories/stories_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?><?cs
+
 def:guide_nav() ?>
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
-
 
 <?cs 
         include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
@@ -99,7 +190,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 
 <?cs
@@ -119,7 +209,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/distribute/distribute_toc.cs" ?>
@@ -139,7 +228,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
@@ -159,7 +247,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
@@ -183,7 +270,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
 
 <?cs
         include:"../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
@@ -198,6 +284,42 @@
     </script>
 <?cs /def ?>
 
+
+<?cs
+def:wear_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+
+<?cs
+        include:"../../../../frameworks/base/docs/html/wear/wear_toc.cs" ?>
+
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?>
+
+<?cs
+def:preview_nav() ?>
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+        <?cs
+          include:"../../../../frameworks/base/docs/html/preview/preview_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?>
+
 <?cs # The default side navigation for the reference docs ?><?cs 
 def:default_left_nav() ?>
 <?cs if:reference.gcm || reference.gms ?>
@@ -206,8 +328,6 @@
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav">
-
-<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
       <div id="api-nav-header">
         <div id="api-level-toggle">
           <label for="apiLevelCheckbox" class="disabled"
@@ -247,6 +367,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) ?>
@@ -255,6 +376,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) ?>
@@ -308,10 +430,111 @@
     <?cs 
 /def ?>
 
+
+<?cs
+def:header_search_widget() ?>
+<div class="menu-container">
+  <div class="moremenu">
+    <div id="more-btn"></div>
+  </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/" target="_googleplay">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="<?cs var:toroot ?>about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+
+      <?cs # Include language switcher only in online docs ?>
+      <?cs if:android.whichdoc == "online" ?>
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文(简体)</option>
+                <option value="zh-tw">中文(繁體)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      <?cs /if ?>
+      <?cs # End of lang switcher ?>
+      <br class="clearfix" />
+    </div><!-- end 'mid' -->
+    <div class="bottom"></div>
+  </div><!-- end 'moremenu' -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+          onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+          onkeydown="return search_changed(event, true, '<?cs var:toroot ?>')"
+          onkeyup="return search_changed(event, false, '<?cs var:toroot ?>')" />
+      </form>
+      <div class="right"></div>
+      <a class="close hide">close</a>
+      <div class="left"></div>
+      <div class="right"></div>
+    </div><!-- end search-inner -->
+  </div><!-- end search-container -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </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">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+</div><!-- end menu-container (search and menu widget) -->
+<?cs /def ?>
+
+
+
 <?cs 
 def:custom_left_nav() ?><?cs
-  if:fullpage ?><?cs 
-    call:fullpage() ?><?cs 
+  if:fullpage ?><?cs
+    call:fullpage() ?><?cs
+  elif:nonavpage ?><?cs
+    call:no_nav() ?><?cs
   elif:guide ?><?cs 
     call:guide_nav() ?><?cs 
   elif:design ?><?cs
@@ -324,15 +547,35 @@
     call:google_nav() ?><?cs 
   elif:samples ?><?cs
     call:samples_nav() ?><?cs
-  elif:more ?><?cs 
-    call:dist_more_nav() ?><?cs
   elif:distribute ?><?cs 
-    call:distribute_nav() ?><?cs 
-  elif:about ?><?cs 
-    call:about_nav() ?><?cs 
-  else ?><?cs 
-    call:default_left_nav() ?> <?cs 
-  /if ?><?cs 
+    if:googleplay ?><?cs
+      call:googleplay_nav() ?><?cs
+    elif:essentials ?><?cs
+      call:essentials_nav() ?><?cs
+    elif:users ?><?cs
+      call:users_nav() ?><?cs
+    elif:engage ?><?cs
+      call:engage_nav() ?><?cs
+    elif:monetize ?><?cs
+      call:monetize_nav() ?><?cs
+    elif:analyze ?><?cs
+      call:analyze_nav() ?><?cs
+    elif:disttools ?><?cs
+      call:disttools_nav() ?><?cs
+    elif:stories ?><?cs
+      call:stories_nav() ?><?cs
+    /if ?><?cs
+  elif:about ?><?cs
+    call:about_nav() ?><?cs
+  elif:distribute ?><?cs
+    call:distribute_nav() ?><?cs
+  elif:wear ?><?cs
+    call:wear_nav() ?><?cs
+  elif:preview ?><?cs
+    call:preview_nav() ?><?cs
+  else ?><?cs
+    call:default_left_nav() ?> <?cs
+  /if ?><?cs
 /def ?>
 
 <?cs # appears at the bottom of every page ?><?cs 
diff --git a/tools/droiddoc/templates-sdk/docpage.cs b/tools/droiddoc/templates-sdk/docpage.cs
index ea462c9..d064222 100644
--- a/tools/droiddoc/templates-sdk/docpage.cs
+++ b/tools/droiddoc/templates-sdk/docpage.cs
@@ -2,19 +2,36 @@
 <?cs include:"macros.cs" ?>
 <html<?cs if:devsite ?> devsite<?cs /if ?>>
 <?cs include:"head_tag.cs" ?>
-<body class="gc-documentation <?cs if:(google || reference.gms || reference.gcm) ?>google<?cs /if ?>
-  <?cs if:(guide||develop||training||reference||tools||sdk||samples) ?>develop<?cs if:guide ?> guide<?cs /if ?><?cs if:samples ?> samples<?cs /if ?><?cs
-  elif:about ?>about<?cs
-  elif:design ?>design<?cs
-  elif:distribute ?>distribute<?cs
-  /if ?><?cs
-  if:page.trainingcourse ?> trainingcourse<?cs /if ?>" itemscope itemtype="http://schema.org/Article">
-<?cs include:"header.cs" ?>
+<body class="gc-documentation
 
-<div <?cs if:fullpage
-?>class="fullpage"<?cs elif:design||tools||about||sdk||distribute
-?>class="col-13" id="doc-col"<?cs else
-?>class="col-12" id="doc-col"<?cs /if ?> >
+<?cs
+if:(google || reference.gms || reference.gcm) ?>google<?cs /if ?><?cs
+  if:(guide||develop||training||reference||tools||sdk||samples) ?>develop<?cs
+    if:guide ?> guide<?cs /if ?><?cs
+    if:samples ?> samples<?cs /if ?><?cs
+  elif:(distribute||googleplay||essentials||users||engage||monetize||disttools||stories)
+    ?>distribute<?cs
+    if:googleplay ?> googleplay<?cs /if ?><?cs
+    if:essentials ?> essentials<?cs /if ?><?cs
+    if:users ?> users<?cs /if ?><?cs
+    if:engage ?> engage<?cs /if ?><?cs
+    if:monetize ?> monetize<?cs /if ?><?cs
+    if:disttools ?> disttools<?cs /if ?><?cs
+    if:stories ?> stories<?cs /if ?><?cs
+  elif:(about||wear||tv||auto) ?>about<?cs
+  elif:design ?>design<?cs
+/if ?><?cs
+if:page.trainingcourse ?> trainingcourse<?cs
+/if ?>" itemscope itemtype="http://schema.org/Article"><?cs
+include:"header.cs" ?>
+
+<div <?cs
+  if:fullpage
+    ?>class="fullpage"<?cs
+  elif:(design||tools||about||sdk||googleplay||essentials||users||monetize||disttools) && !nonavpage
+    ?>class="col-13" id="doc-col"<?cs
+  elif:!nonavpage
+    ?>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 ?>
   <?cs if:header.hide ?>
@@ -73,7 +90,8 @@
       </div>
     <?cs /if ?><?cs # end if training ?>
   </div>
-  <?cs /if ?>
+  <?cs /if ?><?cs # end if header.hide ?>
+
 <?cs elif:samplesProjectIndex ?>
   <div id="api-info-block">
   <div class="sum-details-links">
@@ -83,7 +101,17 @@
   </div><!-- end sum-details-links -->
   </div><!-- end breadcurmb block -->
   <h1 itemprop="name"><?cs var:projectDir ?></h1>
+
 <?cs else ?>
+  <?cs if:training ?>
+<?cs # horrible horrible hack to move TOC up when the next/prev links are not there ?>
+<style>
+  #tb-wrapper {
+    margin-top:6px;
+  }
+</style>
+  <?cs /if ?>
+
   <?cs if:(!fullpage && !header.hide) ?>
     <?cs if:page.landing ?><?cs # header logic for docs that are landing pages ?>
       <div class="landing-banner">
@@ -129,25 +157,9 @@
                     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">
+        <div class="paging-links layout-content-col col-10">
           <?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="下一课"
@@ -164,35 +176,29 @@
                 ja-lang="開始する"
                 es-lang="Empezar"
                 >Get started</a>
+            <a href="#" class="next-class-link hide">Next class</a>
+          <?cs /if ?>
+        </div>
+        <div class="layout-content-col plus-container col-2" >
+          <?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 ?>
       </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" ?>
 </div><!-- end doc-content -->
 
 <?cs include:"trailer.cs" ?>
+  <script src="https://developer.android.com/ytblogger_lists_unified.js" type="text/javascript"></script>
+  <script src="<?cs var:toroot ?>jd_lists_unified.js?v=8" type="text/javascript"></script>
+  <script src="<?cs var:toroot ?>jd_extras.js?v=9" type="text/javascript"></script>
+  <script src="<?cs var:toroot ?>jd_collections.js?v=9" type="text/javascript"></script>
+  <script src="<?cs var:toroot ?>jd_tag_helpers.js?v=5" type="text/javascript"></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/head_tag.cs b/tools/droiddoc/templates-sdk/head_tag.cs
index 54de169..9f79f54 100644
--- a/tools/droiddoc/templates-sdk/head_tag.cs
+++ b/tools/droiddoc/templates-sdk/head_tag.cs
@@ -15,26 +15,32 @@
 ?><?cs
   # END if/else devsite ?>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
+<meta name="viewport" content="width=<?cs
+  if:page.viewport_width ?><?cs
+    var:page.viewport_width ?><?cs
+  else ?>device-width<?cs /if ?>" />
 <?cs
   if:page.metaDescription ?>
 <meta name="Description" content="<?cs var:page.metaDescription ?>"><?cs
-  /if ?><?cs
-  if:page.customHeadTag ?>
-<?cs var:page.customHeadTag ?><?cs
   /if ?>
 <link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>favicon.ico" />
-<title><?cs 
-  if:page.title ?><?cs 
+<title><?cs
+  if:page.title ?><?cs
     var:page.title ?> | <?cs
   /if ?>Android Developers</title>
 
 <!-- STYLESHEETS -->
 <link rel="stylesheet"
-href="<?cs if:android.whichdoc != 'online' ?>http:<?cs /if ?>//fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="<?cs var:toroot ?>assets/css/default.css" rel="stylesheet" type="text/css">
+href="<?cs
+if:android.whichdoc != 'online' ?>http:<?cs
+/if ?>//fonts.googleapis.com/css?family=Roboto+Condensed">
+<link rel="stylesheet" href="<?cs
+if:android.whichdoc != 'online' ?>http:<?cs
+/if ?>//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold"
+  title="roboto">
+<link href="<?cs var:toroot ?>assets/css/default.css?v=5" rel="stylesheet" type="text/css">
 
-<?cs if:reference && !(reference.gms || reference.gcm) ?>
+<?cs if:reference && !(reference.gms || reference.gcm || preview) ?>
 <!-- FULLSCREEN STYLESHEET -->
 <link href="<?cs var:toroot ?>assets/css/fullscreen.css" rel="stylesheet" class="fullscreen"
 type="text/css">
@@ -47,23 +53,34 @@
   ?><script src="<?cs var:toroot ?>_static/js/android_3p-bundle.js" type="text/javascript"></script><?cs
 else
   ?><script src="<?cs var:toroot ?>assets/js/android_3p-bundle.js" type="text/javascript"></script><?cs
-/if ?>
+/if ?><?cs
+  if:page.customHeadTag ?>
+<?cs var:page.customHeadTag ?><?cs
+  /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>
+<script src="<?cs var:toroot ?>assets/js/docs.js?v=3" type="text/javascript"></script>
 
-<script type="text/javascript">
-  var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-5831155-1']);
-  _gaq.push(['_trackPageview']);
+<?cs if:helpoutsWidget ?>
+<script type="text/javascript" src="https://helpouts.google.com/ps/res/embed.js" defer async
+    data-helpouts-embed data-helpouts-vertical="programming"
+    data-helpouts-tags="<?cs var:page.tags ?>" data-helpouts-prefix="android"
+    data-helpouts-standalone="true"></script>
+<?cs /if ?>
 
-  (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>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+  ga('create', 'UA-5831155-1', 'android.com');
+  ga('create', 'UA-49880327-2', 'android.com', {'name': 'universal'});  // New tracker);
+  ga('send', 'pageview');
+  ga('universal.send', 'pageview'); // Send page view for new tracker.
 </script>
-</head>
\ No newline at end of file
+
+</head>
diff --git a/tools/droiddoc/templates-sdk/macros_override.cs b/tools/droiddoc/templates-sdk/macros_override.cs
new file mode 100644
index 0000000..0a94598
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/macros_override.cs
@@ -0,0 +1,36 @@
+<?cs # Create a comma separated list of annotations on obj that were in showAnnotations in Doclava ?>
+<?cs # pre is an HTML string to start the list, post is an HTML string to close the list ?>
+<?cs # for example call:show_annotations_list(cl, "<td>Annotations: ", "</td>") ?>
+<?cs # if obj has nothing on obj.showAnnotations, nothing will be output ?>
+<?cs def:show_annotations_list(obj) ?>
+    <?cs each:anno = obj.showAnnotations ?>
+      <?cs if:first(anno) ?>
+        <span class='annotation-message'>
+          Included in documentation by the annotations:
+      <?cs /if ?>
+      @<?cs var:anno.type.label ?>
+      <?cs if:last(anno) == 0 ?>
+        , &nbsp;
+      <?cs /if ?>
+      <?cs if:last(anno)?>
+        </span>
+      <?cs /if ?>
+    <?cs /each ?>
+<?cs /def ?>
+
+<?cs # Override default class_link_table to display annotations ?>
+<?cs def:class_link_table(classes) ?>
+  <?cs set:count = #1 ?>
+  <table class="jd-sumtable-expando">
+    <?cs each:cl=classes ?>
+      <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:cl.type.since ?>" >
+        <td class="jd-linkcol"><?cs call:type_link(cl.type) ?></td>
+        <td class="jd-descrcol" width="100%">
+          <?cs call:short_descr(cl) ?>&nbsp;
+          <?cs call:show_annotations_list(cl) ?>
+        </td>
+      </tr>
+      <?cs set:count = count + #1 ?>
+    <?cs /each ?>
+  </table>
+<?cs /def ?>
\ No newline at end of file
diff --git a/tools/droiddoc/templates-sdk/package.cs b/tools/droiddoc/templates-sdk/package.cs
index 99eaff2..2225565 100644
--- a/tools/droiddoc/templates-sdk/package.cs
+++ b/tools/droiddoc/templates-sdk/package.cs
@@ -1,10 +1,13 @@
 <?cs include:"doctype.cs" ?>
 <?cs include:"macros.cs" ?>
+<?cs include:"macros_override.cs" ?>
 <html<?cs if:devsite ?> devsite<?cs /if ?>>
 <?cs include:"head_tag.cs" ?>
 
 <body class="gc-documentation <?cs if:(reference.gms || reference.gcm) ?>google<?cs /if ?>
   <?cs if:(guide||develop||training||reference||tools||sdk) ?>develop<?cs
+    if:reference ?> reference<?cs
+    /if ?><?cs
   elif:design ?>design<?cs
   elif:distribute ?>distribute<?cs
   /if ?>">
@@ -45,6 +48,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/packages.cs b/tools/droiddoc/templates-sdk/packages.cs
index 44680c3..5056d3a 100644
--- a/tools/droiddoc/templates-sdk/packages.cs
+++ b/tools/droiddoc/templates-sdk/packages.cs
@@ -4,6 +4,8 @@
 <?cs include:"head_tag.cs" ?>
 <body class="gc-documentation <?cs if:(reference.gms || reference.gcm) ?>google<?cs /if ?>
   <?cs if:(guide||develop||training||reference||tools||sdk) ?>develop<?cs
+    if:reference ?> reference<?cs
+    /if ?><?cs
   elif:design ?>design<?cs
   elif:distribute ?>distribute<?cs
   /if ?>">
diff --git a/tools/droiddoc/templates-sdk/sample.cs b/tools/droiddoc/templates-sdk/sample.cs
index c6f28f8..32a0788 100644
--- a/tools/droiddoc/templates-sdk/sample.cs
+++ b/tools/droiddoc/templates-sdk/sample.cs
@@ -18,7 +18,7 @@
   <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"
-    onclick="_gaq.push(['_trackEvent', 'Samples', 'Download', <?cs var:projectDir ?>]);"
+    onclick="ga('send', 'event', 'Samples', 'Download', <?cs var:projectDir ?>);"
     >Download</a>
 
 </div><!-- end sum-details-links -->
diff --git a/tools/droiddoc/templates-sdk/sampleindex.cs b/tools/droiddoc/templates-sdk/sampleindex.cs
index 98767b1..1bacb53 100644
--- a/tools/droiddoc/templates-sdk/sampleindex.cs
+++ b/tools/droiddoc/templates-sdk/sampleindex.cs
@@ -21,7 +21,7 @@
 &#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"
-    onclick="_gaq.push(['_trackEvent', 'Samples', 'Download', <?cs var:projectDir ?>]);"
+    onclick="ga('send', 'event', 'Samples', 'Download', <?cs var:projectDir ?>);"
     >Download</a>
 
 </div><!-- end sum-details-links -->
diff --git a/tools/droiddoc/templates-sdk/sdkpage.cs b/tools/droiddoc/templates-sdk/sdkpage.cs
index 95f6596..817ac47 100644
--- a/tools/droiddoc/templates-sdk/sdkpage.cs
+++ b/tools/droiddoc/templates-sdk/sdkpage.cs
@@ -183,21 +183,7 @@
     <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>
 
   <?cs ########  HERE IS THE JD DOC CONTENT ######### ?>
@@ -278,89 +264,25 @@
 
 
 
-<h4><a href='' class="expandable"
-  onclick="toggleExpandable(this,'.pax');hideExpandable('.myide,.reqs');return false;"
-  >DOWNLOAD FOR OTHER PLATFORMS</a></h4>
+<div class="pax col-13 online" style="margin:0;">
 
 
-<div class="pax col-13 online" style="display:none;margin:0;">
+<h3>SDK Tools Only</h3>
 
+<p>If you prefer to use a different IDE or run the tools from the
+command line or with build scripts, you can instead download the stand-alone Android SDK Tools.
+These packages provide the basic SDK tools for app development, without an IDE.
+Also see the <a href="<?cs var:toroot ?>tools/sdk/tools-notes.html">SDK tools release notes</a>.</p>
 
-<p class="table-caption"><strong>ADT Bundle</strong></p>
   <table class="download">
     <tr>
       <th>Platform</th>
       <th>Package</th>
       <th>Size</th>
-      <th>MD5 Checksum</th>
+      <th>SHA-1 Checksum</th>
   </tr>
   <tr>
-    <td>Windows 32-bit</td>
-    <td>
-  <a onClick="return onDownload(this)" id="win-bundle32"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.win32_bundle_download ?>"><?cs var:sdk.win32_bundle_download ?></a>
-    </td>
-    <td><?cs var:sdk.win32_bundle_bytes ?> bytes</td>
-    <td><?cs var:sdk.win32_bundle_checksum ?></td>
-  </tr>
-  <tr>
-    <td>Windows 64-bit</td>
-    <td>
-  <a onClick="return onDownload(this)" id="win-bundle64"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.win64_bundle_download ?>"><?cs var:sdk.win64_bundle_download ?></a>
-    </td>
-    <td><?cs var:sdk.win64_bundle_bytes ?> bytes</td>
-    <td><?cs var:sdk.win64_bundle_checksum ?></td>
-  </tr>
-  <tr>
-    <td><nobr>Mac OS X 64-bit</nobr></td>
-    <td>
-  <a onClick="return onDownload(this)" id="mac-bundle64"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.mac64_bundle_download ?>"><?cs var:sdk.mac64_bundle_download ?></a>
-    </td>
-    <td><?cs var:sdk.mac64_bundle_bytes ?> bytes</td>
-    <td><?cs var:sdk.mac64_bundle_checksum ?></td>
-  </tr>
-  <tr>
-    <td>Linux 32-bit</td>
-    <td>
-  <a onClick="return onDownload(this)" id="linux-bundle32"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.linux32_bundle_download ?>"><?cs var:sdk.linux32_bundle_download ?></a>
-    </td>
-    <td><?cs var:sdk.linux32_bundle_bytes ?> bytes</td>
-    <td><?cs var:sdk.linux32_bundle_checksum ?></td>
-  </tr>
-  <tr>
-    <td>Linux 64-bit</td>
-    <td>
-  <a onClick="return onDownload(this)" id="linux-bundle64"
-     href="http://dl.google.com/android/adt/<?cs var:sdk.version ?>/<?cs var:sdk.linux64_bundle_download ?>"><?cs var:sdk.linux64_bundle_download ?></a>
-    </td>
-    <td><?cs var:sdk.linux64_bundle_bytes ?> bytes</td>
-    <td><?cs var:sdk.linux64_bundle_checksum ?></td>
-  </tr>
-  </table>
-
-
-<p class="table-caption"><strong>SDK Tools Only</strong></p>
-  <table class="download">
-    <tr>
-      <th>Platform</th>
-      <th>Package</th>
-      <th>Size</th>
-      <th>MD5 Checksum</th>
-  </tr>
-  <tr>
-    <td rowspan="2">Windows<br>32 &amp; 64-bit</td>
-    <td>
-  <a onclick="return onDownload(this)" href="http://dl.google.com/android/<?cs var:sdk.win_download
-?>"><?cs var:sdk.win_download ?></a>
-    </td>
-    <td><?cs var:sdk.win_bytes ?> bytes</td>
-    <td><?cs var:sdk.win_checksum ?></td>
-  </tr>
-  <tr>
-    <!-- blank TD from Windows rowspan -->
+    <td rowspan="2">Windows</td>
     <td>
   <a onclick="return onDownload(this)" id="win-tools" href="http://dl.google.com/android/<?cs
 var:sdk.win_installer
@@ -370,7 +292,16 @@
     <td><?cs var:sdk.win_installer_checksum ?></td>
   </tr>
   <tr>
-    <td><nobr>Mac OS X</nobr><br>32 &amp; 64-bit</td>
+    <!-- blank TD from Windows rowspan -->
+    <td>
+  <a onclick="return onDownload(this)" href="http://dl.google.com/android/<?cs var:sdk.win_download
+?>"><?cs var:sdk.win_download ?></a>
+    </td>
+    <td><?cs var:sdk.win_bytes ?> bytes</td>
+    <td><?cs var:sdk.win_checksum ?></td>
+  </tr>
+  <tr>
+    <td><nobr>Mac OS X</nobr></td>
     <td>
   <a onclick="return onDownload(this)" id="mac-tools" href="http://dl.google.com/android/<?cs
 var:sdk.mac_download
@@ -380,7 +311,7 @@
     <td><?cs var:sdk.mac_checksum ?></td>
   </tr>
   <tr>
-    <td>Linux<br>32 &amp; 64-bit</td>
+    <td>Linux</td>
     <td>
   <a onclick="return onDownload(this)" id="linux-tools" href="http://dl.google.com/android/<?cs
 var:sdk.linux_download
@@ -391,6 +322,79 @@
   </tr>
   </table>
 
+
+
+<h3>All Android Studio Packages</h3>
+
+<p>Select a specific Android Studio package for your platform. Also see the
+<a href="<?cs var:toroot ?>tools/revisions/studio.html">Android Studio release notes</a>.</p>
+
+  <table class="download">
+    <tr>
+      <th>Platform</th>
+      <th>Package</th>
+      <th>Size</th>
+      <th>SHA-1 Checksum</th>
+  </tr>
+
+  <tr>
+    <td rowspan="3">Windows</td>
+    <td>
+  <a onclick="return onDownload(this)" id="win-bundle"
+    href="https://dl.google.com/dl/android/studio/install/<?cs var:studio.version ?>/<?cs var:studio.win_bundle_exe_download ?>"
+    ><?cs var:studio.win_bundle_exe_download ?></a><br>(Recommended)
+    </td>
+    <td><?cs var:studio.win_bundle_exe_bytes ?> bytes</td>
+    <td><?cs var:studio.win_bundle_exe_checksum ?></td>
+  </tr>
+
+  <tr>
+    <!-- blank TD from Windows rowspan -->
+    <td>
+  <a onclick="return onDownload(this)"
+    href="https://dl.google.com/dl/android/studio/install/<?cs var:studio.version ?>/<?cs var:studio.win_notools_exe_download ?>"
+    ><?cs var:studio.win_notools_exe_download ?></a><br>(No SDK tools included)
+    </td>
+    <td><?cs var:studio.win_notools_exe_bytes ?> bytes</td>
+    <td><?cs var:studio.win_notools_exe_checksum ?></td>
+  </tr>
+
+  <tr>
+    <!-- blank TD from Windows rowspan -->
+    <td>
+  <a onclick="return onDownload(this)"
+    href="https://dl.google.com/dl/android/studio/ide-zips/<?cs var:studio.version ?>/<?cs var:studio.win_bundle_download ?>"
+    ><?cs var:studio.win_bundle_download ?></a>
+    </td>
+    <td><?cs var:studio.win_bundle_bytes ?> bytes</td>
+    <td><?cs var:studio.win_bundle_checksum ?></td>
+  </tr>
+
+  <tr>
+    <td><nobr>Mac OS X</nobr></td>
+    <td>
+  <a onclick="return onDownload(this)" id="mac-bundle"
+    href="https://dl.google.com/dl/android/studio/install/<?cs var:studio.version ?>/<?cs var:studio.mac_bundle_download ?>"
+    ><?cs var:studio.mac_bundle_download ?></a>
+    </td>
+    <td><?cs var:studio.mac_bundle_bytes ?> bytes</td>
+    <td><?cs var:studio.mac_bundle_checksum ?></td>
+  </tr>
+
+  <tr>
+    <td>Linux</td>
+    <td>
+  <a onclick="return onDownload(this)" id="linux-bundle"
+    href="https://dl.google.com/dl/android/studio/ide-zips/<?cs var:studio.version ?>/<?cs var:studio.linux_bundle_download ?>"
+    ><?cs var:studio.linux_bundle_download ?></a>
+    </td>
+    <td><?cs var:studio.linux_bundle_bytes ?> bytes</td>
+    <td><?cs var:studio.linux_bundle_checksum ?></td>
+  </tr>
+  </table>
+
+
+
 </div><!-- end pax -->
 
 
@@ -411,7 +415,9 @@
   var bundlename;
   var $toolslink;
 
-  if (navigator.appVersion.indexOf("Win")!=-1) {
+  if (navigator.appVersion.indexOf("Mobile")!=-1) {
+    // Do nothing for any "mobile" user agent
+  } else if (navigator.appVersion.indexOf("Win")!=-1) {
     os = "Windows";
     bundlename = '#win-bundle';
     $toolslink = $('#win-tools');
@@ -419,26 +425,18 @@
     os = "Mac";
     bundlename = '#mac-bundle';
     $toolslink = $('#mac-tools');
-  } else if (navigator.appVersion.indexOf("Linux")!=-1) {
+  } else if (navigator.appVersion.indexOf("Linux")!=-1 && navigator.appVersion.indexOf("Android")==-1) {
     os = "Linux";
     bundlename = '#linux-bundle';
     $toolslink = $('#linux-tools');
   }
 
-  if (os) {
+  if (os != undefined) {
     $('#not-supported').hide();
 
-    /* set up primary adt download button */
-    $('#download-bundle-button').show();
-    $('#download-bundle-button').append("Download the SDK <br/><span class='small'>ADT Bundle for " + os + "</span>");
-    $('#download-bundle-button').click(function() {return onDownload(this,true,true);}).attr('href', bundlename);
-
-    /* set up sdk tools only button */
-    $('#download-tools-button').show();
-    $('#download-tools-button').append("Download the SDK Tools for " + os);
-    $('#download-tools-button').click(function() {return onDownload(this,true);}).attr('href', $toolslink.attr('href'));
-  } else {
-    $('.pax').show();
+    /* set up primary Android Studio download button */
+    $('.download-bundle-button').append(" <br/><span class='small'>for " + os + "</span>");
+    $('.download-bundle-button').click(function() {return onDownload(this,true,true);}).attr('href', bundlename);
   }
 
 
@@ -451,44 +449,29 @@
       $("#downloadForRealz").html("Download " + $(link).text());
     }
 
-    /* if it's a bundle, show the 32/64-bit picker */
-    if (bundle) {
-      $("#downloadForRealz").attr('bundle','true');
-      if ($("#downloadForRealz").text().indexOf("Mac") == -1) {
-        $("p#bitpicker").show();
-      } else {
-        /* mac is always 64 bit, so set it checked */
-        $("p#bitpicker input[value=64]").attr('checked', true);
-      }
-      /* save link name until the bit version is chosen */
-      $("#downloadForRealz").attr('name',$(link).attr('href'));
-    } else {
-      /* if not using bundle, set download button to ignore bitpicker and set url */
-      $("#downloadForRealz").attr('bundle','false');
-      $("#downloadForRealz").attr('href',$(link).attr('href'));
-      /* set picker checked as a fake default */
-      $("p#bitpicker input[value=64]").attr('checked', true);
-      $("a#next-link").html("Setting Up an Existing IDE").attr('href',toRoot + 'sdk/installing/index.html');
-    }
+    $("#downloadForRealz").attr('bundle', bundle);
+    $("a#downloadForRealz").attr("name", $(link).attr('href'));
 
-    $("#tos").fadeIn('fast');
-    $("#landing").fadeOut('fast');
+    $("#tos").show();
+    $("#landing").hide();
 
-    location.hash = "download";
+    location.hash = "top";
     return false;
   }
 
 
   function onAgreeChecked() {
-    /* verify that the TOS is agreed and a bit version is chosen */
-    if ($("input#agree").is(":checked") && $("#bitpicker input:checked").length) {
+    /* verify that the TOS is agreed */
+    if ($("input#agree").is(":checked")) {
 
       /* if downloading the bundle */
       if ($("#downloadForRealz").attr('bundle')) {
-        /* construct the name of the link we want based on the bit version */
-        linkId = $("a#downloadForRealz").attr("name") + $("#bitpicker input:checked").val();
+        /* construct the name of the link we want */
+        linkId = $("a#downloadForRealz").attr("name");
         /* set the real url for download */
         $("a#downloadForRealz").attr("href", $(linkId).attr("href"));
+      } else {
+        $("a#downloadForRealz").attr("href", $("a#downloadForRealz").attr("name"));
       }
 
       /* reveal the download button */
@@ -499,16 +482,28 @@
   }
 
   function onDownloadForRealz(link) {
-    if ($("input#agree").is(':checked') && $("#bitpicker input:checked").length) {
+    if ($("input#agree").is(':checked')) {
+      location.hash = "";
+      location.hash = "top";
       $("div.sdk-terms").slideUp();
-      $("#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()]);
+      $("h1#tos-header").text('Now downloading...');
+      $(".sdk-terms-intro").text('You\'ll be redirected to the install instructions in a moment.');
+      $("#sdk-terms-form").fadeOut('slow', function() {
+        setTimeout(function() {
+          if ($("#downloadForRealz").attr('bundle') == 'true') {
+            // User downloaded the studio Bundle
+            window.location = "/sdk/installing/index.html?pkg=studio";
+          } else {
+            // User downloaded the SDK Tools
+            window.location = "/sdk/installing/index.html?pkg=tools";
+          }
+        }, 3000);
+      });
+      ga('send', 'event', 'SDK', 'IDE and Tools', $("#downloadForRealz").html());
       return true;
     } else {
-      $("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#258AAF"}, 200,
-        function() {$("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#222"}, 200)}
+      $("label#agreeLabel").parent().stop().animate({color: "#258AAF"}, 200,
+        function() {$("label#agreeLabel").parent().stop().animate({color: "#222"}, 200)}
       );
       return false;
     }
diff --git a/tools/post_process_props.py b/tools/post_process_props.py
index 5d1b350..fa6106f 100755
--- a/tools/post_process_props.py
+++ b/tools/post_process_props.py
@@ -16,9 +16,13 @@
 
 import sys
 
-# See PROP_VALUE_MAX system_properties.h.
-# PROP_VALUE_MAX in system_properties.h includes the termination NUL,
-# so we decrease it by 1 here.
+# Usage: post_process_props.py file.prop [blacklist_key, ...]
+# Blacklisted keys are removed from the property file, if present
+
+# See PROP_NAME_MAX and PROP_VALUE_MAX system_properties.h.
+# The constants in system_properties.h includes the termination NUL,
+# so we decrease the values by 1 here.
+PROP_NAME_MAX = 31
 PROP_VALUE_MAX = 91
 
 # Put the modifications that you need to make into the /system/build.prop into this
@@ -52,24 +56,18 @@
   """
   check_pass = True
   buildprops = prop.to_dict()
-  dev_build = buildprops.get("ro.build.version.incremental",
-                             "").startswith("eng")
   for key, value in buildprops.iteritems():
     # Check build properties' length.
+    if len(key) > PROP_NAME_MAX:
+      check_pass = False
+      sys.stderr.write("error: %s cannot exceed %d bytes: " %
+                       (key, PROP_NAME_MAX))
+      sys.stderr.write("%s (%d)\n" % (key, len(key)))
     if len(value) > PROP_VALUE_MAX:
-      # If dev build, show a warning message, otherwise fail the
-      # build with error message
-      if dev_build:
-        sys.stderr.write("warning: %s exceeds %d bytes: " %
-                         (key, PROP_VALUE_MAX))
-        sys.stderr.write("%s (%d)\n" % (value, len(value)))
-        sys.stderr.write("warning: This will cause the %s " % key)
-        sys.stderr.write("property return as empty at runtime\n")
-      else:
-        check_pass = False
-        sys.stderr.write("error: %s cannot exceed %d bytes: " %
-                         (key, PROP_VALUE_MAX))
-        sys.stderr.write("%s (%d)\n" % (value, len(value)))
+      check_pass = False
+      sys.stderr.write("error: %s cannot exceed %d bytes: " %
+                       (key, PROP_VALUE_MAX))
+      sys.stderr.write("%s (%d)\n" % (value, len(value)))
   return check_pass
 
 class PropFile:
@@ -82,8 +80,9 @@
     for line in self.lines:
       if not line or line.startswith("#"):
         continue
-      key, value = line.split("=", 1)
-      props[key] = value
+      if "=" in line:
+        key, value = line.split("=", 1)
+        props[key] = value
     return props
 
   def get(self, name):
@@ -101,6 +100,10 @@
         return
     self.lines.append(key + value)
 
+  def delete(self, name):
+    key = name + "="
+    self.lines = [ line for line in self.lines if not line.startswith(key) ]
+
   def write(self, f):
     f.write("\n".join(self.lines))
     f.write("\n")
@@ -124,6 +127,10 @@
   if not validate(properties):
     sys.exit(1)
 
+  # Drop any blacklisted keys
+  for key in argv[2:]:
+    properties.delete(key)
+
   f = open(filename, 'w+')
   properties.write(f)
   f.close()
diff --git a/tools/product_debug.py b/tools/product_debug.py
index 661c5b7..ff2657c 100755
--- a/tools/product_debug.py
+++ b/tools/product_debug.py
@@ -89,7 +89,6 @@
       "PRODUCT_COPY_FILES",
       "PRODUCT_PACKAGES",
       "PRODUCT_LOCALES",
-      "PRODUCT_FACTORY_RAMDISK_MODULES",
       "PRODUCT_PROPERTY_OVERRIDES",
     )
 
diff --git a/tools/releasetools/add_img_to_target_files b/tools/releasetools/add_img_to_target_files
new file mode 120000
index 0000000..04323bd
--- /dev/null
+++ b/tools/releasetools/add_img_to_target_files
@@ -0,0 +1 @@
+add_img_to_target_files.py
\ No newline at end of file
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
new file mode 100755
index 0000000..e98e4b6
--- /dev/null
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -0,0 +1,334 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Given a target-files zipfile that does not contain images (ie, does
+not have an IMAGES/ top-level subdirectory), produce the images and
+add them to the zipfile.
+
+Usage:  add_img_to_target_files target_files
+"""
+
+import sys
+
+if sys.hexversion < 0x02070000:
+  print >> sys.stderr, "Python 2.7 or newer is required."
+  sys.exit(1)
+
+import errno
+import os
+import re
+import shutil
+import subprocess
+import tempfile
+import zipfile
+
+# missing in Python 2.4 and before
+if not hasattr(os, "SEEK_SET"):
+  os.SEEK_SET = 0
+
+import build_image
+import common
+
+OPTIONS = common.OPTIONS
+
+OPTIONS.add_missing = False
+OPTIONS.rebuild_recovery = False
+
+def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
+  """Turn the contents of SYSTEM into a system image and store it in
+  output_zip."""
+
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system.img")
+  if os.path.exists(prebuilt_path):
+    print "system.img already exists in %s, no need to rebuild..." % (prefix,)
+    return
+
+  def output_sink(fn, data):
+     ofile = open(os.path.join(OPTIONS.input_tmp,"SYSTEM",fn), "w")
+     ofile.write(data)
+     ofile.close()
+
+  if OPTIONS.rebuild_recovery:
+    print("Building new recovery patch")
+    common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img, boot_img,
+                             info_dict=OPTIONS.info_dict)
+
+  block_list = common.MakeTempFile(prefix="system-blocklist-", suffix=".map")
+  imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict,
+                        block_list=block_list)
+  with open(imgname, "rb") as f:
+    common.ZipWriteStr(output_zip, prefix + "system.img", f.read())
+  with open(block_list, "rb") as f:
+    common.ZipWriteStr(output_zip, prefix + "system.map", f.read())
+
+
+def BuildSystem(input_dir, info_dict, block_list=None):
+  """Build the (sparse) system image and return the name of a temp
+  file containing it."""
+  return CreateImage(input_dir, info_dict, "system", block_list=block_list)
+
+
+def AddVendor(output_zip, prefix="IMAGES/"):
+  """Turn the contents of VENDOR into a vendor image and store in it
+  output_zip."""
+
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "vendor.img")
+  if os.path.exists(prebuilt_path):
+    print "vendor.img already exists in %s, no need to rebuild..." % (prefix,)
+    return
+
+  block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map")
+  imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict,
+                     block_list=block_list)
+  with open(imgname, "rb") as f:
+    common.ZipWriteStr(output_zip, prefix + "vendor.img", f.read())
+  with open(block_list, "rb") as f:
+    common.ZipWriteStr(output_zip, prefix + "vendor.map", f.read())
+
+
+def BuildVendor(input_dir, info_dict, block_list=None):
+  """Build the (sparse) vendor image and return the name of a temp
+  file containing it."""
+  return CreateImage(input_dir, info_dict, "vendor", block_list=block_list)
+
+
+def CreateImage(input_dir, info_dict, what, block_list=None):
+  print "creating " + what + ".img..."
+
+  img = common.MakeTempFile(prefix=what + "-", suffix=".img")
+
+  # The name of the directory it is making an image out of matters to
+  # mkyaffs2image.  It wants "system" but we have a directory named
+  # "SYSTEM", so create a symlink.
+  try:
+    os.symlink(os.path.join(input_dir, what.upper()),
+               os.path.join(input_dir, what))
+  except OSError, e:
+      # bogus error on my mac version?
+      #   File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
+      #     os.path.join(OPTIONS.input_tmp, "system"))
+      # OSError: [Errno 17] File exists
+    if (e.errno == errno.EEXIST):
+      pass
+
+  image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
+  fstab = info_dict["fstab"]
+  if fstab:
+    image_props["fs_type" ] = fstab["/" + what].fs_type
+
+  if what == "system":
+    fs_config_prefix = ""
+  else:
+    fs_config_prefix = what + "_"
+
+  fs_config = os.path.join(
+      input_dir, "META/" + fs_config_prefix + "filesystem_config.txt")
+  if not os.path.exists(fs_config): fs_config = None
+
+  fc_config = os.path.join(input_dir, "BOOT/RAMDISK/file_contexts")
+  if not os.path.exists(fc_config): fc_config = None
+
+  succ = build_image.BuildImage(os.path.join(input_dir, what),
+                                image_props, img,
+                                fs_config=fs_config,
+                                fc_config=fc_config,
+                                block_list=block_list)
+  assert succ, "build " + what + ".img image failed"
+
+  return img
+
+
+def AddUserdata(output_zip, prefix="IMAGES/"):
+  """Create an empty userdata image and store it in output_zip."""
+
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "userdata.img")
+  if os.path.exists(prebuilt_path):
+    print "userdata.img already exists in %s, no need to rebuild..." % (prefix,)
+    return
+
+  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
+                                                    "data")
+  # We only allow yaffs to have a 0/missing partition_size.
+  # Extfs, f2fs must have a size. Skip userdata.img if no size.
+  if (not image_props.get("fs_type", "").startswith("yaffs") and
+      not image_props.get("partition_size")):
+    return
+
+  print "creating userdata.img..."
+
+  # The name of the directory it is making an image out of matters to
+  # mkyaffs2image.  So we create a temp dir, and within it we create an
+  # empty dir named "data", and build the image from that.
+  temp_dir = tempfile.mkdtemp()
+  user_dir = os.path.join(temp_dir, "data")
+  os.mkdir(user_dir)
+  img = tempfile.NamedTemporaryFile()
+
+  fstab = OPTIONS.info_dict["fstab"]
+  if fstab:
+    image_props["fs_type" ] = fstab["/data"].fs_type
+  succ = build_image.BuildImage(user_dir, image_props, img.name)
+  assert succ, "build userdata.img image failed"
+
+  common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
+  output_zip.write(img.name, prefix + "userdata.img")
+  img.close()
+  os.rmdir(user_dir)
+  os.rmdir(temp_dir)
+
+
+def AddCache(output_zip, prefix="IMAGES/"):
+  """Create an empty cache image and store it in output_zip."""
+
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "cache.img")
+  if os.path.exists(prebuilt_path):
+    print "cache.img already exists in %s, no need to rebuild..." % (prefix,)
+    return
+
+  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
+                                                    "cache")
+  # The build system has to explicitly request for cache.img.
+  if "fs_type" not in image_props:
+    return
+
+  print "creating cache.img..."
+
+  # The name of the directory it is making an image out of matters to
+  # mkyaffs2image.  So we create a temp dir, and within it we create an
+  # empty dir named "cache", and build the image from that.
+  temp_dir = tempfile.mkdtemp()
+  user_dir = os.path.join(temp_dir, "cache")
+  os.mkdir(user_dir)
+  img = tempfile.NamedTemporaryFile()
+
+  fstab = OPTIONS.info_dict["fstab"]
+  if fstab:
+    image_props["fs_type" ] = fstab["/cache"].fs_type
+  succ = build_image.BuildImage(user_dir, image_props, img.name)
+  assert succ, "build cache.img image failed"
+
+  common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
+  output_zip.write(img.name, prefix + "cache.img")
+  img.close()
+  os.rmdir(user_dir)
+  os.rmdir(temp_dir)
+
+
+def AddImagesToTargetFiles(filename):
+  OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
+
+  if not OPTIONS.add_missing:
+    for n in input_zip.namelist():
+      if n.startswith("IMAGES/"):
+        print "target_files appears to already contain images."
+        sys.exit(1)
+
+  try:
+    input_zip.getinfo("VENDOR/")
+    has_vendor = True
+  except KeyError:
+    has_vendor = False
+
+  OPTIONS.info_dict = common.LoadInfoDict(input_zip)
+  if "selinux_fc" in OPTIONS.info_dict:
+    OPTIONS.info_dict["selinux_fc"] = os.path.join(
+        OPTIONS.input_tmp, "BOOT", "RAMDISK", "file_contexts")
+
+  input_zip.close()
+  output_zip = zipfile.ZipFile(filename, "a",
+                               compression=zipfile.ZIP_DEFLATED)
+
+  def banner(s):
+    print "\n\n++++ " + s + " ++++\n\n"
+
+  banner("boot")
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
+  boot_image = None
+  if os.path.exists(prebuilt_path):
+    print "boot.img already exists in IMAGES/, no need to rebuild..."
+    if OPTIONS.rebuild_recovery:
+      boot_image = common.GetBootableImage(
+          "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
+  else:
+    boot_image = common.GetBootableImage(
+        "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
+    if boot_image:
+      boot_image.AddToZip(output_zip)
+
+  banner("recovery")
+  recovery_image = None
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
+  if os.path.exists(prebuilt_path):
+    print "recovery.img already exists in IMAGES/, no need to rebuild..."
+    if OPTIONS.rebuild_recovery:
+      recovery_image = common.GetBootableImage(
+          "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
+  else:
+    recovery_image = common.GetBootableImage(
+        "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
+    if recovery_image:
+      recovery_image.AddToZip(output_zip)
+
+  banner("system")
+  AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
+  if has_vendor:
+    banner("vendor")
+    AddVendor(output_zip)
+  banner("userdata")
+  AddUserdata(output_zip)
+  banner("cache")
+  AddCache(output_zip)
+
+  output_zip.close()
+
+def main(argv):
+
+  def option_handler(o, a):
+    if o in ("-a", "--add_missing"):
+      OPTIONS.add_missing = True
+    elif o in ("-r", "--rebuild_recovery",):
+      OPTIONS.rebuild_recovery = True
+    else:
+      return False
+    return True
+
+  args = common.ParseOptions(argv, __doc__,
+                             extra_opts="ar",
+                             extra_long_opts=["add_missing",
+                                              "rebuild_recovery",
+                                              ],
+                             extra_option_handler=option_handler)
+
+
+  if len(args) != 1:
+    common.Usage(__doc__)
+    sys.exit(1)
+
+  AddImagesToTargetFiles(args[0])
+  print "done."
+
+if __name__ == '__main__':
+  try:
+    common.CloseInheritedPipes()
+    main(sys.argv[1:])
+  except common.ExternalError, e:
+    print
+    print "   ERROR: %s" % (e,)
+    print
+    sys.exit(1)
+  finally:
+    common.Cleanup()
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
new file mode 100644
index 0000000..8b179d5
--- /dev/null
+++ b/tools/releasetools/blockimgdiff.py
@@ -0,0 +1,817 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+
+from collections import deque, OrderedDict
+from hashlib import sha1
+import heapq
+import itertools
+import multiprocessing
+import os
+import pprint
+import re
+import subprocess
+import sys
+import threading
+import tempfile
+
+from rangelib import *
+
+__all__ = ["EmptyImage", "DataImage", "BlockImageDiff"]
+
+def compute_patch(src, tgt, imgdiff=False):
+  srcfd, srcfile = tempfile.mkstemp(prefix="src-")
+  tgtfd, tgtfile = tempfile.mkstemp(prefix="tgt-")
+  patchfd, patchfile = tempfile.mkstemp(prefix="patch-")
+  os.close(patchfd)
+
+  try:
+    with os.fdopen(srcfd, "wb") as f_src:
+      for p in src:
+        f_src.write(p)
+
+    with os.fdopen(tgtfd, "wb") as f_tgt:
+      for p in tgt:
+        f_tgt.write(p)
+    try:
+      os.unlink(patchfile)
+    except OSError:
+      pass
+    if imgdiff:
+      p = subprocess.call(["imgdiff", "-z", srcfile, tgtfile, patchfile],
+                          stdout=open("/dev/null", "a"),
+                          stderr=subprocess.STDOUT)
+    else:
+      p = subprocess.call(["bsdiff", srcfile, tgtfile, patchfile])
+
+    if p:
+      raise ValueError("diff failed: " + str(p))
+
+    with open(patchfile, "rb") as f:
+      return f.read()
+  finally:
+    try:
+      os.unlink(srcfile)
+      os.unlink(tgtfile)
+      os.unlink(patchfile)
+    except OSError:
+      pass
+
+class EmptyImage(object):
+  """A zero-length image."""
+  blocksize = 4096
+  care_map = RangeSet()
+  total_blocks = 0
+  file_map = {}
+  def ReadRangeSet(self, ranges):
+    return ()
+  def TotalSha1(self):
+    return sha1().hexdigest()
+
+
+class DataImage(object):
+  """An image wrapped around a single string of data."""
+
+  def __init__(self, data, trim=False, pad=False):
+    self.data = data
+    self.blocksize = 4096
+
+    assert not (trim and pad)
+
+    partial = len(self.data) % self.blocksize
+    if partial > 0:
+      if trim:
+        self.data = self.data[:-partial]
+      elif pad:
+        self.data += '\0' * (self.blocksize - partial)
+      else:
+        raise ValueError(("data for DataImage must be multiple of %d bytes "
+                          "unless trim or pad is specified") %
+                         (self.blocksize,))
+
+    assert len(self.data) % self.blocksize == 0
+
+    self.total_blocks = len(self.data) / self.blocksize
+    self.care_map = RangeSet(data=(0, self.total_blocks))
+
+    zero_blocks = []
+    nonzero_blocks = []
+    reference = '\0' * self.blocksize
+
+    for i in range(self.total_blocks):
+      d = self.data[i*self.blocksize : (i+1)*self.blocksize]
+      if d == reference:
+        zero_blocks.append(i)
+        zero_blocks.append(i+1)
+      else:
+        nonzero_blocks.append(i)
+        nonzero_blocks.append(i+1)
+
+    self.file_map = {"__ZERO": RangeSet(zero_blocks),
+                     "__NONZERO": RangeSet(nonzero_blocks)}
+
+  def ReadRangeSet(self, ranges):
+    return [self.data[s*self.blocksize:e*self.blocksize] for (s, e) in ranges]
+
+  def TotalSha1(self):
+    if not hasattr(self, "sha1"):
+      self.sha1 = sha1(self.data).hexdigest()
+    return self.sha1
+
+
+class Transfer(object):
+  def __init__(self, tgt_name, src_name, tgt_ranges, src_ranges, style, by_id):
+    self.tgt_name = tgt_name
+    self.src_name = src_name
+    self.tgt_ranges = tgt_ranges
+    self.src_ranges = src_ranges
+    self.style = style
+    self.intact = (getattr(tgt_ranges, "monotonic", False) and
+                   getattr(src_ranges, "monotonic", False))
+    self.goes_before = {}
+    self.goes_after = {}
+
+    self.stash_before = []
+    self.use_stash = []
+
+    self.id = len(by_id)
+    by_id.append(self)
+
+  def NetStashChange(self):
+    return (sum(sr.size() for (_, sr) in self.stash_before) -
+            sum(sr.size() for (_, sr) in self.use_stash))
+
+  def __str__(self):
+    return (str(self.id) + ": <" + str(self.src_ranges) + " " + self.style +
+            " to " + str(self.tgt_ranges) + ">")
+
+
+# BlockImageDiff works on two image objects.  An image object is
+# anything that provides the following attributes:
+#
+#    blocksize: the size in bytes of a block, currently must be 4096.
+#
+#    total_blocks: the total size of the partition/image, in blocks.
+#
+#    care_map: a RangeSet containing which blocks (in the range [0,
+#      total_blocks) we actually care about; i.e. which blocks contain
+#      data.
+#
+#    file_map: a dict that partitions the blocks contained in care_map
+#      into smaller domains that are useful for doing diffs on.
+#      (Typically a domain is a file, and the key in file_map is the
+#      pathname.)
+#
+#    ReadRangeSet(): a function that takes a RangeSet and returns the
+#      data contained in the image blocks of that RangeSet.  The data
+#      is returned as a list or tuple of strings; concatenating the
+#      elements together should produce the requested data.
+#      Implementations are free to break up the data into list/tuple
+#      elements in any way that is convenient.
+#
+#    TotalSha1(): a function that returns (as a hex string) the SHA-1
+#      hash of all the data in the image (ie, all the blocks in the
+#      care_map)
+#
+# When creating a BlockImageDiff, the src image may be None, in which
+# case the list of transfers produced will never read from the
+# original image.
+
+class BlockImageDiff(object):
+  def __init__(self, tgt, src=None, threads=None, version=2):
+    if threads is None:
+      threads = multiprocessing.cpu_count() // 2
+      if threads == 0: threads = 1
+    self.threads = threads
+    self.version = version
+
+    assert version in (1, 2)
+
+    self.tgt = tgt
+    if src is None:
+      src = EmptyImage()
+    self.src = src
+
+    # The updater code that installs the patch always uses 4k blocks.
+    assert tgt.blocksize == 4096
+    assert src.blocksize == 4096
+
+    # The range sets in each filemap should comprise a partition of
+    # the care map.
+    self.AssertPartition(src.care_map, src.file_map.values())
+    self.AssertPartition(tgt.care_map, tgt.file_map.values())
+
+  def Compute(self, prefix):
+    # When looking for a source file to use as the diff input for a
+    # target file, we try:
+    #   1) an exact path match if available, otherwise
+    #   2) a exact basename match if available, otherwise
+    #   3) a basename match after all runs of digits are replaced by
+    #      "#" if available, otherwise
+    #   4) we have no source for this target.
+    self.AbbreviateSourceNames()
+    self.FindTransfers()
+
+    # Find the ordering dependencies among transfers (this is O(n^2)
+    # in the number of transfers).
+    self.GenerateDigraph()
+    # Find a sequence of transfers that satisfies as many ordering
+    # dependencies as possible (heuristically).
+    self.FindVertexSequence()
+    # Fix up the ordering dependencies that the sequence didn't
+    # satisfy.
+    if self.version == 1:
+      self.RemoveBackwardEdges()
+    else:
+      self.ReverseBackwardEdges()
+      self.ImproveVertexSequence()
+
+    # Double-check our work.
+    self.AssertSequenceGood()
+
+    self.ComputePatches(prefix)
+    self.WriteTransfers(prefix)
+
+  def WriteTransfers(self, prefix):
+    out = []
+
+    total = 0
+    performs_read = False
+
+    stashes = {}
+    stashed_blocks = 0
+    max_stashed_blocks = 0
+
+    free_stash_ids = []
+    next_stash_id = 0
+
+    for xf in self.transfers:
+
+      if self.version < 2:
+        assert not xf.stash_before
+        assert not xf.use_stash
+
+      for s, sr in xf.stash_before:
+        assert s not in stashes
+        if free_stash_ids:
+          sid = heapq.heappop(free_stash_ids)
+        else:
+          sid = next_stash_id
+          next_stash_id += 1
+        stashes[s] = sid
+        stashed_blocks += sr.size()
+        out.append("stash %d %s\n" % (sid, sr.to_string_raw()))
+
+      if stashed_blocks > max_stashed_blocks:
+        max_stashed_blocks = stashed_blocks
+
+      if self.version == 1:
+        src_string = xf.src_ranges.to_string_raw()
+      elif self.version == 2:
+
+        #   <# blocks> <src ranges>
+        #     OR
+        #   <# blocks> <src ranges> <src locs> <stash refs...>
+        #     OR
+        #   <# blocks> - <stash refs...>
+
+        size = xf.src_ranges.size()
+        src_string = [str(size)]
+
+        unstashed_src_ranges = xf.src_ranges
+        mapped_stashes = []
+        for s, sr in xf.use_stash:
+          sid = stashes.pop(s)
+          stashed_blocks -= sr.size()
+          unstashed_src_ranges = unstashed_src_ranges.subtract(sr)
+          sr = xf.src_ranges.map_within(sr)
+          mapped_stashes.append(sr)
+          src_string.append("%d:%s" % (sid, sr.to_string_raw()))
+          heapq.heappush(free_stash_ids, sid)
+
+        if unstashed_src_ranges:
+          src_string.insert(1, unstashed_src_ranges.to_string_raw())
+          if xf.use_stash:
+            mapped_unstashed = xf.src_ranges.map_within(unstashed_src_ranges)
+            src_string.insert(2, mapped_unstashed.to_string_raw())
+            mapped_stashes.append(mapped_unstashed)
+            self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
+        else:
+          src_string.insert(1, "-")
+          self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
+
+        src_string = " ".join(src_string)
+
+      # both versions:
+      #   zero <rangeset>
+      #   new <rangeset>
+      #   erase <rangeset>
+      #
+      # version 1:
+      #   bsdiff patchstart patchlen <src rangeset> <tgt rangeset>
+      #   imgdiff patchstart patchlen <src rangeset> <tgt rangeset>
+      #   move <src rangeset> <tgt rangeset>
+      #
+      # version 2:
+      #   bsdiff patchstart patchlen <tgt rangeset> <src_string>
+      #   imgdiff patchstart patchlen <tgt rangeset> <src_string>
+      #   move <tgt rangeset> <src_string>
+
+      tgt_size = xf.tgt_ranges.size()
+
+      if xf.style == "new":
+        assert xf.tgt_ranges
+        out.append("%s %s\n" % (xf.style, xf.tgt_ranges.to_string_raw()))
+        total += tgt_size
+      elif xf.style == "move":
+        performs_read = True
+        assert xf.tgt_ranges
+        assert xf.src_ranges.size() == tgt_size
+        if xf.src_ranges != xf.tgt_ranges:
+          if self.version == 1:
+            out.append("%s %s %s\n" % (
+                xf.style,
+                xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw()))
+          elif self.version == 2:
+            out.append("%s %s %s\n" % (
+                xf.style,
+                xf.tgt_ranges.to_string_raw(), src_string))
+          total += tgt_size
+      elif xf.style in ("bsdiff", "imgdiff"):
+        performs_read = True
+        assert xf.tgt_ranges
+        assert xf.src_ranges
+        if self.version == 1:
+          out.append("%s %d %d %s %s\n" % (
+              xf.style, xf.patch_start, xf.patch_len,
+              xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw()))
+        elif self.version == 2:
+          out.append("%s %d %d %s %s\n" % (
+              xf.style, xf.patch_start, xf.patch_len,
+              xf.tgt_ranges.to_string_raw(), src_string))
+        total += tgt_size
+      elif xf.style == "zero":
+        assert xf.tgt_ranges
+        to_zero = xf.tgt_ranges.subtract(xf.src_ranges)
+        if to_zero:
+          out.append("%s %s\n" % (xf.style, to_zero.to_string_raw()))
+          total += to_zero.size()
+      else:
+        raise ValueError, "unknown transfer style '%s'\n" % (xf.style,)
+
+
+      # sanity check: abort if we're going to need more than 512 MB if
+      # stash space
+      assert max_stashed_blocks * self.tgt.blocksize < (512 << 20)
+
+    all_tgt = RangeSet(data=(0, self.tgt.total_blocks))
+    if performs_read:
+      # if some of the original data is used, then at the end we'll
+      # erase all the blocks on the partition that don't contain data
+      # in the new image.
+      new_dontcare = all_tgt.subtract(self.tgt.care_map)
+      if new_dontcare:
+        out.append("erase %s\n" % (new_dontcare.to_string_raw(),))
+    else:
+      # if nothing is read (ie, this is a full OTA), then we can start
+      # by erasing the entire partition.
+      out.insert(0, "erase %s\n" % (all_tgt.to_string_raw(),))
+
+    out.insert(0, "%d\n" % (self.version,))   # format version number
+    out.insert(1, str(total) + "\n")
+    if self.version >= 2:
+      # version 2 only: after the total block count, we give the number
+      # of stash slots needed, and the maximum size needed (in blocks)
+      out.insert(2, str(next_stash_id) + "\n")
+      out.insert(3, str(max_stashed_blocks) + "\n")
+
+    with open(prefix + ".transfer.list", "wb") as f:
+      for i in out:
+        f.write(i)
+
+    if self.version >= 2:
+      print("max stashed blocks: %d  (%d bytes)\n" % (
+          max_stashed_blocks, max_stashed_blocks * self.tgt.blocksize))
+
+  def ComputePatches(self, prefix):
+    print("Reticulating splines...")
+    diff_q = []
+    patch_num = 0
+    with open(prefix + ".new.dat", "wb") as new_f:
+      for xf in self.transfers:
+        if xf.style == "zero":
+          pass
+        elif xf.style == "new":
+          for piece in self.tgt.ReadRangeSet(xf.tgt_ranges):
+            new_f.write(piece)
+        elif xf.style == "diff":
+          src = self.src.ReadRangeSet(xf.src_ranges)
+          tgt = self.tgt.ReadRangeSet(xf.tgt_ranges)
+
+          # We can't compare src and tgt directly because they may have
+          # the same content but be broken up into blocks differently, eg:
+          #
+          #    ["he", "llo"]  vs  ["h", "ello"]
+          #
+          # We want those to compare equal, ideally without having to
+          # actually concatenate the strings (these may be tens of
+          # megabytes).
+
+          src_sha1 = sha1()
+          for p in src:
+            src_sha1.update(p)
+          tgt_sha1 = sha1()
+          tgt_size = 0
+          for p in tgt:
+            tgt_sha1.update(p)
+            tgt_size += len(p)
+
+          if src_sha1.digest() == tgt_sha1.digest():
+            # These are identical; we don't need to generate a patch,
+            # just issue copy commands on the device.
+            xf.style = "move"
+          else:
+            # For files in zip format (eg, APKs, JARs, etc.) we would
+            # like to use imgdiff -z if possible (because it usually
+            # produces significantly smaller patches than bsdiff).
+            # This is permissible if:
+            #
+            #  - the source and target files are monotonic (ie, the
+            #    data is stored with blocks in increasing order), and
+            #  - we haven't removed any blocks from the source set.
+            #
+            # If these conditions are satisfied then appending all the
+            # blocks in the set together in order will produce a valid
+            # zip file (plus possibly extra zeros in the last block),
+            # which is what imgdiff needs to operate.  (imgdiff is
+            # fine with extra zeros at the end of the file.)
+            imgdiff = (xf.intact and
+                       xf.tgt_name.split(".")[-1].lower()
+                       in ("apk", "jar", "zip"))
+            xf.style = "imgdiff" if imgdiff else "bsdiff"
+            diff_q.append((tgt_size, src, tgt, xf, patch_num))
+            patch_num += 1
+
+        else:
+          assert False, "unknown style " + xf.style
+
+    if diff_q:
+      if self.threads > 1:
+        print("Computing patches (using %d threads)..." % (self.threads,))
+      else:
+        print("Computing patches...")
+      diff_q.sort()
+
+      patches = [None] * patch_num
+
+      lock = threading.Lock()
+      def diff_worker():
+        while True:
+          with lock:
+            if not diff_q: return
+            tgt_size, src, tgt, xf, patchnum = diff_q.pop()
+          patch = compute_patch(src, tgt, imgdiff=(xf.style == "imgdiff"))
+          size = len(patch)
+          with lock:
+            patches[patchnum] = (patch, xf)
+            print("%10d %10d (%6.2f%%) %7s %s" % (
+                size, tgt_size, size * 100.0 / tgt_size, xf.style,
+                xf.tgt_name if xf.tgt_name == xf.src_name else (
+                    xf.tgt_name + " (from " + xf.src_name + ")")))
+
+      threads = [threading.Thread(target=diff_worker)
+                 for i in range(self.threads)]
+      for th in threads:
+        th.start()
+      while threads:
+        threads.pop().join()
+    else:
+      patches = []
+
+    p = 0
+    with open(prefix + ".patch.dat", "wb") as patch_f:
+      for patch, xf in patches:
+        xf.patch_start = p
+        xf.patch_len = len(patch)
+        patch_f.write(patch)
+        p += len(patch)
+
+  def AssertSequenceGood(self):
+    # Simulate the sequences of transfers we will output, and check that:
+    # - we never read a block after writing it, and
+    # - we write every block we care about exactly once.
+
+    # Start with no blocks having been touched yet.
+    touched = RangeSet()
+
+    # Imagine processing the transfers in order.
+    for xf in self.transfers:
+      # Check that the input blocks for this transfer haven't yet been touched.
+
+      x = xf.src_ranges
+      if self.version >= 2:
+        for _, sr in xf.use_stash:
+          x = x.subtract(sr)
+
+      assert not touched.overlaps(x)
+      # Check that the output blocks for this transfer haven't yet been touched.
+      assert not touched.overlaps(xf.tgt_ranges)
+      # Touch all the blocks written by this transfer.
+      touched = touched.union(xf.tgt_ranges)
+
+    # Check that we've written every target block.
+    assert touched == self.tgt.care_map
+
+  def ImproveVertexSequence(self):
+    print("Improving vertex order...")
+
+    # At this point our digraph is acyclic; we reversed any edges that
+    # were backwards in the heuristically-generated sequence.  The
+    # previously-generated order is still acceptable, but we hope to
+    # find a better order that needs less memory for stashed data.
+    # Now we do a topological sort to generate a new vertex order,
+    # using a greedy algorithm to choose which vertex goes next
+    # whenever we have a choice.
+
+    # Make a copy of the edge set; this copy will get destroyed by the
+    # algorithm.
+    for xf in self.transfers:
+      xf.incoming = xf.goes_after.copy()
+      xf.outgoing = xf.goes_before.copy()
+
+    L = []   # the new vertex order
+
+    # S is the set of sources in the remaining graph; we always choose
+    # the one that leaves the least amount of stashed data after it's
+    # executed.
+    S = [(u.NetStashChange(), u.order, u) for u in self.transfers
+         if not u.incoming]
+    heapq.heapify(S)
+
+    while S:
+      _, _, xf = heapq.heappop(S)
+      L.append(xf)
+      for u in xf.outgoing:
+        del u.incoming[xf]
+        if not u.incoming:
+          heapq.heappush(S, (u.NetStashChange(), u.order, u))
+
+    # if this fails then our graph had a cycle.
+    assert len(L) == len(self.transfers)
+
+    self.transfers = L
+    for i, xf in enumerate(L):
+      xf.order = i
+
+  def RemoveBackwardEdges(self):
+    print("Removing backward edges...")
+    in_order = 0
+    out_of_order = 0
+    lost_source = 0
+
+    for xf in self.transfers:
+      lost = 0
+      size = xf.src_ranges.size()
+      for u in xf.goes_before:
+        # xf should go before u
+        if xf.order < u.order:
+          # it does, hurray!
+          in_order += 1
+        else:
+          # it doesn't, boo.  trim the blocks that u writes from xf's
+          # source, so that xf can go after u.
+          out_of_order += 1
+          assert xf.src_ranges.overlaps(u.tgt_ranges)
+          xf.src_ranges = xf.src_ranges.subtract(u.tgt_ranges)
+          xf.intact = False
+
+      if xf.style == "diff" and not xf.src_ranges:
+        # nothing left to diff from; treat as new data
+        xf.style = "new"
+
+      lost = size - xf.src_ranges.size()
+      lost_source += lost
+
+    print(("  %d/%d dependencies (%.2f%%) were violated; "
+           "%d source blocks removed.") %
+          (out_of_order, in_order + out_of_order,
+           (out_of_order * 100.0 / (in_order + out_of_order))
+           if (in_order + out_of_order) else 0.0,
+           lost_source))
+
+  def ReverseBackwardEdges(self):
+    print("Reversing backward edges...")
+    in_order = 0
+    out_of_order = 0
+    stashes = 0
+    stash_size = 0
+
+    for xf in self.transfers:
+      lost = 0
+      size = xf.src_ranges.size()
+      for u in xf.goes_before.copy():
+        # xf should go before u
+        if xf.order < u.order:
+          # it does, hurray!
+          in_order += 1
+        else:
+          # it doesn't, boo.  modify u to stash the blocks that it
+          # writes that xf wants to read, and then require u to go
+          # before xf.
+          out_of_order += 1
+
+          overlap = xf.src_ranges.intersect(u.tgt_ranges)
+          assert overlap
+
+          u.stash_before.append((stashes, overlap))
+          xf.use_stash.append((stashes, overlap))
+          stashes += 1
+          stash_size += overlap.size()
+
+          # reverse the edge direction; now xf must go after u
+          del xf.goes_before[u]
+          del u.goes_after[xf]
+          xf.goes_after[u] = None    # value doesn't matter
+          u.goes_before[xf] = None
+
+    print(("  %d/%d dependencies (%.2f%%) were violated; "
+           "%d source blocks stashed.") %
+          (out_of_order, in_order + out_of_order,
+           (out_of_order * 100.0 / (in_order + out_of_order))
+           if (in_order + out_of_order) else 0.0,
+           stash_size))
+
+  def FindVertexSequence(self):
+    print("Finding vertex sequence...")
+
+    # This is based on "A Fast & Effective Heuristic for the Feedback
+    # Arc Set Problem" by P. Eades, X. Lin, and W.F. Smyth.  Think of
+    # it as starting with the digraph G and moving all the vertices to
+    # be on a horizontal line in some order, trying to minimize the
+    # number of edges that end up pointing to the left.  Left-pointing
+    # edges will get removed to turn the digraph into a DAG.  In this
+    # case each edge has a weight which is the number of source blocks
+    # we'll lose if that edge is removed; we try to minimize the total
+    # weight rather than just the number of edges.
+
+    # Make a copy of the edge set; this copy will get destroyed by the
+    # algorithm.
+    for xf in self.transfers:
+      xf.incoming = xf.goes_after.copy()
+      xf.outgoing = xf.goes_before.copy()
+
+    # We use an OrderedDict instead of just a set so that the output
+    # is repeatable; otherwise it would depend on the hash values of
+    # the transfer objects.
+    G = OrderedDict()
+    for xf in self.transfers:
+      G[xf] = None
+    s1 = deque()  # the left side of the sequence, built from left to right
+    s2 = deque()  # the right side of the sequence, built from right to left
+
+    while G:
+
+      # Put all sinks at the end of the sequence.
+      while True:
+        sinks = [u for u in G if not u.outgoing]
+        if not sinks: break
+        for u in sinks:
+          s2.appendleft(u)
+          del G[u]
+          for iu in u.incoming:
+            del iu.outgoing[u]
+
+      # Put all the sources at the beginning of the sequence.
+      while True:
+        sources = [u for u in G if not u.incoming]
+        if not sources: break
+        for u in sources:
+          s1.append(u)
+          del G[u]
+          for iu in u.outgoing:
+            del iu.incoming[u]
+
+      if not G: break
+
+      # Find the "best" vertex to put next.  "Best" is the one that
+      # maximizes the net difference in source blocks saved we get by
+      # pretending it's a source rather than a sink.
+
+      max_d = None
+      best_u = None
+      for u in G:
+        d = sum(u.outgoing.values()) - sum(u.incoming.values())
+        if best_u is None or d > max_d:
+          max_d = d
+          best_u = u
+
+      u = best_u
+      s1.append(u)
+      del G[u]
+      for iu in u.outgoing:
+        del iu.incoming[u]
+      for iu in u.incoming:
+        del iu.outgoing[u]
+
+    # Now record the sequence in the 'order' field of each transfer,
+    # and by rearranging self.transfers to be in the chosen sequence.
+
+    new_transfers = []
+    for x in itertools.chain(s1, s2):
+      x.order = len(new_transfers)
+      new_transfers.append(x)
+      del x.incoming
+      del x.outgoing
+
+    self.transfers = new_transfers
+
+  def GenerateDigraph(self):
+    print("Generating digraph...")
+    for a in self.transfers:
+      for b in self.transfers:
+        if a is b: continue
+
+        # If the blocks written by A are read by B, then B needs to go before A.
+        i = a.tgt_ranges.intersect(b.src_ranges)
+        if i:
+          if b.src_name == "__ZERO":
+            # the cost of removing source blocks for the __ZERO domain
+            # is (nearly) zero.
+            size = 0
+          else:
+            size = i.size()
+          b.goes_before[a] = size
+          a.goes_after[b] = size
+
+  def FindTransfers(self):
+    self.transfers = []
+    empty = RangeSet()
+    for tgt_fn, tgt_ranges in self.tgt.file_map.items():
+      if tgt_fn == "__ZERO":
+        # the special "__ZERO" domain is all the blocks not contained
+        # in any file and that are filled with zeros.  We have a
+        # special transfer style for zero blocks.
+        src_ranges = self.src.file_map.get("__ZERO", empty)
+        Transfer(tgt_fn, "__ZERO", tgt_ranges, src_ranges,
+                 "zero", self.transfers)
+        continue
+
+      elif tgt_fn in self.src.file_map:
+        # Look for an exact pathname match in the source.
+        Transfer(tgt_fn, tgt_fn, tgt_ranges, self.src.file_map[tgt_fn],
+                 "diff", self.transfers)
+        continue
+
+      b = os.path.basename(tgt_fn)
+      if b in self.src_basenames:
+        # Look for an exact basename match in the source.
+        src_fn = self.src_basenames[b]
+        Transfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
+                 "diff", self.transfers)
+        continue
+
+      b = re.sub("[0-9]+", "#", b)
+      if b in self.src_numpatterns:
+        # Look for a 'number pattern' match (a basename match after
+        # all runs of digits are replaced by "#").  (This is useful
+        # for .so files that contain version numbers in the filename
+        # that get bumped.)
+        src_fn = self.src_numpatterns[b]
+        Transfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
+                 "diff", self.transfers)
+        continue
+
+      Transfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
+
+  def AbbreviateSourceNames(self):
+    self.src_basenames = {}
+    self.src_numpatterns = {}
+
+    for k in self.src.file_map.keys():
+      b = os.path.basename(k)
+      self.src_basenames[b] = k
+      b = re.sub("[0-9]+", "#", b)
+      self.src_numpatterns[b] = k
+
+  @staticmethod
+  def AssertPartition(total, seq):
+    """Assert that all the RangeSets in 'seq' form a partition of the
+    'total' RangeSet (ie, they are nonintersecting and their union
+    equals 'total')."""
+    so_far = RangeSet()
+    for i in seq:
+      assert not so_far.overlaps(i)
+      so_far = so_far.union(i)
+    assert so_far == total
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index f8f2ada..55f0058 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -24,6 +24,11 @@
 import os.path
 import subprocess
 import sys
+import commands
+import shutil
+import tempfile
+
+FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
 
 def RunCommand(cmd):
   """ Echo and run the given command
@@ -38,13 +43,176 @@
   p.communicate()
   return p.returncode
 
-def BuildImage(in_dir, prop_dict, out_file):
+def GetVerityTreeSize(partition_size):
+  cmd = "build_verity_tree -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(sparse_image_path, verity_image_path, prop_dict):
+  cmd = ("build_verity_tree -A %s %s %s" % (FIXED_SALT, sparse_image_path, verity_image_path))
+  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"]
+  block_dev = prop_dict["verity_block_device"]
+  signer_key = prop_dict["verity_key"] + ".pk8"
+  signer_path = prop_dict["verity_signer_cmd"]
+
+  # make a tempdir
+  tempdir_name = tempfile.mkdtemp(suffix="_verity_images")
+
+  # 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")
+
+  # build the verity tree and get the root hash and salt
+  if not BuildVerityTree(out_file, verity_image_path, prop_dict):
+    shutil.rmtree(tempdir_name, ignore_errors=True)
+    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, ignore_errors=True)
+    return False
+
+  # build the full verified image
+  if not BuildVerifiedImage(out_file,
+                            verity_image_path,
+                            verity_metadata_path):
+    shutil.rmtree(tempdir_name, ignore_errors=True)
+    return False
+
+  shutil.rmtree(tempdir_name, ignore_errors=True)
+  return True
+
+def BuildImage(in_dir, prop_dict, out_file,
+               fs_config=None,
+               fc_config=None,
+               block_list=None):
   """Build an image to out_file from in_dir with property prop_dict.
 
   Args:
     in_dir: path of input directory.
     prop_dict: property dictionary.
     out_file: path of the output image file.
+    fs_config: path to the fs_config file (typically
+      META/filesystem_config.txt).  If None then the configuration in
+      the local client will be used.
+    fc_config: path to the SELinux file_contexts file.  If None then
+      the value from prop_dict['selinux_fc'] will be used.
 
   Returns:
     True iff the image is built successfully.
@@ -52,6 +220,18 @@
   build_command = []
   fs_type = prop_dict.get("fs_type", "")
   run_fsck = False
+
+  is_verity_partition = "verity_block_device" in prop_dict
+  verity_supported = prop_dict.get("verity") == "true"
+  # adjust the partition size to make room for the hashes if this is to be verified
+  if verity_supported and is_verity_partition:
+    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,10 +239,31 @@
       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"])
-    if "selinux_fc" in prop_dict:
+    build_command.append(prop_dict["partition_size"])
+    if "journal_size" in prop_dict:
+      build_command.extend(["-j", prop_dict["journal_size"]])
+    if "timestamp" in prop_dict:
+      build_command.extend(["-T", str(prop_dict["timestamp"])])
+    if fs_config is not None:
+      build_command.extend(["-C", fs_config])
+    if block_list is not None:
+      build_command.extend(["-B", block_list])
+    build_command.extend(["-L", prop_dict["mount_point"]])
+    if fc_config is not None:
+      build_command.append(fc_config)
+    elif "selinux_fc" in prop_dict:
       build_command.append(prop_dict["selinux_fc"])
+  elif fs_type.startswith("squash"):
+    build_command = ["mksquashfsimage.sh"]
+    build_command.extend([in_dir, out_file])
+    build_command.extend(["-m", prop_dict["mount_point"]])
+    if fc_config is not None:
+      build_command.extend(["-c", fc_config])
+    elif "selinux_fc" in prop_dict:
+      build_command.extend(["-c", prop_dict["selinux_fc"]])
+  elif fs_type.startswith("f2fs"):
+    build_command = ["mkf2fsuserimg.sh"]
+    build_command.extend([out_file, prop_dict["partition_size"]])
   else:
     build_command = ["mkyaffs2image", "-f"]
     if prop_dict.get("mkyaffs2_extra_flags", None):
@@ -77,14 +278,14 @@
   if exit_code != 0:
     return False
 
+  # create the verified image if this is to be verified
+  if verity_supported and is_verity_partition:
+    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 +305,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 +319,9 @@
       "mkyaffs2_extra_flags",
       "selinux_fc",
       "skip_fsck",
+      "verity",
+      "verity_key",
+      "verity_signer_cmd"
       )
   for p in common_props:
     copy_prop(p, p)
@@ -121,9 +329,15 @@
   d["mount_point"] = mount_point
   if mount_point == "system":
     copy_prop("fs_type", "fs_type")
+    # Copy the generic sysetem fs type first, override with specific one if available.
+    copy_prop("system_fs_type", "fs_type")
     copy_prop("system_size", "partition_size")
+    copy_prop("system_journal_size", "journal_size")
+    copy_prop("system_verity_block_device", "verity_block_device")
   elif mount_point == "data":
+    # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
+    copy_prop("userdata_fs_type", "fs_type")
     copy_prop("userdata_size", "partition_size")
   elif mount_point == "cache":
     copy_prop("cache_fs_type", "fs_type")
@@ -131,6 +345,12 @@
   elif mount_point == "vendor":
     copy_prop("vendor_fs_type", "fs_type")
     copy_prop("vendor_size", "partition_size")
+    copy_prop("vendor_journal_size", "journal_size")
+    copy_prop("vendor_verity_block_device", "verity_block_device")
+  elif mount_point == "oem":
+    copy_prop("fs_type", "fs_type")
+    copy_prop("oem_size", "partition_size")
+    copy_prop("oem_journal_size", "journal_size")
 
   return d
 
@@ -169,6 +389,8 @@
     mount_point = "cache"
   elif image_filename == "vendor.img":
     mount_point = "vendor"
+  elif image_filename == "oem.img":
+    mount_point = "oem"
   else:
     print >> sys.stderr, "error: unknown image file name ", image_filename
     exit(1)
diff --git a/tools/releasetools/check_target_files_signatures b/tools/releasetools/check_target_files_signatures
index 45d30a6..b2f46c1 100755
--- a/tools/releasetools/check_target_files_signatures
+++ b/tools/releasetools/check_target_files_signatures
@@ -41,8 +41,8 @@
 
 import sys
 
-if sys.hexversion < 0x02040000:
-  print >> sys.stderr, "Python 2.4 or newer is required."
+if sys.hexversion < 0x02070000:
+  print >> sys.stderr, "Python 2.7 or newer is required."
   sys.exit(1)
 
 import os
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index f179717..8941f89 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -29,6 +29,9 @@
 import time
 import zipfile
 
+import blockimgdiff
+from rangelib import *
+
 try:
   from hashlib import sha1 as sha1
 except ImportError:
@@ -40,10 +43,17 @@
 
 class Options(object): pass
 OPTIONS = Options()
-OPTIONS.search_path = "out/host/linux-x86"
+
+DEFAULT_SEARCH_PATH_BY_PLATFORM = {
+    "linux2": "out/host/linux-x86",
+    "darwin": "out/host/darwin-x86",
+    }
+OPTIONS.search_path = DEFAULT_SEARCH_PATH_BY_PLATFORM.get(sys.platform, None)
+
 OPTIONS.signapk_path = "framework/signapk.jar"  # Relative to search_path
 OPTIONS.extra_signapk_args = []
 OPTIONS.java_path = "java"  # Use the one on the path by default.
+OPTIONS.java_args = "-Xmx2048m" # JVM Args
 OPTIONS.public_key_suffix = ".x509.pem"
 OPTIONS.private_key_suffix = ".pk8"
 OPTIONS.verbose = False
@@ -84,17 +94,24 @@
       pass
 
 
-def LoadInfoDict(zip):
+def LoadInfoDict(input):
   """Read and parse the META/misc_info.txt key/value pairs from the
   input target files and return a dict."""
 
+  def read_helper(fn):
+    if isinstance(input, zipfile.ZipFile):
+      return input.read(fn)
+    else:
+      path = os.path.join(input, *fn.split("/"))
+      try:
+        with open(path) as f:
+          return f.read()
+      except IOError, e:
+        if e.errno == errno.ENOENT:
+          raise KeyError(fn)
   d = {}
   try:
-    for line in zip.read("META/misc_info.txt").split("\n"):
-      line = line.strip()
-      if not line or line.startswith("#"): continue
-      k, v = line.split("=", 1)
-      d[k] = v
+    d = LoadDictionaryFromLines(read_helper("META/misc_info.txt").split("\n"))
   except KeyError:
     # ok if misc_info.txt doesn't exist
     pass
@@ -105,20 +122,20 @@
 
   if "mkyaffs2_extra_flags" not in d:
     try:
-      d["mkyaffs2_extra_flags"] = zip.read("META/mkyaffs2-extra-flags.txt").strip()
+      d["mkyaffs2_extra_flags"] = read_helper("META/mkyaffs2-extra-flags.txt").strip()
     except KeyError:
       # ok if flags don't exist
       pass
 
   if "recovery_api_version" not in d:
     try:
-      d["recovery_api_version"] = zip.read("META/recovery-api-version.txt").strip()
+      d["recovery_api_version"] = read_helper("META/recovery-api-version.txt").strip()
     except KeyError:
       raise ValueError("can't find recovery API version in input target-files")
 
   if "tool_extensions" not in d:
     try:
-      d["tool_extensions"] = zip.read("META/tool-extensions.txt").strip()
+      d["tool_extensions"] = read_helper("META/tool-extensions.txt").strip()
     except KeyError:
       # ok if extensions don't exist
       pass
@@ -127,7 +144,7 @@
     d["fstab_version"] = "1"
 
   try:
-    data = zip.read("META/imagesizes.txt")
+    data = read_helper("META/imagesizes.txt")
     for line in data.split("\n"):
       if not line: continue
       name, value = line.split(" ", 1)
@@ -146,39 +163,43 @@
   makeint("recovery_api_version")
   makeint("blocksize")
   makeint("system_size")
+  makeint("vendor_size")
   makeint("userdata_size")
   makeint("cache_size")
   makeint("recovery_size")
   makeint("boot_size")
   makeint("fstab_version")
 
-  d["fstab"] = LoadRecoveryFSTab(zip, d["fstab_version"])
-  d["build.prop"] = LoadBuildProp(zip)
+  d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"])
+  d["build.prop"] = LoadBuildProp(read_helper)
   return d
 
-def LoadBuildProp(zip):
+def LoadBuildProp(read_helper):
   try:
-    data = zip.read("SYSTEM/build.prop")
+    data = read_helper("SYSTEM/build.prop")
   except KeyError:
     print "Warning: could not find SYSTEM/build.prop in %s" % zip
     data = ""
+  return LoadDictionaryFromLines(data.split("\n"))
 
+def LoadDictionaryFromLines(lines):
   d = {}
-  for line in data.split("\n"):
+  for line in lines:
     line = line.strip()
     if not line or line.startswith("#"): continue
-    name, value = line.split("=", 1)
-    d[name] = value
+    if "=" in line:
+      name, value = line.split("=", 1)
+      d[name] = value
   return d
 
-def LoadRecoveryFSTab(zip, fstab_version):
+def LoadRecoveryFSTab(read_helper, fstab_version):
   class Partition(object):
     pass
 
   try:
-    data = zip.read("RECOVERY/RAMDISK/etc/recovery.fstab")
+    data = read_helper("RECOVERY/RAMDISK/etc/recovery.fstab")
   except KeyError:
-    print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab in %s." % zip
+    print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab"
     data = ""
 
   if fstab_version == 1:
@@ -292,6 +313,11 @@
 
   cmd = [mkbootimg, "--kernel", os.path.join(sourcedir, "kernel")]
 
+  fn = os.path.join(sourcedir, "second")
+  if os.access(fn, os.F_OK):
+    cmd.append("--second")
+    cmd.append(fn)
+
   fn = os.path.join(sourcedir, "cmdline")
   if os.access(fn, os.F_OK):
     cmd.append("--cmdline")
@@ -319,6 +345,13 @@
   assert p.returncode == 0, "mkbootimg of %s image failed" % (
       os.path.basename(sourcedir),)
 
+  if info_dict.get("verity_key", None):
+    path = "/" + os.path.basename(sourcedir).lower()
+    cmd = ["boot_signer", path, img.name, info_dict["verity_key"] + ".pk8", info_dict["verity_key"] + ".x509.pem", img.name]
+    p = Run(cmd, stdout=subprocess.PIPE)
+    p.communicate()
+    assert p.returncode == 0, "boot_signer of %s image failed" % path
+
   img.seek(os.SEEK_SET, 0)
   data = img.read()
 
@@ -332,19 +365,28 @@
                      info_dict=None):
   """Return a File object (with name 'name') with the desired bootable
   image.  Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name
-  'prebuilt_name', otherwise construct it from the source files in
+  'prebuilt_name', otherwise look for it under 'unpack_dir'/IMAGES,
+  otherwise construct it from the source files in
   'unpack_dir'/'tree_subdir'."""
 
   prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name)
   if os.path.exists(prebuilt_path):
-    print "using prebuilt %s..." % (prebuilt_name,)
+    print "using prebuilt %s from BOOTABLE_IMAGES..." % (prebuilt_name,)
     return File.FromLocalFile(name, prebuilt_path)
-  else:
-    print "building image from target_files %s..." % (tree_subdir,)
-    fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
-    return File(name, BuildBootableImage(os.path.join(unpack_dir, tree_subdir),
-                                         os.path.join(unpack_dir, fs_config),
-                                         info_dict))
+
+  prebuilt_path = os.path.join(unpack_dir, "IMAGES", prebuilt_name)
+  if os.path.exists(prebuilt_path):
+    print "using prebuilt %s from IMAGES..." % (prebuilt_name,)
+    return File.FromLocalFile(name, prebuilt_path)
+
+  print "building image from target_files %s..." % (tree_subdir,)
+  fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
+  data = BuildBootableImage(os.path.join(unpack_dir, tree_subdir),
+                            os.path.join(unpack_dir, fs_config),
+                            info_dict)
+  if data:
+    return File(name, data)
+  return None
 
 
 def UnzipTemp(filename, pattern=None):
@@ -453,7 +495,7 @@
   else:
     sign_name = output_name
 
-  cmd = [OPTIONS.java_path, "-Xmx2048m", "-jar",
+  cmd = [OPTIONS.java_path, OPTIONS.java_args, "-jar",
          os.path.join(OPTIONS.search_path, OPTIONS.signapk_path)]
   cmd.extend(OPTIONS.extra_signapk_args)
   if whole_file:
@@ -485,6 +527,8 @@
   if target.endswith(".img"): target = target[:-4]
   mount_point = "/" + target
 
+  fs_type = None
+  limit = None
   if info_dict["fstab"]:
     if mount_point == "/userdata": mount_point = "/data"
     p = info_dict["fstab"][mount_point]
@@ -575,8 +619,8 @@
     opts, args = getopt.getopt(
         argv, "hvp:s:x:" + extra_opts,
         ["help", "verbose", "path=", "signapk_path=", "extra_signapk_args=",
-         "java_path=", "public_key_suffix=", "private_key_suffix=",
-         "device_specific=", "extra="] +
+         "java_path=", "java_args=", "public_key_suffix=",
+         "private_key_suffix=", "device_specific=", "extra="] +
         list(extra_long_opts))
   except getopt.GetoptError, err:
     Usage(docstring)
@@ -599,6 +643,8 @@
       OPTIONS.extra_signapk_args = shlex.split(a)
     elif o in ("--java_path",):
       OPTIONS.java_path = a
+    elif o in ("--java_args",):
+      OPTIONS.java_args = a
     elif o in ("--public_key_suffix",):
       OPTIONS.public_key_suffix = a
     elif o in ("--private_key_suffix",):
@@ -612,12 +658,22 @@
       if extra_option_handler is None or not extra_option_handler(o, a):
         assert False, "unknown option \"%s\"" % (o,)
 
-  os.environ["PATH"] = (os.path.join(OPTIONS.search_path, "bin") +
-                        os.pathsep + os.environ["PATH"])
+  if OPTIONS.search_path:
+    os.environ["PATH"] = (os.path.join(OPTIONS.search_path, "bin") +
+                          os.pathsep + os.environ["PATH"])
 
   return args
 
 
+def MakeTempFile(prefix=None, suffix=None):
+  """Make a temp file and add it to the list of things to be deleted
+  when Cleanup() is called.  Return the filename."""
+  fd, fn = tempfile.mkstemp(prefix=prefix, suffix=suffix)
+  os.close(fd)
+  OPTIONS.tempfiles.append(fn)
+  return fn
+
+
 def Cleanup():
   for i in OPTIONS.tempfiles:
     if os.path.isdir(i):
@@ -725,11 +781,14 @@
     return result
 
 
-def ZipWriteStr(zip, filename, data, perms=0644):
+def ZipWriteStr(zip, filename, data, perms=0644, compression=None):
   # use a fixed timestamp so the output is repeatable.
   zinfo = zipfile.ZipInfo(filename=filename,
                           date_time=(2009, 1, 1, 0, 0, 0))
-  zinfo.compress_type = zip.compression
+  if compression is None:
+    zinfo.compress_type = zip.compression
+  else:
+    zinfo.compress_type = compression
   zinfo.external_attr = perms << 16
   zip.writestr(zinfo, data)
 
@@ -756,6 +815,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"
@@ -834,8 +894,8 @@
     t.flush()
     return t
 
-  def AddToZip(self, z):
-    ZipWriteStr(z, self.name, self.data)
+  def AddToZip(self, z, compression=None):
+    ZipWriteStr(z, self.name, self.data, compression=compression)
 
 DIFF_PROGRAM_BY_EXT = {
     ".gz" : "imgdiff",
@@ -880,10 +940,26 @@
       cmd.append(ttemp.name)
       cmd.append(ptemp.name)
       p = Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-      _, err = p.communicate()
+      err = []
+      def run():
+        _, e = p.communicate()
+        if e: err.append(e)
+      th = threading.Thread(target=run)
+      th.start()
+      th.join(timeout=300)   # 5 mins
+      if th.is_alive():
+        print "WARNING: diff command timed out"
+        p.terminate()
+        th.join(5)
+        if th.is_alive():
+          p.kill()
+          th.join()
+
       if err or p.returncode != 0:
-        print "WARNING: failure running %s:\n%s\n" % (diff_program, err)
-        return None
+        print "WARNING: failure running %s:\n%s\n" % (
+            diff_program, "".join(err))
+        self.patch = None
+        return None, None, None
       diff = ptemp.read()
     finally:
       ptemp.close()
@@ -947,9 +1023,92 @@
     threads.pop().join()
 
 
+class BlockDifference:
+  def __init__(self, partition, tgt, src=None, check_first_block=False):
+    self.tgt = tgt
+    self.src = src
+    self.partition = partition
+    self.check_first_block = check_first_block
+
+    version = 1
+    if OPTIONS.info_dict:
+      version = max(
+          int(i) for i in
+          OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+
+    b = blockimgdiff.BlockImageDiff(tgt, src, threads=OPTIONS.worker_threads,
+                                    version=version)
+    tmpdir = tempfile.mkdtemp()
+    OPTIONS.tempfiles.append(tmpdir)
+    self.path = os.path.join(tmpdir, partition)
+    b.Compute(self.path)
+
+    _, self.device = GetTypeAndDevice("/" + partition, OPTIONS.info_dict)
+
+  def WriteScript(self, script, output_zip, progress=None):
+    if not self.src:
+      # write the output unconditionally
+      script.Print("Patching %s image unconditionally..." % (self.partition,))
+    else:
+      script.Print("Patching %s image after verification." % (self.partition,))
+
+    if progress: script.ShowProgress(progress, 0)
+    self._WriteUpdate(script, output_zip)
+
+  def WriteVerifyScript(self, script):
+    if not self.src:
+      script.Print("Image %s will be patched unconditionally." % (self.partition,))
+    else:
+      if self.check_first_block:
+        self._CheckFirstBlock(script)
+
+      script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' %
+                         (self.device, self.src.care_map.to_string_raw(),
+                          self.src.TotalSha1()))
+      script.Print("Verified %s image..." % (self.partition,))
+      script.AppendExtra(('else\n'
+                          '  (range_sha1("%s", "%s") == "%s") ||\n'
+                          '  abort("%s partition has unexpected contents");\n'
+                          'endif;') %
+                         (self.device, self.tgt.care_map.to_string_raw(),
+                          self.tgt.TotalSha1(), self.partition))
+
+  def _WriteUpdate(self, script, output_zip):
+    partition = self.partition
+    with open(self.path + ".transfer.list", "rb") as f:
+      ZipWriteStr(output_zip, partition + ".transfer.list", f.read())
+    with open(self.path + ".new.dat", "rb") as f:
+      ZipWriteStr(output_zip, partition + ".new.dat", f.read())
+    with open(self.path + ".patch.dat", "rb") as f:
+      ZipWriteStr(output_zip, partition + ".patch.dat", f.read(),
+                         compression=zipfile.ZIP_STORED)
+
+    call = (('block_image_update("%s", '
+             'package_extract_file("%s.transfer.list"), '
+             '"%s.new.dat", "%s.patch.dat");\n') %
+            (self.device, partition, partition, partition))
+    script.AppendExtra(script._WordWrap(call))
+
+  def _CheckFirstBlock(self, script):
+    r = RangeSet((0, 1))
+    h = sha1()
+    for data in self.src.ReadRangeSet(r):
+      h.update(data)
+    h = h.hexdigest()
+
+    script.AppendExtra(('(range_sha1("%s", "%s") == "%s") || '
+                        'abort("%s has been remounted R/W; '
+                        'reflash device to reenable OTA updates");')
+                       % (self.device, r.to_string_raw(), h, self.device))
+
+
+DataImage = blockimgdiff.DataImage
+
+
 # map recovery.fstab's fs_types to mount/format "partition types"
 PARTITION_TYPES = { "yaffs2": "MTD", "mtd": "MTD",
-                    "ext4": "EMMC", "emmc": "EMMC" }
+                    "ext4": "EMMC", "emmc": "EMMC",
+                    "f2fs": "EMMC" }
 
 def GetTypeAndDevice(mount_point, info):
   fstab = info["fstab"]
@@ -972,3 +1131,76 @@
       save = True
   cert = "".join(cert).decode('base64')
   return cert
+
+def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
+                      info_dict=None):
+  """Generate a binary patch that creates the recovery image starting
+  with the boot image.  (Most of the space in these images is just the
+  kernel, which is identical for the two, so the resulting patch
+  should be efficient.)  Add it to the output zip, along with a shell
+  script that is run from init.rc on first boot to actually do the
+  patching and install the new recovery image.
+
+  recovery_img and boot_img should be File objects for the
+  corresponding images.  info should be the dictionary returned by
+  common.LoadInfoDict() on the input target_files.
+  """
+
+  if info_dict is None:
+    info_dict = OPTIONS.info_dict
+
+  diff_program = ["imgdiff"]
+  path = os.path.join(input_dir, "SYSTEM", "etc", "recovery-resource.dat")
+  if os.path.exists(path):
+    diff_program.append("-b")
+    diff_program.append(path)
+    bonus_args = "-b /system/etc/recovery-resource.dat"
+  else:
+    bonus_args = ""
+
+  d = Difference(recovery_img, boot_img, diff_program=diff_program)
+  _, _, patch = d.ComputePatch()
+  output_sink("recovery-from-boot.p", patch)
+
+  td_pair = GetTypeAndDevice("/boot", info_dict)
+  if not td_pair:
+    return
+  boot_type, boot_device = td_pair
+  td_pair = GetTypeAndDevice("/recovery", info_dict)
+  if not td_pair:
+    return
+  recovery_type, recovery_device = td_pair
+
+  sh = """#!/system/bin/sh
+if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
+  applypatch %(bonus_args)s %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s %(recovery_type)s:%(recovery_device)s %(recovery_sha1)s %(recovery_size)d %(boot_sha1)s:/system/recovery-from-boot.p && log -t recovery "Installing new recovery image: succeeded" || log -t recovery "Installing new recovery image: failed"
+else
+  log -t recovery "Recovery image already installed"
+fi
+""" % { 'boot_size': boot_img.size,
+        'boot_sha1': boot_img.sha1,
+        'recovery_size': recovery_img.size,
+        'recovery_sha1': recovery_img.sha1,
+        'boot_type': boot_type,
+        'boot_device': boot_device,
+        'recovery_type': recovery_type,
+        'recovery_device': recovery_device,
+        'bonus_args': bonus_args,
+        }
+
+  # The install script location moved from /system/etc to /system/bin
+  # in the L release.  Parse the init.rc file to find out where the
+  # target-files expects it to be, and put it there.
+  sh_location = "etc/install-recovery.sh"
+  try:
+    with open(os.path.join(input_dir, "BOOT", "RAMDISK", "init.rc")) as f:
+      for line in f:
+        m = re.match("^service flash_recovery /system/(\S+)\s*$", line)
+        if m:
+          sh_location = m.group(1)
+          print "putting script in", sh_location
+          break
+  except (OSError, IOError), e:
+    print "failed to read init.rc: %s" % (e,)
+
+  output_sink(sh_location, sh)
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 426b713..e52c264 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -68,19 +68,43 @@
     with temporary=True) to this one."""
     self.script.extend(other.script)
 
+  def AssertOemProperty(self, name, value):
+    """Assert that a property on the OEM paritition matches a value."""
+    if not name:
+      raise ValueError("must specify an OEM property")
+    if not value:
+      raise ValueError("must specify the OEM value")
+    cmd = ('file_getprop("/oem/oem.prop", "%s") == "%s" || '
+           'abort("This package expects the value \\"%s\\"  for '
+           '\\"%s\\" on the OEM partition; '
+           'this has value \\"" + file_getprop("/oem/oem.prop") + "\\".");'
+           ) % (name, value, name, value)
+    self.script.append(cmd)
+
   def AssertSomeFingerprint(self, *fp):
-    """Assert that the current system build fingerprint is one of *fp."""
+    """Assert that the current recovery build fingerprint is one of *fp."""
     if not fp:
       raise ValueError("must specify some fingerprints")
     cmd = (
-           ' ||\n    '.join([('file_getprop("/system/build.prop", '
-                         '"ro.build.fingerprint") == "%s"')
+           ' ||\n    '.join([('getprop("ro.build.fingerprint") == "%s"')
                         % i for i in fp]) +
            ' ||\n    abort("Package expects build fingerprint of %s; this '
            'device has " + getprop("ro.build.fingerprint") + ".");'
            ) % (" or ".join(fp),)
     self.script.append(cmd)
 
+  def AssertSomeThumbprint(self, *fp):
+    """Assert that the current recovery build thumbprint is one of *fp."""
+    if not fp:
+      raise ValueError("must specify some thumbprints")
+    cmd = (
+           ' ||\n    '.join([('getprop("ro.build.thumbprint") == "%s"')
+                        % i for i in fp]) +
+           ' ||\n    abort("Package expects build thumbprint of %s; this '
+           'device has " + getprop("ro.build.thumbprint") + ".");'
+           ) % (" or ".join(fp),)
+    self.script.append(cmd)
+
   def AssertOlderBuild(self, timestamp, timestamp_text):
     """Assert that the build on the device is older (or the same as)
     the given timestamp."""
@@ -140,14 +164,25 @@
     self.script.append(('apply_patch_space(%d) || abort("Not enough free space '
                         'on /system to apply patches.");') % (amount,))
 
-  def Mount(self, mount_point):
-    """Mount the partition with the given mount_point."""
+  def Mount(self, mount_point, mount_options_by_format=""):
+    """Mount the partition with the given mount_point.
+      mount_options_by_format:
+      [fs_type=option[,option]...[|fs_type=option[,option]...]...]
+      where option is optname[=optvalue]
+      E.g. ext4=barrier=1,nodelalloc,errors=panic|f2fs=errors=recover
+    """
     fstab = self.info.get("fstab", None)
     if fstab:
       p = fstab[mount_point]
-      self.script.append('mount("%s", "%s", "%s", "%s");' %
+      mount_dict = {}
+      if mount_options_by_format is not None:
+        for option in mount_options_by_format.split("|"):
+          if "=" in option:
+            key, value = option.split("=", 1)
+            mount_dict[key] = value
+      self.script.append('mount("%s", "%s", "%s", "%s", "%s");' %
                          (p.fs_type, common.PARTITION_TYPES[p.fs_type],
-                          p.device, p.mount_point))
+                          p.device, p.mount_point, mount_dict.get(p.fs_type, "")))
       self.mounts.add(p.mount_point)
 
   def UnpackPackageDir(self, src, dst):
@@ -166,6 +201,17 @@
     """Log a message to the screen (if the logs are visible)."""
     self.script.append('ui_print("%s");' % (message,))
 
+  def TunePartition(self, partition, *options):
+    fstab = self.info.get("fstab", None)
+    if fstab:
+      p = fstab[partition]
+      if (p.fs_type not in ( "ext2", "ext3", "ext4")):
+        raise ValueError("Partition %s cannot be tuned\n" % (partition,))
+    self.script.append('tune2fs(' +
+                       "".join(['"%s", ' % (i,) for i in options]) +
+                       '"%s") || abort("Failed to tune partition %s");'
+                       % ( p.device,partition));
+
   def FormatPartition(self, partition):
     """Format the given partition, specified by its mount point (eg,
     "/system")."""
@@ -178,6 +224,15 @@
                          (p.fs_type, common.PARTITION_TYPES[p.fs_type],
                           p.device, p.length, p.mount_point))
 
+  def WipeBlockDevice(self, partition):
+    if partition not in ("/system", "/vendor"):
+      raise ValueError(("WipeBlockDevice doesn't work on %s\n") % (partition,))
+    fstab = self.info.get("fstab", None)
+    size = self.info.get(partition.lstrip("/") + "_size", None)
+    device = fstab[partition].device
+
+    self.script.append('wipe_block_device("%s", %s);' % (device, size))
+
   def DeleteFiles(self, file_list):
     """Delete all files in file_list."""
     if not file_list: return
@@ -212,7 +267,7 @@
     cmd = "".join(cmd)
     self.script.append(self._WordWrap(cmd))
 
-  def WriteRawImage(self, mount_point, fn):
+  def WriteRawImage(self, mount_point, fn, mapfn=None):
     """Write the given package file into the partition for the given
     mount point."""
 
@@ -226,8 +281,13 @@
             'write_raw_image(package_extract_file("%(fn)s"), "%(device)s");'
             % args)
       elif partition_type == "EMMC":
-        self.script.append(
-            'package_extract_file("%(fn)s", "%(device)s");' % args)
+        if mapfn:
+          args["map"] = mapfn
+          self.script.append(
+              'package_extract_file("%(fn)s", "%(device)s", "%(map)s");' % args)
+        else:
+          self.script.append(
+              'package_extract_file("%(fn)s", "%(device)s");' % args)
       else:
         raise ValueError("don't know how to write \"%s\" partitions" % (p.fs_type,))
 
@@ -274,6 +334,10 @@
     """Append text verbatim to the output script."""
     self.script.append(extra)
 
+  def Unmount(self, mount_point):
+    self.script.append('unmount("%s");' % (mount_point,))
+    self.mounts.remove(mount_point);
+
   def UnmountAll(self):
     for p in sorted(self.mounts):
       self.script.append('unmount("%s");' % (p,))
@@ -293,6 +357,6 @@
     if input_path is None:
       data = input_zip.read("OTA/bin/updater")
     else:
-      data = open(os.path.join(input_path, "updater")).read()
+      data = open(input_path, "rb").read()
     common.ZipWriteStr(output_zip, "META-INF/com/google/android/update-binary",
                        data, perms=0755)
diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files
deleted file mode 100755
index e894c42..0000000
--- a/tools/releasetools/img_from_target_files
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2008 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.
-
-"""
-Given a target-files zipfile, produces an image zipfile suitable for
-use with 'fastboot update'.
-
-Usage:  img_from_target_files [flags] input_target_files output_image_zip
-
-  -b  (--board_config)  <file>
-      Deprecated.
-
-  -z  (--bootable_zip)
-      Include only the bootable images (eg 'boot' and 'recovery') in
-      the output.
-
-"""
-
-import sys
-
-if sys.hexversion < 0x02040000:
-  print >> sys.stderr, "Python 2.4 or newer is required."
-  sys.exit(1)
-
-import errno
-import os
-import re
-import shutil
-import subprocess
-import tempfile
-import zipfile
-
-# missing in Python 2.4 and before
-if not hasattr(os, "SEEK_SET"):
-  os.SEEK_SET = 0
-
-import build_image
-import common
-
-OPTIONS = common.OPTIONS
-
-
-def AddSystem(output_zip):
-  """Turn the contents of SYSTEM into a system image and store it in
-  output_zip."""
-
-  print "creating system.img..."
-
-  img = tempfile.NamedTemporaryFile()
-
-  # The name of the directory it is making an image out of matters to
-  # mkyaffs2image.  It wants "system" but we have a directory named
-  # "SYSTEM", so create a symlink.
-  try:
-    os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
-               os.path.join(OPTIONS.input_tmp, "system"))
-  except OSError, e:
-      # bogus error on my mac version?
-      #   File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
-      #     os.path.join(OPTIONS.input_tmp, "system"))
-      # OSError: [Errno 17] File exists
-    if (e.errno == errno.EEXIST):
-      pass
-
-  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
-                                                    "system")
-  fstab = OPTIONS.info_dict["fstab"]
-  if fstab:
-    image_props["fs_type" ] = fstab["/system"].fs_type
-  succ = build_image.BuildImage(os.path.join(OPTIONS.input_tmp, "system"),
-                                image_props, img.name)
-  assert succ, "build system.img image failed"
-
-  img.seek(os.SEEK_SET, 0)
-  data = img.read()
-  img.close()
-
-  common.CheckSize(data, "system.img", OPTIONS.info_dict)
-  common.ZipWriteStr(output_zip, "system.img", data)
-
-
-def AddVendor(output_zip):
-  """Turn the contents of VENDOR into vendor.img and store it in
-  output_zip."""
-
-  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
-                                                    "vendor")
-  # The build system has to explicitly request for vendor.img.
-  if "fs_type" not in image_props:
-    return
-
-  print "creating vendor.img..."
-
-  img = tempfile.NamedTemporaryFile()
-
-  # The name of the directory it is making an image out of matters to
-  # mkyaffs2image.  It wants "vendor" but we have a directory named
-  # "VENDOR", so create a symlink or an empty directory if VENDOR does not
-  # exist.
-  if not os.path.exists(os.path.join(OPTIONS.input_tmp, "vendor")):
-    if os.path.exists(os.path.join(OPTIONS.input_tmp, "VENDOR")):
-      os.symlink(os.path.join(OPTIONS.input_tmp, "VENDOR"),
-                 os.path.join(OPTIONS.input_tmp, "vendor"))
-    else:
-      os.mkdir(os.path.join(OPTIONS.input_tmp, "vendor"))
-
-  img = tempfile.NamedTemporaryFile()
-
-  fstab = OPTIONS.info_dict["fstab"]
-  if fstab:
-    image_props["fs_type" ] = fstab["/vendor"].fs_type
-  succ = build_image.BuildImage(os.path.join(OPTIONS.input_tmp, "vendor"),
-                                image_props, img.name)
-  assert succ, "build vendor.img image failed"
-
-  common.CheckSize(img.name, "vendor.img", OPTIONS.info_dict)
-  output_zip.write(img.name, "vendor.img")
-  img.close()
-
-
-def AddUserdata(output_zip):
-  """Create an empty userdata image and store it in output_zip."""
-
-  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
-                                                    "data")
-  # If no userdata_size is provided for extfs, skip userdata.img.
-  if (image_props.get("fs_type", "").startswith("ext") and
-      not image_props.get("partition_size")):
-    return
-
-  print "creating userdata.img..."
-
-  # The name of the directory it is making an image out of matters to
-  # mkyaffs2image.  So we create a temp dir, and within it we create an
-  # empty dir named "data", and build the image from that.
-  temp_dir = tempfile.mkdtemp()
-  user_dir = os.path.join(temp_dir, "data")
-  os.mkdir(user_dir)
-  img = tempfile.NamedTemporaryFile()
-
-  fstab = OPTIONS.info_dict["fstab"]
-  if fstab:
-    image_props["fs_type" ] = fstab["/data"].fs_type
-  succ = build_image.BuildImage(user_dir, image_props, img.name)
-  assert succ, "build userdata.img image failed"
-
-  common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
-  output_zip.write(img.name, "userdata.img")
-  img.close()
-  os.rmdir(user_dir)
-  os.rmdir(temp_dir)
-
-
-def AddCache(output_zip):
-  """Create an empty cache image and store it in output_zip."""
-
-  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
-                                                    "cache")
-  # The build system has to explicitly request for cache.img.
-  if "fs_type" not in image_props:
-    return
-
-  print "creating cache.img..."
-
-  # The name of the directory it is making an image out of matters to
-  # mkyaffs2image.  So we create a temp dir, and within it we create an
-  # empty dir named "cache", and build the image from that.
-  temp_dir = tempfile.mkdtemp()
-  user_dir = os.path.join(temp_dir, "cache")
-  os.mkdir(user_dir)
-  img = tempfile.NamedTemporaryFile()
-
-  fstab = OPTIONS.info_dict["fstab"]
-  if fstab:
-    image_props["fs_type" ] = fstab["/cache"].fs_type
-  succ = build_image.BuildImage(user_dir, image_props, img.name)
-  assert succ, "build cache.img image failed"
-
-  common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
-  output_zip.write(img.name, "cache.img")
-  img.close()
-  os.rmdir(user_dir)
-  os.rmdir(temp_dir)
-
-
-def CopyInfo(output_zip):
-  """Copy the android-info.txt file from the input to the output."""
-  output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
-                   "android-info.txt")
-
-
-def main(argv):
-  bootable_only = [False]
-
-  def option_handler(o, a):
-    if o in ("-b", "--board_config"):
-      pass       # deprecated
-    if o in ("-z", "--bootable_zip"):
-      bootable_only[0] = True
-    else:
-      return False
-    return True
-
-  args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:z",
-                             extra_long_opts=["board_config=",
-                                              "bootable_zip"],
-                             extra_option_handler=option_handler)
-
-  bootable_only = bootable_only[0]
-
-  if len(args) != 2:
-    common.Usage(__doc__)
-    sys.exit(1)
-
-  OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
-  OPTIONS.info_dict = common.LoadInfoDict(input_zip)
-
-  # If this image was originally labelled with SELinux contexts, make sure we
-  # also apply the labels in our new image. During building, the "file_contexts"
-  # is in the out/ directory tree, but for repacking from target-files.zip it's
-  # in the root directory of the ramdisk.
-  if "selinux_fc" in OPTIONS.info_dict:
-    OPTIONS.info_dict["selinux_fc"] = os.path.join(OPTIONS.input_tmp, "BOOT", "RAMDISK",
-        "file_contexts")
-
-  output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
-
-  common.GetBootableImage(
-      "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT").AddToZip(output_zip)
-  common.GetBootableImage(
-      "recovery.img", "recovery.img", OPTIONS.input_tmp,
-      "RECOVERY").AddToZip(output_zip)
-
-  if not bootable_only:
-    AddSystem(output_zip)
-    AddVendor(output_zip)
-    AddUserdata(output_zip)
-    AddCache(output_zip)
-    CopyInfo(output_zip)
-
-  print "cleaning up..."
-  output_zip.close()
-  shutil.rmtree(OPTIONS.input_tmp)
-
-  print "done."
-
-
-if __name__ == '__main__':
-  try:
-    common.CloseInheritedPipes()
-    main(sys.argv[1:])
-  except common.ExternalError, e:
-    print
-    print "   ERROR: %s" % (e,)
-    print
-    sys.exit(1)
diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files
new file mode 120000
index 0000000..afaf24b
--- /dev/null
+++ b/tools/releasetools/img_from_target_files
@@ -0,0 +1 @@
+img_from_target_files.py
\ No newline at end of file
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
new file mode 100755
index 0000000..4b88e73
--- /dev/null
+++ b/tools/releasetools/img_from_target_files.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2008 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.
+
+"""
+Given a target-files zipfile, produces an image zipfile suitable for
+use with 'fastboot update'.
+
+Usage:  img_from_target_files [flags] input_target_files output_image_zip
+
+  -z  (--bootable_zip)
+      Include only the bootable images (eg 'boot' and 'recovery') in
+      the output.
+
+"""
+
+import sys
+
+if sys.hexversion < 0x02070000:
+  print >> sys.stderr, "Python 2.7 or newer is required."
+  sys.exit(1)
+
+import errno
+import os
+import re
+import shutil
+import subprocess
+import tempfile
+import zipfile
+
+# missing in Python 2.4 and before
+if not hasattr(os, "SEEK_SET"):
+  os.SEEK_SET = 0
+
+import common
+
+OPTIONS = common.OPTIONS
+
+
+def CopyInfo(output_zip):
+  """Copy the android-info.txt file from the input to the output."""
+  output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
+                   "android-info.txt")
+
+
+def main(argv):
+  bootable_only = [False]
+
+  def option_handler(o, a):
+    if o in ("-z", "--bootable_zip"):
+      bootable_only[0] = True
+    else:
+      return False
+    return True
+
+  args = common.ParseOptions(argv, __doc__,
+                             extra_opts="z",
+                             extra_long_opts=["bootable_zip"],
+                             extra_option_handler=option_handler)
+
+  bootable_only = bootable_only[0]
+
+  if len(args) != 2:
+    common.Usage(__doc__)
+    sys.exit(1)
+
+  OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
+  output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
+  CopyInfo(output_zip)
+
+  try:
+    done = False
+    images_path = os.path.join(OPTIONS.input_tmp, "IMAGES")
+    if os.path.exists(images_path):
+      # If this is a new target-files, it already contains the images,
+      # and all we have to do is copy them to the output zip.
+      images = os.listdir(images_path)
+      if images:
+        for i in images:
+          if bootable_only and i not in ("boot.img", "recovery.img"): continue
+          if not i.endswith(".img"): continue
+          with open(os.path.join(images_path, i), "r") as f:
+            common.ZipWriteStr(output_zip, i, f.read())
+        done = True
+
+    if not done:
+      # We have an old target-files that doesn't already contain the
+      # images, so build them.
+      import add_img_to_target_files
+
+      OPTIONS.info_dict = common.LoadInfoDict(input_zip)
+
+      # If this image was originally labelled with SELinux contexts,
+      # make sure we also apply the labels in our new image. During
+      # building, the "file_contexts" is in the out/ directory tree,
+      # but for repacking from target-files.zip it's in the root
+      # directory of the ramdisk.
+      if "selinux_fc" in OPTIONS.info_dict:
+        OPTIONS.info_dict["selinux_fc"] = os.path.join(
+            OPTIONS.input_tmp, "BOOT", "RAMDISK", "file_contexts")
+
+      boot_image = common.GetBootableImage(
+          "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
+      if boot_image:
+          boot_image.AddToZip(output_zip)
+      recovery_image = common.GetBootableImage(
+          "recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
+      if recovery_image:
+        recovery_image.AddToZip(output_zip)
+
+      def banner(s):
+        print "\n\n++++ " + s + " ++++\n\n"
+
+      if not bootable_only:
+        banner("AddSystem")
+        add_img_to_target_files.AddSystem(output_zip, prefix="")
+        try:
+          input_zip.getinfo("VENDOR/")
+          banner("AddVendor")
+          add_img_to_target_files.AddVendor(output_zip, prefix="")
+        except KeyError:
+          pass   # no vendor partition for this device
+        banner("AddUserdata")
+        add_img_to_target_files.AddUserdata(output_zip, prefix="")
+        banner("AddCache")
+        add_img_to_target_files.AddCache(output_zip, prefix="")
+
+  finally:
+    print "cleaning up..."
+    output_zip.close()
+    shutil.rmtree(OPTIONS.input_tmp)
+
+  print "done."
+
+
+if __name__ == '__main__':
+  try:
+    common.CloseInheritedPipes()
+    main(sys.argv[1:])
+  except common.ExternalError, e:
+    print
+    print "   ERROR: %s" % (e,)
+    print
+    sys.exit(1)
diff --git a/tools/releasetools/make_recovery_patch b/tools/releasetools/make_recovery_patch
new file mode 100755
index 0000000..08d1450
--- /dev/null
+++ b/tools/releasetools/make_recovery_patch
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+if sys.hexversion < 0x02070000:
+  print >> sys.stderr, "Python 2.7 or newer is required."
+  sys.exit(1)
+
+import os
+import common
+
+OPTIONS = common.OPTIONS
+
+def main(argv):
+  # def option_handler(o, a):
+  #   return False
+
+  args = common.ParseOptions(argv, __doc__)
+  input_dir, output_dir = args
+
+  OPTIONS.info_dict = common.LoadInfoDict(input_dir)
+
+  recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
+                                         input_dir, "RECOVERY")
+  boot_img = common.GetBootableImage("boot.img", "boot.img",
+                                     input_dir, "BOOT")
+
+  if not recovery_img or not boot_img:
+    sys.exit(0)
+
+  def output_sink(fn, data):
+    with open(os.path.join(output_dir, "SYSTEM", *fn.split("/")), "wb") as f:
+      f.write(data)
+
+  common.MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img)
+
+
+if __name__ == '__main__':
+  main(sys.argv[1:])
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index e695218..945f11a 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -21,7 +21,7 @@
 
 Usage:  ota_from_target_files [flags] input_target_files output_ota_package
 
-  -b  (--board_config)  <file>
+  --board_config  <file>
       Deprecated.
 
   -k (--package_key) <key> Key to use to sign the package (default is
@@ -37,6 +37,14 @@
       Generate an incremental OTA using the given target-files zip as
       the starting build.
 
+  -v  (--verify)
+      Remount and verify the checksums of the files written to the
+      system and vendor (if used) partitions.  Incremental builds only.
+
+  -o  (--oem_settings)  <file>
+      Use the file to specify the expected OEM-specific properties
+      on the OEM partition of the intended device.
+
   -w  (--wipe_user_data)
       Generate an OTA package that will wipe the user data partition
       when installed.
@@ -57,6 +65,16 @@
       first, so that any changes made to the system partition are done
       using the new recovery (new kernel, etc.).
 
+  --block
+      Generate a block-based OTA if possible.  Will fall back to a
+      file-based OTA if the target_files is older and doesn't support
+      block-based OTAs.
+
+  -b  (--binary)  <file>
+      Use the given binary as the update-binary in the output package,
+      instead of the binary in the build's target_files.  Use for
+      development only.
+
   -t  (--worker_threads) <int>
       Specifies the number of worker-threads that will be used when
       generating patches for incremental updates (defaults to 3).
@@ -65,12 +83,13 @@
 
 import sys
 
-if sys.hexversion < 0x02040000:
-  print >> sys.stderr, "Python 2.4 or newer is required."
+if sys.hexversion < 0x02070000:
+  print >> sys.stderr, "Python 2.7 or newer is required."
   sys.exit(1)
 
 import copy
 import errno
+import multiprocessing
 import os
 import re
 import subprocess
@@ -78,17 +97,18 @@
 import time
 import zipfile
 
-try:
-  from hashlib import sha1 as sha1
-except ImportError:
-  from sha import sha as sha1
+from hashlib import sha1 as sha1
 
 import common
 import edify_generator
+import build_image
+import blockimgdiff
+import sparse_img
 
 OPTIONS = common.OPTIONS
 OPTIONS.package_key = None
 OPTIONS.incremental_source = None
+OPTIONS.verify = False
 OPTIONS.require_verbatim = set()
 OPTIONS.prohibit_verbatim = set(("system/build.prop",))
 OPTIONS.patch_threshold = 0.95
@@ -96,9 +116,15 @@
 OPTIONS.omit_prereq = False
 OPTIONS.extra_script = None
 OPTIONS.aslr_mode = True
-OPTIONS.worker_threads = 3
+OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
+if OPTIONS.worker_threads == 0:
+  OPTIONS.worker_threads = 1
 OPTIONS.two_step = False
 OPTIONS.no_signing = False
+OPTIONS.block_based = False
+OPTIONS.updater_binary = None
+OPTIONS.oem_source = None
+OPTIONS.fallback_to_full = True
 
 def MostPopularKey(d, default):
   """Given a dict, return the key corresponding to the largest
@@ -144,50 +170,21 @@
     return result
   return None
 
-class Item:
-  """Items represent the metadata (user, group, mode) of files and
-  directories in the system image."""
-  ITEMS = {}
-  def __init__(self, name, dir=False):
-    self.name = name
-    self.uid = None
-    self.gid = None
-    self.mode = None
-    self.selabel = None
-    self.capabilities = None
-    self.dir = dir
+class ItemSet:
+  def __init__(self, partition, fs_config):
+    self.partition = partition
+    self.fs_config = fs_config
+    self.ITEMS = {}
 
-    if name:
-      self.parent = Item.Get(os.path.dirname(name), dir=True)
-      self.parent.children.append(self)
-    else:
-      self.parent = None
-    if dir:
-      self.children = []
+  def Get(self, name, dir=False):
+    if name not in self.ITEMS:
+      self.ITEMS[name] = Item(self, name, dir=dir)
+    return self.ITEMS[name]
 
-  def Dump(self, indent=0):
-    if self.uid is not None:
-      print "%s%s %d %d %o" % ("  "*indent, self.name, self.uid, self.gid, self.mode)
-    else:
-      print "%s%s %s %s %s" % ("  "*indent, self.name, self.uid, self.gid, self.mode)
-    if self.dir:
-      print "%s%s" % ("  "*indent, self.descendants)
-      print "%s%s" % ("  "*indent, self.best_subtree)
-      for i in self.children:
-        i.Dump(indent=indent+1)
-
-  @classmethod
-  def Get(cls, name, dir=False):
-    if name not in cls.ITEMS:
-      cls.ITEMS[name] = Item(name, dir=dir)
-    return cls.ITEMS[name]
-
-  @classmethod
-  def GetMetadata(cls, input_zip):
-
+  def GetMetadata(self, input_zip):
     # The target_files contains a record of what the uid,
     # gid, and mode are supposed to be.
-    output = input_zip.read("META/filesystem_config.txt")
+    output = input_zip.read(self.fs_config)
 
     for line in output.split("\n"):
       if not line: continue
@@ -205,7 +202,7 @@
         if key == "capabilities":
           capabilities = value
 
-      i = cls.ITEMS.get(name, None)
+      i = self.ITEMS.get(name, None)
       if i is not None:
         i.uid = int(uid)
         i.gid = int(gid)
@@ -216,11 +213,44 @@
           i.children.sort(key=lambda i: i.name)
 
     # set metadata for the files generated by this script.
-    i = cls.ITEMS.get("system/recovery-from-boot.p", None)
+    i = self.ITEMS.get("system/recovery-from-boot.p", None)
     if i: i.uid, i.gid, i.mode, i.selabel, i.capabilities = 0, 0, 0644, None, None
-    i = cls.ITEMS.get("system/etc/install-recovery.sh", None)
+    i = self.ITEMS.get("system/etc/install-recovery.sh", None)
     if i: i.uid, i.gid, i.mode, i.selabel, i.capabilities = 0, 0, 0544, None, None
 
+
+class Item:
+  """Items represent the metadata (user, group, mode) of files and
+  directories in the system image."""
+  def __init__(self, itemset, name, dir=False):
+    self.itemset = itemset
+    self.name = name
+    self.uid = None
+    self.gid = None
+    self.mode = None
+    self.selabel = None
+    self.capabilities = None
+    self.dir = dir
+
+    if name:
+      self.parent = itemset.Get(os.path.dirname(name), dir=True)
+      self.parent.children.append(self)
+    else:
+      self.parent = None
+    if dir:
+      self.children = []
+
+  def Dump(self, indent=0):
+    if self.uid is not None:
+      print "%s%s %d %d %o" % ("  "*indent, self.name, self.uid, self.gid, self.mode)
+    else:
+      print "%s%s %s %s %s" % ("  "*indent, self.name, self.uid, self.gid, self.mode)
+    if self.dir:
+      print "%s%s" % ("  "*indent, self.descendants)
+      print "%s%s" % ("  "*indent, self.best_subtree)
+      for i in self.children:
+        i.Dump(indent=indent+1)
+
   def CountChildMetadata(self):
     """Count up the (uid, gid, mode, selabel, capabilities) tuples for
     all children and determine the best strategy for using set_perm_recursive and
@@ -305,9 +335,8 @@
     recurse(self, (-1, -1, -1, -1, None, None))
 
 
-def CopySystemFiles(input_zip, output_zip=None,
-                    substitute=None):
-  """Copies files underneath system/ in the input zip to the output
+def CopyPartitionFiles(itemset, input_zip, output_zip=None, substitute=None):
+  """Copies files for the partition in the input zip to the output
   zip.  Populates the Item class with their metadata, and returns a
   list of symlinks.  output_zip may be None, in which case the copy is
   skipped (but the other side effects still happen).  substitute is an
@@ -317,15 +346,17 @@
 
   symlinks = []
 
+  partition = itemset.partition
+
   for info in input_zip.infolist():
-    if info.filename.startswith("SYSTEM/"):
+    if info.filename.startswith(partition.upper() + "/"):
       basefilename = info.filename[7:]
       if IsSymlink(info):
         symlinks.append((input_zip.read(info.filename),
-                         "/system/" + basefilename))
+                         "/" + partition + "/" + basefilename))
       else:
         info2 = copy.copy(info)
-        fn = info2.filename = "system/" + basefilename
+        fn = info2.filename = partition + "/" + basefilename
         if substitute and fn in substitute and substitute[fn] is None:
           continue
         if output_zip is not None:
@@ -335,9 +366,9 @@
             data = input_zip.read(info.filename)
           output_zip.writestr(info2, data)
         if fn.endswith("/"):
-          Item.Get(fn[:-1], dir=True)
+          itemset.Get(fn[:-1], dir=True)
         else:
-          Item.Get(fn, dir=False)
+          itemset.Get(fn, dir=False)
 
   symlinks.sort()
   return symlinks
@@ -351,63 +382,82 @@
                   whole_file=True)
 
 
-def AppendAssertions(script, info_dict):
-  device = GetBuildProp("ro.product.device", info_dict)
-  script.AssertDevice(device)
-
-
-def MakeRecoveryPatch(input_tmp, output_zip, recovery_img, boot_img):
-  """Generate a binary patch that creates the recovery image starting
-  with the boot image.  (Most of the space in these images is just the
-  kernel, which is identical for the two, so the resulting patch
-  should be efficient.)  Add it to the output zip, along with a shell
-  script that is run from init.rc on first boot to actually do the
-  patching and install the new recovery image.
-
-  recovery_img and boot_img should be File objects for the
-  corresponding images.  info should be the dictionary returned by
-  common.LoadInfoDict() on the input target_files.
-
-  Returns an Item for the shell script, which must be made
-  executable.
-  """
-
-  diff_program = ["imgdiff"]
-  path = os.path.join(input_tmp, "SYSTEM", "etc", "recovery-resource.dat")
-  if os.path.exists(path):
-    diff_program.append("-b")
-    diff_program.append(path)
-    bonus_args = "-b /system/etc/recovery-resource.dat"
+def AppendAssertions(script, info_dict, oem_dict = None):
+  oem_props = info_dict.get("oem_fingerprint_properties")
+  if oem_props is None or len(oem_props) == 0:
+    device = GetBuildProp("ro.product.device", info_dict)
+    script.AssertDevice(device)
   else:
-    bonus_args = ""
+    if oem_dict is None:
+      raise common.ExternalError("No OEM file provided to answer expected assertions")
+    for prop in oem_props.split():
+      if oem_dict.get(prop) is None:
+        raise common.ExternalError("The OEM file is missing the property %s" % prop)
+      script.AssertOemProperty(prop, oem_dict.get(prop))
 
-  d = common.Difference(recovery_img, boot_img, diff_program=diff_program)
-  _, _, patch = d.ComputePatch()
-  common.ZipWriteStr(output_zip, "recovery/recovery-from-boot.p", patch)
-  Item.Get("system/recovery-from-boot.p", dir=False)
 
-  boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict)
-  recovery_type, recovery_device = common.GetTypeAndDevice("/recovery", OPTIONS.info_dict)
+def HasRecoveryPatch(target_files_zip):
+  try:
+    target_files_zip.getinfo("SYSTEM/recovery-from-boot.p")
+    return True
+  except KeyError:
+    return False
 
-  sh = """#!/system/bin/sh
-if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
-  log -t recovery "Installing new recovery image"
-  applypatch %(bonus_args)s %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s %(recovery_type)s:%(recovery_device)s %(recovery_sha1)s %(recovery_size)d %(boot_sha1)s:/system/recovery-from-boot.p
-else
-  log -t recovery "Recovery image already installed"
-fi
-""" % { 'boot_size': boot_img.size,
-        'boot_sha1': boot_img.sha1,
-        'recovery_size': recovery_img.size,
-        'recovery_sha1': recovery_img.sha1,
-        'boot_type': boot_type,
-        'boot_device': boot_device,
-        'recovery_type': recovery_type,
-        'recovery_device': recovery_device,
-        'bonus_args': bonus_args,
-        }
-  common.ZipWriteStr(output_zip, "recovery/etc/install-recovery.sh", sh)
-  return Item.Get("system/etc/install-recovery.sh", dir=False)
+def HasVendorPartition(target_files_zip):
+  try:
+    target_files_zip.getinfo("VENDOR/")
+    return True
+  except KeyError:
+    return False
+
+def GetOemProperty(name, oem_props, oem_dict, info_dict):
+  if oem_props is not None and name in oem_props:
+    return oem_dict[name]
+  return GetBuildProp(name, info_dict)
+
+
+def CalculateFingerprint(oem_props, oem_dict, info_dict):
+  if oem_props is None:
+    return GetBuildProp("ro.build.fingerprint", info_dict)
+  return "%s/%s/%s:%s" % (
+    GetOemProperty("ro.product.brand", oem_props, oem_dict, info_dict),
+    GetOemProperty("ro.product.name", oem_props, oem_dict, info_dict),
+    GetOemProperty("ro.product.device", oem_props, oem_dict, info_dict),
+    GetBuildProp("ro.build.thumbprint", info_dict))
+
+
+def GetImage(which, tmpdir, info_dict):
+  # Return an image object (suitable for passing to BlockImageDiff)
+  # for the 'which' partition (most be "system" or "vendor").  If a
+  # prebuilt image and file map are found in tmpdir they are used,
+  # otherwise they are reconstructed from the individual files.
+
+  assert which in ("system", "vendor")
+
+  path = os.path.join(tmpdir, "IMAGES", which + ".img")
+  mappath = os.path.join(tmpdir, "IMAGES", which + ".map")
+  if os.path.exists(path) and os.path.exists(mappath):
+    print "using %s.img from target-files" % (which,)
+    # This is a 'new' target-files, which already has the image in it.
+
+  else:
+    print "building %s.img from target-files" % (which,)
+
+    # This is an 'old' target-files, which does not contain images
+    # already built.  Build them.
+
+    mappath = tempfile.mkstemp()[1]
+    OPTIONS.tempfiles.append(mappath)
+
+    import add_img_to_target_files
+    if which == "system":
+      path = add_img_to_target_files.BuildSystem(
+          tmpdir, info_dict, block_list=mappath)
+    elif which == "vendor":
+      path = add_img_to_target_files.BuildVendor(
+          tmpdir, info_dict, block_list=mappath)
+
+  return sparse_img.SparseImage(path, mappath)
 
 
 def WriteFullOTAPackage(input_zip, output_zip):
@@ -416,9 +466,18 @@
   # change very often.
   script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
 
-  metadata = {"post-build": GetBuildProp("ro.build.fingerprint",
-                                         OPTIONS.info_dict),
-              "pre-device": GetBuildProp("ro.product.device",
+  oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
+  recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
+  oem_dict = None
+  if oem_props is not None and len(oem_props) > 0:
+    if OPTIONS.oem_source is None:
+      raise common.ExternalError("OEM source required for this build")
+    script.Mount("/oem", recovery_mount_options)
+    oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines())
+
+  metadata = {"post-build": CalculateFingerprint(
+                               oem_props, oem_dict, OPTIONS.info_dict),
+              "pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
                                          OPTIONS.info_dict),
               "post-timestamp": GetBuildProp("ro.build.date.utc",
                                              OPTIONS.info_dict),
@@ -433,12 +492,15 @@
       metadata=metadata,
       info_dict=OPTIONS.info_dict)
 
+  has_recovery_patch = HasRecoveryPatch(input_zip)
+  block_based = OPTIONS.block_based and has_recovery_patch
+
   if not OPTIONS.omit_prereq:
     ts = GetBuildProp("ro.build.date.utc", OPTIONS.info_dict)
     ts_text = GetBuildProp("ro.build.date", OPTIONS.info_dict)
     script.AssertOlderBuild(ts, ts_text)
 
-  AppendAssertions(script, OPTIONS.info_dict)
+  AppendAssertions(script, OPTIONS.info_dict, oem_dict)
   device_specific.FullOTA_Assertions()
 
   # Two-step package strategy (in chronological order, which is *not*
@@ -471,48 +533,92 @@
     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
+if get_stage("%(bcb_dev)s") == "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
+else if get_stage("%(bcb_dev)s") == "3/3" then
 """ % bcb_dev)
 
   device_specific.FullOTA_InstallBegin()
 
-  script.ShowProgress(0.5, 0)
+  system_progress = 0.75
 
   if OPTIONS.wipe_user_data:
-    script.FormatPartition("/data")
+    system_progress -= 0.1
+  if HasVendorPartition(input_zip):
+    system_progress -= 0.1
 
   if "selinux_fc" in OPTIONS.info_dict:
     WritePolicyConfig(OPTIONS.info_dict["selinux_fc"], output_zip)
 
-  script.FormatPartition("/system")
-  script.Mount("/system")
-  script.UnpackPackageDir("recovery", "/system")
-  script.UnpackPackageDir("system", "/system")
+  recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
 
-  symlinks = CopySystemFiles(input_zip, output_zip)
-  script.MakeSymlinks(symlinks)
+  system_items = ItemSet("system", "META/filesystem_config.txt")
+  script.ShowProgress(system_progress, 0)
+
+  if block_based:
+    # Full OTA is done as an "incremental" against an empty source
+    # image.  This has the effect of writing new data from the package
+    # to the entire partition, but lets us reuse the updater code that
+    # writes incrementals to do it.
+    system_tgt = GetImage("system", OPTIONS.input_tmp, OPTIONS.info_dict)
+    system_tgt.ResetFileMap()
+    system_diff = common.BlockDifference("system", system_tgt, src=None)
+    system_diff.WriteScript(script, output_zip)
+  else:
+    script.FormatPartition("/system")
+    script.Mount("/system", recovery_mount_options)
+    if not has_recovery_patch:
+      script.UnpackPackageDir("recovery", "/system")
+    script.UnpackPackageDir("system", "/system")
+
+    symlinks = CopyPartitionFiles(system_items, input_zip, output_zip)
+    script.MakeSymlinks(symlinks)
 
   boot_img = common.GetBootableImage("boot.img", "boot.img",
                                      OPTIONS.input_tmp, "BOOT")
-  MakeRecoveryPatch(OPTIONS.input_tmp, output_zip, recovery_img, boot_img)
 
-  Item.GetMetadata(input_zip)
-  Item.Get("system").SetPermissions(script)
+  if not block_based:
+    def output_sink(fn, data):
+      common.ZipWriteStr(output_zip, "recovery/" + fn, data)
+      system_items.Get("system/" + fn, dir=False)
+
+    common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink,
+                             recovery_img, boot_img)
+
+    system_items.GetMetadata(input_zip)
+    system_items.Get("system").SetPermissions(script)
+
+  if HasVendorPartition(input_zip):
+    vendor_items = ItemSet("vendor", "META/vendor_filesystem_config.txt")
+    script.ShowProgress(0.1, 0)
+
+    if block_based:
+      vendor_tgt = GetImage("vendor", OPTIONS.input_tmp, OPTIONS.info_dict)
+      vendor_tgt.ResetFileMap()
+      vendor_diff = common.BlockDifference("vendor", vendor_tgt)
+      vendor_diff.WriteScript(script, output_zip)
+    else:
+      script.FormatPartition("/vendor")
+      script.Mount("/vendor", recovery_mount_options)
+      script.UnpackPackageDir("vendor", "/vendor")
+
+      symlinks = CopyPartitionFiles(vendor_items, input_zip, output_zip)
+      script.MakeSymlinks(symlinks)
+
+      vendor_items.GetMetadata(input_zip)
+      vendor_items.Get("vendor").SetPermissions(script)
 
   common.CheckSize(boot_img.data, "boot.img", OPTIONS.info_dict)
   common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
-  script.ShowProgress(0.2, 0)
 
-  script.ShowProgress(0.2, 10)
+  script.ShowProgress(0.05, 5)
   script.WriteRawImage("/boot", "boot.img")
 
-  script.ShowProgress(0.1, 0)
+  script.ShowProgress(0.2, 10)
   device_specific.FullOTA_InstallEnd()
 
   if OPTIONS.extra_script is not None:
@@ -520,6 +626,10 @@
 
   script.UnmountAll()
 
+  if OPTIONS.wipe_user_data:
+    script.ShowProgress(0.1, 10)
+    script.FormatPartition("/data")
+
   if OPTIONS.two_step:
     script.AppendExtra("""
 set_stage("%(bcb_dev)s", "");
@@ -532,9 +642,10 @@
 endif;
 endif;
 """ % bcb_dev)
-  script.AddToZip(input_zip, output_zip)
+  script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
   WriteMetadata(metadata, output_zip)
 
+
 def WritePolicyConfig(file_context, output_zip):
   f = open(file_context, 'r');
   basename = os.path.basename(file_context)
@@ -546,14 +657,16 @@
                      "".join(["%s=%s\n" % kv
                               for kv in sorted(metadata.iteritems())]))
 
-def LoadSystemFiles(z):
-  """Load all the files from SYSTEM/... in a given target-files
+
+def LoadPartitionFiles(z, partition):
+  """Load all the files from the given partition in a given target-files
   ZipFile, and return a dict of {filename: File object}."""
   out = {}
+  prefix = partition.upper() + "/"
   for info in z.infolist():
-    if info.filename.startswith("SYSTEM/") and not IsSymlink(info):
+    if info.filename.startswith(prefix) and not IsSymlink(info):
       basefilename = info.filename[7:]
-      fn = "system/" + basefilename
+      fn = partition + "/" + basefilename
       data = z.read(info.filename)
       out[fn] = common.File(fn, data)
   return out
@@ -564,7 +677,8 @@
   try:
     return info_dict.get("build.prop", {})[prop]
   except KeyError:
-    raise common.ExternalError("couldn't find %s in build.prop" % (property,))
+    raise common.ExternalError("couldn't find %s in build.prop" % (prop,))
+
 
 def AddToKnownPaths(filename, known_paths):
   if filename[-1] == "/":
@@ -577,7 +691,8 @@
     known_paths.add(path)
     dirs.pop()
 
-def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
+
+def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
   source_version = OPTIONS.source_info_dict["recovery_api_version"]
   target_version = OPTIONS.target_info_dict["recovery_api_version"]
 
@@ -603,82 +718,11 @@
       metadata=metadata,
       info_dict=OPTIONS.info_dict)
 
-  print "Loading target..."
-  target_data = LoadSystemFiles(target_zip)
-  print "Loading source..."
-  source_data = LoadSystemFiles(source_zip)
-
-  verbatim_targets = []
-  patch_list = []
-  diffs = []
-  renames = {}
-  known_paths = set()
-  largest_source_size = 0
-
-  matching_file_cache = {}
-  for fn, sf in source_data.items():
-    assert fn == sf.name
-    matching_file_cache["path:" + fn] = sf
-    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
-      matching_file_cache["sha:" + sf.sha1] = sf
-
-  for fn in sorted(target_data.keys()):
-    tf = target_data[fn]
-    assert fn == tf.name
-    sf = ClosestFileMatch(tf, matching_file_cache, renames)
-    if sf is not None and sf.name != tf.name:
-      print "File has moved from " + sf.name + " to " + tf.name
-      renames[sf.name] = tf
-
-    if sf is None or fn in OPTIONS.require_verbatim:
-      # This file should be included verbatim
-      if fn in OPTIONS.prohibit_verbatim:
-        raise common.ExternalError("\"%s\" must be sent verbatim" % (fn,))
-      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))
-    else:
-      # Target file data identical to source (may still be renamed)
-      pass
-
-  common.ComputeDifferences(diffs)
-
-  for diff in diffs:
-    tf, sf, d = diff.GetPatch()
-    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((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)
   target_fp = GetBuildProp("ro.build.fingerprint", OPTIONS.target_info_dict)
   metadata["pre-build"] = source_fp
   metadata["post-build"] = target_fp
 
-  script.Mount("/system")
-  script.AssertSomeFingerprint(source_fp, target_fp)
-
   source_boot = common.GetBootableImage(
       "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT",
       OPTIONS.source_info_dict)
@@ -694,13 +738,31 @@
       "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
   updating_recovery = (source_recovery.data != target_recovery.data)
 
-  # Here's how we divide up the progress bar:
-  #  0.1 for verifying the start state (PatchCheck calls)
-  #  0.8 for applying patches (ApplyPatch calls)
-  #  0.1 for unpacking verbatim files, symlinking, and doing the
-  #      device-specific commands.
+  system_src = GetImage("system", OPTIONS.source_tmp, OPTIONS.source_info_dict)
+  system_tgt = GetImage("system", OPTIONS.target_tmp, OPTIONS.target_info_dict)
+  system_diff = common.BlockDifference("system", system_tgt, system_src,
+                                       check_first_block=True)
 
-  AppendAssertions(script, OPTIONS.target_info_dict)
+  if HasVendorPartition(target_zip):
+    if not HasVendorPartition(source_zip):
+      raise RuntimeError("can't generate incremental that adds /vendor")
+    vendor_src = GetImage("vendor", OPTIONS.source_tmp, OPTIONS.source_info_dict)
+    vendor_tgt = GetImage("vendor", OPTIONS.target_tmp, OPTIONS.target_info_dict)
+    vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
+                                         check_first_block=True)
+  else:
+    vendor_diff = None
+
+  oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties")
+  recovery_mount_options = OPTIONS.target_info_dict.get("recovery_mount_options")
+  oem_dict = None
+  if oem_props is not None and len(oem_props) > 0:
+    if OPTIONS.oem_source is None:
+      raise common.ExternalError("OEM source required for this build")
+    script.Mount("/oem", recovery_mount_options)
+    oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines())
+
+  AppendAssertions(script, OPTIONS.target_info_dict, oem_dict)
   device_specific.IncrementalOTA_Assertions()
 
   # Two-step incremental package strategy (in chronological order,
@@ -733,14 +795,375 @@
     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
+if get_stage("%(bcb_dev)s") == "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
+else if get_stage("%(bcb_dev)s") != "3/3" then
+""" % bcb_dev)
+
+  script.Print("Verifying current system...")
+
+  device_specific.IncrementalOTA_VerifyBegin()
+
+  if oem_props is None:
+    script.AssertSomeFingerprint(source_fp, target_fp)
+  else:
+    script.AssertSomeThumbprint(
+        GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
+        GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+
+  if updating_boot:
+    boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict)
+    d = common.Difference(target_boot, source_boot)
+    _, _, d = d.ComputePatch()
+    if d is None:
+      include_full_boot = True
+      common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
+    else:
+      include_full_boot = False
+
+      print "boot      target: %d  source: %d  diff: %d" % (
+          target_boot.size, source_boot.size, len(d))
+
+      common.ZipWriteStr(output_zip, "patch/boot.img.p", d)
+
+      script.PatchCheck("%s:%s:%d:%s:%d:%s" %
+                        (boot_type, boot_device,
+                         source_boot.size, source_boot.sha1,
+                         target_boot.size, target_boot.sha1))
+
+  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)
+
+  # Verify the existing partitions.
+  system_diff.WriteVerifyScript(script)
+  if vendor_diff:
+    vendor_diff.WriteVerifyScript(script)
+
+  script.Comment("---- start making changes here ----")
+
+  device_specific.IncrementalOTA_InstallBegin()
+
+  system_diff.WriteScript(script, output_zip,
+                          progress=0.8 if vendor_diff else 0.9)
+  if vendor_diff:
+    vendor_diff.WriteScript(script, output_zip, progress=0.1)
+
+  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 not OPTIONS.two_step:
+    if updating_boot:
+      if include_full_boot:
+        print "boot image changed; including full."
+        script.Print("Installing boot image...")
+        script.WriteRawImage("/boot", "boot.img")
+      else:
+        # Produce the boot image by applying a patch to the current
+        # contents of the boot partition, and write it back to the
+        # partition.
+        print "boot image changed; including patch."
+        script.Print("Patching boot image...")
+        script.ShowProgress(0.1, 10)
+        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")
+    else:
+      print "boot image unchanged; skipping."
+
+  # Do device-specific installation (eg, write radio image).
+  device_specific.IncrementalOTA_InstallEnd()
+
+  if OPTIONS.extra_script is not None:
+    script.AppendExtra(OPTIONS.extra_script)
+
+  if OPTIONS.wipe_user_data:
+    script.Print("Erasing user data...")
+    script.FormatPartition("/data")
+
+  if OPTIONS.two_step:
+    script.AppendExtra("""
+set_stage("%(bcb_dev)s", "");
+endif;
+endif;
+""" % bcb_dev)
+
+  script.SetProgress(1)
+  script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
+  WriteMetadata(metadata, output_zip)
+
+
+class FileDifference:
+  def __init__(self, partition, source_zip, target_zip, output_zip):
+    print "Loading target..."
+    self.target_data = target_data = LoadPartitionFiles(target_zip, partition)
+    print "Loading source..."
+    self.source_data = source_data = LoadPartitionFiles(source_zip, partition)
+
+    self.verbatim_targets = verbatim_targets = []
+    self.patch_list = patch_list = []
+    diffs = []
+    self.renames = renames = {}
+    known_paths = set()
+    largest_source_size = 0
+
+    matching_file_cache = {}
+    for fn, sf in source_data.items():
+      assert fn == sf.name
+      matching_file_cache["path:" + fn] = sf
+      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
+        matching_file_cache["sha:" + sf.sha1] = sf
+
+    for fn in sorted(target_data.keys()):
+      tf = target_data[fn]
+      assert fn == tf.name
+      sf = ClosestFileMatch(tf, matching_file_cache, renames)
+      if sf is not None and sf.name != tf.name:
+        print "File has moved from " + sf.name + " to " + tf.name
+        renames[sf.name] = tf
+
+      if sf is None or fn in OPTIONS.require_verbatim:
+        # This file should be included verbatim
+        if fn in OPTIONS.prohibit_verbatim:
+          raise common.ExternalError("\"%s\" must be sent verbatim" % (fn,))
+        print "send", fn, "verbatim"
+        tf.AddToZip(output_zip)
+        verbatim_targets.append((fn, tf.size, tf.sha1))
+        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))
+      else:
+        # Target file data identical to source (may still be renamed)
+        pass
+
+    common.ComputeDifferences(diffs)
+
+    for diff in diffs:
+      tf, sf, d = diff.GetPatch()
+      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, tf.sha1))
+        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((tf, sf, tf.size, common.sha1(d).hexdigest()))
+        largest_source_size = max(largest_source_size, sf.size)
+
+    self.largest_source_size = largest_source_size
+
+  def EmitVerification(self, script):
+    so_far = 0
+    for tf, sf, size, patch_sha in self.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
+    return so_far
+
+  def EmitExplicitTargetVerification(self, script):
+    for fn, size, sha1 in self.verbatim_targets:
+      if (fn[-1] != "/"):
+        script.FileCheck("/"+fn, sha1)
+    for tf, _, _, _ in self.patch_list:
+      script.FileCheck(tf.name, tf.sha1)
+
+  def RemoveUnneededFiles(self, script, extras=()):
+    script.DeleteFiles(["/"+i[0] for i in self.verbatim_targets] +
+                       ["/"+i for i in sorted(self.source_data)
+                              if i not in self.target_data and
+                              i not in self.renames] +
+                       list(extras))
+
+  def TotalPatchSize(self):
+    return sum(i[1].size for i in self.patch_list)
+
+  def EmitPatches(self, script, total_patch_size, so_far):
+    self.deferred_patch_list = deferred_patch_list = []
+    for item in self.patch_list:
+      tf, sf, size, _ = item
+      if tf.name == "system/build.prop":
+        deferred_patch_list.append(item)
+        continue
+      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)
+    return so_far
+
+  def EmitDeferredPatches(self, script):
+    for item in self.deferred_patch_list:
+      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)
+
+  def EmitRenames(self, script):
+    if len(self.renames) > 0:
+      script.Print("Renaming files...")
+      for src, tgt in self.renames.iteritems():
+        print "Renaming " + src + " to " + tgt.name
+        script.RenameFile(src, tgt.name)
+
+
+
+
+def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
+  target_has_recovery_patch = HasRecoveryPatch(target_zip)
+  source_has_recovery_patch = HasRecoveryPatch(source_zip)
+
+  if (OPTIONS.block_based and
+      target_has_recovery_patch and
+      source_has_recovery_patch):
+    return WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip)
+
+  source_version = OPTIONS.source_info_dict["recovery_api_version"]
+  target_version = OPTIONS.target_info_dict["recovery_api_version"]
+
+  if source_version == 0:
+    print ("WARNING: generating edify script for a source that "
+           "can't install it.")
+  script = edify_generator.EdifyGenerator(source_version,
+                                          OPTIONS.target_info_dict)
+
+  oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
+  recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
+  oem_dict = None
+  if oem_props is not None and len(oem_props) > 0:
+    if OPTIONS.oem_source is None:
+      raise common.ExternalError("OEM source required for this build")
+    script.Mount("/oem", recovery_mount_options)
+    oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines())
+
+  metadata = {"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
+                                         OPTIONS.source_info_dict),
+              "post-timestamp": GetBuildProp("ro.build.date.utc",
+                                             OPTIONS.target_info_dict),
+              }
+
+  device_specific = common.DeviceSpecificParams(
+      source_zip=source_zip,
+      source_version=source_version,
+      target_zip=target_zip,
+      target_version=target_version,
+      output_zip=output_zip,
+      script=script,
+      metadata=metadata,
+      info_dict=OPTIONS.info_dict)
+
+  system_diff = FileDifference("system", source_zip, target_zip, output_zip)
+  script.Mount("/system", recovery_mount_options)
+  if HasVendorPartition(target_zip):
+    vendor_diff = FileDifference("vendor", source_zip, target_zip, output_zip)
+    script.Mount("/vendor", recovery_mount_options)
+  else:
+    vendor_diff = None
+
+  target_fp = CalculateFingerprint(oem_props, oem_dict, OPTIONS.target_info_dict)
+  source_fp = CalculateFingerprint(oem_props, oem_dict, OPTIONS.source_info_dict)
+
+  if oem_props is None:
+    script.AssertSomeFingerprint(source_fp, target_fp)
+  else:
+    script.AssertSomeThumbprint(
+        GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
+        GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+
+  metadata["pre-build"] = source_fp
+  metadata["post-build"] = target_fp
+
+  source_boot = common.GetBootableImage(
+      "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT",
+      OPTIONS.source_info_dict)
+  target_boot = common.GetBootableImage(
+      "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT")
+  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",
+      OPTIONS.source_info_dict)
+  target_recovery = common.GetBootableImage(
+      "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
+  updating_recovery = (source_recovery.data != target_recovery.data)
+
+  # Here's how we divide up the progress bar:
+  #  0.1 for verifying the start state (PatchCheck calls)
+  #  0.8 for applying patches (ApplyPatch calls)
+  #  0.1 for unpacking verbatim files, symlinking, and doing the
+  #      device-specific commands.
+
+  AppendAssertions(script, OPTIONS.target_info_dict, oem_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") == "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") != "3/3" then
 """ % bcb_dev)
 
   script.Print("Verifying current system...")
@@ -748,17 +1171,9 @@
   device_specific.IncrementalOTA_VerifyBegin()
 
   script.ShowProgress(0.1, 0)
-  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 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)
+  so_far = system_diff.EmitVerification(script)
+  if vendor_diff:
+    so_far += vendor_diff.EmitVerification(script)
 
   if updating_boot:
     d = common.Difference(target_boot, source_boot)
@@ -775,10 +1190,13 @@
                        source_boot.size, source_boot.sha1,
                        target_boot.size, target_boot.sha1))
     so_far += source_boot.size
-    script.SetProgress(so_far / total_verify_size)
 
-  if patch_list or updating_recovery or updating_boot:
-    script.CacheFreeSpaceCheck(largest_source_size)
+  size = []
+  if system_diff.patch_list: size.append(system_diff.largest_source_size)
+  if vendor_diff:
+    if vendor_diff.patch_list: size.append(vendor_diff.largest_source_size)
+  if size or updating_recovery or updating_boot:
+    script.CacheFreeSpaceCheck(max(size))
 
   device_specific.IncrementalOTA_VerifyEnd()
 
@@ -799,35 +1217,23 @@
     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")
-
   script.Print("Removing unneeded files...")
-  script.DeleteFiles(["/"+i[0] for i in verbatim_targets] +
-                     ["/"+i for i in sorted(source_data)
-                            if i not in target_data and
-                            i not in renames] +
-                     ["/system/recovery.img"])
+  system_diff.RemoveUnneededFiles(script, ("/system/recovery.img",))
+  if vendor_diff:
+    vendor_diff.RemoveUnneededFiles(script)
 
   script.ShowProgress(0.8, 0)
-  total_patch_size = float(sum([i[1].size for i in patch_list]) + 1)
+  total_patch_size = 1.0 + system_diff.TotalPatchSize()
+  if vendor_diff:
+    total_patch_size += vendor_diff.TotalPatchSize()
   if updating_boot:
     total_patch_size += target_boot.size
-  so_far = 0
 
   script.Print("Patching system files...")
-  deferred_patch_list = []
-  for item in patch_list:
-    tf, sf, size, _ = item
-    if tf.name == "system/build.prop":
-      deferred_patch_list.append(item)
-      continue
-    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)
+  so_far = system_diff.EmitPatches(script, total_patch_size, 0)
+  if vendor_diff:
+    script.Print("Patching vendor files...")
+    so_far = vendor_diff.EmitPatches(script, total_patch_size, so_far)
 
   if not OPTIONS.two_step:
     if updating_boot:
@@ -848,6 +1254,10 @@
     else:
       print "boot image unchanged; skipping."
 
+  system_items = ItemSet("system", "META/filesystem_config.txt")
+  if vendor_diff:
+    vendor_items = ItemSet("vendor", "META/vendor_filesystem_config.txt")
+
   if updating_recovery:
     # Recovery is generated as a patch using both the boot image
     # (which contains the same linux kernel as recovery) and the file
@@ -858,26 +1268,39 @@
     # For older builds where recovery-resource.dat is not present, we
     # use only the boot image as the source.
 
-    MakeRecoveryPatch(OPTIONS.target_tmp, output_zip,
-                      target_recovery, target_boot)
-    script.DeleteFiles(["/system/recovery-from-boot.p",
-                        "/system/etc/install-recovery.sh"])
+    if not target_has_recovery_patch:
+      def output_sink(fn, data):
+        common.ZipWriteStr(output_zip, "recovery/" + fn, data)
+        system_items.Get("system/" + fn, dir=False)
+
+      common.MakeRecoveryPatch(OPTIONS.target_tmp, output_sink,
+                               target_recovery, target_boot)
+      script.DeleteFiles(["/system/recovery-from-boot.p",
+                          "/system/etc/install-recovery.sh"])
     print "recovery image changed; including as patch from boot."
   else:
     print "recovery image unchanged; skipping."
 
   script.ShowProgress(0.1, 10)
 
-  target_symlinks = CopySystemFiles(target_zip, None)
+  target_symlinks = CopyPartitionFiles(system_items, target_zip, None)
+  if vendor_diff:
+    target_symlinks.extend(CopyPartitionFiles(vendor_items, target_zip, None))
+
+  temp_script = script.MakeTemporary()
+  system_items.GetMetadata(target_zip)
+  system_items.Get("system").SetPermissions(temp_script)
+  if vendor_diff:
+    vendor_items.GetMetadata(target_zip)
+    vendor_items.Get("vendor").SetPermissions(temp_script)
+
+  # Note that this call will mess up the trees of Items, so make sure
+  # we're done with them.
+  source_symlinks = CopyPartitionFiles(system_items, source_zip, None)
+  if vendor_diff:
+    source_symlinks.extend(CopyPartitionFiles(vendor_items, source_zip, None))
 
   target_symlinks_d = dict([(i[1], i[0]) for i in target_symlinks])
-  temp_script = script.MakeTemporary()
-  Item.GetMetadata(target_zip)
-  Item.Get("system").SetPermissions(temp_script)
-
-  # Note that this call will mess up the tree of Items, so make sure
-  # we're done with it.
-  source_symlinks = CopySystemFiles(source_zip, None)
   source_symlinks_d = dict([(i[1], i[0]) for i in source_symlinks])
 
   # Delete all the symlinks in source that aren't in target.  This
@@ -889,20 +1312,20 @@
       to_delete.append(link)
   script.DeleteFiles(to_delete)
 
-  if verbatim_targets:
-    script.Print("Unpacking new files...")
+  if system_diff.verbatim_targets:
+    script.Print("Unpacking new system files...")
     script.UnpackPackageDir("system", "/system")
+  if vendor_diff and vendor_diff.verbatim_targets:
+    script.Print("Unpacking new vendor files...")
+    script.UnpackPackageDir("vendor", "/vendor")
 
-  if updating_recovery:
+  if updating_recovery and not target_has_recovery_patch:
     script.Print("Unpacking new recovery...")
     script.UnpackPackageDir("recovery", "/system")
 
-  if len(renames) > 0:
-    script.Print("Renaming files...")
-
-  for src in renames:
-    print "Renaming " + src + " to " + renames[src].name
-    script.RenameFile(src, renames[src].name)
+  system_diff.EmitRenames(script)
+  if vendor_diff:
+    vendor_diff.EmitRenames(script)
 
   script.Print("Symlinks and permissions...")
 
@@ -933,10 +1356,11 @@
   # device can still come up, it appears to be the old build and will
   # get set the OTA package again to retry.
   script.Print("Patching remaining system files...")
-  for item in deferred_patch_list:
-    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)
+  system_diff.EmitDeferredPatches(script)
+
+  if OPTIONS.wipe_user_data:
+    script.Print("Erasing user data...")
+    script.FormatPartition("/data")
 
   if OPTIONS.two_step:
     script.AppendExtra("""
@@ -945,14 +1369,26 @@
 endif;
 """ % bcb_dev)
 
-  script.AddToZip(target_zip, output_zip)
+  if OPTIONS.verify and system_diff:
+    script.Print("Remounting and verifying system partition files...")
+    script.Unmount("/system")
+    script.Mount("/system")
+    system_diff.EmitExplicitTargetVerification(script)
+
+  if OPTIONS.verify and vendor_diff:
+    script.Print("Remounting and verifying vendor partition files...")
+    script.Unmount("/vendor")
+    script.Mount("/vendor")
+    vendor_diff.EmitExplicitTargetVerification(script)
+  script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
+
   WriteMetadata(metadata, output_zip)
 
 
 def main(argv):
 
   def option_handler(o, a):
-    if o in ("-b", "--board_config"):
+    if o == "--board_config":
       pass   # deprecated
     elif o in ("-k", "--package_key"):
       OPTIONS.package_key = a
@@ -962,6 +1398,8 @@
       OPTIONS.wipe_user_data = True
     elif o in ("-n", "--no_prereq"):
       OPTIONS.omit_prereq = True
+    elif o in ("-o", "--oem_settings"):
+      OPTIONS.oem_source = a
     elif o in ("-e", "--extra_script"):
       OPTIONS.extra_script = a
     elif o in ("-a", "--aslr_mode"):
@@ -977,14 +1415,22 @@
                          "integers are allowed." % (a, o))
     elif o in ("-2", "--two_step"):
       OPTIONS.two_step = True
-    elif o in ("--no_signing"):
+    elif o == "--no_signing":
       OPTIONS.no_signing = True
+    elif o in ("--verify"):
+      OPTIONS.verify = True
+    elif o == "--block":
+      OPTIONS.block_based = True
+    elif o in ("-b", "--binary"):
+      OPTIONS.updater_binary = a
+    elif o in ("--no_fallback_to_full",):
+      OPTIONS.fallback_to_full = False
     else:
       return False
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:k:i:d:wne:t:a:2",
+                             extra_opts="b:k:i:d:wne:t:a:2o:",
                              extra_long_opts=["board_config=",
                                               "package_key=",
                                               "incremental_from=",
@@ -995,6 +1441,11 @@
                                               "aslr_mode=",
                                               "two_step",
                                               "no_signing",
+                                              "block",
+                                              "binary=",
+                                              "oem_settings=",
+                                              "verify",
+                                              "no_fallback_to_full",
                                               ],
                              extra_option_handler=option_handler)
 
@@ -1023,38 +1474,65 @@
     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)
-  else:
-    temp_zip_file = tempfile.NamedTemporaryFile()
-    output_zip = zipfile.ZipFile(temp_zip_file, "w",
-                                 compression=zipfile.ZIP_DEFLATED)
+  while True:
 
-  if OPTIONS.incremental_source is None:
-    WriteFullOTAPackage(input_zip, output_zip)
-    if OPTIONS.package_key is None:
-      OPTIONS.package_key = OPTIONS.info_dict.get(
-          "default_system_dev_certificate",
-          "build/target/product/security/testkey")
-  else:
-    print "unzipping source target-files..."
-    OPTIONS.source_tmp, source_zip = common.UnzipTemp(OPTIONS.incremental_source)
-    OPTIONS.target_info_dict = OPTIONS.info_dict
-    OPTIONS.source_info_dict = common.LoadInfoDict(source_zip)
-    if OPTIONS.package_key is None:
-      OPTIONS.package_key = OPTIONS.source_info_dict.get(
-          "default_system_dev_certificate",
-          "build/target/product/security/testkey")
-    if OPTIONS.verbose:
-      print "--- source info ---"
-      common.DumpInfoDict(OPTIONS.source_info_dict)
-    WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
+    if OPTIONS.no_signing:
+      if os.path.exists(args[1]): os.unlink(args[1])
+      output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
+    else:
+      temp_zip_file = tempfile.NamedTemporaryFile()
+      output_zip = zipfile.ZipFile(temp_zip_file, "w",
+                                   compression=zipfile.ZIP_DEFLATED)
+
+    if OPTIONS.incremental_source is None:
+      WriteFullOTAPackage(input_zip, output_zip)
+      if OPTIONS.package_key is None:
+        OPTIONS.package_key = OPTIONS.info_dict.get(
+            "default_system_dev_certificate",
+            "build/target/product/security/testkey")
+      break
+
+    else:
+      print "unzipping source target-files..."
+      OPTIONS.source_tmp, source_zip = common.UnzipTemp(OPTIONS.incremental_source)
+      OPTIONS.target_info_dict = OPTIONS.info_dict
+      OPTIONS.source_info_dict = common.LoadInfoDict(source_zip)
+      if "selinux_fc" in OPTIONS.source_info_dict:
+        OPTIONS.source_info_dict["selinux_fc"] = os.path.join(OPTIONS.source_tmp, "BOOT", "RAMDISK",
+                                                              "file_contexts")
+      if OPTIONS.package_key is None:
+        OPTIONS.package_key = OPTIONS.source_info_dict.get(
+            "default_system_dev_certificate",
+            "build/target/product/security/testkey")
+      if OPTIONS.verbose:
+        print "--- source info ---"
+        common.DumpInfoDict(OPTIONS.source_info_dict)
+      try:
+        WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
+        break
+      except ValueError:
+        if not OPTIONS.fallback_to_full: raise
+        print "--- failed to build incremental; falling back to full ---"
+        OPTIONS.incremental_source = None
+        output_zip.close()
 
   output_zip.close()
 
@@ -1062,8 +1540,6 @@
     SignOutput(temp_zip_file.name, args[1])
     temp_zip_file.close()
 
-  common.Cleanup()
-
   print "done."
 
 
@@ -1076,3 +1552,5 @@
     print "   ERROR: %s" % (e,)
     print
     sys.exit(1)
+  finally:
+    common.Cleanup()
diff --git a/tools/releasetools/rangelib.py b/tools/releasetools/rangelib.py
new file mode 100644
index 0000000..7279c60
--- /dev/null
+++ b/tools/releasetools/rangelib.py
@@ -0,0 +1,243 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+import heapq
+import itertools
+
+__all__ = ["RangeSet"]
+
+class RangeSet(object):
+  """A RangeSet represents a set of nonoverlapping ranges on the
+  integers (ie, a set of integers, but efficient when the set contains
+  lots of runs."""
+
+  def __init__(self, data=None):
+    if isinstance(data, str):
+      self._parse_internal(data)
+    elif data:
+      self.data = tuple(self._remove_pairs(data))
+    else:
+      self.data = ()
+
+  def __iter__(self):
+    for i in range(0, len(self.data), 2):
+      yield self.data[i:i+2]
+
+  def __eq__(self, other):
+    return self.data == other.data
+  def __ne__(self, other):
+    return self.data != other.data
+  def __nonzero__(self):
+    return bool(self.data)
+
+  def __str__(self):
+    if not self.data:
+      return "empty"
+    else:
+      return self.to_string()
+
+  def __repr__(self):
+    return '<RangeSet("' + self.to_string() + '")>'
+
+  @classmethod
+  def parse(cls, text):
+    """Parse a text string consisting of a space-separated list of
+    blocks and ranges, eg "10-20 30 35-40".  Ranges are interpreted to
+    include both their ends (so the above example represents 18
+    individual blocks.  Returns a RangeSet object.
+
+    If the input has all its blocks in increasing order, then returned
+    RangeSet will have an extra attribute 'monotonic' that is set to
+    True.  For example the input "10-20 30" is monotonic, but the input
+    "15-20 30 10-14" is not, even though they represent the same set
+    of blocks (and the two RangeSets will compare equal with ==).
+    """
+    return cls(text)
+
+  def _parse_internal(self, text):
+    data = []
+    last = -1
+    monotonic = True
+    for p in text.split():
+      if "-" in p:
+        s, e = p.split("-")
+        data.append(int(s))
+        data.append(int(e)+1)
+        if last <= s <= e:
+          last = e
+        else:
+          monotonic = False
+      else:
+        s = int(p)
+        data.append(s)
+        data.append(s+1)
+        if last <= s:
+          last = s+1
+        else:
+          monotonic = True
+    data.sort()
+    self.data = tuple(self._remove_pairs(data))
+    self.monotonic = monotonic
+
+  @staticmethod
+  def _remove_pairs(source):
+    last = None
+    for i in source:
+      if i == last:
+        last = None
+      else:
+        if last is not None:
+          yield last
+        last = i
+    if last is not None:
+      yield last
+
+  def to_string(self):
+    out = []
+    for i in range(0, len(self.data), 2):
+      s, e = self.data[i:i+2]
+      if e == s+1:
+        out.append(str(s))
+      else:
+        out.append(str(s) + "-" + str(e-1))
+    return " ".join(out)
+
+  def to_string_raw(self):
+    return str(len(self.data)) + "," + ",".join(str(i) for i in self.data)
+
+  def union(self, other):
+    """Return a new RangeSet representing the union of this RangeSet
+    with the argument.
+
+    >>> RangeSet("10-19 30-34").union(RangeSet("18-29"))
+    <RangeSet("10-34")>
+    >>> RangeSet("10-19 30-34").union(RangeSet("22 32"))
+    <RangeSet("10-19 22 30-34")>
+    """
+    out = []
+    z = 0
+    for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))),
+                            zip(other.data, itertools.cycle((+1, -1)))):
+      if (z == 0 and d == 1) or (z == 1 and d == -1):
+        out.append(p)
+      z += d
+    return RangeSet(data=out)
+
+  def intersect(self, other):
+    """Return a new RangeSet representing the intersection of this
+    RangeSet with the argument.
+
+    >>> RangeSet("10-19 30-34").intersect(RangeSet("18-32"))
+    <RangeSet("18-19 30-32")>
+    >>> RangeSet("10-19 30-34").intersect(RangeSet("22-28"))
+    <RangeSet("")>
+    """
+    out = []
+    z = 0
+    for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))),
+                            zip(other.data, itertools.cycle((+1, -1)))):
+      if (z == 1 and d == 1) or (z == 2 and d == -1):
+        out.append(p)
+      z += d
+    return RangeSet(data=out)
+
+  def subtract(self, other):
+    """Return a new RangeSet representing subtracting the argument
+    from this RangeSet.
+
+    >>> RangeSet("10-19 30-34").subtract(RangeSet("18-32"))
+    <RangeSet("10-17 33-34")>
+    >>> RangeSet("10-19 30-34").subtract(RangeSet("22-28"))
+    <RangeSet("10-19 30-34")>
+    """
+
+    out = []
+    z = 0
+    for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))),
+                            zip(other.data, itertools.cycle((-1, +1)))):
+      if (z == 0 and d == 1) or (z == 1 and d == -1):
+        out.append(p)
+      z += d
+    return RangeSet(data=out)
+
+  def overlaps(self, other):
+    """Returns true if the argument has a nonempty overlap with this
+    RangeSet.
+
+    >>> RangeSet("10-19 30-34").overlaps(RangeSet("18-32"))
+    True
+    >>> RangeSet("10-19 30-34").overlaps(RangeSet("22-28"))
+    False
+    """
+
+    # This is like intersect, but we can stop as soon as we discover the
+    # output is going to be nonempty.
+    z = 0
+    for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))),
+                            zip(other.data, itertools.cycle((+1, -1)))):
+      if (z == 1 and d == 1) or (z == 2 and d == -1):
+        return True
+      z += d
+    return False
+
+  def size(self):
+    """Returns the total size of the RangeSet (ie, how many integers
+    are in the set).
+
+    >>> RangeSet("10-19 30-34").size()
+    15
+    """
+
+    total = 0
+    for i, p in enumerate(self.data):
+      if i % 2:
+        total += p
+      else:
+        total -= p
+    return total
+
+  def map_within(self, other):
+    """'other' should be a subset of 'self'.  Returns a RangeSet
+    representing what 'other' would get translated to if the integers
+    of 'self' were translated down to be contiguous starting at zero.
+
+    >>> RangeSet("0-9").map_within(RangeSet("3-4"))
+    <RangeSet("3-4")>
+    >>> RangeSet("10-19").map_within(RangeSet("13-14"))
+    <RangeSet("3-4")>
+    >>> RangeSet("10-19 30-39").map_within(RangeSet("17-19 30-32"))
+    <RangeSet("7-12")>
+    >>> RangeSet("10-19 30-39").map_within(RangeSet("12-13 17-19 30-32"))
+    <RangeSet("2-3 7-12")>
+    """
+
+    out = []
+    offset = 0
+    start = None
+    for p, d in heapq.merge(zip(self.data, itertools.cycle((-5, +5))),
+                            zip(other.data, itertools.cycle((-1, +1)))):
+      if d == -5:
+        start = p
+      elif d == +5:
+        offset += p-start
+        start = None
+      else:
+        out.append(offset + p - start)
+    return RangeSet(data=out)
+
+
+if __name__ == "__main__":
+  import doctest
+  doctest.testmod()
diff --git a/tools/releasetools/sign_target_files_apks b/tools/releasetools/sign_target_files_apks
index ab24706..9e61051 100755
--- a/tools/releasetools/sign_target_files_apks
+++ b/tools/releasetools/sign_target_files_apks
@@ -67,8 +67,8 @@
 
 import sys
 
-if sys.hexversion < 0x02040000:
-  print >> sys.stderr, "Python 2.4 or newer is required."
+if sys.hexversion < 0x02070000:
+  print >> sys.stderr, "Python 2.7 or newer is required."
   sys.exit(1)
 
 import base64
@@ -77,10 +77,12 @@
 import errno
 import os
 import re
+import shutil
 import subprocess
 import tempfile
 import zipfile
 
+import add_img_to_target_files
 import common
 
 OPTIONS = common.OPTIONS
@@ -88,6 +90,8 @@
 OPTIONS.extra_apks = {}
 OPTIONS.key_map = {}
 OPTIONS.replace_ota_keys = False
+OPTIONS.replace_verity_public_key = False
+OPTIONS.replace_verity_private_key = False
 OPTIONS.tag_changes = ("-test-keys", "-dev-keys", "+release-keys")
 
 def GetApkCerts(tf_zip):
@@ -139,14 +143,50 @@
   return data
 
 
-def SignApks(input_tf_zip, output_tf_zip, apk_key_map, key_passwords):
+def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
+                       apk_key_map, key_passwords):
+
   maxsize = max([len(os.path.basename(i.filename))
                  for i in input_tf_zip.infolist()
                  if i.filename.endswith('.apk')])
+  rebuild_recovery = False
+
+  tmpdir = tempfile.mkdtemp()
+  def write_to_temp(fn, attr, data):
+    fn = os.path.join(tmpdir, fn)
+    if fn.endswith("/"):
+      fn = os.path.join(tmpdir, fn)
+      os.mkdir(fn)
+    else:
+      d = os.path.dirname(fn)
+      if d and not os.path.exists(d):
+        os.makedirs(d)
+
+      if attr >> 16 == 0xa1ff:
+        os.symlink(data, fn)
+      else:
+        with open(fn, "wb") as f:
+          f.write(data)
 
   for info in input_tf_zip.infolist():
+    if info.filename.startswith("IMAGES/"): continue
+
     data = input_tf_zip.read(info.filename)
     out_info = copy.copy(info)
+
+    if (info.filename == "META/misc_info.txt" and
+        OPTIONS.replace_verity_private_key):
+      ReplaceVerityPrivateKey(input_tf_zip, output_tf_zip, misc_info, OPTIONS.replace_verity_private_key[1])
+    elif (info.filename == "BOOT/RAMDISK/verity_key" and
+        OPTIONS.replace_verity_public_key):
+      new_data = ReplaceVerityPublicKey(output_tf_zip, OPTIONS.replace_verity_public_key[1])
+      write_to_temp(info.filename, info.external_attr, new_data)
+    elif (info.filename.startswith("BOOT/") or
+        info.filename.startswith("RECOVERY/") or
+        info.filename.startswith("META/") or
+        info.filename == "SYSTEM/etc/recovery-resource.dat"):
+      write_to_temp(info.filename, info.external_attr, data)
+
     if info.filename.endswith(".apk"):
       name = os.path.basename(info.filename)
       key = apk_key_map[name]
@@ -159,18 +199,54 @@
         print "NOT signing: %s" % (name,)
         output_tf_zip.writestr(out_info, data)
     elif info.filename in ("SYSTEM/build.prop",
+                           "VENDOR/build.prop",
                            "RECOVERY/RAMDISK/default.prop"):
       print "rewriting %s:" % (info.filename,)
-      new_data = RewriteProps(data)
+      new_data = RewriteProps(data, misc_info)
       output_tf_zip.writestr(out_info, new_data)
+      if info.filename == "RECOVERY/RAMDISK/default.prop":
+        write_to_temp(info.filename, info.external_attr, new_data)
     elif info.filename.endswith("mac_permissions.xml"):
       print "rewriting %s with new keys." % (info.filename,)
       new_data = ReplaceCerts(data)
       output_tf_zip.writestr(out_info, new_data)
+    elif info.filename in ("SYSTEM/recovery-from-boot.p",
+                           "SYSTEM/bin/install-recovery.sh"):
+      rebuild_recovery = True
+    elif (OPTIONS.replace_ota_keys and
+          info.filename in ("RECOVERY/RAMDISK/res/keys",
+                            "SYSTEM/etc/security/otacerts.zip")):
+      # don't copy these files if we're regenerating them below
+      pass
+    elif (OPTIONS.replace_verity_private_key and
+          info.filename == "META/misc_info.txt"):
+      pass
+    elif (OPTIONS.replace_verity_public_key and
+          info.filename == "BOOT/RAMDISK/verity_key"):
+      pass
     else:
       # a non-APK file; copy it verbatim
       output_tf_zip.writestr(out_info, data)
 
+  if OPTIONS.replace_ota_keys:
+    new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
+    if new_recovery_keys:
+      write_to_temp("RECOVERY/RAMDISK/res/keys", 0755 << 16, new_recovery_keys)
+
+  if rebuild_recovery:
+    recovery_img = common.GetBootableImage(
+        "recovery.img", "recovery.img", tmpdir, "RECOVERY", info_dict=misc_info)
+    boot_img = common.GetBootableImage(
+        "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info)
+
+    def output_sink(fn, data):
+      output_tf_zip.writestr("SYSTEM/"+fn, data)
+
+    common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img,
+                             info_dict=misc_info)
+
+  shutil.rmtree(tmpdir)
+
 
 def ReplaceCerts(data):
   """Given a string of data, replace all occurences of a set
@@ -214,14 +290,20 @@
   return ",".join(sorted(tags))
 
 
-def RewriteProps(data):
+def RewriteProps(data, misc_info):
   output = []
   for line in data.split("\n"):
     line = line.strip()
     original_line = line
-    if line and line[0] != '#':
+    if line and line[0] != '#' and "=" in line:
       key, value = line.split("=", 1)
-      if key == "ro.build.fingerprint":
+      if (key in ("ro.build.fingerprint", "ro.vendor.build.fingerprint")
+          and misc_info.get("oem_fingerprint_properties") is None):
+        pieces = value.split("/")
+        pieces[-1] = EditTags(pieces[-1])
+        value = "/".join(pieces)
+      elif (key in ("ro.build.thumbprint", "ro.vendor.build.thumbprint")
+          and misc_info.get("oem_fingerprint_properties") is not None):
         pieces = value.split("/")
         pieces[-1] = EditTags(pieces[-1])
         value = "/".join(pieces)
@@ -235,7 +317,7 @@
       elif key == "ro.build.display.id":
         # change, eg, "JWR66N dev-keys" to "JWR66N"
         value = value.split()
-        if len(value) >  1 and value[-1].endswith("-keys"):
+        if len(value) > 1 and value[-1].endswith("-keys"):
           value.pop()
         value = " ".join(value)
       line = key + "=" + value
@@ -265,7 +347,8 @@
   for k in keylist:
     m = re.match(r"^(.*)\.x509\.pem$", k)
     if not m:
-      raise common.ExternalError("can't parse \"%s\" from META/otakeys.txt" % (k,))
+      raise common.ExternalError(
+          "can't parse \"%s\" from META/otakeys.txt" % (k,))
     k = m.group(1)
     mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem")
 
@@ -287,10 +370,11 @@
                   os.path.join(OPTIONS.search_path, "framework", "dumpkey.jar")]
                  + mapped_keys + extra_recovery_keys,
                  stdout=subprocess.PIPE)
-  data, _ = p.communicate()
+  new_recovery_keys, _ = p.communicate()
   if p.returncode != 0:
     raise common.ExternalError("failed to run dumpkeys")
-  common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", data)
+  common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys",
+                     new_recovery_keys)
 
   # SystemUpdateActivity uses the x509.pem version of the keys, but
   # put into a zipfile system/etc/security/otacerts.zip.
@@ -304,6 +388,22 @@
   common.ZipWriteStr(output_tf_zip, "SYSTEM/etc/security/otacerts.zip",
                      tempfile.getvalue())
 
+  return new_recovery_keys
+
+def ReplaceVerityPublicKey(targetfile_zip, key_path):
+  print "Replacing verity public key with %s" % key_path
+  with open(key_path) as f:
+    data = f.read()
+  common.ZipWriteStr(targetfile_zip, "BOOT/RAMDISK/verity_key", data)
+  return data
+
+def ReplaceVerityPrivateKey(targetfile_input_zip, targetfile_output_zip, misc_info, key_path):
+  print "Replacing verity private key with %s" % key_path
+  current_key = misc_info["verity_key"]
+  original_misc_info = targetfile_input_zip.read("META/misc_info.txt")
+  new_misc_info = original_misc_info.replace(current_key, key_path)
+  common.ZipWriteStr(targetfile_output_zip, "META/misc_info.txt", new_misc_info)
+  misc_info["verity_key"] = key_path
 
 def BuildKeyMap(misc_info, key_mapping_options):
   for s, d in key_mapping_options:
@@ -347,6 +447,10 @@
           raise ValueError("Bad tag change '%s'" % (i,))
         new.append(i[0] + i[1:].strip())
       OPTIONS.tag_changes = tuple(new)
+    elif o == "--replace_verity_public_key":
+      OPTIONS.replace_verity_public_key = (True, a)
+    elif o == "--replace_verity_private_key":
+      OPTIONS.replace_verity_private_key = (True, a)
     else:
       return False
     return True
@@ -357,7 +461,9 @@
                                               "default_key_mappings=",
                                               "key_mapping=",
                                               "replace_ota_keys",
-                                              "tag_changes="],
+                                              "tag_changes=",
+                                              "replace_verity_public_key=",
+                                              "replace_verity_private_key="],
                              extra_option_handler=option_handler)
 
   if len(args) != 2:
@@ -375,14 +481,14 @@
   CheckAllApksSigned(input_zip, apk_key_map)
 
   key_passwords = common.GetKeyPasswords(set(apk_key_map.values()))
-  SignApks(input_zip, output_zip, apk_key_map, key_passwords)
-
-  if OPTIONS.replace_ota_keys:
-    ReplaceOtaKeys(input_zip, output_zip, misc_info)
+  ProcessTargetFiles(input_zip, output_zip, misc_info,
+                     apk_key_map, key_passwords)
 
   input_zip.close()
   output_zip.close()
 
+  add_img_to_target_files.AddImagesToTargetFiles(args[1])
+
   print "done."
 
 
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
new file mode 100644
index 0000000..7574747
--- /dev/null
+++ b/tools/releasetools/sparse_img.py
@@ -0,0 +1,213 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import bisect
+import os
+import sys
+import struct
+import pprint
+from hashlib import sha1
+
+from rangelib import *
+
+class SparseImage(object):
+  """Wraps a sparse image file (and optional file map) into an image
+  object suitable for passing to BlockImageDiff."""
+
+  def __init__(self, simg_fn, file_map_fn=None):
+    self.simg_f = f = open(simg_fn, "rb")
+
+    header_bin = f.read(28)
+    header = struct.unpack("<I4H4I", header_bin)
+
+    magic = header[0]
+    major_version = header[1]
+    minor_version = header[2]
+    file_hdr_sz = header[3]
+    chunk_hdr_sz = header[4]
+    self.blocksize = blk_sz = header[5]
+    self.total_blocks = total_blks = header[6]
+    total_chunks = header[7]
+    image_checksum = header[8]
+
+    if magic != 0xED26FF3A:
+      raise ValueError("Magic should be 0xED26FF3A but is 0x%08X" % (magic,))
+    if major_version != 1 or minor_version != 0:
+      raise ValueError("I know about version 1.0, but this is version %u.%u" %
+                       (major_version, minor_version))
+    if file_hdr_sz != 28:
+      raise ValueError("File header size was expected to be 28, but is %u." %
+                       (file_hdr_sz,))
+    if chunk_hdr_sz != 12:
+      raise ValueError("Chunk header size was expected to be 12, but is %u." %
+                       (chunk_hdr_sz,))
+
+    print("Total of %u %u-byte output blocks in %u input chunks."
+          % (total_blks, blk_sz, total_chunks))
+
+    pos = 0   # in blocks
+    care_data = []
+    self.offset_map = offset_map = []
+
+    for i in range(total_chunks):
+      header_bin = f.read(12)
+      header = struct.unpack("<2H2I", header_bin)
+      chunk_type = header[0]
+      reserved1 = header[1]
+      chunk_sz = header[2]
+      total_sz = header[3]
+      data_sz = total_sz - 12
+
+      if chunk_type == 0xCAC1:
+        if data_sz != (chunk_sz * blk_sz):
+          raise ValueError(
+              "Raw chunk input size (%u) does not match output size (%u)" %
+              (data_sz, chunk_sz * blk_sz))
+        else:
+          care_data.append(pos)
+          care_data.append(pos + chunk_sz)
+          offset_map.append((pos, chunk_sz, f.tell(), None))
+          pos += chunk_sz
+          f.seek(data_sz, os.SEEK_CUR)
+
+      elif chunk_type == 0xCAC2:
+        fill_data = f.read(4)
+        care_data.append(pos)
+        care_data.append(pos + chunk_sz)
+        offset_map.append((pos, chunk_sz, None, fill_data))
+        pos += chunk_sz
+
+      elif chunk_type == 0xCAC3:
+        if data_sz != 0:
+          raise ValueError("Don't care chunk input size is non-zero (%u)" %
+                           (data_sz))
+        else:
+          pos += chunk_sz
+
+      elif chunk_type == 0xCAC4:
+        raise ValueError("CRC32 chunks are not supported")
+
+      else:
+        raise ValueError("Unknown chunk type 0x%04X not supported" %
+                         (chunk_type,))
+
+    self.care_map = RangeSet(care_data)
+    self.offset_index = [i[0] for i in offset_map]
+
+    if file_map_fn:
+      self.LoadFileBlockMap(file_map_fn)
+    else:
+      self.file_map = {"__DATA": self.care_map}
+
+  def ReadRangeSet(self, ranges):
+    return [d for d in self._GetRangeData(ranges)]
+
+  def TotalSha1(self):
+    """Return the SHA-1 hash of all data in the 'care' regions of this image."""
+    h = sha1()
+    for d in self._GetRangeData(self.care_map):
+      h.update(d)
+    return h.hexdigest()
+
+  def _GetRangeData(self, ranges):
+    """Generator that produces all the image data in 'ranges'.  The
+    number of individual pieces returned is arbitrary (and in
+    particular is not necessarily equal to the number of ranges in
+    'ranges'.
+
+    This generator is stateful -- it depends on the open file object
+    contained in this SparseImage, so you should not try to run two
+    instances of this generator on the same object simultaneously."""
+
+    f = self.simg_f
+    for s, e in ranges:
+      to_read = e-s
+      idx = bisect.bisect_right(self.offset_index, s) - 1
+      chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
+
+      # for the first chunk we may be starting partway through it.
+      remain = chunk_len - (s - chunk_start)
+      this_read = min(remain, to_read)
+      if filepos is not None:
+        p = filepos + ((s - chunk_start) * self.blocksize)
+        f.seek(p, os.SEEK_SET)
+        yield f.read(this_read * self.blocksize)
+      else:
+        yield fill_data * (this_read * (self.blocksize >> 2))
+      to_read -= this_read
+
+      while to_read > 0:
+        # continue with following chunks if this range spans multiple chunks.
+        idx += 1
+        chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
+        this_read = min(chunk_len, to_read)
+        if filepos is not None:
+          f.seek(filepos, os.SEEK_SET)
+          yield f.read(this_read * self.blocksize)
+        else:
+          yield fill_data * (this_read * (self.blocksize >> 2))
+        to_read -= this_read
+
+  def LoadFileBlockMap(self, fn):
+    remaining = self.care_map
+    self.file_map = out = {}
+
+    with open(fn) as f:
+      for line in f:
+        fn, ranges = line.split(None, 1)
+        ranges = RangeSet.parse(ranges)
+        out[fn] = ranges
+        assert ranges.size() == ranges.intersect(remaining).size()
+        remaining = remaining.subtract(ranges)
+
+    # For all the remaining blocks in the care_map (ie, those that
+    # aren't part of the data for any file), divide them into blocks
+    # that are all zero and blocks that aren't.  (Zero blocks are
+    # handled specially because (1) there are usually a lot of them
+    # and (2) bsdiff handles files with long sequences of repeated
+    # bytes especially poorly.)
+
+    zero_blocks = []
+    nonzero_blocks = []
+    reference = '\0' * self.blocksize
+
+    f = self.simg_f
+    for s, e in remaining:
+      for b in range(s, e):
+        idx = bisect.bisect_right(self.offset_index, b) - 1
+        chunk_start, chunk_len, filepos, fill_data = self.offset_map[idx]
+        if filepos is not None:
+          filepos += (b-chunk_start) * self.blocksize
+          f.seek(filepos, os.SEEK_SET)
+          data = f.read(self.blocksize)
+        else:
+          if fill_data == reference[:4]:   # fill with all zeros
+            data = reference
+          else:
+            data = None
+
+        if data == reference:
+          zero_blocks.append(b)
+          zero_blocks.append(b+1)
+        else:
+          nonzero_blocks.append(b)
+          nonzero_blocks.append(b+1)
+
+    out["__ZERO"] = RangeSet(data=zero_blocks)
+    out["__NONZERO"] = RangeSet(data=nonzero_blocks)
+
+  def ResetFileMap(self):
+    """Throw away the file map and treat the entire image as
+    undifferentiated data."""
+    self.file_map = {"__DATA": self.care_map}
diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java
index 5ed3e10..88f486a 100644
--- a/tools/signapk/SignApk.java
+++ b/tools/signapk/SignApk.java
@@ -621,8 +621,12 @@
             this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId());
         }
 
+        /**
+         * This should actually return byte[] or something similar, but nothing
+         * actually checks it currently.
+         */
         public Object getContent() {
-            throw new UnsupportedOperationException();
+            return this;
         }
 
         public ASN1ObjectIdentifier getContentType() {
diff --git a/target/board/generic_mips/Android.mk b/tools/signtos/Android.mk
similarity index 60%
copy from target/board/generic_mips/Android.mk
copy to tools/signtos/Android.mk
index abf8d57..94ab944 100644
--- a/target/board/generic_mips/Android.mk
+++ b/tools/signtos/Android.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2011 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -13,5 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-
 LOCAL_PATH := $(call my-dir)
+
+# the signtos tool - signs Trusty images
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := signtos
+LOCAL_SRC_FILES := SignTos.java
+LOCAL_JAR_MANIFEST := SignTos.mf
+LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host bouncycastle-bcpkix-host
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/signtos/SignTos.java b/tools/signtos/SignTos.java
new file mode 100644
index 0000000..485ad2f
--- /dev/null
+++ b/tools/signtos/SignTos.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.signtos;
+
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.EncryptedPrivateKeyInfo;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Signs Trusty images for use with operating systems that support it.
+ */
+public class SignTos {
+    /** Size of the signature footer in bytes. */
+    private static final int SIGNATURE_BLOCK_SIZE = 256;
+
+    /** Current signature version code we use. */
+    private static final int VERSION_CODE = 1;
+
+    /** Size of the header on the file to skip. */
+    private static final int HEADER_SIZE = 512;
+
+    private static BouncyCastleProvider sBouncyCastleProvider;
+
+    /**
+     * Reads the password from stdin and returns it as a string.
+     *
+     * @param keyFile The file containing the private key.  Used to prompt the user.
+     */
+    private static String readPassword(File keyFile) {
+        // TODO: use Console.readPassword() when it's available.
+        System.out.print("Enter password for " + keyFile + " (password will not be hidden): ");
+        System.out.flush();
+        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+        try {
+            return stdin.readLine();
+        } catch (IOException ex) {
+            return null;
+        }
+    }
+
+    /**
+     * Decrypt an encrypted PKCS#8 format private key.
+     *
+     * Based on ghstark's post on Aug 6, 2006 at
+     * http://forums.sun.com/thread.jspa?threadID=758133&messageID=4330949
+     *
+     * @param encryptedPrivateKey The raw data of the private key
+     * @param keyFile The file containing the private key
+     */
+    private static PKCS8EncodedKeySpec decryptPrivateKey(byte[] encryptedPrivateKey, File keyFile)
+        throws GeneralSecurityException {
+        EncryptedPrivateKeyInfo epkInfo;
+        try {
+            epkInfo = new EncryptedPrivateKeyInfo(encryptedPrivateKey);
+        } catch (IOException ex) {
+            // Probably not an encrypted key.
+            return null;
+        }
+
+        char[] password = readPassword(keyFile).toCharArray();
+
+        SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName());
+        Key key = skFactory.generateSecret(new PBEKeySpec(password));
+
+        Cipher cipher = Cipher.getInstance(epkInfo.getAlgName());
+        cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters());
+
+        try {
+            return epkInfo.getKeySpec(cipher);
+        } catch (InvalidKeySpecException ex) {
+            System.err.println("signapk: Password for " + keyFile + " may be bad.");
+            throw ex;
+        }
+    }
+
+    /** Read a PKCS#8 format private key. */
+    private static PrivateKey readPrivateKey(File file) throws IOException,
+            GeneralSecurityException {
+        DataInputStream input = new DataInputStream(new FileInputStream(file));
+        try {
+            byte[] bytes = new byte[(int) file.length()];
+            input.read(bytes);
+
+            /* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
+            PKCS8EncodedKeySpec spec = decryptPrivateKey(bytes, file);
+            if (spec == null) {
+                spec = new PKCS8EncodedKeySpec(bytes);
+            }
+
+            /*
+             * Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
+             * OID and use that to construct a KeyFactory.
+             */
+            ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()));
+            PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
+            String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
+
+            return KeyFactory.getInstance(algOid).generatePrivate(spec);
+        } finally {
+            input.close();
+        }
+    }
+
+    /**
+     * Tries to load a JSE Provider by class name. This is for custom PrivateKey
+     * types that might be stored in PKCS#11-like storage.
+     */
+    private static void loadProviderIfNecessary(String providerClassName) {
+        if (providerClassName == null) {
+            return;
+        }
+
+        final Class<?> klass;
+        try {
+            final ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
+            if (sysLoader != null) {
+                klass = sysLoader.loadClass(providerClassName);
+            } else {
+                klass = Class.forName(providerClassName);
+            }
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+            System.exit(1);
+            return;
+        }
+
+        Constructor<?> constructor = null;
+        for (Constructor<?> c : klass.getConstructors()) {
+            if (c.getParameterTypes().length == 0) {
+                constructor = c;
+                break;
+            }
+        }
+        if (constructor == null) {
+            System.err.println("No zero-arg constructor found for " + providerClassName);
+            System.exit(1);
+            return;
+        }
+
+        final Object o;
+        try {
+            o = constructor.newInstance();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+            return;
+        }
+        if (!(o instanceof Provider)) {
+            System.err.println("Not a Provider class: " + providerClassName);
+            System.exit(1);
+        }
+
+        Security.insertProviderAt((Provider) o, 1);
+    }
+
+    private static String getSignatureAlgorithm(Key key) {
+        if ("EC".equals(key.getAlgorithm())) {
+            ECKey ecKey = (ECKey) key;
+            int curveSize = ecKey.getParams().getOrder().bitLength();
+            if (curveSize <= 256) {
+                return "SHA256withECDSA";
+            } else if (curveSize <= 384) {
+                return "SHA384withECDSA";
+            } else {
+                return "SHA512withECDSA";
+            }
+        } else {
+            throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm());
+        }
+    }
+
+    /**
+     * @param inputFilename
+     * @param outputFilename
+     */
+    private static void signWholeFile(InputStream input, OutputStream output, PrivateKey signingKey)
+            throws Exception {
+        Signature sig = Signature.getInstance(getSignatureAlgorithm(signingKey));
+        sig.initSign(signingKey);
+
+        byte[] buffer = new byte[8192];
+
+        /* Skip the header. */
+        int skippedBytes = 0;
+        while (skippedBytes != HEADER_SIZE) {
+            int bytesRead = input.read(buffer, 0, HEADER_SIZE - skippedBytes);
+            output.write(buffer, 0, bytesRead);
+            skippedBytes += bytesRead;
+        }
+
+        int totalBytes = 0;
+        for (;;) {
+            int bytesRead = input.read(buffer);
+            if (bytesRead == -1) {
+                break;
+            }
+            totalBytes += bytesRead;
+            sig.update(buffer, 0, bytesRead);
+            output.write(buffer, 0, bytesRead);
+        }
+
+        byte[] sigBlock = new byte[SIGNATURE_BLOCK_SIZE];
+        sigBlock[0] = VERSION_CODE;
+        sig.sign(sigBlock, 1, sigBlock.length - 1);
+
+        output.write(sigBlock);
+    }
+
+    private static void usage() {
+        System.err.println("Usage: signtos " +
+                           "[-providerClass <className>] " +
+                           " privatekey.pk8 " +
+                           "input.img output.img");
+        System.exit(2);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length < 3) {
+            usage();
+        }
+
+        String providerClass = null;
+        String providerArg = null;
+
+        int argstart = 0;
+        while (argstart < args.length && args[argstart].startsWith("-")) {
+            if ("-providerClass".equals(args[argstart])) {
+                if (argstart + 1 >= args.length) {
+                    usage();
+                }
+                providerClass = args[++argstart];
+                ++argstart;
+            } else {
+                usage();
+            }
+        }
+
+        /*
+         * Should only be "<privatekey> <input> <output>" left.
+         */
+        if (argstart != args.length - 3) {
+            usage();
+        }
+
+        sBouncyCastleProvider = new BouncyCastleProvider();
+        Security.addProvider(sBouncyCastleProvider);
+
+        loadProviderIfNecessary(providerClass);
+
+        String keyFilename = args[args.length - 3];
+        String inputFilename = args[args.length - 2];
+        String outputFilename = args[args.length - 1];
+
+        PrivateKey privateKey = readPrivateKey(new File(keyFilename));
+
+        InputStream input = new BufferedInputStream(new FileInputStream(inputFilename));
+        OutputStream output = new BufferedOutputStream(new FileOutputStream(outputFilename));
+        try {
+            SignTos.signWholeFile(input, output, privateKey);
+        } finally {
+            input.close();
+            output.close();
+        }
+
+        System.out.println("Successfully signed: " + outputFilename);
+    }
+}
diff --git a/tools/signtos/SignTos.mf b/tools/signtos/SignTos.mf
new file mode 100644
index 0000000..d860296
--- /dev/null
+++ b/tools/signtos/SignTos.mf
@@ -0,0 +1 @@
+Main-Class: com.android.signtos.SignTos
diff --git a/tools/zipalign/Android.mk b/tools/zipalign/Android.mk
index 708c8bf..4194f81 100644
--- a/tools/zipalign/Android.mk
+++ b/tools/zipalign/Android.mk
@@ -12,19 +12,21 @@
 	ZipEntry.cpp \
 	ZipFile.cpp
 
-LOCAL_C_INCLUDES += external/zlib
+LOCAL_C_INCLUDES += external/zlib \
+	external/zopfli/src
 
 LOCAL_STATIC_LIBRARIES := \
 	libandroidfw \
 	libutils \
 	libcutils \
-	liblog
+	liblog \
+	libzopfli
 
 ifeq ($(HOST_OS),linux)
 LOCAL_LDLIBS += -lrt
 endif
 
-ifneq ($(strip $(USE_MINGW)),)
+ifdef USE_MINGW
 LOCAL_STATIC_LIBRARIES += libz
 else
 LOCAL_LDLIBS += -lz
diff --git a/tools/zipalign/README.txt b/tools/zipalign/README.txt
index 9c7d07e..0b80b35 100644
--- a/tools/zipalign/README.txt
+++ b/tools/zipalign/README.txt
@@ -5,6 +5,7 @@
 
   -c : check alignment only (does not modify file)
   -f : overwrite existing outfile.zip
+  -p : page align stored shared object files
   -v : verbose output
   <align> is in bytes, e.g. "4" provides 32-bit alignment
   infile.zip is an existing Zip archive
@@ -33,3 +34,7 @@
 
 You can use the "-c" flag to test whether a zip archive is properly aligned.
 
+The "-p" flag aligns any file with a ".so" extension, and which is stored
+uncompressed in the zip archive, to a 4096-byte page boundary.  This
+facilitates directly loading shared libraries from inside a zip archive.
+
diff --git a/tools/zipalign/ZipAlign.cpp b/tools/zipalign/ZipAlign.cpp
index 8b2d1af..a2dfd02 100644
--- a/tools/zipalign/ZipAlign.cpp
+++ b/tools/zipalign/ZipAlign.cpp
@@ -32,19 +32,39 @@
     fprintf(stderr, "Zip alignment utility\n");
     fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
     fprintf(stderr,
-        "Usage: zipalign [-f] [-v] <align> infile.zip outfile.zip\n"
+        "Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
         "       zipalign -c [-v] <align> infile.zip\n\n" );
     fprintf(stderr,
         "  <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
     fprintf(stderr, "  -c: check alignment only (does not modify file)\n");
     fprintf(stderr, "  -f: overwrite existing outfile.zip\n");
+    fprintf(stderr, "  -p: page align stored shared object files\n");
     fprintf(stderr, "  -v: verbose output\n");
+    fprintf(stderr, "  -z: recompress using Zopfli\n");
+}
+
+static int getAlignment(bool pageAlignSharedLibs, int defaultAlignment,
+    ZipEntry* pEntry) {
+
+    static const int kPageAlignment = 4096;
+
+    if (!pageAlignSharedLibs) {
+        return defaultAlignment;
+    }
+
+    const char* ext = strrchr(pEntry->getFileName(), '.');
+    if (ext && strcmp(ext, ".so") == 0) {
+        return kPageAlignment;
+    }
+
+    return defaultAlignment;
 }
 
 /*
  * Copy all entries from "pZin" to "pZout", aligning as needed.
  */
-static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment)
+static int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfli,
+    bool pageAlignSharedLibs)
 {
     int numEntries = pZin->getNumEntries();
     ZipEntry* pEntry;
@@ -67,21 +87,29 @@
             //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
             //    (long) pEntry->getUncompressedLen());
 
+            if (zopfli) {
+                status = pZout->addRecompress(pZin, pEntry, &pNewEntry);
+                bias += pNewEntry->getCompressedLen() - pEntry->getCompressedLen();
+            } else {
+                status = pZout->add(pZin, pEntry, padding, &pNewEntry);
+            }
         } else {
+            const int alignTo = getAlignment(pageAlignSharedLibs, alignment, pEntry);
+
             /*
              * Copy the entry, adjusting as required.  We assume that the
              * file position in the new file will be equal to the file
              * position in the original.
              */
             long newOffset = pEntry->getFileOffset() + bias;
-            padding = (alignment - (newOffset % alignment)) % alignment;
+            padding = (alignTo - (newOffset % alignTo)) % alignTo;
 
             //printf("--- %s: orig at %ld(+%d) len=%ld, adding pad=%d\n",
             //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
             //    bias, (long) pEntry->getUncompressedLen(), padding);
+            status = pZout->add(pZin, pEntry, padding, &pNewEntry);
         }
 
-        status = pZout->add(pZin, pEntry, padding, &pNewEntry);
         if (status != NO_ERROR)
             return 1;
         bias += padding;
@@ -98,7 +126,7 @@
  * output file exists and "force" wasn't specified.
  */
 static int process(const char* inFileName, const char* outFileName,
-    int alignment, bool force)
+    int alignment, bool force, bool zopfli, bool pageAlignSharedLibs)
 {
     ZipFile zin, zout;
 
@@ -129,7 +157,7 @@
         return 1;
     }
 
-    int result = copyAndAlign(&zin, &zout, alignment);
+    int result = copyAndAlign(&zin, &zout, alignment, zopfli, pageAlignSharedLibs);
     if (result != 0) {
         printf("zipalign: failed rewriting '%s' to '%s'\n",
             inFileName, outFileName);
@@ -140,7 +168,8 @@
 /*
  * Verify the alignment of a zip archive.
  */
-static int verify(const char* fileName, int alignment, bool verbose)
+static int verify(const char* fileName, int alignment, bool verbose,
+    bool pageAlignSharedLibs)
 {
     ZipFile zipFile;
     bool foundBad = false;
@@ -165,11 +194,12 @@
             }
         } else {
             long offset = pEntry->getFileOffset();
-            if ((offset % alignment) != 0) {
+            const int alignTo = getAlignment(pageAlignSharedLibs, alignment, pEntry);
+            if ((offset % alignTo) != 0) {
                 if (verbose) {
                     printf("%8ld %s (BAD - %ld)\n",
                         (long) offset, pEntry->getFileName(),
-                        offset % alignment);
+                        offset % alignTo);
                 }
                 foundBad = true;
             } else {
@@ -196,6 +226,8 @@
     bool check = false;
     bool force = false;
     bool verbose = false;
+    bool zopfli = false;
+    bool pageAlignSharedLibs = false;
     int result = 1;
     int alignment;
     char* endp;
@@ -222,6 +254,12 @@
             case 'v':
                 verbose = true;
                 break;
+            case 'z':
+                zopfli = true;
+                break;
+            case 'p':
+                pageAlignSharedLibs = true;
+                break;
             default:
                 fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
                 wantUsage = true;
@@ -249,14 +287,15 @@
 
     if (check) {
         /* check existing archive for correct alignment */
-        result = verify(argv[1], alignment, verbose);
+        result = verify(argv[1], alignment, verbose, pageAlignSharedLibs);
     } else {
         /* create the new archive */
-        result = process(argv[1], argv[2], alignment, force);
+        result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs);
 
         /* trust, but verify */
-        if (result == 0)
-            result = verify(argv[2], alignment, verbose);
+        if (result == 0) {
+            result = verify(argv[2], alignment, verbose, pageAlignSharedLibs);
+        }
     }
 
 bail:
diff --git a/tools/zipalign/ZipEntry.cpp b/tools/zipalign/ZipEntry.cpp
index d4d366d..b2270cb 100644
--- a/tools/zipalign/ZipEntry.cpp
+++ b/tools/zipalign/ZipEntry.cpp
@@ -356,7 +356,7 @@
  */
 void ZipEntry::setModWhen(time_t when)
 {
-#ifdef HAVE_LOCALTIME_R
+#if !defined(_WIN32)
     struct tm tmResult;
 #endif
     time_t even;
@@ -368,7 +368,7 @@
     even = (time_t)(((unsigned long)(when) + 1) & (~1));
 
     /* expand */
-#ifdef HAVE_LOCALTIME_R
+#if !defined(_WIN32)
     ptm = localtime_r(&even, &tmResult);
 #else
     ptm = localtime(&even);
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index 8057068..3c5ec15 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -28,6 +28,8 @@
 #include <zlib.h>
 #define DEF_MEM_LEVEL 8                // normally in zutil.h?
 
+#include "zopfli/deflate.h"
+
 #include <memory.h>
 #include <sys/stat.h>
 #include <errno.h>
@@ -638,6 +640,141 @@
 }
 
 /*
+ * Add an entry by copying it from another zip file, recompressing with
+ * Zopfli if already compressed.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+    ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result;
+    long lfhPosn, startPosn, endPosn, uncompressedLen;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    if (pEntry == NULL) {
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
+    if (result != NO_ERROR)
+        goto bail;
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH, even though it's still mostly blank.  We need it
+     * as a place-holder.  In theory the LFH isn't necessary, but in
+     * practice some utilities demand it.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+    startPosn = ftell(mZipFp);
+
+    /*
+     * Copy the data over.
+     *
+     * If the "has data descriptor" flag is set, we want to copy the DD
+     * fields as well.  This is a fixed-size area immediately following
+     * the data.
+     */
+    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
+    {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    uncompressedLen = pSourceEntry->getUncompressedLen();
+
+    if (pSourceEntry->isCompressed()) {
+        void *buf = pSourceZip->uncompress(pSourceEntry);
+        if (buf == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        long startPosn = ftell(mZipFp);
+        unsigned long crc;
+        if (compressFpToFp(mZipFp, NULL, buf, uncompressedLen, &crc) != NO_ERROR) {
+            ALOGW("recompress of '%s' failed\n", pEntry->mCDE.mFileName);
+            result = UNKNOWN_ERROR;
+            free(buf);
+            goto bail;
+        }
+        long endPosn = ftell(mZipFp);
+        pEntry->setDataInfo(uncompressedLen, endPosn - startPosn,
+            pSourceEntry->getCRC32(), ZipEntry::kCompressDeflated);
+        free(buf);
+    } else {
+        off_t copyLen;
+        copyLen = pSourceEntry->getCompressedLen();
+        if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
+            copyLen += ZipEntry::kDataDescriptorLen;
+
+        if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
+            != NO_ERROR)
+        {
+            ALOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+    }
+
+    /*
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setLFHOffset(lfhPosn);
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Go back and write the LFH.
+     */
+    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+    result = NO_ERROR;
+
+bail:
+    delete pEntry;
+    return result;
+}
+
+/*
  * Copy all of the bytes in "src" to "dst".
  *
  * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
@@ -744,73 +881,43 @@
     const void* data, size_t size, unsigned long* pCRC32)
 {
     status_t result = NO_ERROR;
-    const size_t kBufSize = 32768;
+    const size_t kBufSize = 1024 * 1024;
     unsigned char* inBuf = NULL;
     unsigned char* outBuf = NULL;
-    z_stream zstream;
+    size_t outSize = 0;
     bool atEof = false;     // no feof() aviailable yet
     unsigned long crc;
-    int zerr;
+    ZopfliOptions options;
+    unsigned char bp = 0;
 
-    /*
-     * Create an input buffer and an output buffer.
-     */
-    inBuf = new unsigned char[kBufSize];
-    outBuf = new unsigned char[kBufSize];
-    if (inBuf == NULL || outBuf == NULL) {
-        result = NO_MEMORY;
-        goto bail;
-    }
-
-    /*
-     * Initialize the zlib stream.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = outBuf;
-    zstream.avail_out = kBufSize;
-    zstream.data_type = Z_UNKNOWN;
-
-    zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
-        Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-    if (zerr != Z_OK) {
-        result = UNKNOWN_ERROR;
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
+    ZopfliInitOptions(&options);
 
     crc = crc32(0L, Z_NULL, 0);
 
-    /*
-     * Loop while we have data.
-     */
-    do {
-        size_t getSize;
-        int flush;
+    if (data) {
+        crc = crc32(crc, (const unsigned char*)data, size);
+        ZopfliDeflate(&options, 2, true, (const unsigned char*)data, size, &bp,
+            &outBuf, &outSize);
+    } else {
+        /*
+         * Create an input buffer and an output buffer.
+         */
+        inBuf = new unsigned char[kBufSize];
+        if (inBuf == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
 
-        /* only read if the input buffer is empty */
-        if (zstream.avail_in == 0 && !atEof) {
-            ALOGV("+++ reading %d bytes\n", (int)kBufSize);
-            if (data) {
-                getSize = size > kBufSize ? kBufSize : size;
-                memcpy(inBuf, data, getSize);
-                data = ((const char*)data) + getSize;
-                size -= getSize;
-            } else {
-                getSize = fread(inBuf, 1, kBufSize, srcFp);
-                if (ferror(srcFp)) {
-                    ALOGD("deflate read failed (errno=%d)\n", errno);
-                    goto z_bail;
-                }
+        /*
+         * Loop while we have data.
+         */
+        do {
+            size_t getSize;
+            getSize = fread(inBuf, 1, kBufSize, srcFp);
+            if (ferror(srcFp)) {
+                ALOGD("deflate read failed (errno=%d)\n", errno);
+                delete[] inBuf;
+                goto bail;
             }
             if (getSize < kBufSize) {
                 ALOGV("+++  got %d bytes, EOF reached\n",
@@ -819,51 +926,21 @@
             }
 
             crc = crc32(crc, inBuf, getSize);
+            ZopfliDeflate(&options, 2, atEof, inBuf, getSize, &bp, &outBuf, &outSize);
+        } while (!atEof);
+        delete[] inBuf;
+    }
 
-            zstream.next_in = inBuf;
-            zstream.avail_in = getSize;
-        }
-
-        if (atEof)
-            flush = Z_FINISH;       /* tell zlib that we're done */
-        else
-            flush = Z_NO_FLUSH;     /* more to come! */
-
-        zerr = deflate(&zstream, flush);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib deflate call failed (zerr=%d)\n", zerr);
-            result = UNKNOWN_ERROR;
-            goto z_bail;
-        }
-
-        /* write when we're full or when we're done */
-        if (zstream.avail_out == 0 ||
-            (zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))
-        {
-            ALOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
-            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
-                (size_t)(zstream.next_out - outBuf))
-            {
-                ALOGD("write %d failed in deflate\n",
-                    (int) (zstream.next_out - outBuf));
-                goto z_bail;
-            }
-
-            zstream.next_out = outBuf;
-            zstream.avail_out = kBufSize;
-        }
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+    ALOGV("+++ writing %d bytes\n", (int)outSize);
+    if (fwrite(outBuf, 1, outSize, dstFp) != outSize) {
+        ALOGD("write %d failed in deflate\n", (int)outSize);
+        goto bail;
+    }
 
     *pCRC32 = crc;
 
-z_bail:
-    deflateEnd(&zstream);        /* free up any allocated structures */
-
 bail:
-    delete[] inBuf;
-    delete[] outBuf;
+    free(outBuf);
 
     return result;
 }
@@ -1148,7 +1225,7 @@
 #endif
 
 // free the memory when you're done
-void* ZipFile::uncompress(const ZipEntry* entry)
+void* ZipFile::uncompress(const ZipEntry* entry) const
 {
     size_t unlen = entry->getUncompressedLen();
     size_t clen = entry->getCompressedLen();
diff --git a/tools/zipalign/ZipFile.h b/tools/zipalign/ZipFile.h
index 7877550..b99cda5 100644
--- a/tools/zipalign/ZipFile.h
+++ b/tools/zipalign/ZipFile.h
@@ -127,6 +127,15 @@
         int padding, ZipEntry** ppEntry);
 
     /*
+     * Add an entry by copying it from another zip file, recompressing with
+     * Zopfli if already compressed.
+     *
+     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+     */
+    status_t addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+        ZipEntry** ppEntry);
+
+    /*
      * Mark an entry as having been removed.  It is not actually deleted
      * from the archive or our internal data structures until flush() is
      * called.
@@ -147,7 +156,7 @@
      */
     //bool uncompress(const ZipEntry* pEntry, void* buf) const;
     //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
-    void* uncompress(const ZipEntry* pEntry);
+    void* uncompress(const ZipEntry* pEntry) const;
 
     /*
      * Get an entry, by name.  Returns NULL if not found.