am fcab8402: Merge "Add in MonkeyRunner target (and dependent libs) to SDK build."

Merge commit 'fcab84025edd6ff0a7b1f380b75b99297e0b7c31' into gingerbread-plus-aosp

* commit 'fcab84025edd6ff0a7b1f380b75b99297e0b7c31':
  Add in MonkeyRunner target (and dependent libs) to SDK build.
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e1b6..2663780 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -44,6 +44,13 @@
 #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
 #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
 
-# ************************************************
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libmediaplayerservice_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libmedia_jni_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libstagefright_omx_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/android-info.txt)
+$(call add-clean-step, find $(PRODUCT_OUT) -name "*.apk" | xargs rm)
+
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 71b42a2..37e625d 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -73,7 +73,7 @@
 
 # The string used to uniquely identify this build;  used by the OTA server.
 ifeq (,$(strip $(BUILD_FINGERPRINT)))
-  BUILD_FINGERPRINT := $(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE)/$(TARGET_BOOTLOADER_BOARD_NAME):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
+  BUILD_FINGERPRINT := $(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)
 endif
 ifneq ($(words $(BUILD_FINGERPRINT)),1)
   $(error BUILD_FINGERPRINT cannot contain spaces: "$(BUILD_FINGERPRINT)")
@@ -206,7 +206,12 @@
 # but it should guarantee that the apkcerts file is rebuilt
 # if any packages change which certs they're signed with.
 all_built_packages := $(foreach p,$(PACKAGES),$(ALL_MODULES.$(p).BUILT))
+ifneq ($(TARGET_BUILD_APPS),)
+# We don't need to really build all the modules for apps_only build.
+$(APKCERTS_FILE):
+else
 $(APKCERTS_FILE): $(all_built_packages)
+endif
 	@echo APK certs list: $@
 	@mkdir -p $(dir $@)
 	@rm -f $@
@@ -220,6 +225,8 @@
 .PHONY: apkcerts-list
 apkcerts-list: $(APKCERTS_FILE)
 
+$(call dist-for-goals, apps_only, $(APKCERTS_FILE):apkcerts.txt)
+
 # -----------------------------------------------------------------
 # module info file
 ifdef CREATE_MODULE_INFO_FILE
@@ -252,8 +259,23 @@
 
 .PHONY: event-log-tags
 
+# Produce an event logs tag file for everything we know about, in order
+# to properly allocate numbers.  Then produce a file that's filtered
+# for what's going to be installed.
+
+all_event_log_tags_file := $(TARGET_OUT_COMMON_INTERMEDIATES)/all-event-log-tags.txt
+
+# Include tags from all packages that we know about
+all_event_log_tags_src := \
+    $(sort $(foreach m, $(ALL_MODULES), $(ALL_MODULES.$(m).EVENT_LOG_TAGS)))
+
+$(all_event_log_tags_file): PRIVATE_SRC_FILES := $(all_event_log_tags_src)
+$(all_event_log_tags_file): $(all_event_log_tags_src)
+	$(hide) mkdir -p $(dir $@)
+	$(hide) build/tools/merge-event-log-tags.py -o $@ $(PRIVATE_SRC_FILES)
+
+
 event_log_tags_file := $(TARGET_OUT)/etc/event-log-tags
-ALL_PREBUILT += $(event_log_tag_file)
 
 # Include tags from all packages included in this product.
 event_log_tags_src := \
@@ -263,14 +285,16 @@
       $(ALL_MODULES.$(m).EVENT_LOG_TAGS)))
 
 $(event_log_tags_file): PRIVATE_SRC_FILES := $(event_log_tags_src)
-$(event_log_tags_file): $(event_log_tags_src)
+$(event_log_tags_file): PRIVATE_MERGED_FILE := $(all_event_log_tags_file)
+$(event_log_tags_file): $(event_log_tags_src) $(all_event_log_tags_file)
 	$(hide) mkdir -p $(dir $@)
-	$(hide) build/tools/merge-event-log-tags.py -o $@ $(PRIVATE_SRC_FILES)
+	$(hide) build/tools/merge-event-log-tags.py -o $@ -m $(PRIVATE_MERGED_FILE) $(PRIVATE_SRC_FILES)
 
 event-log-tags: $(event_log_tags_file)
 
 ALL_DEFAULT_INSTALLED_MODULES += $(event_log_tags_file)
 
+
 ifneq ($(TARGET_SIMULATOR),true)
 
 # #################################################################
@@ -315,6 +339,11 @@
   INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
 endif
 
+BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
+ifdef BOARD_KERNEL_PAGESIZE
+  INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
+endif
+
 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
 
 ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
@@ -521,11 +550,38 @@
 # Targets for user images
 # #################################################################
 
+INTERNAL_USERIMAGES_EXT_VARIANT :=
 ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
-include external/genext2fs/Config.mk
-INTERNAL_MKUSERFS := $(MKEXT2IMG)
+INTERNAL_USERIMAGES_USE_EXT := true
+INTERNAL_USERIMAGES_EXT_VARIANT := ext2
 else
-INTERNAL_MKUSERFS := $(MKYAFFS2)
+ifeq ($(TARGET_USERIMAGES_USE_EXT3),true)
+INTERNAL_USERIMAGES_USE_EXT := true
+INTERNAL_USERIMAGES_EXT_VARIANT := ext3
+else
+ifeq ($(TARGET_USERIMAGES_USE_EXT4),true)
+INTERNAL_USERIMAGES_USE_EXT := true
+INTERNAL_USERIMAGES_EXT_VARIANT := ext4
+endif
+endif
+endif
+
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
+INTERNAL_USERIMAGES_DEPS := $(MKEXT2USERIMG) $(MAKE_EXT4FS)
+INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
+
+# $(1): src directory
+# $(2): output file
+# $(3): mount point
+# $(4): ext variant (ext2, ext3, ext4)
+# $(5): size of the partition
+define build-userimage-ext-target
+  @mkdir -p $(dir $(2))
+    $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$(PATH) \
+	  $(MKEXT2USERIMG) $(1) $(2) $(4) $(3) $(5)
+endef
+else
+INTERNAL_USERIMAGES_DEPS := $(MKYAFFS2)
 endif
 
 # -----------------------------------------------------------------
@@ -545,11 +601,16 @@
 recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res))
 recovery_resource_deps := $(shell find $(recovery_resources_common) \
   $(recovery_resources_private) -type f)
+recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab))
 
 ifeq ($(recovery_resources_private),)
   $(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE))
 endif
 
+ifeq ($(recovery_fstab),)
+  $(info No recovery.fstab for TARGET_DEVICE $(TARGET_DEVICE))
+endif
+
 INTERNAL_RECOVERYIMAGE_ARGS := \
 	$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
 	--kernel $(recovery_kernel) \
@@ -562,6 +623,10 @@
 ifdef BOARD_KERNEL_BASE
   INTERNAL_RECOVERYIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
 endif
+BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
+ifdef BOARD_KERNEL_PAGESIZE
+  INTERNAL_RECOVERYIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
+endif
 
 # Keys authorized to sign OTA packages this build will accept.  The
 # build always uses test-keys for this; release packaging tools will
@@ -587,6 +652,7 @@
 		$(recovery_initrc) $(recovery_kernel) \
 		$(INSTALLED_2NDBOOTLOADER_TARGET) \
 		$(recovery_build_prop) $(recovery_resource_deps) \
+		$(recovery_fstab) \
 		$(RECOVERY_INSTALL_OTA_KEYS)
 	@echo ----- Making recovery image ------
 	rm -rf $(TARGET_RECOVERY_OUT)
@@ -596,12 +662,15 @@
 	mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp
 	echo Copying baseline ramdisk...
 	cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+	rm $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
 	echo Modifying ramdisk contents...
 	cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
 	cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/
 	cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/
 	$(foreach item,$(recovery_resources_private), \
 	  cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)
+	$(foreach item,$(recovery_fstab), \
+	  cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)
 	cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
 	cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
 	        > $(TARGET_RECOVERY_ROOT_OUT)/default.prop
@@ -625,14 +694,11 @@
 
 
 # -----------------------------------------------------------------
-# system yaffs image
+# system image
 #
-# First, the "unoptimized" image, which contains .apk/.jar files
-# that contain regular, unoptimized/unverified .dex entries.
-#
-systemimage_unopt_intermediates := \
-	$(call intermediates-dir-for,PACKAGING,systemimage_unopt)
-BUILT_SYSTEMIMAGE_UNOPT := $(systemimage_unopt_intermediates)/system.img
+systemimage_intermediates := \
+	$(call intermediates-dir-for,PACKAGING,systemimage)
+BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img
 
 INTERNAL_SYSTEMIMAGE_FILES := $(filter $(TARGET_OUT)/%, \
 	$(ALL_PREBUILT) \
@@ -640,15 +706,15 @@
 	$(ALL_GENERATED_SOURCES) \
 	$(ALL_DEFAULT_INSTALLED_MODULES))
 
-ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
 ## generate an ext2 image
 # $(1): output file
 define build-systemimage-target
     @echo "Target system fs image: $(1)"
-    $(call build-userimage-ext2-target,$(TARGET_OUT),$(1),system,)
+    $(call build-userimage-ext-target,$(TARGET_OUT),$(1),system,$(INTERNAL_USERIMAGES_EXT_VARIANT),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 endef
 
-else # TARGET_USERIMAGES_USE_EXT2 != true
+else # INTERNAL_USERIMAGES_USE_EXT != true
 
 ## generate a yaffs2 image
 # $(1): output file
@@ -657,27 +723,13 @@
     @mkdir -p $(dir $(1))
     $(hide) $(MKYAFFS2) -f $(mkyaffs2_extra_flags) $(TARGET_OUT) $(1)
 endef
-endif # TARGET_USERIMAGES_USE_EXT2
+endif # INTERNAL_USERIMAGES_USE_EXT
 
-$(BUILT_SYSTEMIMAGE_UNOPT): $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_MKUSERFS)
+$(BUILT_SYSTEMIMAGE): $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
 	$(call build-systemimage-target,$@)
 
-# The installed image, which may be optimized or unoptimized.
-#
 INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img
-
-ifdef WITH_DEXPREOPT
-  ifndef DISABLE_DEXPREOPT
-    with_dexpreopt := true
-  endif
-endif
-ifdef with_dexpreopt
-  # This file will set BUILT_SYSTEMIMAGE and SYSTEMIMAGE_SOURCE_DIR
-  include build/tools/dexpreopt/Config.mk
-else
-  BUILT_SYSTEMIMAGE := $(BUILT_SYSTEMIMAGE_UNOPT)
-  SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT)
-endif
+SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT)
 
 # The system partition needs room for the recovery image as well.  We
 # now store the recovery image as a binary patch using the boot image
@@ -706,7 +758,7 @@
 
 .PHONY: systemimage-nodeps snod
 systemimage-nodeps snod: $(filter-out systemimage-nodeps snod,$(MAKECMDGOALS)) \
-	            | $(INTERNAL_MKUSERFS)
+	            | $(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)
@@ -772,16 +824,16 @@
 INTERNAL_USERDATAIMAGE_FILES := \
 	$(filter $(TARGET_OUT_DATA)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
 
-ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
-## Generate an ext2 image
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
+## Generate an ext image
 define build-userdataimage-target
     $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
     @mkdir -p $(TARGET_OUT_DATA)
-    $(call build-userimage-ext2-target,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET),userdata,)
+    $(call build-userimage-ext-target,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET),data,$(INTERNAL_USERIMAGES_EXT_VARIANT),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
     $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
 endef
 
-else # TARGET_USERIMAGES_USE_EXT2 != true
+else # INTERNAL_USERIMAGES_USE_EXT != true
 
 ## Generate a yaffs2 image
 define build-userdataimage-target
@@ -790,18 +842,18 @@
     $(hide) $(MKYAFFS2) -f $(mkyaffs2_extra_flags) $(TARGET_OUT_DATA) $(INSTALLED_USERDATAIMAGE_TARGET)
     $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
 endef
-endif # TARGET_USERIMAGES_USE_EXT2
+endif # INTERNAL_USERIMAGES_USE_EXT
 
 BUILT_USERDATAIMAGE_TARGET := $(PRODUCT_OUT)/userdata.img
 
 # We just build this directly to the install location.
 INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)
-$(INSTALLED_USERDATAIMAGE_TARGET): $(INTERNAL_MKUSERFS) \
+$(INSTALLED_USERDATAIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) \
                                    $(INTERNAL_USERDATAIMAGE_FILES)
 	$(build-userdataimage-target)
 
 .PHONY: userdataimage-nodeps
-userdataimage-nodeps: $(INTERNAL_MKUSERFS)
+userdataimage-nodeps: $(INTERNAL_USERIMAGES_DEPS)
 	$(build-userdataimage-target)
 
 #######
@@ -925,6 +977,9 @@
 ifdef BOARD_KERNEL_BASE
 	$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/base
 endif
+ifdef BOARD_KERNEL_PAGESIZE
+	$(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/RECOVERY/pagesize
+endif
 	@# Components of the boot image
 	$(hide) mkdir -p $(zip_root)/BOOT
 	$(hide) $(call package_files-copy-root, \
@@ -942,6 +997,9 @@
 ifdef BOARD_KERNEL_BASE
 	$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base
 endif
+ifdef BOARD_KERNEL_PAGESIZE
+	$(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/BOOT/pagesize
+endif
 	$(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\
 	            mkdir -p $(zip_root)/RADIO; \
 	            $(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)
@@ -960,13 +1018,26 @@
 	$(hide) mkdir -p $(zip_root)/META
 	$(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
 	$(hide)	echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
-	$(hide) echo "$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/recovery-api-version.txt
-	$(hide) echo "blocksize $(BOARD_FLASH_BLOCK_SIZE)" > $(zip_root)/META/imagesizes.txt
-	$(hide) echo "boot $(call image-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "recovery $(call image-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "system $(call image-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "userdata $(call image-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "$(tool_extensions)" > $(zip_root)/META/tool-extensions.txt
+	$(hide) echo "recovery_api_version=$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/misc_info.txt
+ifdef BOARD_FLASH_BLOCK_SIZE
+	$(hide) echo "blocksize=$(BOARD_FLASH_BLOCK_SIZE)" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
+	$(hide) echo "boot_size=$(BOARD_BOOTIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
+	$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_SYSTEMIMAGE_PARTITION_SIZE
+	$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_USERDATAIMAGE_PARTITION_SIZE
+	$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
+endif
+	$(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt
+ifdef mkyaffs2_extra_flags
+	$(hide) echo "mkyaffs2_extra_flags=$(mkyaffs2_extra_flags)" >> $(zip_root)/META/misc_info.txt
+endif
 	@# Zip everything up, preserving symlinks
 	$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
 	@# Run fs_config on all the system files in the zip, and save the output
@@ -982,6 +1053,7 @@
 ifneq ($(TARGET_SIMULATOR),true)
 ifneq ($(TARGET_PRODUCT),sdk)
 ifneq ($(TARGET_DEVICE),generic)
+ifneq ($(TARGET_NO_KERNEL),true)
 
 name := $(TARGET_PRODUCT)
 ifeq ($(TARGET_BUILD_TYPE),debug)
@@ -993,17 +1065,9 @@
 
 $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
 
-ifeq ($(TARGET_OTA_SCRIPT_MODE),)
-# default to "auto"
-$(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := auto
-else
-$(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := $(TARGET_OTA_SCRIPT_MODE)
-endif
-
 $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
 	@echo "Package OTA: $@"
-	$(hide) ./build/tools/releasetools/ota_from_target_files \
-	   -m $(scriptmode) \
+	$(hide) ./build/tools/releasetools/ota_from_target_files -v \
 	   -p $(HOST_OUT) \
            -k $(KEY_CERT_PAIR) \
            $(BUILT_TARGET_FILES_PACKAGE) $@
@@ -1011,6 +1075,7 @@
 .PHONY: otapackage
 otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
 
+endif    # TARGET_NO_KERNEL != true
 endif    # TARGET_DEVICE != generic
 endif    # TARGET_PRODUCT != sdk
 endif    # TARGET_SIMULATOR != true
@@ -1070,8 +1135,20 @@
 		$(TARGET_OUT_DATA),$(zip_root)/DATA)
 	$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
 
+.PHONY: tests-zip-package
 tests-zip-package: $(BUILT_TESTS_ZIP_PACKAGE)
 
+# Target needed by tests build
+.PHONY: tests-build-target
+tests-build-target: $(BUILT_TESTS_ZIP_PACKAGE) \
+                    $(BUILT_USERDATAIMAGE_TARGET)
+
+ifneq (,$(filter $(MAKECMDGOALS),tests-build-target))
+  $(call dist-for-goals, tests-build-target, \
+          $(BUILT_TESTS_ZIP_PACKAGE) \
+          $(BUILT_USERDATAIMAGE_TARGET))
+endif
+
 # -----------------------------------------------------------------
 # A zip of the symbols directory.  Keep the full paths to make it
 # more obvious where these files came from.
@@ -1106,6 +1183,17 @@
 	$(hide) mkdir -p $(dir $@)
 	$(hide) zip -qj $@ $(TARGET_OUT_APPS)/*
 
+
+#------------------------------------------------------------------
+# A zip of emma code coverage meta files. Generated for fully emma
+# instrumented build.
+#
+EMMA_META_ZIP := $(PRODUCT_OUT)/emma_meta.zip
+$(EMMA_META_ZIP): $(INSTALLED_SYSTEMIMAGE)
+	@echo "Collecting Emma coverage meta files."
+	$(hide) find $(TARGET_COMMON_OUT_ROOT) -name "coverage.em" | \
+		zip -@ -q $@
+
 endif	# TARGET_SIMULATOR != true
 
 # -----------------------------------------------------------------
@@ -1136,7 +1224,7 @@
 
 $(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
 	@echo "Package: $@"
-	$(hide) ./build/tools/releasetools/img_from_target_files \
+	$(hide) ./build/tools/releasetools/img_from_target_files -v \
 	   -s $(extensions) \
 	   -p $(HOST_OUT) \
 	   $(BUILT_TARGET_FILES_PACKAGE) $@
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 2b95a5c..7e2e127 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -69,6 +69,36 @@
 $(warning unusual tags $(LOCAL_MODULE_TAGS) on $(LOCAL_MODULE) at $(LOCAL_PATH))
 endif
 
+ifneq ($(filter $(LOCAL_MODULE_TAGS),user),)
+  ifeq ($(filter $(GRANDFATHERED_USER_MODULES),$(LOCAL_MODULE)),)
+    $(warning *** Module name: $(LOCAL_MODULE))
+    $(warning *** Makefile location: $(LOCAL_PATH))
+    $(warning * )
+    $(warning * Each module must use a LOCAL_MODULE_TAGS in its)
+    $(warning * Android.mk. Possible tags declared by a module:)
+    $(warning * )
+    $(warning *     optional, debug, eng, tests, samples)
+    $(warning * )
+    $(warning * If the module is expected to be in all builds)
+    $(warning * of a product, then it should use the)
+    $(warning * "optional" tag: )
+    $(warning * )
+    $(warning *    Add "LOCAL_MODULE_TAGS := optional" in the)
+    $(warning *    Android.mk for the affected module, and add)
+    $(warning *    the LOCAL_MODULE value for that component)
+    $(warning *    into the PRODUCT_PACKAGES section of product)
+    $(warning *    makefile(s) where it's necessary, if)
+    $(warning *    appropriate.)
+    $(warning * )
+    $(warning * If the component should be in EVERY build of ALL)
+    $(warning * products, then add its LOCAL_MODULE value to the)
+    $(warning * PRODUCT_PACKAGES section of)
+    $(warning * build/target/product/core.mk)
+    $(warning * )
+    $(error user tag detected on new module - user tags are only supported on legacy modules)
+  endif
+endif
+
 # Add implicit tags.
 #
 # If the local directory or one of its parents contains a MODULE_LICENSE_GPL
@@ -222,7 +252,7 @@
 logtags_java_sources := $(patsubst %.logtags,%.java,$(addprefix $(intermediates.COMMON)/src/, $(logtags_sources)))
 logtags_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(logtags_sources))
 
-$(logtags_java_sources): $(intermediates.COMMON)/src/%.java: $(TOPDIR)$(LOCAL_PATH)/%.logtags $(TARGET_OUT)/etc/event-log-tags
+$(logtags_java_sources): $(intermediates.COMMON)/src/%.java: $(TOPDIR)$(LOCAL_PATH)/%.logtags $(TARGET_OUT_COMMON_INTERMEDIATES)/all-event-log-tags.txt
 	$(transform-logtags-to-java)
 
 endif
@@ -312,7 +342,7 @@
 full_static_java_libs := \
     $(foreach lib,$(LOCAL_STATIC_JAVA_LIBRARIES), \
       $(call intermediates-dir-for, \
-        JAVA_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE))/javalib.jar)
+        JAVA_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE),COMMON)/javalib.jar)
 
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_INSTALL_DIR := $(dir $(LOCAL_INSTALLED_MODULE))
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates)/classes
@@ -343,23 +373,16 @@
 ifdef LOCAL_IS_HOST_MODULE
 # TODO: make prebuilt java libraries use the same
 #       intermediates path pattern as target java libraries.
+ifeq ($(LOCAL_BUILD_HOST_DEX),true)
+full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+else
 full_java_libs := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,$(addsuffix $(COMMON_JAVA_PACKAGE_SUFFIX),$(LOCAL_JAVA_LIBRARIES)))
 full_java_lib_deps := $(full_java_libs)
-else
-ifdef LOCAL_SDK_VERSION
-ifneq ($(LOCAL_SDK_VERSION),current)
-full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-# For prebuilt sdk versions, we can't depend on the javalib.jar but classes.jar.
-full_java_lib_deps := $(call java-lib-deps,$(filter-out sdk_v$(LOCAL_SDK_VERSION),$(LOCAL_JAVA_LIBRARIES)),$(LOCAL_IS_HOST_MODULE))
-full_java_lib_deps += $(call java-lib-files,sdk_v$(LOCAL_SDK_VERSION),$(LOCAL_IS_HOST_MODULE))
+endif # LOCAL_BUILD_HOST_DEX
 else
 full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
 full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-endif # !current
-else
-full_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-endif # LOCAL_SDK_VERSION
 endif # !LOCAL_IS_HOST_MODULE
 full_java_libs += $(full_static_java_libs) $(LOCAL_CLASSPATH)
 full_java_lib_deps += $(full_static_java_libs) $(LOCAL_CLASSPATH)
@@ -380,11 +403,8 @@
       APPS,$(LOCAL_INSTRUMENTATION_FOR),,COMMON)
 
   # link against the jar with full original names (before proguard processing).
-  full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes-full-names.jar
-
-  # We can't depend on the .jar file, so we depend on something that
-  # depends on the jar file; the final built package file.
-  full_java_lib_deps += $(link_instr_intermediates_dir)/package.apk
+  full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes.jar
+  full_java_lib_deps += $(link_instr_intermediates_dir.COMMON)/classes.jar
 endif
 
 ifneq ($(strip $(LOCAL_JAR_MANIFEST)),)
@@ -420,7 +440,7 @@
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_AAPT_FLAGS:= $(LOCAL_AAPT_FLAGS)
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_JAVA_LIBRARIES:= $(LOCAL_JAVA_LIBRARIES)
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_MANIFEST_PACKAGE_NAME:= $(LOCAL_MANIFEST_PACKAGE_NAME)
-$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME:= $(LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME)
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_MANIFEST_INSTRUMENTATION_FOR:= $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
 
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_ALL_JAVA_LIBRARIES:= $(full_java_libs)
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_IS_HOST_MODULE := $(LOCAL_IS_HOST_MODULE)
@@ -460,6 +480,16 @@
 	$(copy-file-to-target-with-cp)
 endif
 
+ifeq ($(LOCAL_DEX_PREOPT),true)
+installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex
+built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
+$(installed_odex) : $(built_odex) | $(ACP)
+	@echo "Install: $@"
+	$(copy-file-to-target)
+
+$(LOCAL_INSTALLED_MODULE) : | $(installed_odex)
+endif
+
 endif # !LOCAL_UNINSTALLABLE_MODULE
 
 
@@ -507,6 +537,10 @@
     $(ALL_MODULES.$(LOCAL_MODULE).REQUIRED) $(LOCAL_REQUIRED_MODULES)
 ALL_MODULES.$(LOCAL_MODULE).EVENT_LOG_TAGS := \
     $(ALL_MODULES.$(LOCAL_MODULE).EVENT_LOG_TAGS) $(event_log_tags)
+ALL_MODULES.$(LOCAL_MODULE).INTERMEDIATE_SOURCE_DIR := \
+    $(ALL_MODULES.$(LOCAL_MODULE).INTERMEDIATE_SOURCE_DIR) $(LOCAL_INTERMEDIATE_SOURCE_DIR)
+
+INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(LOCAL_MODULE)
 
 ###########################################################
 ## Take care of LOCAL_MODULE_TAGS
diff --git a/core/binary.mk b/core/binary.mk
index 2f0a243..3358544 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -5,6 +5,35 @@
 ## The list of object files is exported in $(all_objects).
 ###########################################################
 
+######################################
+## Sanity check for LOCAL_NDK_VERSION
+######################################
+my_ndk_version_root :=
+ifeq ($(TARGET_SIMULATOR),true)
+  # NDK does not support sim build.
+  LOCAL_NDK_VERSION :=
+endif
+ifdef LOCAL_NDK_VERSION
+  ifdef LOCAL_IS_HOST_MODULE
+    $(error $(LOCAL_PATH): LOCAL_NDK_VERSION can not be used in host module)
+  endif
+  ifneq ($(filter-out SHARED_LIBRARIES STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+    $(error $(LOCAL_PATH): LOCAL_NDK_VERSION can only be used to build target shared/static libraries, \
+          while your module is of class $(LOCAL_MODULE_CLASS))
+  endif
+  ifeq ($(filter $(LOCAL_NDK_VERSION),$(TARGET_AVAILABLE_NDK_VERSIONS)),)
+    $(error $(LOCAL_PATH): Invalid LOCAL_NDK_VERSION '$(LOCAL_NDK_VERSION)' \
+           Choices are $(TARGET_AVAILABLE_NDK_VERSIONS))
+  endif
+  ifndef LOCAL_SDK_VERSION
+    $(error $(LOCAL_PATH): LOCAL_NDK_VERSION must be defined with LOCAL_SDK_VERSION)
+  endif
+  my_ndk_version_root := $(HISTORICAL_NDK_VERSIONS_ROOT)/android-ndk-r$(LOCAL_NDK_VERSION)/platforms/android-$(LOCAL_SDK_VERSION)/arch-$(TARGET_ARCH)
+  ifeq ($(wildcard $(my_ndk_version_root)),)
+    $(error $(LOCAL_PATH): ndk version root does not exist: $(my_ndk_version_root))
+  endif
+endif
+
 #######################################
 include $(BUILD_SYSTEM)/base_rules.mk
 #######################################
@@ -19,6 +48,26 @@
 endif
 
 ###########################################################
+## Define PRIVATE_ variables from global vars
+###########################################################
+ifdef LOCAL_NDK_VERSION
+my_target_project_includes :=
+my_target_c_inclues := $(my_ndk_version_root)/usr/include
+# TODO: more reliable way to remove platform stuff.
+my_target_global_cflags := $(filter-out -include -I system/%, $(TARGET_GLOBAL_CFLAGS))
+my_target_global_cppflags := $(filter-out -include -I system/%, $(TARGET_GLOBAL_CPPFLAGS))
+else
+my_target_project_includes := $(TARGET_PROJECT_INCLUDES)
+my_target_c_inclues := $(TARGET_C_INCLUDES)
+my_target_global_cflags := $(TARGET_GLOBAL_CFLAGS)
+my_target_global_cppflags := $(TARGET_GLOBAL_CPPFLAGS)
+endif
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_PROJECT_INCLUDES := $(my_target_project_includes)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_C_INCLUDES := $(my_target_c_inclues)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CFLAGS := $(my_target_global_cflags)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CPPFLAGS := $(my_target_global_cppflags)
+
+###########################################################
 ## Define PRIVATE_ variables used by multiple module types
 ###########################################################
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_NO_DEFAULT_COMPILER_FLAGS := \
@@ -301,6 +350,10 @@
 
 LOCAL_C_INCLUDES += $(TOPDIR)$(LOCAL_PATH) $(intermediates) $(base_intermediates)
 
+ifndef LOCAL_NDK_VERSION
+  LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
+endif
+
 $(all_objects) : | $(LOCAL_GENERATED_SOURCES)
 ALL_C_CPP_ETC_OBJECTS += $(all_objects)
 
@@ -317,11 +370,13 @@
 # to by supplying a LOCAL_SYSTEM_SHARED_LIBRARIES value.  One would
 # supply that, for example, when building libc itself.
 ###########################################################
-ifndef LOCAL_IS_HOST_MODULE
+ifdef LOCAL_IS_HOST_MODULE
   ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
-    LOCAL_SHARED_LIBRARIES += $($(my_prefix)DEFAULT_SYSTEM_SHARED_LIBRARIES)
-  else
-    LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+    LOCAL_SYSTEM_SHARED_LIBRARIES :=
+  endif
+else
+  ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+    LOCAL_SYSTEM_SHARED_LIBRARIES := $($(my_prefix)DEFAULT_SYSTEM_SHARED_LIBRARIES)
   endif
 endif
 
@@ -380,11 +435,35 @@
 so_suffix := $($(my_prefix)SHLIB_SUFFIX)
 a_suffix := $($(my_prefix)STATIC_LIB_SUFFIX)
 
+ifdef LOCAL_NDK_VERSION
 built_shared_libraries := \
     $(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
       $(addsuffix $(so_suffix), \
         $(LOCAL_SHARED_LIBRARIES)))
 
+# Get the list of INSTALLED libraries.  Strip off the various
+# intermediates directories and point to the common lib dirs.
+installed_shared_libraries := \
+    $(addprefix $($(my_prefix)OUT_SHARED_LIBRARIES)/, \
+      $(notdir $(built_shared_libraries)))
+
+my_system_shared_libraries_fullpath := $(addprefix $(my_ndk_version_root)/usr/lib/, \
+    $(addsuffix $(so_suffix), $(LOCAL_SYSTEM_SHARED_LIBRARIES)))
+
+built_shared_libraries += $(my_system_shared_libraries_fullpath)
+LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+else
+LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+built_shared_libraries := \
+    $(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
+      $(addsuffix $(so_suffix), \
+        $(LOCAL_SHARED_LIBRARIES)))
+
+installed_shared_libraries := \
+    $(addprefix $($(my_prefix)OUT_SHARED_LIBRARIES)/, \
+      $(notdir $(built_shared_libraries)))
+endif
+
 built_static_libraries := \
     $(foreach lib,$(LOCAL_STATIC_LIBRARIES), \
       $(call intermediates-dir-for, \
@@ -395,12 +474,6 @@
       $(call intermediates-dir-for, \
         STATIC_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE))/$(lib)$(a_suffix))
 
-# Get the list of INSTALLED libraries.  Strip off the various
-# intermediates directories and point to the common lib dirs.
-installed_shared_libraries := \
-    $(addprefix $($(my_prefix)OUT_SHARED_LIBRARIES)/, \
-      $(notdir $(built_shared_libraries)))
-
 # We don't care about installed static libraries, since the
 # libraries have already been linked into the module at that point.
 # We do, however, care about the NOTICE files for any static
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index 7e68d6f..cf25ce1 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -181,14 +181,14 @@
 	./$(PRODUCT_OUT)/*.xlb \
 	./$(PRODUCT_OUT)/*.zip \
 	./$(PRODUCT_OUT)/data \
-	./$(PRODUCT_OUT)/obj/lib \
 	./$(PRODUCT_OUT)/obj/APPS \
 	./$(PRODUCT_OUT)/obj/NOTICE_FILES \
 	./$(PRODUCT_OUT)/obj/PACKAGING \
 	./$(PRODUCT_OUT)/recovery \
 	./$(PRODUCT_OUT)/root \
-	./$(PRODUCT_OUT)/symbols/system/lib \
-	./$(PRODUCT_OUT)/system
+	./$(PRODUCT_OUT)/system \
+	./$(PRODUCT_OUT)/dex_bootjars \
+	./$(PRODUCT_OUT)/obj/JAVA_LIBRARIES
 
 # The files/dirs to delete during a dataclean, which removes any files
 # in the staging and emulator data partitions.
diff --git a/core/cleanspec.mk b/core/cleanspec.mk
index c85c450..d4a8eed 100644
--- a/core/cleanspec.mk
+++ b/core/cleanspec.mk
@@ -22,7 +22,7 @@
 # IDEALLY, THOSE STEPS SHOULD BE DONE ATOMICALLY.
 # **********************************************************************
 #
-INTERNAL_CLEAN_BUILD_VERSION := 4
+INTERNAL_CLEAN_BUILD_VERSION := 6
 #
 # ***********************************************************************
 # Do not touch INTERNAL_CLEAN_BUILD_VERSION if you've added a clean step!
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 4520956..2c27300 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -51,6 +51,7 @@
 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
 LOCAL_PREBUILT_STRIP_COMMENTS:=
 LOCAL_INTERMEDIATE_SOURCES:=
+LOCAL_INTERMEDIATE_SOURCE_DIR:=
 LOCAL_JAVACFLAGS:=
 LOCAL_JAVA_LIBRARIES:=
 LOCAL_NO_STANDARD_LIBRARIES:=
@@ -80,7 +81,7 @@
 LOCAL_JNI_SHARED_LIBRARIES:=
 LOCAL_JAR_MANIFEST:=
 LOCAL_INSTRUMENTATION_FOR:=
-LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME:=
+LOCAL_MANIFEST_INSTRUMENTATION_FOR:=
 LOCAL_AIDL_INCLUDES:=
 LOCAL_JARJAR_RULES:=
 LOCAL_ADDITIONAL_JAVA_DIR:=
@@ -88,11 +89,17 @@
 LOCAL_DX_FLAGS:=
 LOCAL_CERTIFICATE:=
 LOCAL_SDK_VERSION:=
+LOCAL_NDK_VERSION:=
 LOCAL_NO_EMMA_INSTRUMENT:=
 LOCAL_NO_EMMA_COMPILE:=
 LOCAL_PROGUARD_ENABLED:= # '',optonly,full,custom
 LOCAL_PROGUARD_FLAGS:=
+LOCAL_PROGUARD_FLAG_FILES:=
+LOCAL_EMMA_COVERAGE_FILTER:=
 LOCAL_WARNINGS_ENABLE:=
+LOCAL_MANIFEST_FILE:=
+LOCAL_BUILD_HOST_DEX:=
+LOCAL_DEX_PREOPT:=
 
 # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
 # iterate over thousands of entries every time.
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index f998cf4..6139b67 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -44,7 +44,7 @@
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
 TARGET_TOOLS_PREFIX := \
-	prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
+	prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
 endif
 
 TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
@@ -99,12 +99,25 @@
 			-ffunction-sections \
 			-funwind-tables \
 			-fstack-protector \
+			-Wa,--noexecstack \
+			-Werror=format-security \
 			-fno-short-enums \
 			$(arch_variant_cflags) \
 			-include $(android_config_h) \
 			-I $(arch_include_dir)
 
+# 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
+
 TARGET_GLOBAL_LDFLAGS += \
+			-Wl,-z,noexecstack \
 			$(arch_variant_ldflags)
 
 # We only need thumb interworking in cases where thumb support
@@ -200,6 +213,9 @@
 TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
 TARGET_CRTEND_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_android.o
 
+TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_so.o
+TARGET_CRTEND_SO_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_so.o
+
 TARGET_STRIP_MODULE:=true
 
 TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
@@ -216,18 +232,20 @@
 	-nostdlib -Wl,-soname,$(notdir $@) -Wl,-T,$(BUILD_SYSTEM)/armelf.xsc \
 	-Wl,--gc-sections \
 	-Wl,-shared,-Bsymbolic \
-	$(TARGET_GLOBAL_LD_DIRS) \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
 	$(PRIVATE_ALL_OBJECTS) \
+	$(PRIVATE_TARGET_CRTBEGIN_SO_O) \
 	-Wl,--whole-archive \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
 	-Wl,--no-whole-archive \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_LDFLAGS) \
-	$(TARGET_GLOBAL_LDFLAGS) \
-	$(TARGET_FDO_LIB) \
-	$(TARGET_LIBGCC)
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_CRTEND_SO_O)
 endef
 
 define transform-o-to-executable-inner
@@ -242,8 +260,8 @@
 	$(TARGET_CRTBEGIN_DYNAMIC_O) \
 	$(PRIVATE_ALL_OBJECTS) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(PRIVATE_LDFLAGS) \
 	$(TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
 	$(TARGET_FDO_LIB) \
 	$(TARGET_LIBGCC) \
 	$(TARGET_CRTEND_O)
@@ -255,8 +273,8 @@
 	-o $@ \
 	$(TARGET_GLOBAL_LD_DIRS) \
 	$(TARGET_CRTBEGIN_STATIC_O) \
-	$(PRIVATE_LDFLAGS) \
 	$(TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
 	$(PRIVATE_ALL_OBJECTS) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(TARGET_FDO_LIB) \
diff --git a/core/combo/TARGET_linux-sh.mk b/core/combo/TARGET_linux-sh.mk
index 450fd70..cf945fe 100644
--- a/core/combo/TARGET_linux-sh.mk
+++ b/core/combo/TARGET_linux-sh.mk
@@ -105,8 +105,8 @@
 TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_static.o
 TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtbegin_dynamic.o
 TARGET_CRTEND_O := $(TARGET_OUT_STATIC_LIBRARIES)/crtend_android.o
-TARGET_SOBEGIN := $(TARGET_OUT_STATIC_LIBRARIES)/sobegin.o
-TARGET_SOEND := $(TARGET_OUT_STATIC_LIBRARIES)/soend.o
+TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_STATIC_LIBRARIES)/sobegin.o
+TARGET_CRTEND_SO_O := $(TARGET_OUT_STATIC_LIBRARIES)/soend.o
 
 TARGET_STRIP_MODULE:=true
 
@@ -118,8 +118,8 @@
 	-nostdlib -Wl,-soname,$(notdir $@) -Wl,-T,$(BUILD_SYSTEM)/shlelf.xsc \
 	-Wl,--gc-sections -Wl,-z,norelro \
 	-Wl,-shared,-Bsymbolic \
-	$(TARGET_GLOBAL_LD_DIRS) \
-	$(TARGET_SOBEGIN) \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(PRIVATE_TARGET_CRTBEGIN_SO_O) \
 	$(PRIVATE_ALL_OBJECTS) \
 	-Wl,--whole-archive \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
@@ -129,8 +129,8 @@
 	-o $@ \
 	$(PRIVATE_LDFLAGS) \
 	$(subst -lrt,, $(subst -lpthread,,$(PRIVATE_LDLIBS))) \
-	$(TARGET_LIBGCC) \
-	$(TARGET_SOEND)
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_CRTEND_SO_O)
 endef
 
 define transform-o-to-executable-inner
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
index 1477ae6..f0eb209 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -106,12 +106,12 @@
 TARGET_CUSTOM_LD_COMMAND := true
 define transform-o-to-shared-lib-inner
 $(TARGET_CXX) \
-	$(TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	 -nostdlib -Wl,-soname,$(notdir $@) \
 	 -shared -Bsymbolic \
 	-fPIC -march=i686 \
-	$(TARGET_GLOBAL_LD_DIRS) \
-	$(TARGET_CRTBEGIN_SO_O) \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(PRIVATE_TARGET_CRTBEGIN_SO_O) \
 	$(PRIVATE_ALL_OBJECTS) \
 	-Wl,--whole-archive \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
@@ -120,8 +120,8 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_LDFLAGS) \
-	$(TARGET_LIBGCC) \
-	$(TARGET_CRTEND_SO_O)
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_CRTEND_SO_O)
 endef
 
 
diff --git a/core/combo/select.mk b/core/combo/select.mk
index bd6c8c0..c886342 100644
--- a/core/combo/select.mk
+++ b/core/combo/select.mk
@@ -51,7 +51,7 @@
 $(combo_target)GLOBAL_LDFLAGS :=
 $(combo_target)GLOBAL_ARFLAGS := crsP
 
-$(combo_target)EXECUTABLE_SUFFIX := 
+$(combo_target)EXECUTABLE_SUFFIX :=
 $(combo_target)SHLIB_SUFFIX := .so
 $(combo_target)JNILIB_SUFFIX := $($(combo_target)SHLIB_SUFFIX)
 $(combo_target)STATIC_LIB_SUFFIX := .a
@@ -63,7 +63,12 @@
 
 ifneq ($(USE_CCACHE),)
   ccache := prebuilt/$(HOST_PREBUILT_TAG)/ccache/ccache
-  $(combo_target)CC := $(ccache) $($(combo_target)CC)
-  $(combo_target)CXX := $(ccache) $($(combo_target)CXX)
+  # prepend ccache if necessary
+  ifneq ($(ccache),$(firstword $($(combo_target)CC)))
+    $(combo_target)CC := $(ccache) $($(combo_target)CC)
+  endif
+  ifneq ($(ccache),$(firstword $($(combo_target)CXX)))
+    $(combo_target)CXX := $(ccache) $($(combo_target)CXX)
+  endif
   ccache =
 endif
diff --git a/core/config.mk b/core/config.mk
index 61cd0c6..ba09895 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -31,6 +31,7 @@
 	$(TOPDIR)dalvik/libnativehelper/include \
 	$(TOPDIR)frameworks/base/include \
 	$(TOPDIR)frameworks/base/opengl/include \
+    $(TOPDIR)frameworks/base/native/include \
 	$(TOPDIR)external/skia/include
 SRC_HOST_HEADERS:=$(TOPDIR)tools/include
 SRC_LIBRARIES:= $(TOPDIR)libs
@@ -208,13 +209,17 @@
 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)
+MKEXT2USERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg.sh
 MKEXT2BOOTIMG := external/genext2fs/mkbootimg_ext2.sh
 MKTARBALL := build/tools/mktarball.sh
 TUNE2FS := tune2fs
 E2FSCK := e2fsck
-JARJAR := java -jar $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
+JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
 PROGUARD := external/proguard/bin/proguard.sh
 JAVATAGS := build/tools/java-event-log-tags.py
+DEXOPT := $(HOST_OUT_EXECUTABLES)/dexopt$(HOST_EXECUTABLE_SUFFIX)
+DEXPREOPT := dalvik/tools/dex-preopt
 
 # ACP is always for the build OS, not for the host OS
 ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX)
@@ -317,6 +322,7 @@
 # ###############################################################
 
 HISTORICAL_SDK_VERSIONS_ROOT := $(TOPDIR)prebuilt/sdk
+HISTORICAL_NDK_VERSIONS_ROOT := $(TOPDIR)prebuilt/ndk
 
 # Historical SDK version N is stored in $(HISTORICAL_SDK_VERSIONS_ROOT)/N.
 # The 'current' version is whatever this source tree is.
@@ -338,6 +344,10 @@
     $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/android.jar,%, \
     $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/android.jar)))
 
+TARGET_AVAILABLE_NDK_VERSIONS := $(call numerically_sort,\
+    $(patsubst $(HISTORICAL_NDK_VERSIONS_ROOT)/android-ndk-r%,%, \
+    $(wildcard $(HISTORICAL_NDK_VERSIONS_ROOT)/android-ndk-r*)))
+
 INTERNAL_PLATFORM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/public_api.xml
 
 include $(BUILD_SYSTEM)/dumpvar.mk
diff --git a/core/definitions.mk b/core/definitions.mk
index 7e2d1fb..be427b6 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -381,7 +381,7 @@
     $(if $(_idfName),, \
         $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
     $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \
-    $(if $(filter $(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
+    $(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
         $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \
       , \
         $(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) \
@@ -473,8 +473,7 @@
 
 
 ###########################################################
-## Convert "framework framework-res ext" to "out/.../javalib.jar ..."
-## This lets us treat framework-res as a normal library.
+## Convert "core ext framework" to "out/.../javalib.jar ..."
 ## $(1): library list
 ## $(2): Non-empty if IS_HOST_MODULE
 ###########################################################
@@ -483,18 +482,13 @@
 # $(2): Non-empty if IS_HOST_MODULE
 define _java-lib-dir
 $(call intermediates-dir-for, \
-	$(if $(filter framework-res,$(1)),APPS,JAVA_LIBRARIES),$(1),$(2))
-endef
-
-# $(1): library name
-define _java-lib-classes.jar
-$(if $(filter framework-res,$(1)),package$(COMMON_ANDROID_PACKAGE_SUFFIX),classes$(COMMON_JAVA_PACKAGE_SUFFIX))
+	JAVA_LIBRARIES,$(1),$(2),COMMON)
 endef
 
 # $(1): library name
 # $(2): Non-empty if IS_HOST_MODULE
 define _java-lib-full-classes.jar
-$(call _java-lib-dir,$(1),$(2))/$(call _java-lib-classes.jar,$(1))
+$(call _java-lib-dir,$(1),$(2))/classes$(COMMON_JAVA_PACKAGE_SUFFIX)
 endef
 
 # $(1): library name list
@@ -504,14 +498,9 @@
 endef
 
 # $(1): library name
-define _java-lib-dep
-$(if $(filter framework-res,$(1)),package$(COMMON_ANDROID_PACKAGE_SUFFIX),javalib$(COMMON_JAVA_PACKAGE_SUFFIX))
-endef
-
-# $(1): library name
 # $(2): Non-empty if IS_HOST_MODULE
 define _java-lib-full-dep
-$(call _java-lib-dir,$(1),$(2))/$(call _java-lib-dep,$(1))
+$(call _java-lib-dir,$(1),$(2))/javalib$(COMMON_JAVA_PACKAGE_SUFFIX)
 endef
 
 # $(1): library name list
@@ -767,16 +756,16 @@
 	$(foreach incdir, \
 	    $(PRIVATE_C_INCLUDES) \
 	    $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
-		$(TARGET_PROJECT_INCLUDES) \
-		$(TARGET_C_INCLUDES) \
+		$(PRIVATE_TARGET_PROJECT_INCLUDES) \
+		$(PRIVATE_TARGET_C_INCLUDES) \
 	     ) \
 	  , \
 	    -I $(incdir) \
 	 ) \
 	-c \
 	$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
-	    $(TARGET_GLOBAL_CFLAGS) \
-	    $(TARGET_GLOBAL_CPPFLAGS) \
+	    $(PRIVATE_TARGET_GLOBAL_CFLAGS) \
+	    $(PRIVATE_TARGET_GLOBAL_CPPFLAGS) \
 	    $(PRIVATE_ARM_CFLAGS) \
 	 ) \
 	-fno-rtti \
@@ -799,15 +788,15 @@
 	$(foreach incdir, \
 	    $(PRIVATE_C_INCLUDES) \
 	    $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
-		$(TARGET_PROJECT_INCLUDES) \
-		$(TARGET_C_INCLUDES) \
+		$(PRIVATE_TARGET_PROJECT_INCLUDES) \
+		$(PRIVATE_TARGET_C_INCLUDES) \
 	     ) \
 	  , \
 	    -I $(incdir) \
 	 ) \
 	-c \
 	$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
-	    $(TARGET_GLOBAL_CFLAGS) \
+	    $(PRIVATE_TARGET_GLOBAL_CFLAGS) \
 	    $(PRIVATE_ARM_CFLAGS) \
 	 ) \
 	$(PRIVATE_CFLAGS) \
@@ -949,7 +938,7 @@
 
 define extract-and-include-target-whole-static-libs
 $(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
-	@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
+	$(hide) echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
 	ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(lib)))_objs;\
 	rm -rf $$ldir; \
 	mkdir -p $$ldir; \
@@ -969,7 +958,8 @@
 @rm -f $@
 $(extract-and-include-target-whole-static-libs)
 @echo "target StaticLib: $(PRIVATE_MODULE) ($@)"
-$(hide) echo $^ | xargs $(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@
+$(hide) echo $(filter %.o, $^) | \
+    xargs $(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@
 endef
 
 ###########################################################
@@ -1062,12 +1052,12 @@
 ifneq ($(TARGET_CUSTOM_LD_COMMAND),true)
 define transform-o-to-shared-lib-inner
 $(TARGET_CXX) \
-	$(TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	-Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
 	-Wl,-rpath,\$$ORIGIN/../lib \
 	-shared -Wl,-soname,$(notdir $@) \
 	$(PRIVATE_LDFLAGS) \
-	$(TARGET_GLOBAL_LD_DIRS) \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
 	$(PRIVATE_ALL_OBJECTS) \
 	-Wl,--whole-archive \
 	$(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
@@ -1229,10 +1219,10 @@
     $(addprefix -G , $(PRIVATE_PROGUARD_OPTIONS_FILE)) \
     $(addprefix --min-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
-    $(addprefix --version-code , $(PLATFORM_SDK_VERSION)) \
-    $(addprefix --version-name , $(PLATFORM_VERSION)) \
+    $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
+    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION))) \
     $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
-    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME))
+    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR))
 endef
 
 ifeq ($(HOST_OS),windows)
@@ -1323,7 +1313,8 @@
 
 define transform-classes.jar-to-emma
 $(hide) java -classpath $(EMMA_JAR) emma instr -outmode fullcopy -outfile \
-    $(PRIVATE_EMMA_COVERAGE_FILE) -ip $< -d $(PRIVATE_EMMA_INTERMEDIATES_DIR)
+    $(PRIVATE_EMMA_COVERAGE_FILE) -ip $< -d $(PRIVATE_EMMA_INTERMEDIATES_DIR) \
+    $(addprefix -ix , $(PRIVATE_EMMA_COVERAGE_FILTER))
 endef
 
 #TODO: use a smaller -Xmx value for most libraries;
@@ -1374,10 +1365,11 @@
     $(addprefix -I , $(PRIVATE_AAPT_INCLUDES)) \
     $(addprefix --min-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
-    $(addprefix --version-code , $(PLATFORM_SDK_VERSION)) \
-    $(addprefix --version-name , $(PLATFORM_VERSION)) \
+    $(addprefix --product , $(TARGET_AAPT_CHARACTERISTICS)) \
+    $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
+    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION))) \
     $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
-    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME)) \
+    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
     -F $@
 endef
 
@@ -1391,7 +1383,12 @@
 
 #TODO: update the manifest to point to the dex file
 define add-dex-to-package
-$(hide) $(AAPT) add -k $@ $(PRIVATE_DEX_FILE)
+$(if $(filter classes.dex,$(notdir $(PRIVATE_DEX_FILE))),\
+$(hide) $(AAPT) add -k $@ $(PRIVATE_DEX_FILE),\
+$(eval _adtp_classes.dex := $(dir $(PRIVATE_DEX_FILE))/classes.dex)\
+$(hide) cp $(PRIVATE_DEX_FILE) $(_adtp_classes.dex) && \
+$(AAPT) add -k $@ $(_adtp_classes.dex) && \
+rm -f $(_adtp_classes.dex))
 endef
 
 define add-java-resources-to-package
@@ -1739,20 +1736,21 @@
 #        tree root)
 #  $(2): Old LOCAL_PACKAGE_NAME value.
 #  $(3): New LOCAL_PACKAGE_NAME value.
-#  $(4): New LOCALE_MANIFEST_PACKAGE_NAME value.
-#  $(5): New LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME value.
-#  $(6): New LOCAL_CERTIFICATE value.
+#  $(4): New LOCAL_MANIFEST_PACKAGE_NAME value.
+#  $(5): New LOCAL_CERTIFICATE value.
+#  $(6): New LOCAL_INSTRUMENTATION_FOR value.
+#  $(7): New LOCAL_MANIFEST_INSTRUMENTATION_FOR value.
 #
 # Note that LOCAL_PACKAGE_OVERRIDES is NOT cleared in
 # clear_vars.mk.
 ###########################################################
 define inherit-package
-  $(eval $(call inherit-package-internal,$(1),$(2),$(3),$(4),$(5),$(6)))
+  $(eval $(call inherit-package-internal,$(1),$(2),$(3),$(4),$(5),$(6),$(7)))
 endef
 
 define inherit-package-internal
   LOCAL_PACKAGE_OVERRIDES \
-      := $(strip $(1))||$(strip $(2))||$(strip $(3))||$(strip $(4))||&&$(strip $(5))||$(strip $(6)) $(LOCAL_PACKAGE_OVERRIDES)
+      := $(strip $(1))||$(strip $(2))||$(strip $(3))||$(strip $(4))||&&$(strip $(5))||&&$(strip $(6))||&&$(strip $(7)) $(LOCAL_PACKAGE_OVERRIDES)
   include $(1)
   LOCAL_PACKAGE_OVERRIDES \
       := $(wordlist 1,$(words $(LOCAL_PACKAGE_OVERRIDES)), $(LOCAL_PACKAGE_OVERRIDES))
@@ -1774,8 +1772,9 @@
   $(if $(filter $(word 2,$(_n)),$(LOCAL_PACKAGE_NAME)), \
     $(eval LOCAL_PACKAGE_NAME := $(word 3,$(_o))) \
     $(eval LOCAL_MANIFEST_PACKAGE_NAME := $(word 4,$(_o))) \
-    $(call keep-or-override,LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME,$(patsubst &&%,%,$(word 5,$(_o)))) \
-    $(call keep-or-override,LOCAL_CERTIFICATE,$(word 6,$(_o))) \
+    $(call keep-or-override,LOCAL_CERTIFICATE,$(patsubst &&%,%,$(word 5,$(_o)))) \
+    $(call keep-or-override,LOCAL_INSTRUMENTATION_FOR,$(patsubst &&%,%,$(word 6,$(_o)))) \
+    $(call keep-or-override,LOCAL_MANIFEST_INSTRUMENTATION_FOR,$(patsubst &&%,%,$(word 7,$(_o)))) \
     $(eval LOCAL_OVERRIDES_PACKAGES := $(sort $(LOCAL_OVERRIDES_PACKAGES) $(word 2,$(_o)))) \
     true \
   ,)
@@ -1791,6 +1790,9 @@
 # when requested.
 include $(BUILD_SYSTEM)/distdir.mk
 
+# -----------------------------------------------------------------
+# The modules allowed to use a user tag
+include $(BUILD_SYSTEM)/user_tags.mk
 
 # broken:
 #	$(foreach file,$^,$(if $(findstring,.a,$(suffix $file)),-l$(file),$(file)))
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
new file mode 100644
index 0000000..6e0b093
--- /dev/null
+++ b/core/dex_preopt.mk
@@ -0,0 +1,81 @@
+####################################
+# Dexpreopt on the boot jars
+#
+####################################
+
+# TODO: replace it with device's BOOTCLASSPATH
+DEXPREOPT_BOOT_JARS := core:bouncycastle:ext:framework:android.policy:services:core-junit
+DEXPREOPT_BOOT_JARS_MODULES := $(subst :, ,$(DEXPREOPT_BOOT_JARS))
+
+DEXPREOPT_BUILD_DIR := $(OUT_DIR)
+DEXPREOPT_PRODUCT_DIR := $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(PRODUCT_OUT))/dex_bootjars
+DEXPREOPT_BOOT_JAR_DIR := system/framework
+DEXPREOPT_DEXOPT := $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(DEXOPT))
+
+DEXPREOPT_BOOT_JAR_DIR_FULL_PATH := $(DEXPREOPT_BUILD_DIR)/$(DEXPREOPT_PRODUCT_DIR)/$(DEXPREOPT_BOOT_JAR_DIR)
+
+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
+
+# $(1): the .jar or .apk to remove classes.dex
+define dexpreopt-remove-classes.dex
+$(hide) $(AAPT) remove $(1) classes.dex
+endef
+
+# $(1): the input .jar or .apk file
+# $(2): the output .odex file
+define dexpreopt-one-file
+$(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
+
+# $(1): boot jar module name
+define _dexpreopt-boot-jar
+$(eval _dbj_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1).jar)
+$(eval _dbj_odex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1).odex)
+$(eval _dbj_jar_no_dex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1)_nodex.jar)
+$(eval _dbj_src_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(1),,COMMON)/javalib.jar)
+$(eval $(_dbj_odex): PRIVATE_DBJ_JAR := $(_dbj_jar))
+$(_dbj_odex) : $(_dbj_src_jar) | $(ACP) $(DEXPREOPT) $(DEXOPT)
+	@echo "Dexpreopt Boot Jar: $$@"
+	$(hide) rm -f $$@
+	$(hide) mkdir -p $$(dir $$@)
+	$(hide) $(ACP) -fpt $$< $$(PRIVATE_DBJ_JAR)
+	$$(call dexpreopt-one-file,$$(PRIVATE_DBJ_JAR),$$@)
+
+$(_dbj_jar_no_dex) : $(_dbj_src_jar) | $(ACP) $(AAPT)
+	$$(call copy-file-to-target)
+	$$(call dexpreopt-remove-classes.dex,$$@)
+
+$(eval _dbj_jar :=)
+$(eval _dbj_odex :=)
+$(eval _dbj_src_jar :=)
+endef
+
+$(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),$(eval $(call _dexpreopt-boot-jar,$(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/droiddoc.mk b/core/droiddoc.mk
index ba4857b..87576dc 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -144,7 +144,7 @@
 $(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)
 ifneq ($(strip $(LOCAL_DROIDDOC_HTML_DIR)),)
-$(full_target): PRIVATE_DROIDDOC_HTML_DIR := -htmldir $(LOCAL_PATH)/$(LOCAL_DROIDDOC_HTML_DIR)
+$(full_target): PRIVATE_DROIDDOC_HTML_DIR := $(foreach dir,$(LOCAL_DROIDDOC_HTML_DIR),-htmldir $(dir))
 else
 $(full_target): PRIVATE_DROIDDOC_HTML_DIR := 
 endif
@@ -154,7 +154,7 @@
 
 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)
+$(full_target): $(full_src_files) $(droiddoc_templates) $(droiddoc) $(html_dir_files) $(full_java_lib_deps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Docs droiddoc: $(PRIVATE_OUT_DIR)
 	$(hide) mkdir -p $(dir $(full_target))
 	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index fa20ece..f469f35 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -9,7 +9,7 @@
 	ABP:=$(ABP):$(TARGET_OUT_EXECUTABLES)
 else
 	# this should be copied to HOST_OUT_EXECUTABLES instead
-	ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.0/bin
+	ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.3/bin
 endif
 ANDROID_BUILD_PATHS := $(ABP)
 ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index c04deef..0fa7647 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -14,7 +14,12 @@
 
 LOCAL_UNSTRIPPED_PATH := $(strip $(LOCAL_UNSTRIPPED_PATH))
 ifeq ($(LOCAL_UNSTRIPPED_PATH),)
-  LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_$(LOCAL_MODULE_CLASS)_UNSTRIPPED)
+  ifeq ($(LOCAL_MODULE_PATH),)
+    LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_$(LOCAL_MODULE_CLASS)_UNSTRIPPED)
+  else
+    # We have to figure out the corresponding unstripped path if LOCAL_MODULE_PATH is customized.
+    LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(LOCAL_MODULE_PATH))
+  endif
 endif
 
 # The name of the target file, without any path prepended.
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 87ac2f6..e2d4d11 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -119,6 +119,17 @@
   HOST_PREBUILT_TAG := $(HOST_OS)-$(HOST_ARCH)
 endif
 
+# Default to building dalvikvm on hosts that support it...
+ifeq ($(HOST_OS),linux)
+# ... but not if we're building the sim...
+ifneq ($(TARGET_SIMULATOR),true)
+# ... or if the if the option is already set
+ifeq ($(WITH_HOST_DALVIK),)
+	WITH_HOST_DALVIK := true
+endif
+endif
+endif
+
 
 # ---------------------------------------------------------------
 # Set up configuration for target machine.
@@ -263,7 +274,7 @@
 TARGET_INSTALLER_ROOT_OUT := $(TARGET_INSTALLER_OUT)/root
 TARGET_INSTALLER_SYSTEM_OUT := $(TARGET_INSTALLER_OUT)/root/system
 
-COMMON_MODULE_CLASSES := JAVA_LIBRARIES NOTICE_FILES
+COMMON_MODULE_CLASSES := TARGET-NOTICE_FILES HOST-NOTICE_FILES HOST-JAVA_LIBRARIES
 
 ifeq (,$(strip $(DIST_DIR)))
   DIST_DIR := $(OUT_DIR)/dist
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index 1977115..27174f2 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -23,8 +23,50 @@
 LOCAL_IS_HOST_MODULE := true
 LOCAL_BUILT_MODULE_STEM := javalib.jar
 
+ifeq ($(LOCAL_BUILD_HOST_DEX),true)
+intermediates := $(call local-intermediates-dir)
+intermediates.COMMON := $(call local-intermediates-dir,COMMON)
+
+full_classes_jar := $(intermediates.COMMON)/classes.jar
+built_dex := $(intermediates.COMMON)/classes.dex
+
+LOCAL_INTERMEDIATE_TARGETS += \
+    $(full_classes_jar) \
+    $(built_dex)
+
+LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
+endif # LOCAL_BUILD_HOST_DEX
+
 include $(BUILD_SYSTEM)/base_rules.mk
 
-$(LOCAL_BUILT_MODULE): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
-$(LOCAL_BUILT_MODULE): $(java_sources) $(java_resource_sources) $(full_java_lib_deps)
+ifeq ($(LOCAL_BUILD_HOST_DEX),true)
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates.COMMON)/classes
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_SOURCE_INTERMEDIATES_DIR := $(LOCAL_INTERMEDIATE_SOURCE_DIR)
+
+$(cleantarget): PRIVATE_CLEAN_FILES += $(intermediates.COMMON)
+
+$(full_classes_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
+$(full_classes_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) $(jar_manifest_file)
 	$(transform-host-java-to-package)
+
+$(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
+$(built_dex): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
+$(built_dex): $(full_classes_jar) $(DX)
+	$(transform-classes.jar-to-dex)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
+$(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources) | $(AAPT)
+	@echo "Host Jar: $(PRIVATE_MODULE) ($@)"
+	$(create-empty-package)
+	$(add-dex-to-package)
+ifneq ($(extra_jar_args),)
+	$(add-java-resources-to-package)
+endif
+
+else
+$(LOCAL_BUILT_MODULE): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
+$(LOCAL_BUILT_MODULE): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) $(jar_manifest_file)
+	$(transform-host-java-to-package)
+endif  # LOCAL_BUILD_HOST_DEX
diff --git a/core/java.mk b/core/java.mk
index baa83ee..6b8d04d 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -29,7 +29,7 @@
   endif
 else
   ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-    LOCAL_JAVA_LIBRARIES := core ext framework $(LOCAL_JAVA_LIBRARIES)
+    LOCAL_JAVA_LIBRARIES := core core-junit ext framework $(LOCAL_JAVA_LIBRARIES)
   endif
 endif
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
@@ -51,9 +51,6 @@
 intermediates := $(call local-intermediates-dir)
 intermediates.COMMON := $(call local-intermediates-dir,COMMON)
 
-# This is cleared below, and re-set if we really need it.
-full_classes_jar := $(intermediates.COMMON)/classes.jar
-
 # Emma source code coverage
 ifneq ($(EMMA_INSTRUMENT),true)
 LOCAL_NO_EMMA_INSTRUMENT := true
@@ -63,31 +60,59 @@
 # Choose leaf name for the compiled jar file.
 ifneq ($(LOCAL_NO_EMMA_COMPILE),true)
 full_classes_compiled_jar_leaf := classes-no-debug-var.jar
+built_dex_intermediate_leaf := classes-no-local.dex
 else
 full_classes_compiled_jar_leaf := classes-full-debug.jar
+built_dex_intermediate_leaf := classes-with-local.dex
 endif
-full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_jar_leaf)
 
+LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
+ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
+LOCAL_PROGUARD_ENABLED :=
+endif
+
+# By giving different file name, files can be updated correctly when switching
+# between builds with and without Proguard enabled.
+# Note that ANY intermediate targets between the proguard and
+# the final built_dex should be differently named!
+ifdef LOCAL_PROGUARD_ENABLED
+proguard_jar_leaf := proguard.classes.jar
+built_dex_intermediate_leaf := proguard.$(built_dex_intermediate_leaf)
+built_dex_leaf := progaurd.classes.dex
+else
+proguard_jar_leaf := noproguard.classes.jar
+built_dex_intermediate_leaf := noproguard.$(built_dex_intermediate_leaf)
+built_dex_leaf := noproguard.classes.dex
+endif
+
+full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_jar_leaf)
+jarjar_leaf := classes-jarjar.jar
+full_classes_jarjar_jar := $(intermediates.COMMON)/$(jarjar_leaf)
 emma_intermediates_dir := $(intermediates.COMMON)/emma_out
-# the 'lib/$(full_classes_compiled_jar_leaf)' portion of this path is fixed in
-# the emma tool
-full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf)
+# 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/$(jarjar_leaf)
+full_classes_proguard_jar := $(intermediates.COMMON)/$(proguard_jar_leaf)
+built_dex_intermediate := $(intermediates.COMMON)/$(built_dex_intermediate_leaf)
 full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
-full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
-full_classes_full_names_jar := $(intermediates.COMMON)/classes-full-names.jar
-full_classes_proguard_jar := $(full_classes_jar)
-built_dex := $(intermediates.COMMON)/classes.dex
+
+# full_classes_jar and built_dex are cleared below, and re-set if we really need them.
+full_classes_jar := $(intermediates.COMMON)/classes.jar
+built_dex := $(intermediates.COMMON)/$(built_dex_leaf)
 
 LOCAL_INTERMEDIATE_TARGETS += \
-    $(full_classes_jar) \
     $(full_classes_compiled_jar) \
-    $(full_classes_emma_jar) \
-    $(full_classes_full_names_jar) \
-    $(full_classes_stubs_jar) \
     $(full_classes_jarjar_jar) \
-    $(built_dex)
+    $(full_classes_emma_jar) \
+    $(full_classes_jar) \
+    $(full_classes_proguard_jar) \
+    $(built_dex_intermediate) \
+    $(built_dex) \
+    $(full_classes_stubs_jar)
 
 
+LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
+
 # TODO: It looks like the only thing we need from base_rules is
 # all_java_sources.  See if we can get that by adding a
 # common_java.mk, and moving the include of base_rules.mk to
@@ -104,7 +129,7 @@
 $(LOCAL_INTERMEDIATE_TARGETS): \
 	PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates.COMMON)/classes
 $(LOCAL_INTERMEDIATE_TARGETS): \
-	PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/src
+	PRIVATE_SOURCE_INTERMEDIATES_DIR := $(LOCAL_INTERMEDIATE_SOURCE_DIR)
 
 # Since we're using intermediates.COMMON, make sure that it gets cleaned
 # properly.
@@ -121,7 +146,7 @@
 # LOCAL_BUILT_MODULE, so it will inherit the necessary PRIVATE_*
 # variable definitions.
 full_classes_jar := $(intermediates.COMMON)/classes.jar
-built_dex := $(intermediates.COMMON)/classes.dex
+built_dex := $(intermediates.COMMON)/$(built_dex_leaf)
 
 # Droiddoc isn't currently able to generate stubs for modules, so we're just
 # allowing it to use the classes.jar as the "stubs" that would be use to link
@@ -142,7 +167,7 @@
 # Deps for generated source files must be handled separately,
 # via deps on the target that generates the sources.
 $(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
-$(full_classes_compiled_jar): $(java_sources) $(full_java_lib_deps)
+$(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) $(jar_manifest_file)
 	$(transform-java-to-classes.jar)
 
 # All of the rules after full_classes_compiled_jar are very unlikely
@@ -154,17 +179,18 @@
 # be done after the inclusion of base_rules.mk.
 ALL_MODULES.$(LOCAL_MODULE).CHECKED := $(full_classes_compiled_jar)
 
-ifneq ($(LOCAL_NO_EMMA_COMPILE),true)
-# If you instrument class files that have local variable debug information in
-# them emma does not correctly maintain the local variable table.
-# This will cause an error when you try to convert the class files for Android.
-# The workaround for this to compile the java classes with only
-# line and source debug information, not local information.
-$(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g:{lines,source}
-else
-# when emma is off, compile with the default flags, which contain full debug
-# info
 $(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
+
+# Run jarjar if necessary, otherwise just copy the file.
+ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
+$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
+$(full_classes_jarjar_jar): $(full_classes_compiled_jar) | $(JARJAR)
+	@echo JarJar: $@
+	$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+else
+$(full_classes_jarjar_jar): $(full_classes_compiled_jar) | $(ACP)
+	@echo Copying: $@
+	$(hide) $(ACP) $< $@
 endif
 
 ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
@@ -176,39 +202,35 @@
 ifneq ($(LOCAL_NO_EMMA_INSTRUMENT),true)
 $(full_classes_emma_jar): PRIVATE_EMMA_COVERAGE_FILE := $(intermediates.COMMON)/coverage.em
 $(full_classes_emma_jar): PRIVATE_EMMA_INTERMEDIATES_DIR := $(emma_intermediates_dir)
+# module level coverage filter can be defined using LOCAL_EMMA_COVERAGE_FILTER
+# in Android.mk
+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)
+$(full_classes_emma_jar): $(full_classes_jarjar_jar) | $(EMMA_JAR)
 	$(transform-classes.jar-to-emma)
 $(PRIVATE_EMMA_COVERAGE_FILE): $(full_classes_emma_jar)
 
 # tell proguard to load emma jar
 LOCAL_PROGUARD_FLAGS := $(LOCAL_PROGUARD_FLAGS) $(addprefix -libraryjars ,$(EMMA_JAR))
 else
-$(full_classes_emma_jar): $(full_classes_compiled_jar) | $(ACP)
-	@echo Copying: $<
+$(full_classes_emma_jar): $(full_classes_jarjar_jar) | $(ACP)
+	@echo Copying: $@
 	$(copy-file-to-target)
 endif
 
-# Run jarjar if necessary, otherwise just copy the file.
-ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
-$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
-$(full_classes_jarjar_jar): $(full_classes_emma_jar) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
-else
-$(full_classes_jarjar_jar): $(full_classes_emma_jar) | $(ACP)
-	@echo Copying: $@
-	$(hide) $(ACP) $< $@
-endif
-
 # Keep a copy of the jar just before proguard processing.
-$(full_classes_full_names_jar): $(full_classes_emma_jar) | $(ACP)
+$(full_classes_jar): $(full_classes_emma_jar) | $(ACP)
 	@echo Copying: $@
 	$(hide) $(ACP) $< $@
 
-# Run proguard if necessary, otherwise just copy the file.  This is the last
-# part of this step, so the output of this command is full_classes_jar.
+# Run proguard if necessary, otherwise just copy the file.
 proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary
 # Proguard doesn't like a class in both library and the jar to be processed.
 proguard_full_java_libs := $(filter-out $(full_static_java_libs),$(full_java_libs))
@@ -221,10 +243,6 @@
 proguard_flags := $(proguard_flags) -include $(BUILD_SYSTEM)/proguard_tests.flags
 endif # test package
 
-LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
-ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
-    LOCAL_PROGUARD_ENABLED :=
-endif
 ifneq ($(LOCAL_PROGUARD_ENABLED),)
 ifeq ($(LOCAL_PROGUARD_ENABLED),full)
     # full
@@ -243,21 +261,36 @@
 endif # full
 endif # LOCAL_PROGUARD_ENABLED
 
+proguard_flag_files := $(addprefix $(LOCAL_PATH)/, $(LOCAL_PROGUARD_FLAG_FILES))
+LOCAL_PROGUARD_FLAGS += $(addprefix -include , $(proguard_flag_files))
+
 $(full_classes_proguard_jar): PRIVATE_PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED)
 $(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(proguard_flags) $(LOCAL_PROGUARD_FLAGS)
 $(full_classes_proguard_jar): PRIVATE_INSTRUMENTATION_FOR:=$(strip $(LOCAL_INSTRUMENTATION_FOR))
-
-$(full_classes_proguard_jar): $(full_classes_full_names_jar) | $(ACP) $(PROGUARD)
+$(full_classes_proguard_jar) : $(full_classes_jar) $(proguard_flag_files) | $(ACP) $(PROGUARD)
 	$(call transform-jar-to-proguard)
 
 ALL_MODULES.$(LOCAL_MODULE).PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED)
 
+# If you instrument class files that have local variable debug information in
+# them emma does not correctly maintain the local variable table.
+# This will cause an error when you try to convert the class files for Android.
+# The workaround here is to build different dex file here based on emma switch
+# then later copy into classes.dex. When emma is on, dx is run with --no-locals
+# option to remove local variable information
+
 # Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
 # will work even when intermediates != intermediates.COMMON.
-$(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
-$(built_dex): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
-$(built_dex): $(full_classes_jar) $(DX)
+$(built_dex_intermediate): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
+$(built_dex_intermediate): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
+ifneq ($(LOCAL_NO_EMMA_COMPILE),true)
+$(built_dex_intermediate): PRIVATE_DX_FLAGS += --no-locals
+endif
+$(built_dex_intermediate): $(full_classes_proguard_jar) $(DX)
 	$(transform-classes.jar-to-dex)
+$(built_dex): $(built_dex_intermediate) | $(ACP)
+	@echo Copying: $@
+	$(hide) $(ACP) $< $@
 ifneq ($(GENERATE_DEX_DEBUG),)
 	$(install-dex-debug)
 endif
diff --git a/core/java_library.mk b/core/java_library.mk
index a33bf2e..abc4728 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -23,20 +23,35 @@
 
 LOCAL_BUILT_MODULE_STEM := javalib.jar
 
+intermediates.COMMON := $(call local-intermediates-dir,COMMON)
+
+# This file will be the one that other modules should depend on.
+common_javalib.jar := $(intermediates.COMMON)/$(LOCAL_BUILT_MODULE_STEM)
+LOCAL_INTERMEDIATE_TARGETS += $(common_javalib.jar)
+
+ifeq (true,$(WITH_DEXPREOPT))
+ifndef LOCAL_DEX_PREOPT
+LOCAL_DEX_PREOPT := true
+endif
+endif
+
 #################################
 include $(BUILD_SYSTEM)/java.mk
 #################################
 
 ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
 # No dex or resources; all we want are the .class files.
-$(LOCAL_BUILT_MODULE): $(full_classes_jar)
+$(common_javalib.jar) : $(full_classes_jar)
 	@echo "target Static Jar: $(PRIVATE_MODULE) ($@)"
 	$(copy-file-to-target)
 
+$(LOCAL_BUILT_MODULE): $(common_javalib.jar)
+	$(copy-file-to-target)
+
 else # !LOCAL_IS_STATIC_JAVA_LIBRARY
 
-$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
-$(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources) | $(AAPT)
+$(common_javalib.jar): PRIVATE_DEX_FILE := $(built_dex)
+$(common_javalib.jar) : $(built_dex) $(java_resource_sources) | $(AAPT)
 	@echo "target Jar: $(PRIVATE_MODULE) ($@)"
 	$(create-empty-package)
 	$(add-dex-to-package)
@@ -44,4 +59,38 @@
 	$(add-java-resources-to-package)
 endif
 
+ifeq ($(LOCAL_DEX_PREOPT),true)
+dexpreopt_boot_jar_module := $(filter $(LOCAL_MODULE),$(DEXPREOPT_BOOT_JARS_MODULES))
+ifneq ($(dexpreopt_boot_jar_module),)
+# boot jar's rules are defined in dex_preopt.mk
+dexpreopted_boot_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module)_nodex.jar
+$(LOCAL_BUILT_MODULE) : $(dexpreopted_boot_jar) | $(ACP)
+	$(call copy-file-to-target)
+
+dexpreopted_boot_odex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module).odex
+built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
+$(built_odex) : $(dexpreopted_boot_odex) | $(ACP)
+	$(call copy-file-to-target)
+
+else # dexpreopt_boot_jar_module
+built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
+$(built_odex): PRIVATE_MODULE := $(LOCAL_MODULE)
+# Make sure the boot jars get dex-preopt-ed first
+$(built_odex) : $(DEXPREOPT_BOOT_ODEXS)
+$(built_odex) : $(common_javalib.jar) | $(DEXPREOPT) $(DEXOPT)
+	@echo "Dexpreopt Jar: $(PRIVATE_MODULE) ($@)"
+	$(hide) rm -f $@
+	$(call dexpreopt-one-file,$<,$@)
+
+$(LOCAL_BUILT_MODULE) : $(common_javalib.jar) | $(ACP) $(AAPT)
+	$(call copy-file-to-target)
+	$(call dexpreopt-remove-classes.dex,$@)
+
+endif # dexpreopt_boot_jar_module
+
+else # LOCAL_DEX_PREOPT
+$(LOCAL_BUILT_MODULE) : $(common_javalib.jar) | $(ACP)
+	$(call copy-file-to-target)
+
+endif # LOCAL_DEX_PREOPT
 endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
diff --git a/core/main.mk b/core/main.mk
index f761ba5..c6076d7 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -50,6 +50,10 @@
 DEFAULT_GOAL := droid
 $(DEFAULT_GOAL):
 
+# Used to force goals to build.  Only use for conditionally defined goals.
+.PHONY: FORCE
+FORCE:
+
 # Set up various standard variables based on configuration
 # and host information.
 include $(BUILD_SYSTEM)/config.mk
@@ -153,6 +157,9 @@
 # Bring in standard build system definitions.
 include $(BUILD_SYSTEM)/definitions.mk
 
+# Bring in dex_preopt.mk
+include $(BUILD_SYSTEM)/dex_preopt.mk
+
 ifneq ($(filter eng user userdebug tests,$(MAKECMDGOALS)),)
 $(info ***************************************************************)
 $(info ***************************************************************)
@@ -213,16 +220,19 @@
     # Disable debugging in plain user builds.
     enable_target_debugging :=
   endif
- 
-  # TODO: Always set WITH_DEXPREOPT (for user builds) once it works on OSX.
-  # Also, remove the corresponding block in config/product_config.make.
+
+  # TODO: Remove this and the corresponding block in
+  # config/product_config.make once host-based Dalvik preoptimization is
+  # working.
+  ifneq (true,$(DISABLE_DEXPREOPT))
   ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)
     WITH_DEXPREOPT := true
   endif
-  
+  endif
+
   # Disallow mock locations by default for user builds
   ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=0
-  
+
 else # !user_variant
   # Turn on checkjni for non-user builds.
   ADDITIONAL_BUILD_PROPERTIES += ro.kernel.android.checkjni=1
@@ -273,10 +283,7 @@
 else # !sdk
 endif
 
-# build the full stagefright library
-ifneq ($(strip BUILD_WITH_FULL_STAGEFRIGHT),)
-BUILD_WITH_FULL_STAGEFRIGHT := true
-endif
+BUILD_WITHOUT_PV := true
 
 ## precise GC ##
 
@@ -697,6 +704,13 @@
 	$(INSTALLED_USERDATAIMAGE_TARGET) \
 	$(INSTALLED_FILES_FILE)
 
+ifeq ($(EMMA_INSTRUMENT),true)
+  $(call dist-for-goals, droid, $(EMMA_META_ZIP))
+endif
+
+# dist_libraries only for putting your library into the dist directory with a full build.
+.PHONY: dist_libraries
+
 ifneq ($(TARGET_BUILD_APPS),)
   # If this build is just for apps, only build apps and not the full system by default.
 
@@ -730,28 +744,22 @@
     $(INSTALLED_BUILD_PROP_TARGET) \
     $(BUILT_TARGET_FILES_PACKAGE) \
     $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
+    $(INSTALLED_RAMDISK_TARGET) \
    )
 
-  # Tests are installed in userdata.img.  If we're building the tests
-  # variant, copy it for "make tests dist".  Also copy a zip of the
-  # contents of userdata.img, so that people can easily extract a
-  # single .apk.
-  ifeq ($(TARGET_BUILD_VARIANT),tests)
-  $(call dist-for-goals, droid, \
-    $(INSTALLED_USERDATAIMAGE_TARGET) \
-    $(BUILT_TESTS_ZIP_PACKAGE) \
-   )
-  endif
-
 # Building a full system-- the default is to build droidcore
-droid: droidcore
+droid: droidcore dist_libraries
 
-endif # TARGET_BUILD_APPS
+endif
 
 
 .PHONY: droid tests
 tests: droidcore
 
+# phony target that include any targets in $(ALL_MODULES)
+.PHONY: all_modules
+all_modules: $(ALL_MODULES)
+
 .PHONY: docs
 docs: $(ALL_DOCS)
 
@@ -767,23 +775,13 @@
 findbugs: $(INTERNAL_FINDBUGS_HTML_TARGET) $(INTERNAL_FINDBUGS_XML_TARGET)
 
 .PHONY: clean
-dirs_to_clean := \
-	$(PRODUCT_OUT) \
-	$(TARGET_COMMON_OUT_ROOT) \
-	$(HOST_OUT) \
-	$(HOST_COMMON_OUT_ROOT)
 clean:
-	@for dir in $(dirs_to_clean) ; do \
-	    echo "Cleaning $$dir..."; \
-	    rm -rf $$dir; \
-	done
-	@echo "Clean."; \
-
-.PHONY: clobber
-clobber:
 	@rm -rf $(OUT_DIR)
 	@echo "Entire build directory removed."
 
+.PHONY: clobber
+clobber: clean
+
 # The rules for dataclean and installclean are defined in cleanbuild.mk.
 
 #xxx scrape this from ALL_MODULE_NAME_TAGS
diff --git a/core/multi_prebuilt.mk b/core/multi_prebuilt.mk
index 738a88d..7602673 100644
--- a/core/multi_prebuilt.mk
+++ b/core/multi_prebuilt.mk
@@ -21,6 +21,7 @@
 prebuilt_java_libraries := $(LOCAL_PREBUILT_JAVA_LIBRARIES)
 prebuilt_static_java_libraries := $(LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES)
 prebuilt_is_host := $(LOCAL_IS_HOST_MODULE)
+prebuilt_module_tags := $(LOCAL_MODULE_TAGS)
 
 
 ifndef multi_prebuilt_once
@@ -29,9 +30,10 @@
 # $(1): file list
 # $(2): IS_HOST_MODULE
 # $(3): MODULE_CLASS
-# $(4): OVERRIDE_BUILT_MODULE_PATH
-# $(5): UNINSTALLABLE_MODULE
-# $(6): BUILT_MODULE_STEM
+# $(4): MODULE_TAGS
+# $(5): OVERRIDE_BUILT_MODULE_PATH
+# $(6): UNINSTALLABLE_MODULE
+# $(7): BUILT_MODULE_STEM
 #
 # Elements in the file list may be bare filenames,
 # or of the form "<modulename>:<filename>".
@@ -45,8 +47,9 @@
   $(eval include $(CLEAR_VARS)) \
   $(eval LOCAL_IS_HOST_MODULE := $(2)) \
   $(eval LOCAL_MODULE_CLASS := $(3)) \
-  $(eval OVERRIDE_BUILT_MODULE_PATH := $(4)) \
-  $(eval LOCAL_UNINSTALLABLE_MODULE := $(5)) \
+  $(eval LOCAL_MODULE_TAGS := $(4)) \
+  $(eval OVERRIDE_BUILT_MODULE_PATH := $(5)) \
+  $(eval LOCAL_UNINSTALLABLE_MODULE := $(6)) \
   $(eval tw := $(subst :, ,$(strip $(t)))) \
   $(if $(word 3,$(tw)),$(error $(LOCAL_PATH): Bad prebuilt filename '$(t)')) \
   $(if $(word 2,$(tw)), \
@@ -56,8 +59,8 @@
     $(eval LOCAL_MODULE := $(basename $(notdir $(t)))) \
     $(eval LOCAL_SRC_FILES := $(t)) \
    ) \
-  $(if $(6), \
-    $(eval LOCAL_BUILT_MODULE_STEM := $(6)) \
+  $(if $(7), \
+    $(eval LOCAL_BUILT_MODULE_STEM := $(7)) \
    , \
     $(eval LOCAL_BUILT_MODULE_STEM := $(notdir $(LOCAL_SRC_FILES))) \
    ) \
@@ -73,6 +76,7 @@
     $(prebuilt_static_libs), \
     $(prebuilt_is_host), \
     STATIC_LIBRARIES, \
+    $(prebuilt_module_tags), \
     , \
     true)
 
@@ -80,17 +84,20 @@
     $(prebuilt_shared_libs), \
     $(prebuilt_is_host), \
     SHARED_LIBRARIES, \
+    $(prebuilt_module_tags), \
     $($(if $(prebuilt_is_host),HOST,TARGET)_OUT_INTERMEDIATE_LIBRARIES))
 
 $(call auto-prebuilt-boilerplate, \
     $(prebuilt_executables), \
     $(prebuilt_is_host), \
-    EXECUTABLES)
+    EXECUTABLES, \
+    $(prebuilt_module_tags))
 
 $(call auto-prebuilt-boilerplate, \
     $(prebuilt_java_libraries), \
     $(prebuilt_is_host), \
     JAVA_LIBRARIES, \
+    $(prebuilt_module_tags), \
     , \
     , \
     javalib.jar)
@@ -99,6 +106,7 @@
     $(prebuilt_static_java_libraries), \
     $(prebuilt_is_host), \
     JAVA_LIBRARIES, \
+    $(prebuilt_module_tags), \
     , \
     true, \
     javalib.jar)
@@ -109,3 +117,4 @@
 prebuilt_java_libraries :=
 prebuilt_static_java_libraries :=
 prebuilt_is_host :=
+prebuilt_module_tags :=
diff --git a/core/package.mk b/core/package.mk
index cdeefb4..6834995 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -61,6 +61,10 @@
 $(error $(LOCAL_PATH): Package modules may not set LOCAL_JAVA_RESOURCE_FILES)
 endif
 
+ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
+LOCAL_MANIFEST_FILE := AndroidManifest.xml
+endif
+
 ifneq ($(strip $(LOCAL_MODULE_CLASS)),)
 $(error $(LOCAL_PATH): Package modules may not set LOCAL_MODULE_CLASS)
 endif
@@ -150,6 +154,14 @@
 endif # !custom
 LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
 
+ifeq (true,$(WITH_DEXPREOPT))
+ifneq (,$(LOCAL_SRC_FILES))
+ifndef LOCAL_DEX_PREOPT
+LOCAL_DEX_PREOPT := true
+endif
+endif
+endif
+
 # The dex files go in the package, so we don't
 # want to install them separately for this module.
 old_DONT_INSTALL_DEX_FILES := $(DONT_INSTALL_DEX_FILES)
@@ -160,7 +172,7 @@
 DONT_INSTALL_DEX_FILES := $(old_DONT_INSTALL_DEX_FILES)
 old_DONT_INSTALL_DEX_FILES =
 
-full_android_manifest := $(LOCAL_PATH)/AndroidManifest.xml
+full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
 $(LOCAL_INTERMEDIATE_TARGETS): \
 	PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
 
@@ -310,6 +322,10 @@
 
 # Define the rule to build the actual package.
 $(LOCAL_BUILT_MODULE): $(AAPT) | $(ZIPALIGN)
+ifeq ($(LOCAL_DEX_PREOPT),true)
+# Make sure the boot jars get dexpreopt-ed first
+$(LOCAL_BUILT_MODULE): $(DEXPREOPT_BOOT_ODEXS) | $(DEXPREOPT) $(DEXOPT)
+endif
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries)
 ifneq ($(TARGET_BUILD_APPS),)
     # Include all resources for unbundled apps.
@@ -328,6 +344,14 @@
 	$(sign-package)
 	@# Alignment must happen after all other zip operations.
 	$(align-package)
+ifeq ($(LOCAL_DEX_PREOPT),true)
+	$(hide) rm -f $(patsubst %.apk,%.odex,$@)
+	$(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@))
+	$(call dexpreopt-remove-classes.dex,$@)
+
+built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
+$(built_odex): $(LOCAL_BUILT_MODULE)
+endif
 
 # Save information about this package
 PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
diff --git a/core/pathmap.mk b/core/pathmap.mk
index f204c76..fe7ba1a 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -37,7 +37,6 @@
     graphics:external/skia/include/core \
     libc:bionic/libc/include \
     libdrm1:frameworks/base/media/libdrm/mobile1/include \
-    libdrm2:frameworks/base/media/libdrm/mobile2/include \
     libhardware:hardware/libhardware/include \
     libhardware_legacy:hardware/libhardware_legacy/include \
     libhost:build/libs/host/include \
@@ -90,6 +89,7 @@
 	    wifi \
 	    vpn \
 	    keystore \
+	    voip \
 	 )
 
 #
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index b03f2af..b4717e0 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -42,6 +42,14 @@
 endif
 endif
 
+ifeq ($(LOCAL_IS_HOST_MODULE)$(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
+# for target java libraries, the LOCAL_BUILT_MODULE is in a product-specific dir,
+# while the deps should be in the common dir, so we make a copy in the common dir.
+common_library_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),,COMMON)/$(notdir $(LOCAL_BUILT_MODULE))
+$(common_library_jar) : $(LOCAL_PATH)/$(LOCAL_SRC_FILES) | $(ACP)
+	$(transform-prebuilt-to-target)
+endif
+
 ifeq ($(LOCAL_CERTIFICATE),EXTERNAL)
   # The magic string "EXTERNAL" means this package will be signed with
   # the test key throughout the build process, but we expect the final
diff --git a/core/prelink-linux-arm.map b/core/prelink-linux-arm.map
index 22f5f34..7daaf98 100644
--- a/core/prelink-linux-arm.map
+++ b/core/prelink-linux-arm.map
@@ -16,6 +16,11 @@
 #     [<64K] observed to be less than 64K
 #     [~1M] rounded up, one megabyte (similarly for other sizes)
 #     [???] no size observed, assumed to be one megabyte
+#
+# note: look at the LOAD sections in the library header:
+#
+#   arm-eabi-objdump -x <lib>
+#
 
 # core system libraries
 libdl.so                0xAFF00000 # [<64K]
@@ -77,18 +82,19 @@
 libexif.so              0xABB00000 # [~1M]
 libcamera_client.so     0xABA80000 # [~1M]
 libui.so                0xAB900000 # [~1M]
-# libsgl is for backward-compatibility with donut
-libsgl.so               0xAB800000 # [???]
-libskia.so              0xAB100000 # [~7M]
+libgui.so               0xAB800000 # [~1M]
+libskia.so              0xAB100000 # [~2M]
 librs_jni.so            0xAB000000 # [~1M]
 libRS.so                0xA9E00000 # [~2M]
+libandroid.so           0xA9D80000 # [<64K]
 libjnigraphics.so       0xA9D00000 # [<64K]
 libskiagl.so            0xA9C00000 # [~1M]
 
 # audio
 libFLAC.so              0xA9B00000 # [???]
 libaudiopolicy.so       0xA9A00000 # [~1M]
-libaudiopolicygeneric.so 0xA9900000 # [???]
+libeffects.so           0xA9980000 # [<64K]
+libaudioeffect_jni.so   0xA9900000 # [<64K]
 libsoundpool.so         0xA9800000 # [~1M]
 libaudio.so             0xA9700000 # [~1M]
 libspeech.so            0xA9600000 # [~1M]
diff --git a/core/product.mk b/core/product.mk
index 38d1148..4a0ee01 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -68,9 +68,9 @@
     PRODUCT_MANUFACTURER \
     PRODUCT_BRAND \
     PRODUCT_PROPERTY_OVERRIDES \
+    PRODUCT_CHARACTERISTICS \
     PRODUCT_COPY_FILES \
     PRODUCT_OTA_PUBLIC_KEYS \
-    PRODUCT_POLICY \
     PRODUCT_PACKAGE_OVERLAYS \
     DEVICE_PACKAGE_OVERLAYS \
     PRODUCT_CONTRIBUTORS_FILE \
diff --git a/core/product_config.mk b/core/product_config.mk
index 04f6ce1..70ac894 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -119,12 +119,16 @@
     default_goal_substitution := $(DEFAULT_GOAL)
   endif
 
-  # Hack to make the linux build servers use dexpreopt.
-  # OSX is still a little flaky.  Most engineers don't use this
-  # type of target ("make PRODUCT-blah-user"), so this should
-  # only tend to happen when using buildbot.
-  # TODO: remove this and fix the matching lines in build/core/main.mk
-  # once dexpreopt works better on OSX.
+  # For tests build, only build tests-build-target
+  ifeq (tests,$(TARGET_BUILD_VARIANT))
+    default_goal_substitution := tests-build-target
+  endif
+
+  # Hack to make the linux build servers use dexpreopt (emulator-based
+  # preoptimization). Most engineers don't use this type of target
+  # ("make PRODUCT-blah-user"), so this should only tend to happen when
+  # using buildbot.
+  # TODO: Remove this once host Dalvik preoptimization is working.
   ifeq ($(TARGET_BUILD_VARIANT),user)
     WITH_DEXPREOPT_buildbot := true
   endif
@@ -249,12 +253,15 @@
   PRODUCT_MANUFACTURER := unknown
 endif
 
+ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CHARACTERISTICS),)
+  TARGET_AAPT_CHARACTERISTICS := default
+else
+  TARGET_AAPT_CHARACTERISTICS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CHARACTERISTICS))
+endif
+
 PRODUCT_DEFAULT_WIFI_CHANNELS := \
 	$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEFAULT_WIFI_CHANNELS))
 
-# Which policy should this product use
-PRODUCT_POLICY := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_POLICY))
-
 # A list of words like <source path>:<destination path>.  The file at
 # the source path should be copied to the destination path when building
 # this product.  <destination path> is relative to $(PRODUCT_OUT), so
diff --git a/core/proguard.flags b/core/proguard.flags
index 06e32cc..447e7c5 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -44,6 +44,19 @@
 @com.google.common.annotations.VisibleForTesting *;
 }
 
+# Keep serializable classes and necessary members for serializable classes
+# Copied from the ProGuard manual at http://proguard.sourceforge.net.
+-keepnames class * implements java.io.Serializable
+-keepclassmembers class * implements java.io.Serializable {
+    static final long serialVersionUID;
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+    !static !transient <fields>;
+    private void writeObject(java.io.ObjectOutputStream);
+    private void readObject(java.io.ObjectInputStream);
+    java.lang.Object writeReplace();
+    java.lang.Object readResolve();
+}
+
 # Please specify classes to be kept explicitly in your package's configuration.
 # -keep class * extends android.app.Activity
 # -keep class * extends android.view.View
diff --git a/core/raw_executable.mk b/core/raw_executable.mk
index 30e0ade..b64173a 100644
--- a/core/raw_executable.mk
+++ b/core/raw_executable.mk
@@ -7,10 +7,10 @@
 $(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) : TARGET_PROJECT_INCLUDES := 
-$(all_objects) : TARGET_C_INCLUDES := 
-$(all_objects) : TARGET_GLOBAL_CFLAGS := 
-$(all_objects) : TARGET_GLOBAL_CPPFLAGS := 
+$(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 $@)
@@ -23,4 +23,3 @@
 		--start-group $(PRIVATE_ALL_STATIC_LIBRARIES) --end-group \
 		$(PRIVATE_LIBS)
 	$(hide) $(TARGET_OBJCOPY) -O binary $(PRIVATE_ELF_FILE) $@
-
diff --git a/core/shared_library.mk b/core/shared_library.mk
index a30d868..77d253f 100644
--- a/core/shared_library.mk
+++ b/core/shared_library.mk
@@ -26,7 +26,29 @@
 
 include $(BUILD_SYSTEM)/dynamic_binary.mk
 
+# Define PRIVATE_ variables from global vars
+my_target_global_ld_dirs := $(TARGET_GLOBAL_LD_DIRS)
+my_target_global_ldflags := $(TARGET_GLOBAL_LDFLAGS)
+my_target_fdo_lib := $(TARGET_FDO_LIB)
+my_target_libgcc := $(TARGET_LIBGCC)
+my_target_crtbegin_so_o := $(TARGET_CRTBEGIN_SO_O)
+my_target_crtend_so_o := $(TARGET_CRTEND_SO_O)
+ifdef LOCAL_NDK_VERSION
+my_target_global_ld_dirs += -L$(my_ndk_version_root)/usr/lib
+# The latest ndk does NOT support TARGET_CRTBEGIN_SO_O and TARGET_CRTEND_SO_O yet.
+# my_target_crtbegin_so_o := $(my_ndk_version_root)/usr/lib/crtbegin_so.o
+# my_target_crtend_so_o := $(my_ndk_version_root)/usr/lib/crtend_so.o
+my_target_crtbegin_so_o :=
+my_target_crtend_so_o :=
+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_LIBGCC := $(my_target_libgcc)
+$(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) \
-                  $(TARGET_CRTBEGIN_SO_O) $(TARGET_CRTEND_SO_O)
+                  $(my_target_crtbegin_so_o) $(my_target_crtend_so_o)
 	$(transform-o-to-shared-lib)
diff --git a/core/static_library.mk b/core/static_library.mk
index 2138e46..4ff5a34 100644
--- a/core/static_library.mk
+++ b/core/static_library.mk
@@ -19,10 +19,10 @@
 
 ifeq ($(LOCAL_RAW_STATIC_LIBRARY),true)
 LOCAL_RAW_STATIC_LIBRARY:=
-$(all_objects) : TARGET_PROJECT_INCLUDES := 
-$(all_objects) : TARGET_C_INCLUDES := 
-$(all_objects) : TARGET_GLOBAL_CFLAGS := 
-$(all_objects) : TARGET_GLOBAL_CPPFLAGS := 
+$(all_objects) : PRIVATE_TARGET_PROJECT_INCLUDES :=
+$(all_objects) : PRIVATE_TARGET_C_INCLUDES :=
+$(all_objects) : PRIVATE_TARGET_GLOBAL_CFLAGS :=
+$(all_objects) : PRIVATE_TARGET_GLOBAL_CPPFLAGS :=
 endif
 
 $(LOCAL_BUILT_MODULE): $(built_whole_libraries)
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index a1276f4..8e22552 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -29,85 +29,24 @@
 junit_host_jar := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
 HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
 
-CTS_CORE_CASE_LIST := android.core.tests.annotation \
-	android.core.tests.archive \
-	android.core.tests.concurrent \
-	android.core.tests.crypto \
+CTS_CORE_CASE_LIST := \
 	android.core.tests.dom \
-	android.core.tests.logging \
 	android.core.tests.luni.io \
 	android.core.tests.luni.lang \
 	android.core.tests.luni.net \
 	android.core.tests.luni.util \
-	android.core.tests.math \
-	android.core.tests.nio \
-	android.core.tests.nio_char \
-	android.core.tests.prefs \
-	android.core.tests.regex \
-	android.core.tests.security \
-	android.core.tests.sql \
-	android.core.tests.text \
 	android.core.tests.xml \
-	android.core.tests.xnet \
 	android.core.tests.runner
 
-CTS_SECURITY_APPS_LIST := \
-	CtsAppAccessData \
-	CtsAppWithData \
-	CtsInstrumentationAppDiffCert \
-	CtsPermissionDeclareApp \
-	CtsSharedUidInstall \
-	CtsSharedUidInstallDiffCert \
-	CtsSimpleAppInstall \
-	CtsSimpleAppInstallDiffCert \
-	CtsTargetInstrumentationApp \
-	CtsUsePermissionDiffCert
-
-CTS_CASE_LIST := \
-	TestDeviceSetup \
-	CtsTestStubs \
-	CtsAccountManagerTestCases \
-	CtsAppTestCases \
-	CtsBluetoothTestCases \
-	CtsContentTestCases \
-	CtsDatabaseTestCases \
-	CtsDpiTestCases \
-	CtsDpiTestCases2 \
-	CtsExampleTestCases \
-	CtsGestureTestCases \
-	CtsGraphicsTestCases \
-	CtsHardwareTestCases \
-	CtsJniTestCases \
-	CtsLocationTestCases \
-	CtsMediaTestCases \
-	CtsOsTestCases \
-	CtsPermissionTestCases \
-	CtsPermission2TestCases \
-	CtsProviderTestCases \
-	CtsSpeechTestCases \
-	CtsTelephonyTestCases \
-	CtsTextTestCases \
-	CtsUtilTestCases \
-	CtsViewTestCases \
-	CtsWebkitTestCases \
-	CtsWidgetTestCases \
-	CtsNetTestCases \
-	SignatureTest \
-	CtsPerformanceTestCases \
-	CtsPerformance2TestCases \
-	CtsPerformance3TestCases \
-	CtsPerformance4TestCases \
-	CtsPerformance5TestCases \
-	ApiDemos \
-	ApiDemosReferenceTest \
-	$(CTS_CORE_CASE_LIST) \
-	$(CTS_SECURITY_APPS_LIST)
+-include cts/CtsTestCaseList.mk
+CTS_CASE_LIST := $(CTS_CORE_CASE_LIST) $(CTS_TEST_CASE_LIST)
 
 DEFAULT_TEST_PLAN := $(PRIVATE_DIR)/resource/plans
 
 $(cts_dir)/all_cts_files_stamp: PRIVATE_JUNIT_HOST_JAR := $(junit_host_jar)
 
-$(cts_dir)/all_cts_files_stamp: $(CTS_CASE_LIST) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(ACP)
+-include cts/CtsHostLibraryList.mk
+$(cts_dir)/all_cts_files_stamp: $(CTS_CASE_LIST) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(ACP)
 # Make necessary directory for CTS
 	@rm -rf $(PRIVATE_CTS_DIR)
 	@mkdir -p $(TMP_DIR)
@@ -115,15 +54,8 @@
 	@mkdir -p $(PRIVATE_DIR)/tools
 	@mkdir -p $(PRIVATE_DIR)/repository/testcases
 	@mkdir -p $(PRIVATE_DIR)/repository/plans
-# Copy executable to CTS directory
-	$(hide) $(ACP) -fp $(CTS_HOST_JAR) $(PRIVATE_DIR)/tools
-	$(hide) $(ACP) -fp $(CTS_EXECUTABLE_PATH) $(PRIVATE_DIR)/tools
-# Copy ddmlib prebuilt jar
-	$(hide) $(ACP) -fp $(DDMLIB_JAR) $(PRIVATE_DIR)/tools
-# Copy junit jar
-	$(hide) $(ACP) -fp $(PRIVATE_JUNIT_HOST_JAR) $(PRIVATE_DIR)/tools
-# Copy hosttestlib jar
-	$(hide) $(ACP) -fp $(HOSTTESTLIB_JAR) $(PRIVATE_DIR)/tools
+# Copy executable and JARs to CTS directory
+	$(hide) $(ACP) -fp $(CTS_HOST_JAR) $(CTS_EXECUTABLE_PATH) $(DDMLIB_JAR) $(PRIVATE_JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(PRIVATE_DIR)/tools
 # Change mode of the executables
 	$(hide) chmod ug+rwX $(PRIVATE_DIR)/tools/$(notdir $(CTS_EXECUTABLE_PATH))
 	$(foreach apk,$(CTS_CASE_LIST), \
@@ -147,8 +79,13 @@
 endef
 
 CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core,,COMMON)
+JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
+RUNNER_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junitrunner,,COMMON)
+SUPPORT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests-support,,COMMON)
+DOM_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests-dom,,COMMON)
+XML_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests-xml,,COMMON)
 TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
-GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(CORE_INTERMEDIATES)/javalib.jar:$(TESTS_INTERMEDIATES)/javalib.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(RUNNER_INTERMEDIATES)/classes.jar:$(SUPPORT_INTERMEDIATES)/classes.jar:$(DOM_INTERMEDIATES)/classes.jar:$(XML_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(CORE_INTERMEDIATES)/javalib.jar:$(JUNIT_INTERMEDIATES)/javalib.jar:$(RUNNER_INTERMEDIATES)/javalib.jar:$(SUPPORT_INTERMEDIATES)/javalib.jar:$(DOM_INTERMEDIATES)/javalib.jar:$(XML_INTERMEDIATES)/javalib.jar:$(TESTS_INTERMEDIATES)/javalib.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
 
 $(cts_dir)/all_cts_core_files_stamp: PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 $(cts_dir)/all_cts_core_files_stamp: PRIVATE_JAVAOPTS:=-Xmx256M
@@ -159,25 +96,10 @@
 # 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_dir)/all_cts_core_files_stamp: $(CTS_CORE_CASE_LIST) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.annotation,\
-		cts/tests/core/annotation/AndroidManifest.xml,\
-		tests.annotation.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.archive,\
-		cts/tests/core/archive/AndroidManifest.xml,\
-		tests.archive.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.concurrent,\
-		cts/tests/core/concurrent/AndroidManifest.xml,\
-		tests.concurrent.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.crypto,\
-		cts/tests/core/crypto/AndroidManifest.xml,\
-		tests.crypto.AllTests)
+$(cts_dir)/all_cts_core_files_stamp: $(CTS_CORE_CASE_LIST) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(RUNNER_INTERMEDIATES)/javalib.jar $(SUPPORT_INTERMEDIATES)/javalib.jar $(DOM_INTERMEDIATES)/javalib.jar $(XML_INTERMEDIATES)/javalib.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.dom,\
 		cts/tests/core/dom/AndroidManifest.xml,\
 		tests.dom.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.logging,\
-		cts/tests/core/logging/AndroidManifest.xml,\
-		tests.logging.AllTests)
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.luni.io,\
 		cts/tests/core/luni-io/AndroidManifest.xml,\
 		tests.luni.AllTestsIo)
@@ -190,36 +112,9 @@
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.luni.util,\
 		cts/tests/core/luni-util/AndroidManifest.xml,\
 		tests.luni.AllTestsUtil)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.math,\
-		cts/tests/core/math/AndroidManifest.xml,\
-		tests.math.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.nio,\
-		cts/tests/core/nio/AndroidManifest.xml,\
-		tests.nio.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.nio_char,\
-		cts/tests/core/nio_char/AndroidManifest.xml,\
-		tests.nio_char.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.prefs,\
-		cts/tests/core/prefs/AndroidManifest.xml,\
-		tests.prefs.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.regex,\
-		cts/tests/core/regex/AndroidManifest.xml,\
-		tests.regex.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.security,\
-		cts/tests/core/security/AndroidManifest.xml,\
-		tests.security.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.sql,\
-		cts/tests/core/sql/AndroidManifest.xml,\
-		tests.sql.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.text,\
-		cts/tests/core/text/AndroidManifest.xml,\
-		tests.text.AllTests)
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.xml,\
 		cts/tests/core/xml/AndroidManifest.xml,\
 		tests.xml.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.xnet,\
-		cts/tests/core/xnet/AndroidManifest.xml,\
-		tests.xnet.AllTests)
 	$(hide) touch $@
 
 
@@ -229,17 +124,19 @@
 
 VMTESTS_INTERMEDIATES :=$(call intermediates-dir-for,EXECUTABLES,vm-tests,1,)
 # core tests only needed to get hold of junit-framework-classes
-TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
 CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core,,COMMON)
+JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
+RUNNER_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junitrunner,,COMMON)
+TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
 
-GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(RUNNER_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
 
 $(CORE_VM_TEST_DESC): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 $(CORE_VM_TEST_DESC): PRIVATE_PARAMS:=-Dcts.useSuppliedTestResult=true
 $(CORE_VM_TEST_DESC): PRIVATE_PARAMS+=-Dcts.useEnhancedJunit=true
 $(CORE_VM_TEST_DESC): PRIVATE_JAVAOPTS:=-Xmx256M
 # Please see big comment above on why this line depends on javalib.jar instead of classes.jar
-$(CORE_VM_TEST_DESC): vm-tests $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
+$(CORE_VM_TEST_DESC): vm-tests $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(RUNNER_INTERMEDIATES)/javalib.jar $(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
 	$(call generate-core-test-description,$(CORE_VM_TEST_DESC),\
 		cts/tests/vm-tests/AndroidManifest.xml,\
 		dot.junit.AllJunitHostTests, cts/tools/vm-tests/Android.mk)
diff --git a/core/tasks/ide.mk b/core/tasks/ide.mk
new file mode 100644
index 0000000..e557e60
--- /dev/null
+++ b/core/tasks/ide.mk
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2010 The Android Open 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.
+#
+
+define filter-ide-goals
+$(strip $(filter $(1)-%,$(MAKECMDGOALS)))
+endef
+
+define filter-ide-modules
+$(strip $(subst -,$(space),$(patsubst $(1)-%,%,$(2))))
+endef
+
+# eclipse
+eclipse_project_goals := $(call filter-ide-goals,ECLIPSE)
+ifdef eclipse_project_goals
+  ifneq ($(words $(eclipse_project_goals)),1)
+    $(error Only one ECLIPSE- goal may be specified: $(eclipse_project_goals))
+  endif
+  eclipse_project_modules := $(call filter-ide-modules,ECLIPSE,$(eclipse_project_goals))
+
+  ifneq ($(filter lunch,$(eclipse_project_modules)),)
+    eclipse_project_modules := $(filter-out lunch,$(eclipse_project_modules))
+    installed_modules := $(foreach m,$(ALL_DEFAULT_INSTALLED_MODULES),\
+        $(INSTALLABLE_FILES.$(m).MODULE))
+    java_modules := $(foreach m,$(installed_modules),\
+        $(if $(filter JAVA_LIBRARIES APPS,$(ALL_MODULES.$(m).CLASS)),$(m),))
+    eclipse_project_modules := $(sort $(eclipse_project_modules) $(java_modules))
+  endif
+
+  source_paths := $(foreach m,$(eclipse_project_modules),$(ALL_MODULES.$(m).PATH)) \
+              $(foreach m,$(eclipse_project_modules),$(ALL_MODULES.$(m).INTERMEDIATE_SOURCE_DIR)) \
+              $(INTERNAL_SDK_SOURCE_DIRS)
+  source_paths := $(sort $(source_paths))
+
+.classpath: PRIVATE_MODULES := $(eclipse_project_modules)
+.classpath: PRIVATE_DIRS := $(source_paths)
+
+# the mess below with ./src tries to guess whether the src
+$(eclipse_project_goals): .classpath
+.classpath: FORCE
+	$(hide) echo Generating .classpath for eclipse
+	$(hide) echo '<classpath>' > $@
+	$(hide) for p in $(PRIVATE_DIRS) ; do \
+		echo -n '  <classpathentry kind="src" path="' >> $@ ; \
+		( if [ -d $$p/src ] ; then echo -n $$p/src ; else echo -n $$p ; fi ) >> $@ ; \
+		echo '"/>' >> $@ ; \
+	done
+	$(hide) echo '</classpath>' >> $@
+endif
+
diff --git a/core/user_tags.mk b/core/user_tags.mk
new file mode 100644
index 0000000..7800710
--- /dev/null
+++ b/core/user_tags.mk
@@ -0,0 +1,481 @@
+#
+# Copyright (C) 2010 The Android Open 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 the list of modules grandfathered to use a user tag
+
+# DO NOT ADD ANY NEW MODULE TO THIS FILE
+#
+# user modules are hard to control and audit and we don't want
+# to add any new such module in the system
+
+GRANDFATHERED_USER_MODULES :=
+
+-include vendor/google/user_tags.mk
+
+GRANDFATHERED_USER_MODULES += \
+	20-dns.conf \
+	95-configured \
+	aapt \
+	acp \
+	adb \
+	AdbWinApi \
+	AdbWinUsbApi \
+	adbd \
+	aidl \
+	am \
+	android \
+	android-common \
+	android.policy \
+	androidprefs \
+	android.test.runner \
+	ant \
+	antlr-2.7.7 \
+	anttasks \
+	apicheck \
+	apkcheck \
+	applypatch \
+	app_process \
+	apriori \
+	archquery \
+	asm-3.1 \
+	atree \
+	audio \
+	bb2sym \
+	bb_dump \
+	bbprof \
+	bison \
+	bluetoothd \
+	bmgr \
+	bootanimation \
+	brcm_patchram_plus \
+	bugreport \
+	cfassembler \
+	check_stack \
+	check_trace \
+	clearsilver \
+	cmu2nuance \
+	com.android.inputmethod.pinyin.lib \
+	com.android.phone.common \
+	commons-compress-1.0 \
+	copybit.qsd8k \
+	coverage \
+	cpufeatures \
+	cts \
+	CtsAppSecurityTests \
+	cts-dalvik-buildutil \
+	dasm \
+	dbus-daemon \
+	ddmlib \
+	ddmlibTests \
+	ddmlib-prebuilt \
+	ddms \
+	ddmuilib \
+	debuggerd \
+	descGen \
+	dexpreopt \
+	dex-tools \
+	dhcpcd \
+	dhcpcd.conf \
+	dhcpcd-run-hooks \
+	dictTest \
+	dnsmasq \
+	draw9patch \
+	droiddoc \
+	dumpeventlog \
+	dumpkey \
+	dump_regions \
+	dumpstate \
+	dumpsys \
+	dx-tests \
+	easymock \
+	edify \
+	emmalib \
+	emulator \
+	emulator-arm \
+	emulator-core \
+	emulator-elff \
+	emulator-hw \
+	emulator-memcheck \
+	emulator-tcg \
+	emulator-ui \
+	etc1tool \
+	eventanalyzer \
+	exc_dump \
+	fastboot \
+	framework \
+	FrameworkCoreHostTests \
+	frameworks-core-util-lib \
+	fsck_msdos \
+	fs_get_stats \
+	fw_bcm4329_apsta.bin \
+	fw_bcm4329.bin \
+	genext2fs \
+	gps.mahimahi \
+	gralloc.default \
+	gralloc.qsd8k \
+	groovy-all-1.7.0 \
+	grxmlcompile \
+	guava \
+	guavalib \
+	gzip \
+	hciattach \
+	hierarchyviewer \
+	hierarchyviewer1 \
+	hierarchyviewer2 \
+	hierarchyviewerlib \
+	hist_trace \
+	hosttestlib \
+	icudata \
+	idegen \
+	ime \
+	init \
+	input \
+	installd \
+	iptables \
+	ip-up-vpn \
+	iself \
+	isprelinked \
+	jarjar \
+	javax.obex \
+	jcommon-1.0.12 \
+	jdiff \
+	jdwpspy \
+	jfreechart-1.0.9 \
+	jfreechart-1.0.9-swt \
+	jsilver \
+	jsr305 \
+	jsr305lib \
+	junit \
+	jython \
+	kcm \
+	keystore \
+	kxml2-2.3.0 \
+	launch-wrapper \
+	layoutlib \
+	layoutlib_api \
+	layoutlib_create \
+	layoutlib_utils \
+	layoutopt \
+	liba2dp \
+	libabi \
+	libacc \
+	libandroid \
+	libandroid_runtime \
+	libandroid_servers \
+	libarity \
+	libastl \
+	libastl_host \
+	libaudio \
+	libaudioeffect_jni \
+	libaudioflinger \
+	libaudiointerface \
+	libaudiopolicy \
+	libaudiopolicybase \
+	libbinder \
+	libbluedroid \
+	libbluetooth \
+	libbluetoothd \
+	libbuiltinplugin \
+	libbundlewrapper \
+	libbz \
+	libc \
+	libcamera_client \
+	libcameraservice \
+	libcamerastub \
+	libc_common \
+	libc_nomalloc \
+	libctest \
+	libcutils \
+	libdb \
+	libdbus \
+	libdiskconfig \
+	libdiskconfig_host \
+	libdl \
+	libdrm1 \
+	libdrm1_jni \
+	libebl \
+	libebl_arm \
+	libebl_sh \
+	libedify \
+	libeffects \
+	libEGL \
+	libelf \
+	libelfcopy \
+	libESR_Portable \
+	libESR_Shared \
+	libETC1 \
+	libexif \
+	libext \
+	libfdlibm \
+	libfdlibm-host \
+	libFFTEm \
+	libfst \
+	libft2 \
+	libgdbus_static \
+	libgif \
+	libGLES_android \
+	libGLESv1_CM \
+	libGLESv2 \
+	libglib_static \
+	libgui \
+	libhardware \
+	libhardware_legacy \
+	libhost \
+	libiprouteutil \
+	libiptc \
+	libjnigraphics \
+	libjni_latinime \
+	libjni_pinyinime \
+	libjpeg \
+	libjs \
+	liblinenoise \
+	libloc_api-rpc \
+	liblog \
+	libm \
+	libmedia \
+	libmedia_jni \
+	libmediaplayerservice \
+	libmincrypt \
+	libminui \
+	libminzip \
+	libmtdutils \
+	libmusicbundle \
+	libneo_cgi \
+	libneo_cs \
+	libneo_util \
+	libnetlink \
+	libnetutils \
+	libop \
+	libOpenSLES \
+	libopensles_helper \
+	libOpenSLESUT \
+	libpcap \
+	libpixelflinger \
+	libpixelflinger_armv6 \
+	libpixelflinger_static \
+	libpng \
+	libpopt \
+	libpower \
+	librecovery_ui_htc \
+	libreference-cdma-sms \
+	libreference-ril \
+	libreverb \
+	libreverbwrapper \
+	libril \
+	librpc \
+	librtp_jni \
+	libsafe_iop \
+	libSDL \
+	libSDLmain \
+	libsensorservice \
+	libskia \
+	libskiagl \
+	libsonivox \
+	libsoundpool \
+	libspeex \
+	libsqlite \
+	libsqlite3_android \
+	libSR_AcousticModels \
+	libSR_AcousticState \
+	libSR_AudioIn \
+	libSR_Core \
+	libsrec_jni \
+	libSR_EventLog \
+	libSR_G2P \
+	libSR_Grammar \
+	libSR_Nametag \
+	libSR_Recognizer \
+	libSR_Semproc \
+	libSR_Session \
+	libSR_Vocabulary \
+	libstagefright \
+	libstagefright_aacdec \
+	libstagefright_aacenc \
+	libstagefright_amrnb_common \
+	libstagefright_amrnbdec \
+	libstagefright_amrnbenc \
+	libstagefright_amrwbdec \
+	libstagefright_amrwbenc \
+	libstagefright_avc_common \
+	libstagefright_avcdec \
+	libstagefright_avcenc \
+	libstagefright_color_conversion \
+	libstagefright_enc_common \
+	libstagefright_foundation \
+	libstagefright_g711dec \
+	libstagefright_httplive \
+	libstagefrighthw \
+	libstagefright_id3 \
+	libstagefright_m4vh263dec \
+	libstagefright_m4vh263enc \
+	libstagefright_matroska \
+	libstagefright_mp3dec \
+	libstagefright_mpeg2ts \
+	libstagefright_omx \
+	libstagefright_rtsp \
+	libstagefright_vorbisdec \
+	libstagefright_vpxdec \
+	libstdc++ \
+	libstlport \
+	libstlport_static \
+	libstorage \
+	libsurfaceflinger \
+	libsurfaceflinger_client \
+	libsvoxpico \
+	libsystem_server \
+	libsysutils \
+	libthread_db \
+	libtinyxml \
+	libtomcrypt \
+	libtommath \
+	libttspico \
+	libttssynthproxy \
+	libui \
+	libunz \
+	libutil \
+	libutils \
+	libv8 \
+	libvisualizer \
+	libvorbisidec \
+	libvpx \
+	libwebcore \
+	libwpa_client \
+	libwrapsim \
+	libxml2 \
+	libzipfile \
+	lights.kraken \
+	lights.qsd8k \
+	line_endings \
+	linker \
+	localize \
+	logcat \
+	logwrapper \
+	lsd \
+	mahimahi-keypad.kcm \
+	make_cfst \
+	makedict \
+	make_ext4fs \
+	make_g2g \
+	makekeycodes \
+	make_ve_grammar \
+	mediaserver \
+	minigzip \
+	mkbootfs \
+	mkbootimg \
+	mksdcard \
+	mksnapshot \
+	mkstubs \
+	mkuserimg.sh \
+	mkyaffs2image \
+	monkey \
+	monkeyrunner \
+	MonkeyRunnerTest \
+	mtpd \
+	ndc \
+	netcfg \
+	netd \
+	ninepatch \
+	oauth \
+	obbtool \
+	omx_tests \
+	org.eclipse.core.commands_3.4.0.I20080509-2000 \
+	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
+	org.eclipse.jface_3.4.2.M20090107-0800 \
+	org-netbeans-api-visual \
+	org-openide-util \
+	osgi \
+	pand \
+	parseStringTest \
+	ping \
+	platform.xml \
+	pm \
+	post_trace \
+	pppd \
+	preload \
+	profile_pid \
+	profile_trace \
+	q2dm \
+	q2g \
+	qemu-android \
+	qwerty2.kcm \
+	qwerty.kcm \
+	racoon \
+	read_addr \
+	read_method \
+	read_pid \
+	read_trace \
+	rgb2565 \
+	rild \
+	rsg-generator \
+	run-as \
+	runtime \
+	schedtest \
+	screenshot2 \
+	sdcard \
+	sdklauncher \
+	sdklib \
+	sdkmanager \
+	sdkstats \
+	sdkuilib \
+	sdk_v4 \
+	sdk_v5 \
+	sdk_v6 \
+	sdk_v7 \
+	sdk_v8 \
+	sdptool \
+	service \
+	servicemanager \
+	services \
+	sh \
+	sig \
+	sig-check \
+	sig-create \
+	signapk \
+	signature-tools \
+	simg2img \
+	simulator \
+	soslim \
+	spec-progress \
+	sqlite3 \
+	stack_dump \
+	stringtemplate \
+	surfaceflinger \
+	svc \
+	swing-worker-1.1 \
+	swt \
+	system_server \
+	tc \
+	temp_layoutlib \
+	test_g2g \
+	test-progress \
+	test-progress-new \
+	test_swiarb \
+	test_zipfile \
+	toolbox \
+	traceview \
+	tuttle2.kcm \
+	uix \
+	usbtest \
+	vdc \
+	vm-tests \
+	vold \
+	wdsclient \
+	wpa_supplicant \
+	wpa_supplicant.conf \
+	xmlwriter \
+	yuv420sp2rgb \
+	zipalign
+
diff --git a/envsetup.sh b/envsetup.sh
index 202e6c2..045e464 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -106,7 +106,7 @@
     # and in with the new
     CODE_REVIEWS=
     prebuiltdir=$(getprebuilt)
-    export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/toolchain/arm-eabi-4.4.0/bin
+    export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/toolchain/arm-eabi-4.4.3/bin
     export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN
     export ANDROID_QTOOLS=$T/development/emulator/qtools
     export ANDROID_BUILD_PATHS=:$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_QTOOLS:$ANDROID_TOOLCHAIN:$ANDROID_EABI_TOOLCHAIN$CODE_REVIEWS
@@ -150,9 +150,6 @@
     setpaths
     set_sequence_number
 
-    # Don't try to do preoptimization until it works better on OSX.
-    export DISABLE_DEXPREOPT=true
-
     export ANDROID_BUILD_TOP=$(gettop)
 }
 
@@ -650,7 +647,7 @@
         elif [ ! "$M" ]; then
             echo "Couldn't locate a makefile from the current directory."
         else
-            ONE_SHOT_MAKEFILE=$M make -C $T files $@
+            ONE_SHOT_MAKEFILE=$M make -C $T all_modules $@
         fi
     fi
 }
@@ -667,7 +664,7 @@
         for DIR in $DIRS ; do
             DIR=`echo $DIR | sed -e 's:/$::'`
             if [ -f $DIR/Android.mk ]; then
-                TO_CHOP=`echo $T | wc -c | tr -d ' '`
+                TO_CHOP=`(cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
                 TO_CHOP=`expr $TO_CHOP + 1`
                 START=`PWD= /bin/pwd`
                 MFILE=`echo $START | cut -c${TO_CHOP}-`
@@ -682,13 +679,15 @@
                     ARGS="$ARGS snod"
                 elif [ "$DIR" = showcommands ]; then
                     ARGS="$ARGS showcommands"
+                elif [ "$DIR" = dist ]; then
+                    ARGS="$ARGS dist"
                 else
                     echo "No Android.mk in $DIR."
                     return 1
                 fi
             fi
         done
-        ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS files $ARGS
+        ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS all_modules $ARGS
     else
         echo "Couldn't locate the top of the tree.  Try setting TOP."
     fi
diff --git a/target/board/Android.mk b/target/board/Android.mk
index ac8cb44..82dee3c 100644
--- a/target/board/Android.mk
+++ b/target/board/Android.mk
@@ -23,16 +23,7 @@
 # Use the add-radio-file function to add values to this variable.
 INSTALLED_RADIOIMAGE_TARGET :=
 
-ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/AndroidBoard.mk))
-  ifeq (,$(wildcard $(TARGET_DEVICE_DIR)/Android.mk))
-    $(error Missing "$(TARGET_DEVICE_DIR)/AndroidBoard.mk")
-  else
-    # TODO: Remove this check after people have had a chance to switch,
-    # after April 2009.
-    $(error Please rename "$(TARGET_DEVICE_DIR)/Android.mk" to "$(TARGET_DEVICE_DIR)/AndroidBoard.mk")
-  endif
-endif
-include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
+-include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
 
 # Generate a file that contains various information about the
 # device we're building for.  This file is typically packaged up
diff --git a/target/board/emulator/BoardConfig.mk b/target/board/emulator/BoardConfig.mk
index 784118a..9ab607a 100644
--- a/target/board/emulator/BoardConfig.mk
+++ b/target/board/emulator/BoardConfig.mk
@@ -7,3 +7,6 @@
 TARGET_NO_BOOTLOADER := true
 TARGET_NO_KERNEL := true
 HAVE_HTC_AUDIO_DRIVER := true
+
+# no hardware camera
+USE_CAMERA_STUB := true
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index f630dac..26bf6ab 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -10,5 +10,8 @@
 HAVE_HTC_AUDIO_DRIVER := true
 BOARD_USES_GENERIC_AUDIO := true
 
+# no hardware camera
+USE_CAMERA_STUB := true
+
 # Set /system/bin/sh to mksh, not ash, to test the transition.
 TARGET_SHELL := mksh
diff --git a/target/board/sim/BoardConfig.mk b/target/board/sim/BoardConfig.mk
index 491b30f..ba25c18 100644
--- a/target/board/sim/BoardConfig.mk
+++ b/target/board/sim/BoardConfig.mk
@@ -20,6 +20,12 @@
 # The simulator does not support native code at all
 TARGET_CPU_ABI := none
 
+# But it is very likely SMP.
+TARGET_CPU_SMP := true
+
 #the simulator partially emulates the original HTC /dev/eac audio interface
 HAVE_HTC_AUDIO_DRIVER := true
 BOARD_USES_GENERIC_AUDIO := true
+
+# no hardware camera
+USE_CAMERA_STUB := true
diff --git a/target/product/core.mk b/target/product/core.mk
index 7fe3889..a1cc4df 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -18,17 +18,45 @@
 PRODUCT_DEVICE := generic
 PRODUCT_NAME := core
 
-PRODUCT_POLICY := android.policy_phone
-
 PRODUCT_PROPERTY_OVERRIDES := \
     ro.config.notification_sound=OnTheHunt.ogg \
     ro.config.alarm_alert=Alarm_Classic.ogg
 
 PRODUCT_PACKAGES := \
+    bouncycastle \
+    com.android.location.provider \
+    com.android.location.provider.xml \
+    core \
+    core-junit \
+    create_test_dmtrace \
+    dalvikvm \
+    dexdeps \
+    dexdump \
+    dexlist \
+    dexopt \
+    dmtracedump \
+    dvz \
+    dx \
+    ext \
     framework-res \
+    hprof-conv \
+    icu.dat \
     ip-up-vpn \
+    jasmin \
+    jasmin.jar \
+    libcrypto \
+    libdex \
+    libdvm \
+    libexpat \
+    libicui18n \
+    libicuuc \
+    libjavacore \
+    libnativehelper \
+    libsqlite_jni \
+    libssl \
+    libz \
+    sqlite-jdbc \
     Browser \
-    CarHomeLauncher \
     Contacts \
     Home \
     HTMLViewer \
@@ -36,6 +64,7 @@
     ApplicationsProvider \
     ContactsProvider \
     DownloadProvider \
+    DownloadProviderUi \
     MediaProvider \
     PicoTts \
     SettingsProvider \
@@ -47,8 +76,11 @@
     DefaultContainerService \
     Bugreport
 
-PRODUCT_PROPERTY_OVERRIDES += \
-    media.stagefright.enable-player=true \
-    media.stagefright.enable-meta=true   \
-    media.stagefright.enable-scan=true   \
-    media.stagefright.enable-http=true
+# host-only dependencies
+ifeq ($(WITH_HOST_DALVIK),true)
+    PRODUCT_PACKAGES += \
+        bouncycastle-hostdex \
+        core-hostdex \
+        libjavacore-host
+endif
+
diff --git a/target/product/full.mk b/target/product/full.mk
index 8725804..c204aad 100644
--- a/target/product/full.mk
+++ b/target/product/full.mk
@@ -43,6 +43,9 @@
 # on smaller devices.
 $(call inherit-product, frameworks/base/data/sounds/OriginalAudio.mk)
 
+# Get the TTS language packs
+$(call inherit-product-if-exists, external/svox/pico/lang/all_pico_languages.mk)
+
 # Get a list of languages. We use the small list to save space
 # on smaller devices.
 $(call inherit-product, build/target/product/languages_small.mk)
@@ -54,4 +57,3 @@
 PRODUCT_BRAND := generic
 PRODUCT_DEVICE := generic
 PRODUCT_MODEL := Full Android
-
diff --git a/target/product/generic.mk b/target/product/generic.mk
index f05c441..eed354a 100644
--- a/target/product/generic.mk
+++ b/target/product/generic.mk
@@ -19,7 +19,6 @@
 
 PRODUCT_PACKAGES := \
     AccountAndSyncSettings \
-    CarHome \
     DeskClock \
     AlarmProvider \
     Bluetooth \
@@ -39,6 +38,7 @@
     QuickSearchBox \
     Settings \
     Sync \
+    SystemUI \
     Updater \
     CalendarProvider \
     SyncProvider
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 37293e8..877bc40 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -20,7 +20,6 @@
 	AccountAndSyncSettings \
 	Camera \
 	Calculator \
-	CarHome \
 	DeskClock \
 	Development \
 	DrmProvider \
@@ -56,6 +55,61 @@
 	jython \
         jsilver
 
+# Host tools that are parts of the SDK.
+# See development/build/sdk.atree
+PRODUCT_PACKAGES += \
+	adb \
+	dmtracedump \
+	etc1tool \
+	hprof-conv \
+	mksdcard \
+	emulator \
+	ddms \
+	hierarchyviewer \
+	draw9patch \
+	layoutopt \
+	traceview \
+	android \
+	dexdump \
+        monkeyrunner
+
+# Native host Java libraries that are parts of the SDK.
+# See development/build/sdk.atree
+PRODUCT_PACKAGES += \
+	androidprefs \
+	sdkstats \
+	archquery \
+	ddms \
+	ddmlib \
+	ddmuilib \
+	hierarchyviewer \
+	draw9patch \
+	layoutopt \
+	uix \
+	traceview \
+	anttasks \
+	sdklib \
+	sdkuilib \
+	sdkmanager \
+	swing-worker-1.1 \
+	groovy-all-1.7.0 \
+	commons-compress-1.0 \
+	emmalib \
+	org-netbeans-api-visual \
+	org-openide-util \
+	jcommon-1.0.12 \
+	jfreechart-1.0.9 \
+	jfreechart-1.0.9-swt \
+	org.eclipse.core.commands_3.4.0.I20080509-2000 \
+	org.eclipse.equinox.common_3.4.0.v20080421-2006 \
+	org.eclipse.jface_3.4.2.M20090107-0800 \
+	osgi \
+	layoutlib \
+        monkeyrunner \
+        guavalib \
+        jsr305lib \
+	jython
+
 PRODUCT_PACKAGE_OVERLAYS := development/sdk_overlay
 
 PRODUCT_COPY_FILES := \
@@ -74,32 +128,63 @@
 	ldpi \
 	hdpi \
 	mdpi \
-	en_US \
-	en_GB \
-	en_CA \
+	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 \
-	ja_JP \
-	fr_FR \
+	en_US \
+	en_ZA \
+	es_ES \
+	es_US \
+	fi_FI \
 	fr_BE \
 	fr_CA \
 	fr_CH \
-	it_IT \
+	fr_FR \
+	he_IL \
+	hi_IN \
+	hr_HR \
+	hu_HU \
+	id_ID \
 	it_CH \
-	es_ES \
-	de_DE \
-	de_AT \
-	de_CH \
-	de_LI \
-	nl_NL \
+	it_IT \
+	ja_JP \
+	ko_KR \
+	lt_LT \
+	lv_LV \
+	nb_NO \
 	nl_BE \
-	cs_CZ \
+	nl_NL \
 	pl_PL \
-	zh_CN \
-	zh_TW \
+	pt_BR \
+	pt_PT \
+	ro_RO \
 	ru_RU \
-	ko_KR
+	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
diff --git a/tools/adbs b/tools/adbs
index 815ae10..8277790 100755
--- a/tools/adbs
+++ b/tools/adbs
@@ -144,13 +144,13 @@
       uname = "darwin-ppc"
   elif uname == "Linux":
     uname = "linux-x86"
-  prefix = "./prebuilt/" + uname + "/toolchain/arm-eabi-4.4.0/bin/"
+  prefix = "./prebuilt/" + uname + "/toolchain/arm-eabi-4.4.3/bin/"
   addr2line_cmd = prefix + "arm-eabi-addr2line"
 
   if (not os.path.exists(addr2line_cmd)):
     try:
       prefix = os.environ['ANDROID_BUILD_TOP'] + "/prebuilt/" + uname + \
-               "/toolchain/arm-eabi-4.4.0/bin/"
+               "/toolchain/arm-eabi-4.4.3/bin/"
     except:
       prefix = "";
 
diff --git a/tools/dexpreopt/Android.mk b/tools/dexpreopt/Android.mk
deleted file mode 100644
index 40aeee2..0000000
--- a/tools/dexpreopt/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# 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.
-#
-ifneq ($(TARGET_SIMULATOR),true)
-ifneq ($(DISABLE_DEXPREOPT),true)
-
-LOCAL_PATH := $(my-dir)
-include $(CLEAR_VARS)
-LOCAL_PREBUILT_EXECUTABLES := dexpreopt.py
-include $(BUILD_SYSTEM)/host_prebuilt.mk
-DEXPREOPT := $(LOCAL_INSTALLED_MODULE)
-
-# The script uses some other tools; make sure that they're
-# installed along with it.
-tools := \
-	emulator$(HOST_EXECUTABLE_SUFFIX)
-
-$(DEXPREOPT): | $(addprefix $(HOST_OUT_EXECUTABLES)/,$(tools))
-
-subdir_makefiles := \
-		$(LOCAL_PATH)/dexopt-wrapper/Android.mk \
-		$(LOCAL_PATH)/afar/Android.mk
-include $(subdir_makefiles)
-
-endif # !disable_dexpreopt
-endif # !sim
diff --git a/tools/dexpreopt/Config.mk b/tools/dexpreopt/Config.mk
deleted file mode 100644
index b2b32c6..0000000
--- a/tools/dexpreopt/Config.mk
+++ /dev/null
@@ -1,153 +0,0 @@
-#
-# 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.
-#
-
-#
-# Included by config/Makefile.
-# Defines the pieces necessary for the dexpreopt process.
-#
-# inputs: INSTALLED_RAMDISK_TARGET, BUILT_SYSTEMIMAGE_UNOPT
-# outputs: BUILT_SYSTEMIMAGE, SYSTEMIMAGE_SOURCE_DIR
-#
-LOCAL_PATH := $(my-dir)
-
-# TODO: see if we can make the .odex files not be product-specific.
-# They can't be completely common, though, because their format
-# depends on the architecture of the target system; ARM and x86
-# would have different versions.
-intermediates := \
-	$(call intermediates-dir-for,PACKAGING,dexpreopt)
-dexpreopt_system_dir := $(intermediates)/system
-built_afar := $(call intermediates-dir-for,EXECUTABLES,afar)/afar
-built_dowrapper := \
-	$(call intermediates-dir-for,EXECUTABLES,dexopt-wrapper)/dexopt-wrapper
-
-# Generate a stripped-down init.rc based on the real one.
-dexpreopt_initrc := $(intermediates)/etc/init.rc
-geninitrc_script := $(LOCAL_PATH)/geninitrc.awk
-$(dexpreopt_initrc): script := $(geninitrc_script)
-$(dexpreopt_initrc): system/core/rootdir/init.rc $(geninitrc_script)
-	@echo "Dexpreopt init.rc: $@"
-	@mkdir -p $(dir $@)
-	$(hide) awk -f $(script) < $< > $@
-
-BUILT_DEXPREOPT_RAMDISK := $(intermediates)/ramdisk.img
-$(BUILT_DEXPREOPT_RAMDISK): intermediates := $(intermediates)
-$(BUILT_DEXPREOPT_RAMDISK): dexpreopt_root_out := $(intermediates)/root
-$(BUILT_DEXPREOPT_RAMDISK): dexpreopt_initrc := $(dexpreopt_initrc)
-$(BUILT_DEXPREOPT_RAMDISK): built_afar := $(built_afar)
-$(BUILT_DEXPREOPT_RAMDISK): built_dowrapper := $(built_dowrapper)
-$(BUILT_DEXPREOPT_RAMDISK): \
-	$(INSTALLED_RAMDISK_TARGET) \
-	$(dexpreopt_initrc) \
-	$(built_afar) \
-	$(built_dowrapper) \
-	| $(MKBOOTFS) $(ACP)
-$(BUILT_DEXPREOPT_RAMDISK):
-	@echo "Dexpreopt ramdisk: $@"
-	$(hide) rm -f $@
-	$(hide) rm -rf $(dexpreopt_root_out)
-	$(hide) mkdir -p $(dexpreopt_root_out)
-	$(hide) $(ACP) -rd $(TARGET_ROOT_OUT) $(intermediates)
-	$(hide) $(ACP) -f $(dexpreopt_initrc) $(dexpreopt_root_out)/
-	$(hide) $(ACP) $(built_afar) $(dexpreopt_root_out)/sbin/
-	$(hide) $(ACP) $(built_dowrapper) $(dexpreopt_root_out)/sbin/
-	$(MKBOOTFS) $(dexpreopt_root_out) | gzip > $@
-
-sign_dexpreopt := true
-ifdef sign_dexpreopt
-  # Such a huge hack.  We need to re-sign the .apks with the
-  # same certs that they were originally signed with.
-  dexpreopt_package_certs_file := $(intermediates)/package-certs
-  $(shell mkdir -p $(intermediates))
-  $(shell rm -f $(dexpreopt_package_certs_file))
-  $(foreach p,$(PACKAGES),\
-    $(shell echo "$(p) $(PACKAGES.$(p).CERTIFICATE) $(PACKAGES.$(p).PRIVATE_KEY)" >> $(dexpreopt_package_certs_file)))
-endif
-
-# The kernel used for ARMv7 system images is different
-ifeq ($(ARCH_ARM_HAVE_ARMV7A),true)
-BUILD_DEXPREOPT_KERNEL := prebuilt/android-arm/kernel/kernel-qemu-armv7
-else
-BUILD_DEXPREOPT_KERNEL := prebuilt/android-arm/kernel/kernel-qemu
-endif
-
-# Build an optimized image from the unoptimized image
-BUILT_DEXPREOPT_SYSTEMIMAGE := $(intermediates)/system.img
-$(BUILT_DEXPREOPT_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE_UNOPT)
-$(BUILT_DEXPREOPT_SYSTEMIMAGE): $(BUILT_DEXPREOPT_RAMDISK)
-$(BUILT_DEXPREOPT_SYSTEMIMAGE): | $(DEXPREOPT) $(ACP) $(ZIPALIGN)
-$(BUILT_DEXPREOPT_SYSTEMIMAGE): SYSTEM_DIR := $(dexpreopt_system_dir)
-$(BUILT_DEXPREOPT_SYSTEMIMAGE): DEXPREOPT_TMP := $(intermediates)/emutmp
-ifdef sign_dexpreopt
-$(BUILT_DEXPREOPT_SYSTEMIMAGE): | $(SIGNAPK_JAR)
-endif
-$(BUILT_DEXPREOPT_SYSTEMIMAGE):
-	@rm -f $@
-	@echo "dexpreopt: copy system to $(SYSTEM_DIR)"
-	@rm -rf $(SYSTEM_DIR)
-	@mkdir -p $(dir $(SYSTEM_DIR))
-	$(hide) $(ACP) -rd $(TARGET_OUT) $(SYSTEM_DIR)
-	@echo "dexpreopt: optimize dex files"
-	@rm -rf $(DEXPREOPT_TMP)
-	@mkdir -p $(DEXPREOPT_TMP)
-	$(hide) \
-	    PATH=$(HOST_OUT_EXECUTABLES):$$PATH \
-	    $(DEXPREOPT) \
-		    --kernel $(BUILD_DEXPREOPT_KERNEL) \
-		    --ramdisk $(BUILT_DEXPREOPT_RAMDISK) \
-		    --image $(BUILT_SYSTEMIMAGE_UNOPT) \
-		    --system $(PRODUCT_OUT) \
-		    --tmpdir $(DEXPREOPT_TMP) \
-		    --outsystemdir $(SYSTEM_DIR)
-ifdef sign_dexpreopt
-	@echo "dexpreopt: re-sign apk files"
-	$(hide) \
-	    export PATH=$(HOST_OUT_EXECUTABLES):$$PATH; \
-	    for apk in $(SYSTEM_DIR)/app/*.apk; do \
-		packageName=`basename $$apk`; \
-		packageName=`echo $$packageName | sed -e 's/.apk$$//'`; \
-		cert=`grep "^$$packageName " $(dexpreopt_package_certs_file) | \
-		      awk '{print $$2}'`; \
-		pkey=`grep "^$$packageName " $(dexpreopt_package_certs_file) | \
-		      awk '{print $$3}'`; \
-		if [ "$$cert" -a "$$pkey" ]; then \
-		    echo "dexpreopt: re-sign app/"$$packageName".apk"; \
-		    tmpApk=$$apk~; \
-		    rm -f $$tmpApk; \
-		    java -jar $(SIGNAPK_JAR) $$cert $$pkey $$apk $$tmpApk || \
-			  exit 11; \
-		    mv -f $$tmpApk $$apk; \
-		else \
-		    echo "dexpreopt: no keys for app/"$$packageName".apk"; \
-		    rm $(SYSTEM_DIR)/app/$$packageName.* && \
-			cp $(TARGET_OUT)/app/$$packageName.apk \
-			   $(SYSTEM_DIR)/app || exit 12; \
-		fi; \
-		tmpApk=$$apk~; \
-		rm -f $$tmpApk; \
-		$(ZIPALIGN) -f 4 $$apk $$tmpApk || exit 13; \
-		mv -f $$tmpApk $$apk; \
-	    done
-endif
-	@echo "Dexpreopt system image: $@"
-	$(hide) $(MKYAFFS2) -f $(SYSTEM_DIR) $@
-
-.PHONY: dexpreoptimage
-dexpreoptimage: $(BUILT_DEXPREOPT_SYSTEMIMAGE)
-
-# Tell our caller to use the optimized systemimage
-BUILT_SYSTEMIMAGE := $(BUILT_DEXPREOPT_SYSTEMIMAGE)
-SYSTEMIMAGE_SOURCE_DIR := $(dexpreopt_system_dir)
diff --git a/tools/dexpreopt/afar/Android.mk b/tools/dexpreopt/afar/Android.mk
deleted file mode 100644
index 9f1b987..0000000
--- a/tools/dexpreopt/afar/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH := $(my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	main.c
-
-# Just for adler32()
-LOCAL_C_INCLUDES := external/zlib
-LOCAL_SHARED_LIBRARIES := libz
-
-LOCAL_MODULE := afar
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
diff --git a/tools/dexpreopt/afar/main.c b/tools/dexpreopt/afar/main.c
deleted file mode 100644
index d66d59c..0000000
--- a/tools/dexpreopt/afar/main.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-#include <stdarg.h>
-#include <fcntl.h>
-#include <termios.h>
-
-#include <zlib.h>   // for adler32()
-
-static int verbose = 0;
-
-/*
- * Android File Archive format:
- *
- * magic[5]: 'A' 'F' 'A' 'R' '\n'
- * version[4]: 0x00 0x00 0x00 0x01
- * for each file:
- *     file magic[4]: 'F' 'I' 'L' 'E'
- *     namelen[4]: Length of file name, including NUL byte (big-endian)
- *     name[*]: NUL-terminated file name
- *     datalen[4]: Length of file (big-endian)
- *     data[*]: Unencoded file data
- *     adler32[4]: adler32 of the unencoded file data (big-endian)
- *     file end magic[4]: 'f' 'i' 'l' 'e'
- * end magic[4]: 'E' 'N' 'D' 0x00
- *
- * This format is about as simple as possible;  it was designed to
- * make it easier to transfer multiple files over an stdin/stdout
- * pipe to another process, so word-alignment wasn't necessary.
- */
-
-static void
-die(const char *why, ...)
-{
-    va_list ap;
-    
-    va_start(ap, why);
-    fprintf(stderr, "error: ");
-    vfprintf(stderr, why, ap);
-    fprintf(stderr, "\n");
-    va_end(ap);
-    exit(1);
-}
-
-static void
-write_big_endian(size_t v)
-{
-    putchar((v >> 24) & 0xff);
-    putchar((v >> 16) & 0xff);
-    putchar((v >>  8) & 0xff);
-    putchar( v        & 0xff);
-}
-
-static void
-_eject(struct stat *s, char *out, int olen, char *data, size_t datasize)
-{
-    unsigned long adler;
-
-    /* File magic.
-     */
-    printf("FILE");
-
-    /* Name length includes the NUL byte.
-     */
-    write_big_endian(olen + 1);
-
-    /* File name and terminating NUL.
-     */
-    printf("%s", out);
-    putchar('\0');
-
-    /* File length.
-     */
-    write_big_endian(datasize);
-
-    /* File data.
-     */
-    if (fwrite(data, 1, datasize, stdout) != datasize) {
-        die("Error writing file data");
-    }
-
-    /* Checksum.
-     */
-    adler = adler32(0, NULL, 0);
-    adler = adler32(adler, (unsigned char *)data, datasize);
-    write_big_endian(adler);
-
-    /* File end magic.
-     */
-    printf("file");
-}
-
-static void _archive(char *in, int ilen);
-
-static void
-_archive_dir(char *in, int ilen)
-{
-    int t;
-    DIR *d;
-    struct dirent *de;
-
-    if (verbose) {
-        fprintf(stderr, "_archive_dir('%s', %d)\n", in, ilen);
-    }
-    
-    d = opendir(in);
-    if (d == 0) {
-        die("cannot open directory '%s'", in);
-    }
-    
-    while ((de = readdir(d)) != 0) {
-            /* xxx: feature? maybe some dotfiles are okay */
-        if (strcmp(de->d_name, ".") == 0 ||
-            strcmp(de->d_name, "..") == 0)
-        {
-            continue;
-        }
-
-        t = strlen(de->d_name);
-        in[ilen] = '/';
-        memcpy(in + ilen + 1, de->d_name, t + 1);
-
-        _archive(in, ilen + t + 1);
-
-        in[ilen] = '\0';
-    }
-}
-
-static void
-_archive(char *in, int ilen)
-{
-    struct stat s;
-
-    if (verbose) {
-        fprintf(stderr, "_archive('%s', %d)\n", in, ilen);
-    }
-    
-    if (lstat(in, &s)) {
-        die("could not stat '%s'\n", in);
-    }
-
-    if (S_ISREG(s.st_mode)) {
-        char *tmp;
-        int fd;
-
-        fd = open(in, O_RDONLY);
-        if (fd < 0) {
-            die("cannot open '%s' for read", in);
-        }
-
-        tmp = (char*) malloc(s.st_size);
-        if (tmp == 0) {
-            die("cannot allocate %d bytes", s.st_size);
-        }
-
-        if (read(fd, tmp, s.st_size) != s.st_size) {
-            die("cannot read %d bytes", s.st_size);
-        }
-
-        _eject(&s, in, ilen, tmp, s.st_size);
-        
-        free(tmp);
-        close(fd);
-    } else if (S_ISDIR(s.st_mode)) {
-        _archive_dir(in, ilen);
-    } else {
-        /* We don't handle links, etc. */
-        die("Unknown '%s' (mode %d)?\n", in, s.st_mode);
-    }
-}
-
-void archive(const char *start)
-{
-    char in[8192];
-
-    strcpy(in, start);
-
-    _archive_dir(in, strlen(in));
-}
-
-int
-main(int argc, char *argv[])
-{
-    struct termios old_termios;
-
-    if (argc == 1) {
-        die("usage: %s <dir-list>", argv[0]);
-    }
-    argc--;
-    argv++;
-
-    /* Force stdout into raw mode.
-     */
-    struct termios s;
-    if (tcgetattr(1, &s) < 0) {
-        die("Could not get termios for stdout");
-    }
-    old_termios = s;
-    cfmakeraw(&s);
-    if (tcsetattr(1, TCSANOW, &s) < 0) {
-        die("Could not set termios for stdout");
-    }
-
-    /* Print format magic and version.
-     */
-    printf("AFAR\n");
-    write_big_endian(1);
-
-    while (argc-- > 0) {
-        archive(*argv++);
-    }
-
-    /* Print end magic.
-     */
-    printf("END");
-    putchar('\0');
-
-    /* Restore stdout.
-     */
-    if (tcsetattr(1, TCSANOW, &old_termios) < 0) {
-        die("Could not restore termios for stdout");
-    }
-
-    return 0;
-}
diff --git a/tools/dexpreopt/dexopt-wrapper/Android.mk b/tools/dexpreopt/dexopt-wrapper/Android.mk
deleted file mode 100644
index ae2b6a3..0000000
--- a/tools/dexpreopt/dexopt-wrapper/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-       DexOptWrapper.cpp
-
-LOCAL_C_INCLUDES += \
-        dalvik
-
-LOCAL_STATIC_LIBRARIES := \
-        libdex
-
-LOCAL_SHARED_LIBRARIES := \
-        libcutils
-
-LOCAL_MODULE := dexopt-wrapper
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
diff --git a/tools/dexpreopt/dexopt-wrapper/DexOptWrapper.cpp b/tools/dexpreopt/dexopt-wrapper/DexOptWrapper.cpp
deleted file mode 100644
index 102cf0e..0000000
--- a/tools/dexpreopt/dexopt-wrapper/DexOptWrapper.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * dexopt invocation test.
- *
- * You must have BOOTCLASSPATH defined.  On the simulator, you will also
- * need ANDROID_ROOT.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "cutils/properties.h"
-
-//using namespace android;
-
-/*
- * Privilege reduction function.
- *
- * Returns 0 on success, nonzero on failure.
- */
-static int privFunc(void)
-{
-    printf("--- would reduce privs here\n");
-    return 0;
-}
-
-/*
- * We're in the child process.  exec dexopt.
- */
-static void runDexopt(int zipFd, int odexFd, const char* inputFileName)
-{
-    static const char* kDexOptBin = "/bin/dexopt";
-    static const int kMaxIntLen = 12;   // '-'+10dig+'\0' -OR- 0x+8dig
-    char zipNum[kMaxIntLen];
-    char odexNum[kMaxIntLen];
-    char dexoptFlags[PROPERTY_VALUE_MAX];
-    const char* androidRoot;
-    char* execFile;
-
-    /* pull optional configuration tweaks out of properties */
-    property_get("dalvik.vm.dexopt-flags", dexoptFlags, "");
-
-    /* find dexopt executable; this exists for simulator compatibility */
-    androidRoot = getenv("ANDROID_ROOT");
-    if (androidRoot == NULL)
-        androidRoot = "/system";
-    execFile = (char*) malloc(strlen(androidRoot) + strlen(kDexOptBin) +1);
-    sprintf(execFile, "%s%s", androidRoot, kDexOptBin);
-
-    sprintf(zipNum, "%d", zipFd);
-    sprintf(odexNum, "%d", odexFd);
-
-    execl(execFile, execFile, "--zip", zipNum, odexNum, inputFileName,
-        dexoptFlags, (char*) NULL);
-    fprintf(stderr, "execl(%s) failed: %s\n", kDexOptBin, strerror(errno));
-}
-
-/*
- * Run dexopt on the specified Jar/APK.
- *
- * This uses fork() and exec() to mimic the way this would work in an
- * installer; in practice for something this simple you could just exec()
- * unless you really wanted the status messages.
- *
- * Returns 0 on success.
- */
-int doStuff(const char* zipName, const char* odexName)
-{
-    int zipFd, odexFd;
-
-    /*
-     * Open the zip archive and the odex file, creating the latter (and
-     * failing if it already exists).  This must be done while we still
-     * have sufficient privileges to read the source file and create a file
-     * in the target directory.  The "classes.dex" file will be extracted.
-     */
-    zipFd = open(zipName, O_RDONLY, 0);
-    if (zipFd < 0) {
-        fprintf(stderr, "Unable to open '%s': %s\n", zipName, strerror(errno));
-        return 1;
-    }
-
-    odexFd = open(odexName, O_RDWR | O_CREAT | O_EXCL, 0644);
-    if (odexFd < 0) {
-        fprintf(stderr, "Unable to create '%s': %s\n",
-            odexName, strerror(errno));
-        close(zipFd);
-        return 1;
-    }
-
-    printf("--- BEGIN '%s' (bootstrap=%d) ---\n", zipName, 0);
-
-    /*
-     * Fork a child process.
-     */
-    pid_t pid = fork();
-    if (pid == 0) {
-        /* child -- drop privs */
-        if (privFunc() != 0)
-            exit(66);
-
-        /* lock the input file */
-        if (flock(odexFd, LOCK_EX | LOCK_NB) != 0) {
-            fprintf(stderr, "Unable to lock '%s': %s\n",
-                odexName, strerror(errno));
-            exit(65);
-        }
-
-        runDexopt(zipFd, odexFd, zipName);  /* does not return */
-        exit(67);                           /* usually */
-    } else {
-        /* parent -- wait for child to finish */
-        printf("--- waiting for verify+opt, pid=%d\n", (int) pid);
-        int status, oldStatus;
-        pid_t gotPid;
-
-        close(zipFd);
-        close(odexFd);
-
-        /*
-         * Wait for the optimization process to finish.
-         */
-        while (true) {
-            gotPid = waitpid(pid, &status, 0);
-            if (gotPid == -1 && errno == EINTR) {
-                printf("waitpid interrupted, retrying\n");
-            } else {
-                break;
-            }
-        }
-        if (gotPid != pid) {
-            fprintf(stderr, "waitpid failed: wanted %d, got %d: %s\n",
-                (int) pid, (int) gotPid, strerror(errno));
-            return 1;
-        }
-
-        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
-            printf("--- END '%s' (success) ---\n", zipName);
-            return 0;
-        } else {
-            printf("--- END '%s' --- status=0x%04x, process failed\n",
-                zipName, status);
-            return 1;
-        }
-    }
-
-    /* notreached */
-}
-
-/*
- * Parse args, do stuff.
- */
-int main(int argc, char** argv)
-{
-    if (argc < 3 || argc > 4) {
-        fprintf(stderr, "Usage: %s <input jar/apk> <output odex> "
-            "[<bootclasspath>]\n\n", argv[0]);
-        fprintf(stderr, "Example: dexopttest "
-            "/system/app/NotePad.apk /system/app/NotePad.odex\n");
-        return 2;
-    }
-
-    if (argc > 3) {
-        setenv("BOOTCLASSPATH", argv[3], 1);
-    }
-
-    return (doStuff(argv[1], argv[2]) != 0);
-}
diff --git a/tools/dexpreopt/dexpreopt.py b/tools/dexpreopt/dexpreopt.py
deleted file mode 100755
index 376f135..0000000
--- a/tools/dexpreopt/dexpreopt.py
+++ /dev/null
@@ -1,986 +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.
-#
-
-"""Creates optimized versions of APK files.
-
-A tool and associated functions to communicate with an Android
-emulator instance, run commands, and scrape out files.
-
-Requires at least python2.4.
-"""
-
-import array
-import datetime
-import optparse
-import os
-import posix
-import select
-import signal
-import struct
-import subprocess
-import sys
-import tempfile
-import time
-import zlib
-
-
-_emulator_popen = None
-_DEBUG_READ = 1
-
-
-def EnsureTempDir(path=None):
-  """Creates a temporary directory and returns its path.
-
-  Creates any necessary parent directories.
-
-  Args:
-    path: If specified, used as the temporary directory.  If not specified,
-          a safe temporary path is created.  The caller is responsible for
-          deleting the directory.
-
-  Returns:
-    The path to the new directory, or None if a problem occurred.
-  """
-  if path is None:
-    path = tempfile.mkdtemp('', 'dexpreopt-')
-  elif not os.path.exists(path):
-    os.makedirs(path)
-  elif not os.path.isdir(path):
-    return None
-  return path
-
-
-def CreateZeroedFile(path, length):
-  """Creates the named file and writes <length> zero bytes to it.
-
-  Unlinks the file first if it already exists.
-  Creates its containing directory if necessary.
-
-  Args:
-    path: The path to the file to create.
-    length: The number of zero bytes to write to the file.
-
-  Returns:
-    True on success.
-  """
-  subprocess.call(['rm', '-f', path])
-  d = os.path.dirname(path)
-  if d and not os.path.exists(d): os.makedirs(os.path.dirname(d))
-  # TODO: redirect child's stdout to /dev/null
-  ret = subprocess.call(['dd', 'if=/dev/zero', 'of=%s' % path,
-                         'bs=%d' % length, 'count=1'])
-  return not ret  # i.e., ret == 0;  i.e., the child exited successfully.
-
-
-def StartEmulator(exe_name='emulator', kernel=None,
-                  ramdisk=None, image=None, userdata=None, system=None):
-  """Runs the emulator with the specified arguments.
-
-  Args:
-    exe_name: The name of the emulator to run.  May be absolute, relative,
-              or unqualified (and left to exec() to find).
-    kernel: If set, passed to the emulator as "-kernel".
-    ramdisk: If set, passed to the emulator as "-ramdisk".
-    image: If set, passed to the emulator as "-system".
-    userdata: If set, passed to the emulator as "-initdata" and "-data".
-    system: If set, passed to the emulator as "-sysdir".
-
-  Returns:
-    A subprocess.Popen that refers to the emulator process, or None if
-    a problem occurred.
-  """
-  #exe_name = './stuff'
-  args = [exe_name]
-  if kernel: args += ['-kernel', kernel]
-  if ramdisk: args += ['-ramdisk', ramdisk]
-  if image: args += ['-system', image]
-  if userdata: args += ['-initdata', userdata, '-data', userdata]
-  if system: args += ['-sysdir', system]
-  args += ['-partition-size', '128']
-  args += ['-no-window', '-netfast', '-noaudio']
-
-  _USE_PIPE = True
-
-  if _USE_PIPE:
-    # Use dedicated fds instead of stdin/out to talk to the
-    # emulator so that the emulator doesn't try to tty-cook
-    # the data.
-    em_stdin_r, em_stdin_w = posix.pipe()
-    em_stdout_r, em_stdout_w = posix.pipe()
-    args += ['-shell-serial', 'fdpair:%d:%d' % (em_stdin_r, em_stdout_w)]
-  else:
-    args += ['-shell']
-
-  # This is a work-around for the ARMv7 emulation bug.
-  # XXX: It only works by chance, if any ! A real emulation fix is on the way
-  args += ['-qemu', '-singlestep']
-
-  # Ensure that this environment variable isn't set;
-  # if it is, the emulator will print the log to stdout.
-  if os.environ.get('ANDROID_LOG_TAGS'):
-    del os.environ['ANDROID_LOG_TAGS']
-
-  try:
-    # bufsize=1 line-buffered, =0 unbuffered,
-    # <0 system default (fully buffered)
-    Trace('Running emulator: %s' % ' '.join(args))
-    if _USE_PIPE:
-      ep = subprocess.Popen(args)
-    else:
-      ep = subprocess.Popen(args, close_fds=True,
-                            stdin=subprocess.PIPE,
-                            stdout=subprocess.PIPE,
-                            stderr=subprocess.PIPE)
-    if ep:
-      if _USE_PIPE:
-        # Hijack the Popen.stdin/.stdout fields to point to our
-        # pipes.  These are the same fields that would have been set
-        # if we called Popen() with stdin=subprocess.PIPE, etc.
-        # Note that these names are from the point of view of the
-        # child process.
-        #
-        # Since we'll be using select.select() to read data a byte
-        # at a time, it's important that these files are unbuffered
-        # (bufsize=0).  If Popen() took care of the pipes, they're
-        # already unbuffered.
-        ep.stdin = os.fdopen(em_stdin_w, 'w', 0)
-        ep.stdout = os.fdopen(em_stdout_r, 'r', 0)
-      return ep
-  except OSError, e:
-    print >>sys.stderr, 'Could not start emulator:', e
-  return None
-
-
-def IsDataAvailable(fo, timeout=0):
-  """Indicates whether or not data is available to be read from a file object.
-
-  Args:
-    fo: A file object to read from.
-    timeout: The number of seconds to wait for data, or zero for no timeout.
-
-  Returns:
-    True iff data is available to be read.
-  """
-  return select.select([fo], [], [], timeout) == ([fo], [], [])
-
-
-def ConsumeAvailableData(fo):
-  """Reads data from a file object while it's available.
-
-  Stops when no more data is immediately available or upon reaching EOF.
-
-  Args:
-    fo: A file object to read from.
-
-  Returns:
-    An unsigned byte array.array of the data that was read.
-  """
-  buf = array.array('B')
-  while IsDataAvailable(fo):
-    try:
-      buf.fromfile(fo, 1)
-    except EOFError:
-      break
-  return buf
-
-
-def ShowTimeout(timeout, end_time):
-    """For debugging, display the timeout info.
-
-    Args:
-      timeout: the timeout in seconds.
-      end_time: a time.time()-based value indicating when the timeout should
-                expire.
-    """
-    if _DEBUG_READ:
-      if timeout:
-        remaining = end_time - time.time()
-        Trace('ok, time remaining %.1f of %.1f' % (remaining, timeout))
-      else:
-        Trace('ok (no timeout)')
-
-
-def WaitForString(inf, pattern, timeout=0, max_len=0, eat_to_eol=True,
-                  reset_on_activity=False):
-  """Reads from a file object and returns when the pattern matches the data.
-
-  Reads a byte at a time to avoid consuming extra data, so do not call
-  this function when you expect the pattern to match a large amount of data.
-
-  Args:
-    inf: The file object to read from.
-    pattern: The string to look for in the input data.
-             May be a tuple of strings.
-    timeout: How long to wait, in seconds. No timeout if it evaluates to False.
-    max_len: Return None if this many bytes have been read without matching.
-             No upper bound if it evaluates to False.
-    eat_to_eol: If true, the input data will be consumed until a '\\n' or EOF
-                is encountered.
-    reset_on_activity: If True, reset the timeout whenever a character is
-                       read.
-
-  Returns:
-    The input data matching the expression as an unsigned char array,
-    or None if the operation timed out or didn't match after max_len bytes.
-
-  Raises:
-    IOError: An error occurred reading from the input file.
-  """
-  if timeout:
-    end_time = time.time() + timeout
-  else:
-    end_time = 0
-
-  if _DEBUG_READ:
-    Trace('WaitForString: "%s", %.1f' % (pattern, timeout))
-
-  buf = array.array('B')  # unsigned char array
-  eating = False
-  while True:
-    if end_time:
-      remaining = end_time - time.time()
-      if remaining <= 0:
-        Trace('Timeout expired after %.1f seconds' % timeout)
-        return None
-    else:
-      remaining = None
-
-    if IsDataAvailable(inf, remaining):
-      if reset_on_activity and timeout:
-        end_time = time.time() + timeout
-
-      buf.fromfile(inf, 1)
-      if _DEBUG_READ:
-        c = buf.tostring()[-1:]
-        ci = ord(c)
-        if ci < 0x20: c = '.'
-        if _DEBUG_READ > 1:
-          print 'read [%c] 0x%02x' % (c, ci)
-
-      if not eating:
-        if buf.tostring().endswith(pattern):
-          if eat_to_eol:
-            if _DEBUG_READ > 1:
-              Trace('Matched; eating to EOL')
-            eating = True
-          else:
-            ShowTimeout(timeout, end_time)
-            return buf
-        if _DEBUG_READ > 2:
-          print '/%s/ ? "%s"' % (pattern, buf.tostring())
-      else:
-        if buf.tostring()[-1:] == '\n':
-          ShowTimeout(timeout, end_time)
-          return buf
-
-      if max_len and len(buf) >= max_len: return None
-
-
-def WaitForEmulator(ep, timeout=0):
-  """Waits for the emulator to start up and print the first prompt.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    timeout: How long to wait, in seconds. No timeout if it evaluates to False.
-
-  Returns:
-    True on success, False if the timeout occurred.
-  """
-  # Prime the pipe; the emulator doesn't start without this.
-  print >>ep.stdin, ''
-
-  # Wait until the console is ready and the first prompt appears.
-  buf = WaitForString(ep.stdout, '#', timeout=timeout, eat_to_eol=False)
-  if buf:
-    Trace('Saw the prompt: "%s"' % buf.tostring())
-    return True
-  return False
-
-
-def WaitForPrompt(ep, prompt=None, timeout=0, reset_on_activity=False):
-  """Blocks until the prompt appears on ep.stdout or the timeout elapses.
-
-  Args:
-    ep: A subprocess.Popen connection to the emulator process.
-    prompt: The prompt to wait for.  If None, uses ep.prompt.
-    timeout: How many seconds to wait for the prompt.  Waits forever
-             if timeout is zero.
-    reset_on_activity: If True, reset the timeout whenever a character is
-                       read.
-
-  Returns:
-    A string containing the data leading up to the prompt.  The string
-    will always end in '\\n'.  Returns None if the prompt was not seen
-    within the timeout, or if some other error occurred.
-  """
-  if not prompt: prompt = ep.prompt
-  if prompt:
-    #Trace('waiting for prompt "%s"' % prompt)
-    data = WaitForString(ep.stdout, prompt,
-                         timeout=timeout, reset_on_activity=reset_on_activity)
-    if data:
-      # data contains everything on ep.stdout up to and including the prompt,
-      # plus everything up 'til the newline.  Scrape out the prompt
-      # and everything that follows, and ensure that the result ends
-      # in a newline (which is important if it would otherwise be empty).
-      s = data.tostring()
-      i = s.rfind(prompt)
-      s = s[:i]
-      if s[-1:] != '\n':
-        s += '\n'
-      if _DEBUG_READ:
-        print 'WaitForPrompt saw """\n%s"""' % s
-      return s
-  return None
-
-
-def ReplaceEmulatorPrompt(ep, prompt=None):
-  """Replaces PS1 in the emulator with a different value.
-
-  This is useful for making the prompt unambiguous; i.e., something
-  that probably won't appear in the output of another command.
-
-  Assumes that the emulator is already sitting at a prompt,
-  waiting for shell input.
-
-  Puts the new prompt in ep.prompt.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    prompt: The new prompt to use
-
-  Returns:
-    True on success, False if the timeout occurred.
-  """
-  if not prompt:
-    prompt = '-----DEXPREOPT-PROMPT-----'
-  print >>ep.stdin, 'PS1="%s\n"' % prompt
-  ep.prompt = prompt
-
-  # Eat the command echo.
-  data = WaitForPrompt(ep, timeout=2)
-  if not data:
-    return False
-
-  # Make sure it's actually there.
-  return WaitForPrompt(ep, timeout=2)
-
-
-def RunEmulatorCommand(ep, cmd, timeout=0):
-  """Sends the command to the emulator's shell and waits for the result.
-
-  Assumes that the emulator is already sitting at a prompt,
-  waiting for shell input.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    cmd: The shell command to run in the emulator.
-    timeout: The number of seconds to wait for the command to complete,
-             or zero for no timeout.
-
-  Returns:
-    If the command ran and returned to the console prompt before the
-    timeout, returns the output of the command as a string.
-    Returns None otherwise.
-  """
-  ConsumeAvailableData(ep.stdout)
-
-  Trace('Running "%s"' % cmd)
-  print >>ep.stdin, '%s' % cmd
-
-  # The console will echo the command.
-  #Trace('Waiting for echo')
-  if WaitForString(ep.stdout, cmd, timeout=timeout):
-    #Trace('Waiting for completion')
-    return WaitForPrompt(ep, timeout=timeout, reset_on_activity=True)
-
-  return None
-
-
-def ReadFileList(ep, dir_list, timeout=0):
-  """Returns a list of emulator files in each dir in dir_list.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    dir_list: List absolute paths to directories to read.
-    timeout: The number of seconds to wait for the command to complete,
-             or zero for no timeout.
-
-  Returns:
-    A list of absolute paths to files in the named directories,
-    in the context of the emulator's filesystem.
-    None on failure.
-  """
-  ret = []
-  for d in dir_list:
-    output = RunEmulatorCommand(ep, 'ls ' + d, timeout=timeout)
-    if not output:
-      Trace('Could not ls ' + d)
-      return None
-    ret += ['%s/%s' % (d, f) for f in output.splitlines()]
-  return ret
-
-
-def DownloadDirectoryHierarchy(ep, src, dest, timeout=0):
-  """Recursively downloads an emulator directory to the local filesystem.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    src: The path on the emulator's filesystem to download from.
-    dest: The path on the local filesystem to download to.
-    timeout: The number of seconds to wait for the command to complete,
-             or zero for no timeout. (CURRENTLY IGNORED)
-
-  Returns:
-    True iff the files downloaded successfully, False otherwise.
-  """
-  ConsumeAvailableData(ep.stdout)
-
-  if not os.path.exists(dest):
-    os.makedirs(dest)
-
-  cmd = 'afar %s' % src
-  Trace('Running "%s"' % cmd)
-  print >>ep.stdin, '%s' % cmd
-
-  # The console will echo the command.
-  #Trace('Waiting for echo')
-  if not WaitForString(ep.stdout, cmd, timeout=timeout):
-    return False
-
-  #TODO: use a signal to support timing out?
-
-  #
-  # Android File Archive format:
-  #
-  # magic[5]: 'A' 'F' 'A' 'R' '\n'
-  # version[4]: 0x00 0x00 0x00 0x01
-  # for each file:
-  #     file magic[4]: 'F' 'I' 'L' 'E'
-  #     namelen[4]: Length of file name, including NUL byte (big-endian)
-  #     name[*]: NUL-terminated file name
-  #     datalen[4]: Length of file (big-endian)
-  #     data[*]: Unencoded file data
-  #     adler32[4]: adler32 of the unencoded file data (big-endian)
-  #     file end magic[4]: 'f' 'i' 'l' 'e'
-  # end magic[4]: 'E' 'N' 'D' 0x00
-  #
-
-  # Read the header.
-  HEADER = array.array('B', 'AFAR\n\000\000\000\001')
-  buf = array.array('B')
-  buf.fromfile(ep.stdout, len(HEADER))
-  if buf != HEADER:
-    Trace('Header does not match: "%s"' % buf)
-    return False
-
-  # Read the file entries.
-  FILE_START = array.array('B', 'FILE')
-  FILE_END = array.array('B', 'file')
-  END = array.array('B', 'END\000')
-  while True:
-    # Entry magic.
-    buf = array.array('B')
-    buf.fromfile(ep.stdout, 4)
-    if buf == FILE_START:
-      # Name length (4 bytes, big endian)
-      buf = array.array('B')
-      buf.fromfile(ep.stdout, 4)
-      (name_len,) = struct.unpack('>I', buf)
-      #Trace('name len %d' % name_len)
-
-      # Name, NUL-terminated.
-      buf = array.array('B')
-      buf.fromfile(ep.stdout, name_len)
-      buf.pop()  # Remove trailing NUL byte.
-      file_name = buf.tostring()
-      Trace('FILE: %s' % file_name)
-
-      # File length (4 bytes, big endian)
-      buf = array.array('B')
-      buf.fromfile(ep.stdout, 4)
-      (file_len,) = struct.unpack('>I', buf)
-
-      # File data.
-      data = array.array('B')
-      data.fromfile(ep.stdout, file_len)
-      #Trace('FILE: read %d bytes from %s' % (file_len, file_name))
-
-      # adler32 (4 bytes, big endian)
-      buf = array.array('B')
-      buf.fromfile(ep.stdout, 4)
-      (adler32,) = struct.unpack('>i', buf)  # adler32 wants a signed int ('i')
-      data_adler32 = zlib.adler32(data)
-      # Because of a difference in behavior of zlib.adler32 on 32-bit and 64-bit
-      # systems (one returns signed values, the other unsigned), we take the
-      # modulo 2**32 of the checksums, and compare those.
-      # See also http://bugs.python.org/issue1202
-      if (adler32 % (2**32)) != (data_adler32 % (2**32)):
-        Trace('adler32 does not match: calculated 0x%08x != expected 0x%08x' %
-              (data_adler32, adler32))
-        return False
-
-      # File end magic.
-      buf = array.array('B')
-      buf.fromfile(ep.stdout, 4)
-      if buf != FILE_END:
-        Trace('Unexpected file end magic "%s"' % buf)
-        return False
-
-      # Write to the output file
-      out_file_name = dest + '/' + file_name[len(src):]
-      p = os.path.dirname(out_file_name)
-      if not os.path.exists(p): os.makedirs(p)
-      fo = file(out_file_name, 'w+b')
-      fo.truncate(0)
-      Trace('FILE: Writing %d bytes to %s' % (len(data), out_file_name))
-      data.tofile(fo)
-      fo.close()
-
-    elif buf == END:
-      break
-    else:
-      Trace('Unexpected magic "%s"' % buf)
-      return False
-
-  return WaitForPrompt(ep, timeout=timeout, reset_on_activity=True)
-
-
-def ReadBootClassPath(ep, timeout=0):
-  """Reads and returns the default bootclasspath as a list of files.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    timeout: The number of seconds to wait for the command to complete,
-             or zero for no timeout.
-
-  Returns:
-    The bootclasspath as a list of strings.
-    None on failure.
-  """
-  bcp = RunEmulatorCommand(ep, 'echo $BOOTCLASSPATH', timeout=timeout)
-  if not bcp:
-    Trace('Could not find bootclasspath')
-    return None
-  return bcp.strip().split(':')  # strip trailing newline
-
-
-def RunDexoptOnFileList(ep, files, dest_root, move=False, timeout=0):
-  """Creates the corresponding .odex file for all jar/apk files in 'files'.
-  Copies the .odex file to a location under 'dest_root'.  If 'move' is True,
-  the file is moved instead of copied.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    files: The list of files to optimize
-    dest_root: directory to copy/move odex files to.  Must already exist.
-    move: if True, move rather than copy files
-    timeout: The number of seconds to wait for the command to complete,
-             or zero for no timeout.
-
-  Returns:
-    True on success, False on failure.
-  """
-  for jar_file in files:
-    if jar_file.endswith('.apk') or jar_file.endswith('.jar'):
-      odex_file = jar_file[:jar_file.rfind('.')] + '.odex'
-      cmd = 'dexopt-wrapper %s %s' % (jar_file, odex_file)
-      if not RunEmulatorCommand(ep, cmd, timeout=timeout):
-        Trace('"%s" failed' % cmd)
-        return False
-
-      # Always copy the odex file.  There's no cp(1), so we
-      # cat out to the new file.
-      dst_odex = dest_root + odex_file
-      cmd = 'cat %s > %s' % (odex_file, dst_odex)  # no cp(1)
-      if not RunEmulatorCommand(ep, cmd, timeout=timeout):
-        Trace('"%s" failed' % cmd)
-        return False
-
-      # Move it if we're asked to.  We can't use mv(1) because
-      # the files tend to move between filesystems.
-      if move:
-        cmd = 'rm %s' % odex_file
-        if not RunEmulatorCommand(ep, cmd, timeout=timeout):
-          Trace('"%s" failed' % cmd)
-          return False
-  return True
-
-
-def InstallCacheFiles(cache_system_dir, out_system_dir):
-  """Install files in cache_system_dir to the proper places in out_system_dir.
-
-  cache_system_dir contains various files from /system, plus .odex files
-  for most of the .apk/.jar files that live there.
-  This function copies each .odex file from the cache dir to the output dir
-  and removes "classes.dex" from each appropriate .jar/.apk.
-
-  E.g., <cache_system_dir>/app/NotePad.odex would be copied to
-  <out_system_dir>/app/NotePad.odex, and <out_system_dir>/app/NotePad.apk
-  would have its classes.dex file removed.
-
-  Args:
-    cache_system_dir: The directory containing the cache files scraped from
-                      the emulator.
-    out_system_dir: The local directory that corresponds to "/system"
-                    on the device filesystem. (the root of system.img)
-
-  Returns:
-    True if everything succeeded, False if any problems occurred.
-  """
-  # First, walk through cache_system_dir and copy every .odex file
-  # over to out_system_dir, ensuring that the destination directory
-  # contains the corresponding source file.
-  for root, dirs, files in os.walk(cache_system_dir):
-    for name in files:
-      if name.endswith('.odex'):
-        odex_file = os.path.join(root, name)
-
-        # Find the path to the .odex file's source apk/jar file.
-        out_stem = odex_file[len(cache_system_dir):odex_file.rfind('.')]
-        out_stem = out_system_dir + out_stem;
-        jar_file = out_stem + '.jar'
-        if not os.path.exists(jar_file):
-          jar_file = out_stem + '.apk'
-        if not os.path.exists(jar_file):
-          Trace('Cannot find source .jar/.apk for %s: %s' %
-                (odex_file, out_stem + '.{jar,apk}'))
-          return False
-
-        # Copy the cache file next to the source file.
-        cmd = ['cp', odex_file, out_stem + '.odex']
-        ret = subprocess.call(cmd)
-        if ret:  # non-zero exit status
-          Trace('%s failed' % ' '.join(cmd))
-          return False
-
-  # Walk through the output /system directory, making sure
-  # that every .jar/.apk has an odex file.  While we do this,
-  # remove the classes.dex entry from each source archive.
-  for root, dirs, files in os.walk(out_system_dir):
-    for name in files:
-      if name.endswith('.apk') or name.endswith('.jar'):
-        jar_file = os.path.join(root, name)
-        odex_file = jar_file[:jar_file.rfind('.')] + '.odex'
-        if not os.path.exists(odex_file):
-          if root.endswith('/system/app') or root.endswith('/system/framework'):
-            Trace('jar/apk %s has no .odex file %s' % (jar_file, odex_file))
-            return False
-          else:
-            continue
-
-        # Attempting to dexopt a jar with no classes.dex currently
-        # creates a 40-byte odex file.
-        # TODO: use a more reliable check
-        if os.path.getsize(odex_file) > 100:
-          # Remove classes.dex from the .jar file.
-          cmd = ['zip', '-dq', jar_file, 'classes.dex']
-          ret = subprocess.call(cmd)
-          if ret:  # non-zero exit status
-            Trace('"%s" failed' % ' '.join(cmd))
-            return False
-        else:
-          # Some of the apk files don't contain any code.
-          if not name.endswith('.apk'):
-            Trace('%s has a zero-length odex file' % jar_file)
-            return False
-          cmd = ['rm', odex_file]
-          ret = subprocess.call(cmd)
-          if ret:  # non-zero exit status
-            Trace('"%s" failed' % ' '.join(cmd))
-            return False
-
-  return True
-
-
-def KillChildProcess(p, sig=signal.SIGTERM, timeout=0):
-  """Waits for a child process to die without getting stuck in wait().
-
-  After Jean Brouwers's 2004 post to python-list.
-
-  Args:
-    p: A subprocess.Popen representing the child process to kill.
-    sig: The signal to send to the child process.
-    timeout: How many seconds to wait for the child process to die.
-             If zero, do not time out.
-
-  Returns:
-    The exit status of the child process, if it was successfully killed.
-    The final value of p.returncode if it wasn't.
-  """
-  os.kill(p.pid, sig)
-  if timeout > 0:
-    while p.poll() < 0:
-      if timeout > 0.5:
-        timeout -= 0.25
-        time.sleep(0.25)
-      else:
-        os.kill(p.pid, signal.SIGKILL)
-        time.sleep(0.5)
-        p.poll()
-        break
-  else:
-    p.wait()
-  return p.returncode
-
-
-def Trace(msg):
-  """Prints a message to stdout.
-
-  Args:
-    msg: The message to print.
-  """
-  #print 'dexpreopt: %s' % msg
-  when = datetime.datetime.now()
-  print '%02d:%02d.%d  dexpreopt: %s' % (when.minute, when.second, when.microsecond, msg)
-
-
-def KillEmulator():
-  """Attempts to kill the emulator process, if it is running.
-
-  Returns:
-    The exit status of the emulator process, or None if the emulator
-    was not running or was unable to be killed.
-  """
-  global _emulator_popen
-  if _emulator_popen:
-    Trace('Killing emulator')
-    try:
-      ret = KillChildProcess(_emulator_popen, sig=signal.SIGINT, timeout=5)
-    except OSError:
-      Trace('Could not kill emulator')
-      ret = None
-    _emulator_popen = None
-    return ret
-  return None
-
-
-def Fail(msg=None):
-  """Prints an error and causes the process to exit.
-
-  Args:
-    msg: Additional error string to print (optional).
-
-  Returns:
-    Does not return.
-  """
-  s = 'dexpreopt: ERROR'
-  if msg: s += ': %s' % msg
-  print >>sys.stderr, msg
-  KillEmulator()
-  sys.exit(1)
-
-
-def PrintUsage(msg=None):
-  """Prints commandline usage information for the tool and exits with an error.
-
-  Args:
-    msg: Additional string to print (optional).
-
-  Returns:
-    Does not return.
-  """
-  if msg:
-    print >>sys.stderr, 'dexpreopt: %s', msg
-  print >>sys.stderr, """Usage: dexpreopt <options>
-Required options:
-    -kernel <kernel file>         Kernel to use when running the emulator
-    -ramdisk <ramdisk.img file>   Ramdisk to use when running the emulator
-    -image <system.img file>      System image to use when running the
-                                      emulator.  /system/app should contain the
-                                      .apk files to optimize, and any required
-                                      bootclasspath libraries must be present
-                                      in the correct locations.
-    -system <path>                The product directory, which usually contains
-                                      files like 'system.img' (files other than
-                                      the kernel in that directory won't
-                                      be used)
-    -outsystemdir <path>          A fully-populated /system directory, ready
-                                      to be modified to contain the optimized
-                                      files.  The appropriate .jar/.apk files
-                                      will be stripped of their classes.dex
-                                      entries, and the optimized .dex files
-                                      will be added alongside the packages
-                                      that they came from.
-Optional:
-    -tmpdir <path>                If specified, use this directory for
-                                      intermediate objects.  If not specified,
-                                      a unique directory under the system
-                                      temp dir is used.
-  """
-  sys.exit(2)
-
-
-def ParseArgs(argv):
-  """Parses commandline arguments.
-
-  Args:
-    argv: A list of arguments; typically sys.argv[1:]
-
-  Returns:
-    A tuple containing two dictionaries; the first contains arguments
-    that will be passsed to the emulator, and the second contains other
-    arguments.
-  """
-  parser = optparse.OptionParser()
-
-  parser.add_option('--kernel', help='Passed to emulator')
-  parser.add_option('--ramdisk', help='Passed to emulator')
-  parser.add_option('--image', help='Passed to emulator')
-  parser.add_option('--system', help='Passed to emulator')
-  parser.add_option('--outsystemdir', help='Destination /system directory')
-  parser.add_option('--tmpdir', help='Optional temp directory to use')
-
-  options, args = parser.parse_args(args=argv)
-  if args: PrintUsage()
-
-  emulator_args = {}
-  other_args = {}
-  if options.kernel: emulator_args['kernel'] = options.kernel
-  if options.ramdisk: emulator_args['ramdisk'] = options.ramdisk
-  if options.image: emulator_args['image'] = options.image
-  if options.system: emulator_args['system'] = options.system
-  if options.outsystemdir: other_args['outsystemdir'] = options.outsystemdir
-  if options.tmpdir: other_args['tmpdir'] = options.tmpdir
-
-  return (emulator_args, other_args)
-
-
-def DexoptEverything(ep, dest_root):
-  """Logic for finding and dexopting files in the necessary order.
-
-  Args:
-    ep: A subprocess.Popen object referring to the emulator process.
-    dest_root: directory to copy/move odex files to
-
-  Returns:
-    True on success, False on failure.
-  """
-  _extra_tests = False
-  if _extra_tests:
-    if not RunEmulatorCommand(ep, 'ls /system/app', timeout=5):
-      Fail('Could not ls')
-
-  # We're very short on space, so remove a bunch of big stuff that we
-  # don't need.
-  cmd = 'rm -r /system/sounds /system/media /system/fonts /system/xbin'
-  if not RunEmulatorCommand(ep, cmd, timeout=40):
-    Trace('"%s" failed' % cmd)
-    return False
-
-  Trace('Read file list')
-  jar_dirs = ['/system/framework', '/system/app']
-  files = ReadFileList(ep, jar_dirs, timeout=5)
-  if not files:
-    Fail('Could not list files in %s' % ' '.join(jar_dirs))
-  #Trace('File list:\n"""\n%s\n"""' % '\n'.join(files))
-
-  bcp = ReadBootClassPath(ep, timeout=2)
-  if not files:
-    Fail('Could not sort by bootclasspath')
-
-  # Remove bootclasspath entries from the main file list.
-  for jar in bcp:
-    try:
-      files.remove(jar)
-    except ValueError:
-      Trace('File list does not contain bootclasspath entry "%s"' % jar)
-      return False
-
-  # Create the destination directories.
-  for d in ['', '/system'] + jar_dirs:
-    cmd = 'mkdir %s%s' % (dest_root, d)
-    if not RunEmulatorCommand(ep, cmd, timeout=4):
-      Trace('"%s" failed' % cmd)
-      return False
-
-  # First, dexopt the bootclasspath.  Keep their cache files in place.
-  Trace('Dexopt %d bootclasspath files' % len(bcp))
-  if not RunDexoptOnFileList(ep, bcp, dest_root, timeout=120):
-    Trace('Could not dexopt bootclasspath')
-    return False
-
-  # dexopt the rest.  To avoid running out of space on the emulator
-  # volume, move each cache file after it's been created.
-  Trace('Dexopt %d files' % len(files))
-  if not RunDexoptOnFileList(ep, files, dest_root, move=True, timeout=120):
-    Trace('Could not dexopt files')
-    return False
-
-  if _extra_tests:
-    if not RunEmulatorCommand(ep, 'ls /system/app', timeout=5):
-      Fail('Could not ls')
-
-  return True
-
-
-
-def MainInternal():
-  """Main function that can be wrapped in a try block.
-
-  Returns:
-    Nothing.
-  """
-  emulator_args, other_args = ParseArgs(sys.argv[1:])
-
-  tmp_dir = EnsureTempDir(other_args.get('tmpdir'))
-  if not tmp_dir: Fail('Could not create temp dir')
-
-  Trace('Creating data image')
-  userdata = '%s/data.img' % tmp_dir
-  if not CreateZeroedFile(userdata, 32 * 1024 * 1024):
-    Fail('Could not create data image file')
-  emulator_args['userdata'] = userdata
-
-  ep = StartEmulator(**emulator_args)
-  if not ep: Fail('Could not start emulator')
-  global _emulator_popen
-  _emulator_popen = ep
-
-  # TODO: unlink the big userdata file now, since the emulator
-  # has it open.
-
-  if not WaitForEmulator(ep, timeout=20): Fail('Emulator did not respond')
-  if not ReplaceEmulatorPrompt(ep): Fail('Could not replace prompt')
-
-  dest_root = '/data/dexpreopt-root'
-  if not DexoptEverything(ep, dest_root): Fail('Could not dexopt files')
-
-  # Grab the odex files that were left in dest_root.
-  cache_system_dir = tmp_dir + '/cache-system'
-  if not DownloadDirectoryHierarchy(ep, dest_root + '/system',
-                                    cache_system_dir,
-                                    timeout=20):
-    Fail('Could not download %s/system from emulator' % dest_root)
-
-  if not InstallCacheFiles(cache_system_dir=cache_system_dir,
-                           out_system_dir=other_args['outsystemdir']):
-    Fail('Could not install files')
-
-  Trace('dexpreopt successful')
-  # Success!
-
-
-def main():
-  try:
-    MainInternal()
-  finally:
-    KillEmulator()
-
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/dexpreopt/geninitrc.awk b/tools/dexpreopt/geninitrc.awk
deleted file mode 100644
index 4b67e78..0000000
--- a/tools/dexpreopt/geninitrc.awk
+++ /dev/null
@@ -1,62 +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.
-#
-BEGIN {
-    fixed_remount = 0;
-    console_state = 0;
-}
-
-/^    mount yaffs2 mtd@system \/system ro remount$/ {
-    fixed_remount = 1;
-    print "    #   dexpreopt needs to write to /system";
-    print "    ### " $0;
-    next;
-}
-
-console_state == 0 && /^service console \/system\/bin\/sh$/ {
-    console_state = 1;
-    print;
-    next;
-}
-
-console_state == 1 && /^    console$/ {
-    console_state = 2;
-    print;
-    exit;
-}
-
-console_state == 1 {
-    # The second line of the console entry should always immediately
-    # follow the first.
-    exit;
-}
-
-{ print }
-
-END {
-    failed = 0;
-    if (fixed_remount != 1) {
-        print "ERROR: no match for remount line" > "/dev/stderr";
-        failed = 1;
-    }
-    if (console_state != 2) {
-        print "ERROR: no match for console lines" > "/dev/stderr";
-        failed = 1;
-    }
-    if (failed == 1) {
-        print ">>>> FAILED <<<<"
-        exit 1;
-    }
-}
diff --git a/tools/droiddoc/src/ClearPage.java b/tools/droiddoc/src/ClearPage.java
index 184c8b8..016ca93 100644
--- a/tools/droiddoc/src/ClearPage.java
+++ b/tools/droiddoc/src/ClearPage.java
@@ -23,6 +23,7 @@
 import java.io.OutputStreamWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
 
 public class ClearPage
 {
@@ -43,7 +44,7 @@
     private static boolean mTemplateDirSet = false;
 
     public static String outputDir = "docs";
-    public static String htmlDir = null;
+    public static List<String> htmlDirs = new ArrayList<String>();
     public static String toroot = null;
 
     public static void addTemplateDir(String dir)
@@ -76,7 +77,7 @@
 
     public static void write(HDF data, String templ, String filename, boolean fullPath)
     {
-        if (htmlDir != null) {
+        if (!htmlDirs.isEmpty()) {
             data.setValue("hasindex", "true");
         }
 
@@ -103,9 +104,11 @@
         }
 
         int i=0;
-        if (htmlDir != null) {
-            data.setValue("hdf.loadpaths." + i, htmlDir);
-            i++;
+        if (!htmlDirs.isEmpty()) {
+            for (String dir : htmlDirs) {
+                data.setValue("hdf.loadpaths." + i, dir);
+                i++;
+            }
         }
         if (mTemplateDirSet) {
             for (String dir: mTemplateDirs) {
diff --git a/tools/droiddoc/src/Comment.java b/tools/droiddoc/src/Comment.java
index 553cdf2..68b6d20 100644
--- a/tools/droiddoc/src/Comment.java
+++ b/tools/droiddoc/src/Comment.java
@@ -55,8 +55,6 @@
             "@sample",
             "@include",
             "@serial",
-            "@com.intel.drl.spec_ref",
-            "@ar.org.fitc.spec_ref",
         };
 
     public Comment(String text, ContainerInfo base, SourcePositionInfo sp)
@@ -185,6 +183,9 @@
                 }
             }
             if (!known) {
+                known = DroidDoc.knownTags.contains(name);
+            }
+            if (!known) {
                 Errors.error(Errors.UNKNOWN_TAG, pos == null ? null : new SourcePositionInfo(pos),
                         "Unknown tag: " + name);
             }
@@ -334,8 +335,17 @@
     {
         isHidden();
         isDocOnly();
-        parseRegex(mText);
-        parseBriefTags();
+
+        // Don't bother parsing text if we aren't generating documentation.
+        if (DroidDoc.parseComments()) {
+            parseRegex(mText);
+            parseBriefTags();
+        } else {
+          // Forces methods to be recognized by findOverriddenMethods in MethodInfo.
+          mInlineTagsList.add(new TextTagInfo("Text", "Text", mText,
+                  SourcePositionInfo.add(mPosition, mText, 0)));
+        }
+
         mText = null;
         mInitialized = true;
 
diff --git a/tools/droiddoc/src/DroidDoc.java b/tools/droiddoc/src/DroidDoc.java
index 4e9d6b1..dfdbda6 100644
--- a/tools/droiddoc/src/DroidDoc.java
+++ b/tools/droiddoc/src/DroidDoc.java
@@ -58,6 +58,18 @@
     public static Map<Character,String> escapeChars = new HashMap<Character,String>();
     public static String title = "";
     public static SinceTagger sinceTagger = new SinceTagger();
+    public static HashSet<String> knownTags = new HashSet<String>();
+
+    private static boolean parseComments = false;
+    private static boolean generateDocs = true;
+    
+    /**
+    * Returns true if we should parse javadoc comments,
+    * reporting errors in the process.
+    */
+    public static boolean parseComments() {
+        return generateDocs || parseComments;
+    }
 
     public static boolean checkLevel(int level)
     {
@@ -96,11 +108,11 @@
         String stubsDir = null;
         //Create the dependency graph for the stubs directory
         boolean apiXML = false;
-        boolean noDocs = false;
         boolean offlineMode = false;
         String apiFile = null;
         String debugStubsFile = "";
         HashSet<String> stubPackages = null;
+        ArrayList<String> knownTagsFiles = new ArrayList<String>();
 
         root = r;
 
@@ -115,6 +127,9 @@
             else if (a[0].equals("-hdf")) {
                 mHDFData.add(new String[] {a[1], a[2]});
             }
+            else if (a[0].equals("-knowntags")) {
+                knownTagsFiles.add(a[1]);
+            }
             else if (a[0].equals("-toroot")) {
                 ClearPage.toroot = a[1];
             }
@@ -122,7 +137,7 @@
                 sampleCodes.add(new SampleCode(a[1], a[2], a[3]));
             }
             else if (a[0].equals("-htmldir")) {
-                ClearPage.htmlDir = a[1];
+                ClearPage.htmlDirs.add(a[1]);
             }
             else if (a[0].equals("-title")) {
                 DroidDoc.title = a[1];
@@ -191,7 +206,10 @@
                 apiFile = a[1];
             }
             else if (a[0].equals("-nodocs")) {
-                noDocs = true;
+                generateDocs = false;
+            }
+            else if (a[0].equals("-parsecomments")) {
+                parseComments = true;
             }
             else if (a[0].equals("-since")) {
                 sinceTagger.addVersion(a[1], a[2]);
@@ -201,6 +219,10 @@
             }
         }
 
+        if (!readKnownTagsFiles(knownTags, knownTagsFiles)) {
+            return false;
+        }
+
         // read some prefs from the template
         if (!readTemplateSettings()) {
             return false;
@@ -209,7 +231,7 @@
         // Set up the data structures
         Converter.makeInfo(r);
 
-        if (!noDocs) {
+        if (generateDocs) {
             long startTime = System.nanoTime();
 
             // Apply @since tags from the XML file
@@ -224,7 +246,7 @@
             }
 
             // HTML Pages
-            if (ClearPage.htmlDir != null) {
+            if (!ClearPage.htmlDirs.isEmpty()) {
                 writeHTMLPages();
             }
 
@@ -233,7 +255,7 @@
 
             // Packages Pages
             writePackages(javadocDir
-                            + (ClearPage.htmlDir!=null
+                            + (!ClearPage.htmlDirs.isEmpty()
                                 ? "packages" + htmlExtension
                                 : "index" + htmlExtension));
 
@@ -303,6 +325,55 @@
         return true;
     }
 
+    private static boolean readKnownTagsFiles(HashSet<String> knownTags,
+            ArrayList<String> knownTagsFiles) {
+        for (String fn: knownTagsFiles) {
+            BufferedReader in = null;
+            try {
+                in = new BufferedReader(new FileReader(fn));
+                int lineno = 0;
+                boolean fail = false;
+                while (true) {
+                    lineno++;
+                    String line = in.readLine();
+                    if (line == null) {
+                        break;
+                    }
+                    line = line.trim();
+                    if (line.length() == 0) {
+                        continue;
+                    } else if (line.charAt(0) == '#') {
+                        continue;
+                    }
+                    String[] words = line.split("\\s+", 2);
+                    if (words.length == 2) {
+                        if (words[1].charAt(0) != '#') {
+                            System.err.println(fn + ":" + lineno
+                                    + ": Only one tag allowed per line: " + line);
+                            fail = true;
+                            continue;
+                        }
+                    }
+                    knownTags.add(words[0]);
+                }
+                if (fail) {
+                    return false;
+                }
+            } catch (IOException ex) {
+                System.err.println("Error reading file: " + fn + " (" + ex.getMessage() + ")");
+                return false;
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
     public static String escape(String s) {
         if (escapeChars.size() == 0) {
             return s;
@@ -358,6 +429,9 @@
         if (option.equals("-hdf")) {
             return 3;
         }
+        if (option.equals("-knowntags")) {
+            return 2;
+        }
         if (option.equals("-toroot")) {
             return 2;
         }
@@ -421,6 +495,9 @@
         if (option.equals("-nodocs")) {
             return 1;
         }
+        if (option.equals("-parsecomments")) {
+            return 1;
+        }
         if (option.equals("-since")) {
             return 3;
         }
@@ -575,11 +652,14 @@
 
     public static void writeHTMLPages()
     {
-        File f = new File(ClearPage.htmlDir);
-        if (!f.isDirectory()) {
-            System.err.println("htmlDir not a directory: " + ClearPage.htmlDir);
+        for (String htmlDir : ClearPage.htmlDirs) {
+            File f = new File(htmlDir);
+            if (!f.isDirectory()) {
+                System.err.println("htmlDir not a directory: " + htmlDir);
+                continue;
+            }
+            writeDirectory(f, "");
         }
-        writeDirectory(f, "");
     }
 
     public static void writeLists()
diff --git a/tools/droiddoc/src/Errors.java b/tools/droiddoc/src/Errors.java
index 7ba5623..0a91abc 100644
--- a/tools/droiddoc/src/Errors.java
+++ b/tools/droiddoc/src/Errors.java
@@ -130,6 +130,8 @@
             UNAVAILABLE_SYMBOL,
             HIDDEN_SUPERCLASS,
             DEPRECATED,
+            DEPRECATION_MISMATCH,
+            MISSING_COMMENT,
             IO_ERROR,
             NO_SINCE_DATA,
         };
diff --git a/tools/droiddoc/src/Stubs.java b/tools/droiddoc/src/Stubs.java
index e1ec76a..b988ef5 100644
--- a/tools/droiddoc/src/Stubs.java
+++ b/tools/droiddoc/src/Stubs.java
@@ -315,6 +315,12 @@
             return;
         }
 
+        // Work around the bogus "Array" class we invent for
+        // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505)
+        if (cl.containingPackage() != null && cl.containingPackage().name().equals("")) {
+            return;
+        }
+
         String filename = stubsDir + '/' + javaFileName(cl);
         File file = new File(filename);
         ClearPage.ensureDirectory(file);
@@ -788,6 +794,11 @@
                                 HashSet notStrippable) {
         ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]);
         Arrays.sort(classes, ClassInfo.comparator);
+        // Work around the bogus "Array" class we invent for
+        // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505)
+        if (pack.name().equals("")) {
+            return;
+        }
         xmlWriter.println("<package name=\"" + pack.name() + "\"\n"
                 //+ " source=\"" + pack.position() + "\"\n"
                 + ">");
diff --git a/tools/droiddoc/templates-sdk/sdkpage.cs b/tools/droiddoc/templates-sdk/sdkpage.cs
index a062af3..0205408 100644
--- a/tools/droiddoc/templates-sdk/sdkpage.cs
+++ b/tools/droiddoc/templates-sdk/sdkpage.cs
@@ -24,10 +24,10 @@
   <div id="jd-content">
     <p>Redirecting to 
     <a href="<?cs var:toroot ?>sdk/<?cs 
-      if:sdk.redirect.path ?><?cs var:sdk.redirect.path ?><?cs 
-      else ?><?cs var:sdk.current ?>/index.html<?cs /if ?>">sdk/<?cs 
-      if:sdk.redirect.path ?><?cs var:sdk.redirect.path ?><?cs 
-      else ?><?cs var:sdk.current ?>/index.html<?cs /if ?>
+      if:sdk.redirect.path ?><?cs var:sdk.redirect.path ?><?cs
+      else ?>index.html<?cs /if ?>"><?cs
+      if:sdk.redirect.path ?><?cs var:sdk.redirect.path ?><?cs
+      else ?>Download the SDK<?cs /if ?>
     </a> ...</p>
 <?cs else ?>
 <div class="g-unit" id="doc-content" >
diff --git a/tools/droiddoc/templates/assets/android-developer-docs.css b/tools/droiddoc/templates/assets/android-developer-docs.css
index da39a4a..bc9e98b 100644
--- a/tools/droiddoc/templates/assets/android-developer-docs.css
+++ b/tools/droiddoc/templates/assets/android-developer-docs.css
@@ -884,7 +884,8 @@
   text-decoration:none;
 }
 
-#qv a {
+#qv a,
+#qv a code {
   color:#cc6600;
 }
 
diff --git a/tools/droiddoc/templates/assets/images/home/devphone-large.png b/tools/droiddoc/templates/assets/images/home/devphone-large.png
index 6221e0a..0db0f6c 100644
--- a/tools/droiddoc/templates/assets/images/home/devphone-large.png
+++ b/tools/droiddoc/templates/assets/images/home/devphone-large.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/home/devphone-small.png b/tools/droiddoc/templates/assets/images/home/devphone-small.png
old mode 100755
new mode 100644
index b8487f5..e10bfa9
--- a/tools/droiddoc/templates/assets/images/home/devphone-small.png
+++ b/tools/droiddoc/templates/assets/images/home/devphone-small.png
Binary files differ
diff --git a/tools/merge-event-log-tags.py b/tools/merge-event-log-tags.py
index df9ebce..bddda90 100755
--- a/tools/merge-event-log-tags.py
+++ b/tools/merge-event-log-tags.py
@@ -36,6 +36,7 @@
 warnings = []
 
 output_file = None
+pre_merged_file = None
 
 # Tags with a tag number of ? are assigned a tag in the range
 # [ASSIGN_START, ASSIGN_LIMIT).
@@ -43,7 +44,7 @@
 ASSIGN_LIMIT = 1000000
 
 try:
-  opts, args = getopt.getopt(sys.argv[1:], "ho:")
+  opts, args = getopt.getopt(sys.argv[1:], "ho:m:")
 except getopt.GetoptError, err:
   print str(err)
   print __doc__
@@ -55,6 +56,8 @@
     sys.exit(2)
   elif o == "-o":
     output_file = a
+  elif o == "-m":
+    pre_merged_file = a
   else:
     print >> sys.stderr, "unhandled option %s" % (o,)
     sys.exit(1)
@@ -71,6 +74,11 @@
 by_tagname = {}
 by_tagnum = {}
 
+pre_merged_tags = {}
+if pre_merged_file:
+  for t in event_log_tags.TagFile(pre_merged_file).tags:
+    pre_merged_tags[t.tagname] = t
+
 for fn in args:
   tagfile = event_log_tags.TagFile(fn)
 
@@ -140,15 +148,26 @@
 # assigned.  We do this based on a hash of the tag name so that the
 # numbers should stay relatively stable as tags are added.
 
+# If we were provided pre-merged tags (w/ the -m option), then don't
+# ever try to allocate one, just fail if we don't have a number
+
 for name, t in sorted(by_tagname.iteritems()):
   if t.tagnum is None:
-    while True:
-      x = (hashname(name) % (ASSIGN_LIMIT - ASSIGN_START - 1)) + ASSIGN_START
-      if x not in by_tagnum:
-        t.tagnum = x
-        by_tagnum[x] = t
-        break
-      name = "_" + name
+    if pre_merged_tags:
+      try:
+        t.tagnum = pre_merged_tags[t.tagname]
+      except KeyError:
+        print >> sys.stderr, ("Error: Tag number not defined for tag `%s'."
+            +" Have you done a full build?") % t.tagname
+        sys.exit(1)
+    else:
+      while True:
+        x = (hashname(name) % (ASSIGN_LIMIT - ASSIGN_START - 1)) + ASSIGN_START
+        if x not in by_tagnum:
+          t.tagnum = x
+          by_tagnum[x] = t
+          break
+        name = "_" + name
 
 # by_tagnum should be complete now; we've assigned numbers to all tags.
 
diff --git a/tools/releasetools/amend_generator.py b/tools/releasetools/amend_generator.py
deleted file mode 100644
index b543bf7..0000000
--- a/tools/releasetools/amend_generator.py
+++ /dev/null
@@ -1,222 +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.
-
-import os
-
-import common
-
-class AmendGenerator(object):
-  """Class to generate scripts in the 'amend' recovery script language
-  used up through cupcake."""
-
-  def __init__(self):
-    self.script = ['assert compatible_with("0.2") == "true"']
-    self.included_files = set()
-
-  def MakeTemporary(self):
-    """Make a temporary script object whose commands can latter be
-    appended to the parent script with AppendScript().  Used when the
-    caller wants to generate script commands out-of-order."""
-    x = AmendGenerator()
-    x.script = []
-    x.included_files = self.included_files
-    return x
-
-  @staticmethod
-  def _FileRoot(fn):
-    """Convert a file path to the 'root' notation used by amend."""
-    if fn.startswith("/system/"):
-      return "SYSTEM:" + fn[8:]
-    elif fn == "/system":
-      return "SYSTEM:"
-    elif fn.startswith("/tmp/"):
-      return "CACHE:.." + fn
-    else:
-      raise ValueError("don't know root for \"%s\"" % (fn,))
-
-  @staticmethod
-  def _PartitionRoot(partition):
-    """Convert a partition name to the 'root' notation used by amend."""
-    if partition == "userdata":
-      return "DATA:"
-    else:
-      return partition.upper() + ":"
-
-  def AppendScript(self, other):
-    """Append the contents of another script (which should be created
-    with temporary=True) to this one."""
-    self.script.extend(other.script)
-    self.included_files.update(other.included_files)
-
-  def AssertSomeFingerprint(self, *fp):
-    """Assert that the current fingerprint is one of *fp."""
-    x = [('file_contains("SYSTEM:build.prop", '
-          '"ro.build.fingerprint=%s") == "true"') % i for i in fp]
-    self.script.append("assert %s" % (" || ".join(x),))
-
-  def AssertOlderBuild(self, timestamp):
-    """Assert that the build on the device is older (or the same as)
-    the given timestamp."""
-    self.script.append("run_program PACKAGE:check_prereq %s" % (timestamp,))
-    self.included_files.add("check_prereq")
-
-  def AssertDevice(self, device):
-    """Assert that the device identifier is the given string."""
-    self.script.append('assert getprop("ro.product.device") == "%s" || '
-                       'getprop("ro.build.product") == "%s"' % (device, device))
-
-  def AssertSomeBootloader(self, *bootloaders):
-    """Asert that the bootloader version is one of *bootloaders."""
-    self.script.append("assert " +
-                  " || ".join(['getprop("ro.bootloader") == "%s"' % (b,)
-                               for b in bootloaders]))
-
-  def ShowProgress(self, frac, dur):
-    """Update the progress bar, advancing it over 'frac' over the next
-    'dur' seconds."""
-    self.script.append("show_progress %f %d" % (frac, int(dur)))
-
-  def SetProgress(self, frac):
-    """Not implemented in amend."""
-    pass
-
-  def PatchCheck(self, filename, *sha1):
-    """Check that the given file (or MTD reference) has one of the
-    given *sha1 hashes."""
-    out = ["run_program PACKAGE:applypatch -c %s" % (filename,)]
-    for i in sha1:
-      out.append(" " + i)
-    self.script.append("".join(out))
-    self.included_files.add(("applypatch_static", "applypatch"))
-
-  # Not quite right since we don't need to check /cache/saved.file on
-  # failure, but shouldn't hurt.
-  FileCheck = PatchCheck
-
-  def CacheFreeSpaceCheck(self, amount):
-    """Check that there's at least 'amount' space that can be made
-    available on /cache."""
-    self.script.append("run_program PACKAGE:applypatch -s %d" % (amount,))
-    self.included_files.add(("applypatch_static", "applypatch"))
-
-  def Mount(self, kind, what, path):
-    # no-op; amend uses it's 'roots' system to automatically mount
-    # things when they're referred to
-    pass
-
-  def UnpackPackageDir(self, src, dst):
-    """Unpack a given directory from the OTA package into the given
-    destination directory."""
-    dst = self._FileRoot(dst)
-    self.script.append("copy_dir PACKAGE:%s %s" % (src, dst))
-
-  def Comment(self, comment):
-    """Write a comment into the update script."""
-    self.script.append("")
-    for i in comment.split("\n"):
-      self.script.append("# " + i)
-    self.script.append("")
-
-  def Print(self, message):
-    """Log a message to the screen (if the logs are visible)."""
-    # no way to do this from amend; substitute a script comment instead
-    self.Comment(message)
-
-  def FormatPartition(self, partition):
-    """Format the given MTD partition."""
-    self.script.append("format %s" % (self._PartitionRoot(partition),))
-
-  def DeleteFiles(self, file_list):
-    """Delete all files in file_list."""
-    line = []
-    t = 0
-    for i in file_list:
-      i = self._FileRoot(i)
-      line.append(i)
-      t += len(i) + 1
-      if t > 80:
-        self.script.append("delete " + " ".join(line))
-        line = []
-        t = 0
-    if line:
-      self.script.append("delete " + " ".join(line))
-
-  def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
-    """Apply binary patches (in *patchpairs) to the given srcfile to
-    produce tgtfile (which may be "-" to indicate overwriting the
-    source file."""
-    if len(patchpairs) % 2 != 0:
-      raise ValueError("bad patches given to ApplyPatch")
-    self.script.append(
-        ("run_program PACKAGE:applypatch %s %s %s %d " %
-         (srcfile, tgtfile, tgtsha1, tgtsize)) +
-        " ".join(["%s:%s" % patchpairs[i:i+2]
-                  for i in range(0, len(patchpairs), 2)]))
-    self.included_files.add(("applypatch_static", "applypatch"))
-
-  def WriteFirmwareImage(self, kind, fn):
-    """Arrange to update the given firmware image (kind must be
-    "hboot" or "radio") when recovery finishes."""
-    self.script.append("write_%s_image PACKAGE:%s" % (kind, fn))
-
-  def WriteRawImage(self, partition, fn):
-    """Write the given file into the given MTD partition."""
-    self.script.append("write_raw_image PACKAGE:%s %s" %
-                       (fn, self._PartitionRoot(partition)))
-
-  def SetPermissions(self, fn, uid, gid, mode):
-    """Set file ownership and permissions."""
-    fn = self._FileRoot(fn)
-    self.script.append("set_perm %d %d 0%o %s" % (uid, gid, mode, fn))
-
-  def SetPermissionsRecursive(self, fn, uid, gid, dmode, fmode):
-    """Recursively set path ownership and permissions."""
-    fn = self._FileRoot(fn)
-    self.script.append("set_perm_recursive %d %d 0%o 0%o %s" %
-                       (uid, gid, dmode, fmode, fn))
-
-  def MakeSymlinks(self, symlink_list):
-    """Create symlinks, given a list of (dest, link) pairs."""
-    self.DeleteFiles([i[1] for i in symlink_list])
-    self.script.extend(["symlink %s %s" % (i[0], self._FileRoot(i[1]))
-                        for i in sorted(symlink_list)])
-
-  def AppendExtra(self, extra):
-    """Append text verbatim to the output script."""
-    self.script.append(extra)
-
-  def UnmountAll(self):
-    pass
-
-  def AddToZip(self, input_zip, output_zip, input_path=None):
-    """Write the accumulated script to the output_zip file.  input_zip
-    is used as the source for any ancillary binaries needed by the
-    script.  If input_path is not None, it will be used as a local
-    path for binaries instead of input_zip."""
-    common.ZipWriteStr(output_zip, "META-INF/com/google/android/update-script",
-                       "\n".join(self.script) + "\n")
-    for i in self.included_files:
-      if isinstance(i, tuple):
-        sourcefn, targetfn = i
-      else:
-        sourcefn = i
-        targetfn = i
-      try:
-        if input_path is None:
-          data = input_zip.read(os.path.join("OTA/bin", sourcefn))
-        else:
-          data = open(os.path.join(input_path, sourcefn)).read()
-        common.ZipWriteStr(output_zip, targetfn, data, perms=0755)
-      except (IOError, KeyError), e:
-        raise ExternalError("unable to include binary %s: %s" % (i, e))
diff --git a/tools/releasetools/both_generator.py b/tools/releasetools/both_generator.py
deleted file mode 100644
index 4ae8d50..0000000
--- a/tools/releasetools/both_generator.py
+++ /dev/null
@@ -1,62 +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.
-
-import edify_generator
-import amend_generator
-
-class BothGenerator(object):
-  def __init__(self, version):
-    self.version = version
-    self.edify = edify_generator.EdifyGenerator(version)
-    self.amend = amend_generator.AmendGenerator()
-
-  def MakeTemporary(self):
-    x = BothGenerator(self.version)
-    x.edify = self.edify.MakeTemporary()
-    x.amend = self.amend.MakeTemporary()
-    return x
-
-  def AppendScript(self, other):
-    self.edify.AppendScript(other.edify)
-    self.amend.AppendScript(other.amend)
-
-  def _DoBoth(self, name, *args):
-    getattr(self.edify, name)(*args)
-    getattr(self.amend, name)(*args)
-
-  def AssertSomeFingerprint(self, *a): self._DoBoth("AssertSomeFingerprint", *a)
-  def AssertOlderBuild(self, *a): self._DoBoth("AssertOlderBuild", *a)
-  def AssertDevice(self, *a): self._DoBoth("AssertDevice", *a)
-  def AssertSomeBootloader(self, *a): self._DoBoth("AssertSomeBootloader", *a)
-  def ShowProgress(self, *a): self._DoBoth("ShowProgress", *a)
-  def PatchCheck(self, *a): self._DoBoth("PatchCheck", *a)
-  def FileCheck(self, filename, *sha1): self._DoBoth("FileCheck", *a)
-  def CacheFreeSpaceCheck(self, *a): self._DoBoth("CacheFreeSpaceCheck", *a)
-  def Mount(self, *a): self._DoBoth("Mount", *a)
-  def UnpackPackageDir(self, *a): self._DoBoth("UnpackPackageDir", *a)
-  def Comment(self, *a): self._DoBoth("Comment", *a)
-  def Print(self, *a): self._DoBoth("Print", *a)
-  def FormatPartition(self, *a): self._DoBoth("FormatPartition", *a)
-  def DeleteFiles(self, *a): self._DoBoth("DeleteFiles", *a)
-  def ApplyPatch(self, *a): self._DoBoth("ApplyPatch", *a)
-  def WriteFirmwareImage(self, *a): self._DoBoth("WriteFirmwareImage", *a)
-  def WriteRawImage(self, *a): self._DoBoth("WriteRawImage", *a)
-  def SetPermissions(self, *a): self._DoBoth("SetPermissions", *a)
-  def SetPermissionsRecursive(self, *a): self._DoBoth("SetPermissionsRecursive", *a)
-  def MakeSymlinks(self, *a): self._DoBoth("MakeSymlinks", *a)
-  def AppendExtra(self, *a): self._DoBoth("AppendExtra", *a)
-  def UnmountAll(self, *a): self._DoBoth("UnmountAll", *a)
-
-  def AddToZip(self, input_zip, output_zip, input_path=None):
-    self._DoBoth("AddToZip", input_zip, output_zip, input_path)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index ab6678a..a236a12 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -12,16 +12,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import copy
 import errno
 import getopt
 import getpass
 import imp
 import os
 import re
+import sha
 import shutil
 import subprocess
 import sys
 import tempfile
+import threading
+import time
 import zipfile
 
 # missing in Python 2.4 and before
@@ -31,11 +35,11 @@
 class Options(object): pass
 OPTIONS = Options()
 OPTIONS.search_path = "out/host/linux-x86"
-OPTIONS.max_image_size = {}
 OPTIONS.verbose = False
 OPTIONS.tempfiles = []
 OPTIONS.device_specific = None
 OPTIONS.extras = {}
+OPTIONS.info_dict = None
 
 
 # Values for "certificate" in apkcerts that mean special things.
@@ -53,23 +57,113 @@
   return subprocess.Popen(args, **kwargs)
 
 
-def LoadMaxSizes():
-  """Load the maximum allowable images sizes from the input
-  target_files size."""
-  OPTIONS.max_image_size = {}
+def LoadInfoDict(zip):
+  """Read and parse the META/misc_info.txt key/value pairs from the
+  input target files and return a dict."""
+
+  d = {}
   try:
-    for line in open(os.path.join(OPTIONS.input_tmp, "META", "imagesizes.txt")):
-      pieces = line.split()
-      if len(pieces) != 2: continue
-      image = pieces[0]
-      size = int(pieces[1])
-      OPTIONS.max_image_size[image + ".img"] = size
-  except IOError, e:
-    if e.errno == errno.ENOENT:
+    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
+  except KeyError:
+    # ok if misc_info.txt doesn't exist
+    pass
+
+  # backwards compatibility: These values used to be in their own
+  # files.  Look for them, in case we're processing an old
+  # target_files zip.
+
+  if "mkyaffs2_extra_flags" not in d:
+    try:
+      d["mkyaffs2_extra_flags"] = zip.read("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()
+    except KeyError:
+      raise ValueError("can't find recovery API version in input target-files")
 
-def BuildAndAddBootableImage(sourcedir, targetname, output_zip):
+  if "tool_extensions" not in d:
+    try:
+      d["tool_extensions"] = zip.read("META/tool-extensions.txt").strip()
+    except KeyError:
+      # ok if extensions don't exist
+      pass
+
+  try:
+    data = zip.read("META/imagesizes.txt")
+    for line in data.split("\n"):
+      if not line: continue
+      name, value = line.split(" ", 1)
+      if not value: continue
+      if name == "blocksize":
+        d[name] = value
+      else:
+        d[name + "_size"] = value
+  except KeyError:
+    pass
+
+  def makeint(key):
+    if key in d:
+      d[key] = int(d[key], 0)
+
+  makeint("recovery_api_version")
+  makeint("blocksize")
+  makeint("system_size")
+  makeint("userdata_size")
+  makeint("recovery_size")
+  makeint("boot_size")
+
+  d["fstab"] = LoadRecoveryFSTab(zip)
+  if not d["fstab"]:
+    if "fs_type" not in d: d["fs_type"] = "yaffs2"
+    if "partition_type" not in d: d["partition_type"] = "MTD"
+
+  return d
+
+def LoadRecoveryFSTab(zip):
+  class Partition(object):
+    pass
+
+  try:
+    data = zip.read("RECOVERY/RAMDISK/etc/recovery.fstab")
+  except KeyError:
+    # older target-files that doesn't have a recovery.fstab; fall back
+    # to the fs_type and partition_type keys.
+    return
+
+  d = {}
+  for line in data.split("\n"):
+    line = line.strip()
+    if not line or line.startswith("#"): continue
+    pieces = line.split()
+    if not (3 <= len(pieces) <= 4):
+      raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
+
+    p = Partition()
+    p.mount_point = pieces[0]
+    p.fs_type = pieces[1]
+    p.device = pieces[2]
+    if len(pieces) == 4:
+      p.device2 = pieces[3]
+    else:
+      p.device2 = None
+
+    d[p.mount_point] = p
+  return d
+
+
+def DumpInfoDict(d):
+  for k, v in sorted(d.items()):
+    print "%-25s = (%s) %s" % (k, type(v).__name__, v)
+
+def BuildAndAddBootableImage(sourcedir, targetname, output_zip, info_dict):
   """Take a kernel, cmdline, and ramdisk directory from the input (in
   'sourcedir'), and turn them into a boot image.  Put the boot image
   into the output zip file under the name 'targetname'.  Returns
@@ -82,7 +176,7 @@
   if img is None:
     return None
 
-  CheckSize(img, targetname)
+  CheckSize(img, targetname, info_dict)
   ZipWriteStr(output_zip, targetname, img)
   return targetname
 
@@ -121,6 +215,11 @@
     cmd.append("--base")
     cmd.append(open(fn).read().rstrip("\n"))
 
+  fn = os.path.join(sourcedir, "pagesize")
+  if os.access(fn, os.F_OK):
+    cmd.append("--pagesize")
+    cmd.append(open(fn).read().rstrip("\n"))
+
   cmd.extend(["--ramdisk", ramdisk_img.name,
               "--output", img.name])
 
@@ -138,13 +237,13 @@
   return data
 
 
-def AddRecovery(output_zip):
+def AddRecovery(output_zip, info_dict):
   BuildAndAddBootableImage(os.path.join(OPTIONS.input_tmp, "RECOVERY"),
-                           "recovery.img", output_zip)
+                           "recovery.img", output_zip, info_dict)
 
-def AddBoot(output_zip):
+def AddBoot(output_zip, info_dict):
   BuildAndAddBootableImage(os.path.join(OPTIONS.input_tmp, "BOOT"),
-                           "boot.img", output_zip)
+                           "boot.img", output_zip, info_dict)
 
 def UnzipTemp(filename, pattern=None):
   """Unzip the given archive into a temporary directory and return the name."""
@@ -238,12 +337,28 @@
     temp.close()
 
 
-def CheckSize(data, target):
+def CheckSize(data, target, info_dict):
   """Check the data string passed against the max size limit, if
   any, for the given target.  Raise exception if the data is too big.
   Print a warning if the data is nearing the maximum size."""
-  limit = OPTIONS.max_image_size.get(target, None)
-  if limit is None: return
+
+  if target.endswith(".img"): target = target[:-4]
+  mount_point = "/" + target
+
+  if info_dict["fstab"]:
+    if mount_point == "/userdata": mount_point = "/data"
+    p = info_dict["fstab"][mount_point]
+    fs_type = p.fs_type
+    limit = info_dict.get(p.device + "_size", None)
+  else:
+    fs_type = info_dict.get("fs_type", None)
+    limit = info_dict.get(target + "_size", None)
+  if not fs_type or not limit: return
+
+  if fs_type == "yaffs2":
+    # image size should be increased by 1/64th to account for the
+    # spare area (64 bytes per 2k page)
+    limit = limit / 2048 * (2048+64)
 
   size = len(data)
   pct = float(size) * 100.0 / limit
@@ -530,3 +645,141 @@
     this is used to install the image for the device's baseband
     processor."""
     return self._DoCall("IncrementalOTA_InstallEnd")
+
+class File(object):
+  def __init__(self, name, data):
+    self.name = name
+    self.data = data
+    self.size = len(data)
+    self.sha1 = sha.sha(data).hexdigest()
+
+  def WriteToTemp(self):
+    t = tempfile.NamedTemporaryFile()
+    t.write(self.data)
+    t.flush()
+    return t
+
+  def AddToZip(self, z):
+    ZipWriteStr(z, self.name, self.data)
+
+DIFF_PROGRAM_BY_EXT = {
+    ".gz" : "imgdiff",
+    ".zip" : ["imgdiff", "-z"],
+    ".jar" : ["imgdiff", "-z"],
+    ".apk" : ["imgdiff", "-z"],
+    ".img" : "imgdiff",
+    }
+
+class Difference(object):
+  def __init__(self, tf, sf):
+    self.tf = tf
+    self.sf = sf
+    self.patch = None
+
+  def ComputePatch(self):
+    """Compute the patch (as a string of data) needed to turn sf into
+    tf.  Returns the same tuple as GetPatch()."""
+
+    tf = self.tf
+    sf = self.sf
+
+    ext = os.path.splitext(tf.name)[1]
+    diff_program = DIFF_PROGRAM_BY_EXT.get(ext, "bsdiff")
+
+    ttemp = tf.WriteToTemp()
+    stemp = sf.WriteToTemp()
+
+    ext = os.path.splitext(tf.name)[1]
+
+    try:
+      ptemp = tempfile.NamedTemporaryFile()
+      if isinstance(diff_program, list):
+        cmd = copy.copy(diff_program)
+      else:
+        cmd = [diff_program]
+      cmd.append(stemp.name)
+      cmd.append(ttemp.name)
+      cmd.append(ptemp.name)
+      p = Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+      _, err = p.communicate()
+      if err or p.returncode != 0:
+        print "WARNING: failure running %s:\n%s\n" % (diff_program, err)
+        return None
+      diff = ptemp.read()
+    finally:
+      ptemp.close()
+      stemp.close()
+      ttemp.close()
+
+    self.patch = diff
+    return self.tf, self.sf, self.patch
+
+
+  def GetPatch(self):
+    """Return a tuple (target_file, source_file, patch_data).
+    patch_data may be None if ComputePatch hasn't been called, or if
+    computing the patch failed."""
+    return self.tf, self.sf, self.patch
+
+
+def ComputeDifferences(diffs):
+  """Call ComputePatch on all the Difference objects in 'diffs'."""
+  print len(diffs), "diffs to compute"
+
+  # Do the largest files first, to try and reduce the long-pole effect.
+  by_size = [(i.tf.size, i) for i in diffs]
+  by_size.sort(reverse=True)
+  by_size = [i[1] for i in by_size]
+
+  lock = threading.Lock()
+  diff_iter = iter(by_size)   # accessed under lock
+
+  def worker():
+    try:
+      lock.acquire()
+      for d in diff_iter:
+        lock.release()
+        start = time.time()
+        d.ComputePatch()
+        dur = time.time() - start
+        lock.acquire()
+
+        tf, sf, patch = d.GetPatch()
+        if sf.name == tf.name:
+          name = tf.name
+        else:
+          name = "%s (%s)" % (tf.name, sf.name)
+        if patch is None:
+          print "patching failed!                                  %s" % (name,)
+        else:
+          print "%8.2f sec %8d / %8d bytes (%6.2f%%) %s" % (
+              dur, len(patch), tf.size, 100.0 * len(patch) / tf.size, name)
+      lock.release()
+    except Exception, e:
+      print e
+      raise
+
+  # start worker threads; wait for them all to finish.
+  threads = [threading.Thread(target=worker)
+             for i in range(OPTIONS.worker_threads)]
+  for th in threads:
+    th.start()
+  while threads:
+    threads.pop().join()
+
+
+# map recovery.fstab's fs_types to mount/format "partition types"
+PARTITION_TYPES = { "yaffs2": "MTD", "mtd": "MTD",
+                    "ext4": "EMMC", "emmc": "EMMC" }
+
+def GetTypeAndDevice(mount_point, info):
+  fstab = info["fstab"]
+  if fstab:
+    return PARTITION_TYPES[fstab[mount_point].fs_type], fstab[mount_point].device
+  else:
+    devices = {"/boot": "boot",
+               "/recovery": "recovery",
+               "/radio": "radio",
+               "/data": "userdata",
+               "/cache": "cache"}
+    return info["partition_type"], info.get("partition_path", "") + devices[mount_point]
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 68b0850..756d673 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -21,16 +21,17 @@
   """Class to generate scripts in the 'edify' recovery script language
   used from donut onwards."""
 
-  def __init__(self, version):
+  def __init__(self, version, info):
     self.script = []
     self.mounts = set()
     self.version = version
+    self.info = info
 
   def MakeTemporary(self):
     """Make a temporary script object whose commands can latter be
     appended to the parent script with AppendScript().  Used when the
     caller wants to generate script commands out-of-order."""
-    x = EdifyGenerator(self.version)
+    x = EdifyGenerator(self.version, self.info)
     x.mounts = self.mounts
     return x
 
@@ -130,12 +131,22 @@
     available on /cache."""
     self.script.append("assert(apply_patch_space(%d));" % (amount,))
 
-  def Mount(self, kind, what, path):
-    """Mount the given 'what' at the given path.  'what' should be a
-    partition name if kind is "MTD", or a block device if kind is
-    "vfat".  No other values of 'kind' are supported."""
-    self.script.append('mount("%s", "%s", "%s");' % (kind, what, path))
-    self.mounts.add(path)
+  def Mount(self, mount_point):
+    """Mount the partition with the given mount_point."""
+    fstab = self.info.get("fstab", None)
+    if fstab:
+      p = fstab[mount_point]
+      self.script.append('mount("%s", "%s", "%s", "%s");' %
+                         (p.fs_type, common.PARTITION_TYPES[p.fs_type],
+                          p.device, p.mount_point))
+      self.mounts.add(p.mount_point)
+    else:
+      what = mount_point.lstrip("/")
+      what = self.info.get("partition_path", "") + what
+      self.script.append('mount("%s", "%s", "%s", "%s");' %
+                         (self.info["fs_type"], self.info["partition_type"],
+                          what, mount_point))
+      self.mounts.add(mount_point)
 
   def UnpackPackageDir(self, src, dst):
     """Unpack a given directory from the OTA package into the given
@@ -154,8 +165,20 @@
     self.script.append('ui_print("%s");' % (message,))
 
   def FormatPartition(self, partition):
-    """Format the given MTD partition."""
-    self.script.append('format("MTD", "%s");' % (partition,))
+    """Format the given partition, specified by its mount point (eg,
+    "/system")."""
+
+    fstab = self.info.get("fstab", None)
+    if fstab:
+      p = fstab[partition]
+      self.script.append('format("%s", "%s", "%s");' %
+                         (p.fs_type, common.PARTITION_TYPES[p.fs_type], p.device))
+    else:
+      # older target-files without per-partition types
+      partition = self.info.get("partition_path", "") + partition
+      self.script.append('format("%s", "%s", "%s");' %
+                         (self.info["fs_type"], self.info["partition_type"],
+                          partition))
 
   def DeleteFiles(self, file_list):
     """Delete all files in file_list."""
@@ -189,13 +212,42 @@
       self.script.append(
           'write_firmware_image("PACKAGE:%s", "%s");' % (fn, kind))
 
-  def WriteRawImage(self, partition, fn):
-    """Write the given package file into the given MTD partition."""
-    self.script.append(
-        ('assert(package_extract_file("%(fn)s", "/tmp/%(partition)s.img"),\n'
-         '       write_raw_image("/tmp/%(partition)s.img", "%(partition)s"),\n'
-         '       delete("/tmp/%(partition)s.img"));')
-        % {'partition': partition, 'fn': fn})
+  def WriteRawImage(self, mount_point, fn):
+    """Write the given package file into the partition for the given
+    mount point."""
+
+    fstab = self.info["fstab"]
+    if fstab:
+      p = fstab[mount_point]
+      partition_type = common.PARTITION_TYPES[p.fs_type]
+      args = {'device': p.device, 'fn': fn}
+      if partition_type == "MTD":
+        self.script.append(
+            ('assert(package_extract_file("%(fn)s", "/tmp/%(device)s.img"),\n'
+             '       write_raw_image("/tmp/%(device)s.img", "%(device)s"),\n'
+             '       delete("/tmp/%(device)s.img"));') % args)
+      elif partition_type == "EMMC":
+        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,))
+    else:
+      # backward compatibility with older target-files that lack recovery.fstab
+      if self.info["partition_type"] == "MTD":
+        self.script.append(
+            ('assert(package_extract_file("%(fn)s", "/tmp/%(partition)s.img"),\n'
+             '       write_raw_image("/tmp/%(partition)s.img", "%(partition)s"),\n'
+             '       delete("/tmp/%(partition)s.img"));')
+            % {'partition': partition, 'fn': fn})
+      elif self.info["partition_type"] == "EMMC":
+        self.script.append(
+            ('package_extract_file("%(fn)s", "%(dir)s%(partition)s");')
+            % {'partition': partition, 'fn': fn,
+               'dir': self.info.get("partition_path", ""),
+               })
+      else:
+        raise ValueError("don't know how to write \"%s\" partitions" %
+                         (self.info["partition_type"],))
 
   def SetPermissions(self, fn, uid, gid, mode):
     """Set file ownership and permissions."""
diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files
index d157dca..f10af49 100755
--- a/tools/releasetools/img_from_target_files
+++ b/tools/releasetools/img_from_target_files
@@ -47,7 +47,6 @@
 
 OPTIONS = common.OPTIONS
 
-
 def AddUserdata(output_zip):
   """Create an empty userdata image and store it in output_zip."""
 
@@ -61,11 +60,26 @@
   os.mkdir(user_dir)
   img = tempfile.NamedTemporaryFile()
 
-  p = common.Run(["mkyaffs2image", "-f", user_dir, img.name])
-  p.communicate()
-  assert p.returncode == 0, "mkyaffs2image of userdata.img image failed"
+  build_command = []
+  if OPTIONS.info_dict["fstab"]["/data"].fs_type.startswith("ext"):
+    build_command = ["mkuserimg.sh",
+                     user_dir, img.name,
+                     OPTIONS.info_dict["fstab"]["/data"].fs_type, "data"]
+    if "userdata_size" in OPTIONS.info_dict:
+      build_command.append(str(OPTIONS.info_dict["userdata_size"]))
+  else:
+    build_command = ["mkyaffs2image", "-f"]
+    extra = OPTIONS.info_dict.get("mkyaffs2_extra_flags", None)
+    if extra:
+      build_command.extend(extra.split())
+    build_command.append(user_dir)
+    build_command.append(img.name)
 
-  common.CheckSize(img.name, "userdata.img")
+  p = common.Run(build_command)
+  p.communicate()
+  assert p.returncode == 0, "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)
@@ -94,16 +108,30 @@
     if (e.errno == errno.EEXIST):
       pass
 
-  p = common.Run(["mkyaffs2image", "-f",
-                  os.path.join(OPTIONS.input_tmp, "system"), img.name])
+  build_command = []
+  if OPTIONS.info_dict["fstab"]["/system"].fs_type.startswith("ext"):
+    build_command = ["mkuserimg.sh",
+                     os.path.join(OPTIONS.input_tmp, "system"), img.name,
+                     OPTIONS.info_dict["fstab"]["/system"].fs_type, "system"]
+    if "system_size" in OPTIONS.info_dict:
+      build_command.append(str(OPTIONS.info_dict["system_size"]))
+  else:
+    build_command = ["mkyaffs2image", "-f"]
+    extra = OPTIONS.info_dict.get("mkyaffs2_extra_flags", None)
+    if extra:
+      build_command.extend(extra.split())
+    build_command.append(os.path.join(OPTIONS.input_tmp, "system"))
+    build_command.append(img.name)
+
+  p = common.Run(build_command)
   p.communicate()
-  assert p.returncode == 0, "mkyaffs2image of system.img image failed"
+  assert p.returncode == 0, "build system.img image failed"
 
   img.seek(os.SEEK_SET, 0)
   data = img.read()
   img.close()
 
-  common.CheckSize(data, "system.img")
+  common.CheckSize(data, "system.img", OPTIONS.info_dict)
   common.ZipWriteStr(output_zip, "system.img", data)
 
 
@@ -133,17 +161,13 @@
 
   OPTIONS.input_tmp = common.UnzipTemp(args[0])
 
-  common.LoadMaxSizes()
-  if not OPTIONS.max_image_size:
-    print
-    print "  WARNING:  Failed to load max image sizes; will not enforce"
-    print "  image size limits."
-    print
+  input_zip = zipfile.ZipFile(args[0], "r")
+  OPTIONS.info_dict = common.LoadInfoDict(input_zip)
 
   output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
 
-  common.AddBoot(output_zip)
-  common.AddRecovery(output_zip)
+  common.AddBoot(output_zip, OPTIONS.info_dict)
+  common.AddRecovery(output_zip, OPTIONS.info_dict)
   AddSystem(output_zip)
   AddUserdata(output_zip)
   CopyInfo(output_zip)
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index 932d5b0..aa691b4 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -44,10 +44,6 @@
   -e  (--extra_script)  <file>
       Insert the contents of file at the end of the update script.
 
-  -m  (--script_mode)  <mode>
-      Specify 'amend' or 'edify' scripts, or 'auto' to pick
-      automatically (this is the default).
-
 """
 
 import sys
@@ -63,14 +59,11 @@
 import sha
 import subprocess
 import tempfile
-import threading
 import time
 import zipfile
 
 import common
-import amend_generator
 import edify_generator
-import both_generator
 
 OPTIONS = common.OPTIONS
 OPTIONS.package_key = "build/target/product/security/testkey"
@@ -81,7 +74,6 @@
 OPTIONS.wipe_user_data = False
 OPTIONS.omit_prereq = False
 OPTIONS.extra_script = None
-OPTIONS.script_mode = 'auto'
 OPTIONS.worker_threads = 3
 
 def MostPopularKey(d, default):
@@ -99,7 +91,6 @@
   return (info.external_attr >> 16) == 0120777
 
 
-
 class Item:
   """Items represent the metadata (user, group, mode) of files and
   directories in the system image."""
@@ -315,20 +306,23 @@
   executable.
   """
 
-  d = Difference(recovery_img, boot_img)
+  d = common.Difference(recovery_img, boot_img)
   _, _, 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)
+
   # Images with different content will have a different first page, so
   # we check to see if this recovery has already been installed by
   # testing just the first 2k.
   HEADER_SIZE = 2048
   header_sha1 = sha.sha(recovery_img.data[:HEADER_SIZE]).hexdigest()
   sh = """#!/system/bin/sh
-if ! applypatch -c MTD:recovery:%(header_size)d:%(header_sha1)s; then
+if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(header_size)d:%(header_sha1)s; then
   log -t recovery "Installing new recovery image"
-  applypatch MTD:boot:%(boot_size)d:%(boot_sha1)s MTD:recovery %(recovery_sha1)s %(recovery_size)d %(boot_sha1)s:/system/recovery-from-boot.p
+  applypatch %(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
@@ -337,21 +331,21 @@
         'header_size': HEADER_SIZE,
         'header_sha1': header_sha1,
         'recovery_size': recovery_img.size,
-        'recovery_sha1': recovery_img.sha1 }
+        'recovery_sha1': recovery_img.sha1,
+        'boot_type': boot_type,
+        'boot_device': boot_device,
+        'recovery_type': recovery_type,
+        'recovery_device': recovery_device,
+        }
   common.ZipWriteStr(output_zip, "recovery/etc/install-recovery.sh", sh)
   return Item.Get("system/etc/install-recovery.sh", dir=False)
 
 
 def WriteFullOTAPackage(input_zip, output_zip):
-  if OPTIONS.script_mode == "auto":
-    script = both_generator.BothGenerator(2)
-  elif OPTIONS.script_mode == "amend":
-    script = amend_generator.AmendGenerator()
-  else:
-    # TODO: how to determine this?  We don't know what version it will
-    # be installed on top of.  For now, we expect the API just won't
-    # change very often.
-    script = edify_generator.EdifyGenerator(2)
+  # TODO: how to determine this?  We don't know what version it will
+  # be installed on top of.  For now, we expect the API just won't
+  # change very often.
+  script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
 
   metadata = {"post-build": GetBuildProp("ro.build.fingerprint", input_zip),
               "pre-device": GetBuildProp("ro.product.device", input_zip),
@@ -360,11 +354,12 @@
 
   device_specific = common.DeviceSpecificParams(
       input_zip=input_zip,
-      input_version=GetRecoveryAPIVersion(input_zip),
+      input_version=OPTIONS.info_dict["recovery_api_version"],
       output_zip=output_zip,
       script=script,
       input_tmp=OPTIONS.input_tmp,
-      metadata=metadata)
+      metadata=metadata,
+      info_dict=OPTIONS.info_dict)
 
   if not OPTIONS.omit_prereq:
     ts = GetBuildProp("ro.build.date.utc", input_zip)
@@ -376,31 +371,31 @@
   script.ShowProgress(0.5, 0)
 
   if OPTIONS.wipe_user_data:
-    script.FormatPartition("userdata")
+    script.FormatPartition("/data")
 
-  script.FormatPartition("system")
-  script.Mount("MTD", "system", "/system")
+  script.FormatPartition("/system")
+  script.Mount("/system")
   script.UnpackPackageDir("recovery", "/system")
   script.UnpackPackageDir("system", "/system")
 
   symlinks = CopySystemFiles(input_zip, output_zip)
   script.MakeSymlinks(symlinks)
 
-  boot_img = File("boot.img", common.BuildBootableImage(
+  boot_img = common.File("boot.img", common.BuildBootableImage(
       os.path.join(OPTIONS.input_tmp, "BOOT")))
-  recovery_img = File("recovery.img", common.BuildBootableImage(
+  recovery_img = common.File("recovery.img", common.BuildBootableImage(
       os.path.join(OPTIONS.input_tmp, "RECOVERY")))
   MakeRecoveryPatch(output_zip, recovery_img, boot_img)
 
   Item.GetMetadata(input_zip)
   Item.Get("system").SetPermissions(script)
 
-  common.CheckSize(boot_img.data, "boot.img")
+  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.WriteRawImage("boot", "boot.img")
+  script.WriteRawImage("/boot", "boot.img")
 
   script.ShowProgress(0.1, 0)
   device_specific.FullOTA_InstallEnd()
@@ -419,21 +414,6 @@
                               for kv in sorted(metadata.iteritems())]))
 
 
-class File(object):
-  def __init__(self, name, data):
-    self.name = name
-    self.data = data
-    self.size = len(data)
-    self.sha1 = sha.sha(data).hexdigest()
-
-  def WriteToTemp(self):
-    t = tempfile.NamedTemporaryFile()
-    t.write(self.data)
-    t.flush()
-    return t
-
-  def AddToZip(self, z):
-    common.ZipWriteStr(z, self.name, self.data)
 
 
 def LoadSystemFiles(z):
@@ -444,117 +424,10 @@
     if info.filename.startswith("SYSTEM/") and not IsSymlink(info):
       fn = "system/" + info.filename[7:]
       data = z.read(info.filename)
-      out[fn] = File(fn, data)
+      out[fn] = common.File(fn, data)
   return out
 
 
-DIFF_PROGRAM_BY_EXT = {
-    ".gz" : "imgdiff",
-    ".zip" : ["imgdiff", "-z"],
-    ".jar" : ["imgdiff", "-z"],
-    ".apk" : ["imgdiff", "-z"],
-    ".img" : "imgdiff",
-    }
-
-
-class Difference(object):
-  def __init__(self, tf, sf):
-    self.tf = tf
-    self.sf = sf
-    self.patch = None
-
-  def ComputePatch(self):
-    """Compute the patch (as a string of data) needed to turn sf into
-    tf.  Returns the same tuple as GetPatch()."""
-
-    tf = self.tf
-    sf = self.sf
-
-    ext = os.path.splitext(tf.name)[1]
-    diff_program = DIFF_PROGRAM_BY_EXT.get(ext, "bsdiff")
-
-    ttemp = tf.WriteToTemp()
-    stemp = sf.WriteToTemp()
-
-    ext = os.path.splitext(tf.name)[1]
-
-    try:
-      ptemp = tempfile.NamedTemporaryFile()
-      if isinstance(diff_program, list):
-        cmd = copy.copy(diff_program)
-      else:
-        cmd = [diff_program]
-      cmd.append(stemp.name)
-      cmd.append(ttemp.name)
-      cmd.append(ptemp.name)
-      p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-      _, err = p.communicate()
-      if err or p.returncode != 0:
-        print "WARNING: failure running %s:\n%s\n" % (diff_program, err)
-        return None
-      diff = ptemp.read()
-    finally:
-      ptemp.close()
-      stemp.close()
-      ttemp.close()
-
-    self.patch = diff
-    return self.tf, self.sf, self.patch
-
-
-  def GetPatch(self):
-    """Return a tuple (target_file, source_file, patch_data).
-    patch_data may be None if ComputePatch hasn't been called, or if
-    computing the patch failed."""
-    return self.tf, self.sf, self.patch
-
-
-def ComputeDifferences(diffs):
-  """Call ComputePatch on all the Difference objects in 'diffs'."""
-  print len(diffs), "diffs to compute"
-
-  # Do the largest files first, to try and reduce the long-pole effect.
-  by_size = [(i.tf.size, i) for i in diffs]
-  by_size.sort(reverse=True)
-  by_size = [i[1] for i in by_size]
-
-  lock = threading.Lock()
-  diff_iter = iter(by_size)   # accessed under lock
-
-  def worker():
-    try:
-      lock.acquire()
-      for d in diff_iter:
-        lock.release()
-        start = time.time()
-        d.ComputePatch()
-        dur = time.time() - start
-        lock.acquire()
-
-        tf, sf, patch = d.GetPatch()
-        if sf.name == tf.name:
-          name = tf.name
-        else:
-          name = "%s (%s)" % (tf.name, sf.name)
-        if patch is None:
-          print "patching failed!                                  %s" % (name,)
-        else:
-          print "%8.2f sec %8d / %8d bytes (%6.2f%%) %s" % (
-              dur, len(patch), tf.size, 100.0 * len(patch) / tf.size, name)
-      lock.release()
-    except Exception, e:
-      print e
-      raise
-
-  # start worker threads; wait for them all to finish.
-  threads = [threading.Thread(target=worker)
-             for i in range(OPTIONS.worker_threads)]
-  for th in threads:
-    th.start()
-  while threads:
-    threads.pop().join()
-
-
 def GetBuildProp(property, z):
   """Return the fingerprint of the build of a given target-files
   ZipFile object."""
@@ -567,40 +440,14 @@
   return m.group(1).strip()
 
 
-def GetRecoveryAPIVersion(zip):
-  """Returns the version of the recovery API.  Version 0 is the older
-  amend code (no separate binary)."""
-  try:
-    version = zip.read("META/recovery-api-version.txt")
-    return int(version)
-  except KeyError:
-    try:
-      # version one didn't have the recovery-api-version.txt file, but
-      # it did include an updater binary.
-      zip.getinfo("OTA/bin/updater")
-      return 1
-    except KeyError:
-      return 0
-
-
 def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
-  source_version = GetRecoveryAPIVersion(source_zip)
-  target_version = GetRecoveryAPIVersion(target_zip)
+  source_version = OPTIONS.source_info_dict["recovery_api_version"]
+  target_version = OPTIONS.target_info_dict["recovery_api_version"]
 
-  if OPTIONS.script_mode == 'amend':
-    script = amend_generator.AmendGenerator()
-  elif OPTIONS.script_mode == 'edify':
-    if source_version == 0:
-      print ("WARNING: generating edify script for a source that "
-             "can't install it.")
-    script = edify_generator.EdifyGenerator(source_version)
-  elif OPTIONS.script_mode == 'auto':
-    if source_version > 0:
-      script = edify_generator.EdifyGenerator(source_version)
-    else:
-      script = amend_generator.AmendGenerator()
-  else:
-    raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
+  if source_version == 0:
+    print ("WARNING: generating edify script for a source that "
+           "can't install it.")
+  script = edify_generator.EdifyGenerator(source_version, OPTIONS.info_dict)
 
   metadata = {"pre-device": GetBuildProp("ro.product.device", source_zip),
               "post-timestamp": GetBuildProp("ro.build.date.utc", target_zip),
@@ -613,7 +460,8 @@
       target_version=target_version,
       output_zip=output_zip,
       script=script,
-      metadata=metadata)
+      metadata=metadata,
+      info_dict=OPTIONS.info_dict)
 
   print "Loading target..."
   target_data = LoadSystemFiles(target_zip)
@@ -638,12 +486,12 @@
       verbatim_targets.append((fn, tf.size))
     elif tf.sha1 != sf.sha1:
       # File is different; consider sending as a patch
-      diffs.append(Difference(tf, sf))
+      diffs.append(common.Difference(tf, sf))
     else:
       # Target file identical to source.
       pass
 
-  ComputeDifferences(diffs)
+  common.ComputeDifferences(diffs)
 
   for diff in diffs:
     tf, sf, d = diff.GetPatch()
@@ -661,23 +509,23 @@
   metadata["pre-build"] = source_fp
   metadata["post-build"] = target_fp
 
-  script.Mount("MTD", "system", "/system")
+  script.Mount("/system")
   script.AssertSomeFingerprint(source_fp, target_fp)
 
-  source_boot = File("/tmp/boot.img",
-                     common.BuildBootableImage(
-      os.path.join(OPTIONS.source_tmp, "BOOT")))
-  target_boot = File("/tmp/boot.img",
-                     common.BuildBootableImage(
-      os.path.join(OPTIONS.target_tmp, "BOOT")))
+  source_boot = common.File("/tmp/boot.img",
+                            common.BuildBootableImage(
+                                os.path.join(OPTIONS.source_tmp, "BOOT")))
+  target_boot = common.File("/tmp/boot.img",
+                            common.BuildBootableImage(
+                                os.path.join(OPTIONS.target_tmp, "BOOT")))
   updating_boot = (source_boot.data != target_boot.data)
 
-  source_recovery = File("system/recovery.img",
-                         common.BuildBootableImage(
-      os.path.join(OPTIONS.source_tmp, "RECOVERY")))
-  target_recovery = File("system/recovery.img",
-                         common.BuildBootableImage(
-      os.path.join(OPTIONS.target_tmp, "RECOVERY")))
+  source_recovery = common.File("system/recovery.img",
+                                common.BuildBootableImage(
+                                    os.path.join(OPTIONS.source_tmp, "RECOVERY")))
+  target_recovery = common.File("system/recovery.img",
+                                common.BuildBootableImage(
+                                    os.path.join(OPTIONS.target_tmp, "RECOVERY")))
   updating_recovery = (source_recovery.data != target_recovery.data)
 
   # Here's how we divide up the progress bar:
@@ -703,15 +551,18 @@
     script.SetProgress(so_far / total_verify_size)
 
   if updating_boot:
-    d = Difference(target_boot, source_boot)
+    d = common.Difference(target_boot, source_boot)
     _, _, d = d.ComputePatch()
     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("MTD:boot:%d:%s:%d:%s" %
-                      (source_boot.size, source_boot.sha1,
+    boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict)
+
+    script.PatchCheck("%s:%s:%d:%s:%d:%s" %
+                      (boot_type, boot_device,
+                       source_boot.size, source_boot.sha1,
                        target_boot.size, target_boot.sha1))
     so_far += source_boot.size
     script.SetProgress(so_far / total_verify_size)
@@ -725,7 +576,7 @@
 
   if OPTIONS.wipe_user_data:
     script.Print("Erasing user data...")
-    script.FormatPartition("userdata")
+    script.FormatPartition("/data")
 
   script.Print("Removing unneeded files...")
   script.DeleteFiles(["/"+i[0] for i in verbatim_targets] +
@@ -750,8 +601,9 @@
     # contents of the boot partition, and write it back to the
     # partition.
     script.Print("Patching boot image...")
-    script.ApplyPatch("MTD:boot:%d:%s:%d:%s"
-                      % (source_boot.size, source_boot.sha1,
+    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,
@@ -856,8 +708,6 @@
       OPTIONS.omit_prereq = True
     elif o in ("-e", "--extra_script"):
       OPTIONS.extra_script = a
-    elif o in ("-m", "--script_mode"):
-      OPTIONS.script_mode = a
     elif o in ("--worker_threads"):
       OPTIONS.worker_threads = int(a)
     else:
@@ -865,14 +715,13 @@
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:k:i:d:wne:m:",
+                             extra_opts="b:k:i:d:wne:",
                              extra_long_opts=["board_config=",
                                               "package_key=",
                                               "incremental_from=",
                                               "wipe_user_data",
                                               "no_prereq",
                                               "extra_script=",
-                                              "script_mode=",
                                               "worker_threads="],
                              extra_option_handler=option_handler)
 
@@ -880,41 +729,25 @@
     common.Usage(__doc__)
     sys.exit(1)
 
-  if OPTIONS.script_mode not in ("amend", "edify", "auto"):
-    raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
-
   if OPTIONS.extra_script is not None:
     OPTIONS.extra_script = open(OPTIONS.extra_script).read()
 
   print "unzipping target target-files..."
   OPTIONS.input_tmp = common.UnzipTemp(args[0])
 
-  if OPTIONS.device_specific is None:
-    # look for the device-specific tools extension location in the input
-    try:
-      f = open(os.path.join(OPTIONS.input_tmp, "META", "tool-extensions.txt"))
-      ds = f.read().strip()
-      f.close()
-      if ds:
-        ds = os.path.normpath(ds)
-        print "using device-specific extensions in", ds
-        OPTIONS.device_specific = ds
-    except IOError, e:
-      if e.errno == errno.ENOENT:
-        # nothing specified in the file
-        pass
-      else:
-        raise
-
-  common.LoadMaxSizes()
-  if not OPTIONS.max_image_size:
-    print
-    print "  WARNING:  Failed to load max image sizes; will not enforce"
-    print "  image size limits."
-    print
-
   OPTIONS.target_tmp = OPTIONS.input_tmp
   input_zip = zipfile.ZipFile(args[0], "r")
+  OPTIONS.info_dict = common.LoadInfoDict(input_zip)
+  if OPTIONS.verbose:
+    print "--- target info ---"
+    common.DumpInfoDict(OPTIONS.info_dict)
+
+  if OPTIONS.device_specific is None:
+    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
+
   if OPTIONS.package_key:
     temp_zip_file = tempfile.NamedTemporaryFile()
     output_zip = zipfile.ZipFile(temp_zip_file, "w",
@@ -929,6 +762,11 @@
     print "unzipping source target-files..."
     OPTIONS.source_tmp = common.UnzipTemp(OPTIONS.incremental_source)
     source_zip = zipfile.ZipFile(OPTIONS.incremental_source, "r")
+    OPTIONS.target_info_dict = OPTIONS.info_dict
+    OPTIONS.source_info_dict = common.LoadInfoDict(source_zip)
+    if OPTIONS.verbose:
+      print "--- source info ---"
+      common.DumpInfoDict(OPTIONS.source_info_dict)
     WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
 
   output_zip.close()
diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java
index 3244a49..c4d73c8 100644
--- a/tools/signapk/SignApk.java
+++ b/tools/signapk/SignApk.java
@@ -220,10 +220,12 @@
     /** Write to another stream and also feed it to the Signature object. */
     private static class SignatureOutputStream extends FilterOutputStream {
         private Signature mSignature;
+        private int mCount;
 
         public SignatureOutputStream(OutputStream out, Signature sig) {
             super(out);
             mSignature = sig;
+            mCount = 0;
         }
 
         @Override
@@ -234,6 +236,7 @@
                 throw new IOException("SignatureException: " + e);
             }
             super.write(b);
+            mCount++;
         }
 
         @Override
@@ -244,11 +247,16 @@
                 throw new IOException("SignatureException: " + e);
             }
             super.write(b, off, len);
+            mCount += len;
+        }
+
+        public int size() {
+            return mCount;
         }
     }
 
     /** Write a .SF file with a digest of the specified manifest. */
-    private static void writeSignatureFile(Manifest manifest, OutputStream out)
+    private static void writeSignatureFile(Manifest manifest, SignatureOutputStream out)
             throws IOException, GeneralSecurityException {
         Manifest sf = new Manifest();
         Attributes main = sf.getMainAttributes();
@@ -282,6 +290,15 @@
         }
 
         sf.write(out);
+
+        // A bug in the java.util.jar implementation of Android platforms
+        // up to version 1.6 will cause a spurious IOException to be thrown
+        // if the length of the signature file is a multiple of 1024 bytes.
+        // As a workaround, add an extra CRLF in this case.
+        if ((out.size() % 1024) == 0) {
+            out.write('\r');
+            out.write('\n');
+        }
     }
 
     /** Write a .RSA file with a digital signature. */
diff --git a/tools/soslim/main.c b/tools/soslim/main.c
index fa5a315..dd8a60b 100644
--- a/tools/soslim/main.c
+++ b/tools/soslim/main.c
@@ -337,7 +337,7 @@
                             section_name = "(undefined)";
                         }
                         /* value size binding type section symname */
-                        PRINT("%-15s %8d: %08llx %08llx %c%c %5d %n%s%n",
+                        PRINT("%-15s %8zd: %08llx %08llx %c%c %5d %n%s%n",
                               file,
                               index,
                               sym->st_value, sym->st_size, bind, type,
diff --git a/tools/soslim/prelink_info.c b/tools/soslim/prelink_info.c
index 36516b1..81d5de3 100644
--- a/tools/soslim/prelink_info.c
+++ b/tools/soslim/prelink_info.c
@@ -14,13 +14,13 @@
 typedef struct {
 	uint32_t mmap_addr;
 	char tag[4]; /* 'P', 'R', 'E', ' ' */
-} prelink_info_t __attribute__((packed));
+} __attribute__((packed)) prelink_info_t;
 
 static inline void set_prelink(long *prelink_addr, 
 							   int elf_little,
 							   prelink_info_t *info)
 {
-    FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %d!\n", sizeof(prelink_info_t));
+    FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %zd!\n", sizeof(prelink_info_t));
 	if (prelink_addr) {
 		if (!(elf_little ^ is_host_little())) {
 			/* Same endianness */
@@ -35,11 +35,14 @@
 
 int check_prelinked(const char *fname, int elf_little, long *prelink_addr)
 {
-    FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %d!\n", sizeof(prelink_info_t));
+    FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %zd!\n", sizeof(prelink_info_t));
 	int fd = open(fname, O_RDONLY);
 	FAILIF(fd < 0, "open(%s, O_RDONLY): %s (%d)!\n",
 		   fname, strerror(errno), errno);
 	off_t end = lseek(fd, 0, SEEK_END);
+#ifndef DEBUG
+	(void)end;
+#endif
 
     int nr = sizeof(prelink_info_t);
 
@@ -50,14 +53,14 @@
 		   fd, strerror(errno), errno);
 
 	prelink_info_t info;
-	int num_read = read(fd, &info, nr);
+	ssize_t num_read = read(fd, &info, nr);
 	FAILIF(num_read < 0, 
 		   "read(%d, &info, sizeof(prelink_info_t)): %s (%d)!\n",
 		   fd, strerror(errno), errno);
-	FAILIF(num_read != sizeof(info),
-		   "read(%d, &info, sizeof(prelink_info_t)): did not read %d bytes as "
-		   "expected (read %d)!\n",
-		   fd, sizeof(info), num_read);
+	FAILIF((size_t)num_read != sizeof(info),
+		   "read(%d, &info, sizeof(prelink_info_t)): did not read %zd bytes as "
+		   "expected (read %zd)!\n",
+		   fd, sizeof(info), (size_t)num_read);
 
 	int prelinked = 0;
 	if (!strncmp(info.tag, "PRE ", 4)) {
@@ -70,7 +73,7 @@
 
 void setup_prelink_info(const char *fname, int elf_little, long base)
 {
-    FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %d!\n", sizeof(prelink_info_t));
+    FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %zd!\n", sizeof(prelink_info_t));
     int fd = open(fname, O_WRONLY);
     FAILIF(fd < 0, 
            "open(%s, O_WRONLY): %s (%d)\n" ,
@@ -93,13 +96,13 @@
     }
     strncpy(info.tag, "PRE ", 4);
 
-    int num_written = write(fd, &info, sizeof(info));
+    ssize_t num_written = write(fd, &info, sizeof(info));
     FAILIF(num_written < 0, 
            "write(%d, &info, sizeof(info)): %s (%d)\n",
            fd, strerror(errno), errno);
-    FAILIF(sizeof(info) != num_written, 
-           "Could not write %d bytes (wrote only %d bytes) as expected!\n",
-           sizeof(info), num_written);
+    FAILIF(sizeof(info) != (size_t)num_written,
+           "Could not write %zd bytes (wrote only %zd bytes) as expected!\n",
+           sizeof(info), (size_t)num_written);
     FAILIF(close(fd) < 0, "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
 }
 
diff --git a/tools/soslim/soslim.c b/tools/soslim/soslim.c
index d32e247..125e29e 100644
--- a/tools/soslim/soslim.c
+++ b/tools/soslim/soslim.c
@@ -42,7 +42,7 @@
     int dynsym_idx = -1; /* index in shdr_info[] of dynamic symbol table
                             section */
 
-    int cnt;	  /* general-purpose counter */
+    unsigned int cnt;	  /* general-purpose counter */
     /* This flag is true when at least one section is dropped or when the
        relative order of sections has changed, so that section indices in
        the resulting file will be different from those in the original. */
@@ -51,7 +51,7 @@
 	size_t idx;	  /* general-purporse section index */
 
 	shdr_info_t *shdr_info = NULL;
-    int shdr_info_len = 0;
+    unsigned int shdr_info_len = 0;
     GElf_Phdr *phdr_info = NULL;
 
 	/* Get the information from the old file. */
@@ -95,7 +95,7 @@
 
 	/* Get the number of sections. */
 	FAILIF_LIBELF(elf_getshnum (elf, &shnum) < 0, elf_getshnum);
-	INFO("Original ELF file has %d sections.\n", shnum);
+	INFO("Original ELF file has %zd sections.\n", shnum);
 
 	/* Allocate the section-header-info buffer.  We allocate one more entry
        for the section-strings section because we regenerate that one and
@@ -104,7 +104,7 @@
        one more section the header.  We just mark the old section for removal
        and create one as the last section.
     */
-	INFO("Allocating section-header info structure (%d) bytes...\n",
+	INFO("Allocating section-header info structure (%zd) bytes...\n",
 		 shnum*sizeof (shdr_info_t));
     shdr_info_len = rebuild_shstrtab ? shnum + 1 : shnum;
 	shdr_info = (shdr_info_t *)CALLOC(shdr_info_len, sizeof (shdr_info_t));
@@ -305,9 +305,9 @@
 
               /* Check the length of the dynamic-symbol filter. */
               FAILIF(sym_filter != NULL &&
-                     num_symbols != symdata->d_size / elsize,
+                     (size_t)num_symbols != symdata->d_size / elsize,
                      "Length of dynsym filter (%d) must equal the number"
-                     " of dynamic symbols (%d)!\n",
+                     " of dynamic symbols (%zd)!\n",
                      num_symbols,
                      symdata->d_size / elsize);
 
@@ -443,14 +443,14 @@
 			shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
 
 			INFO("\tsection [%s]  (old offset %lld, old size %lld) will have index %d "
-				 "(was %d).\n",
+				 "(was %zd).\n",
 				 shdr_info[cnt].name,
 				 shdr_info[cnt].old_shdr.sh_offset,
 				 shdr_info[cnt].old_shdr.sh_size,
 				 shdr_info[cnt].idx,
 				 elf_ndxscn(shdr_info[cnt].scn));
 		} else {
-			INFO("\tIgnoring section [%s] (offset %lld, size %lld, index %d), "
+			INFO("\tIgnoring section [%s] (offset %lld, size %lld, index %zd), "
 				 "it will be discarded.\n",
 				 shdr_info[cnt].name,
 				 shdr_info[cnt].shdr.sh_offset,
diff --git a/tools/soslim/symfilter.c b/tools/soslim/symfilter.c
index c21ab2e..b59e68a 100644
--- a/tools/soslim/symfilter.c
+++ b/tools/soslim/symfilter.c
@@ -38,9 +38,9 @@
            strerror(errno),
            errno);
 
-    INFO("Symbol-filter file %s is %ld bytes long...\n", 
+    INFO("Symbol-filter file %s is %zd bytes long...\n",
          name,
-         fsize);
+         (size_t)fsize);
     filter->fsize = fsize;
 
     /* mmap the symbols file */
@@ -48,8 +48,8 @@
                         PROT_READ | PROT_WRITE, MAP_PRIVATE, 
                         filter->fd, 0);
     FAILIF(MAP_FAILED == filter->mmap, 
-           "mmap(NULL, %ld, PROT_READ, MAP_PRIVATE, %d, 0): %s (%d)\n",
-           fsize,
+           "mmap(NULL, %zd, PROT_READ, MAP_PRIVATE, %d, 0): %s (%d)\n",
+           (size_t)fsize,
            filter->fd,
            strerror(errno),
            errno);
@@ -202,6 +202,8 @@
 
 static int match_hash_table_section(Elf *elf, Elf_Scn *sect, void *data)
 {
+    (void)elf; // unused argument
+
     symfilter_t *filter = (symfilter_t *)data;
     Elf32_Shdr *shdr;
 
@@ -224,6 +226,8 @@
 
 static int match_dynsym_section(Elf *elf, Elf_Scn *sect, void *data)
 {
+    (void)elf; // unused argument
+
     symfilter_t *filter = (symfilter_t *)data;
     Elf32_Shdr *shdr;