merge from open-source master

Change-Id: I058f809f7e7eb69a757cb75f934a3630dfd7d777
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/cleanspec.mk b/CleanSpec.mk
similarity index 80%
copy from cleanspec.mk
copy to CleanSpec.mk
index b40b5f2..b84e1b6 100644
--- a/cleanspec.mk
+++ b/CleanSpec.mk
@@ -13,17 +13,6 @@
 # limitations under the License.
 #
 
-# Just bump this if you want to force a clean build.
-# **********************************************************************
-# WHEN DOING SO, DELETE ANY "add-clean-step" ENTRIES THAT HAVE PILED UP.
-# **********************************************************************
-#
-INTERNAL_CLEAN_BUILD_VERSION := 4
-#
-# ***********************************************************************
-# Do not touch INTERNAL_CLEAN_BUILD_VERSION if you've added a clean step!
-# ***********************************************************************
-
 # If you don't need to do a full clean build but would like to touch
 # a file or delete some intermediate files, add a clean step to the end
 # of the list.  These steps will only be run once, if they haven't been
diff --git a/core/Makefile b/core/Makefile
index 46f5311..9cb8c82 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -14,12 +14,15 @@
 # PRODUCT_COPY_FILES contains words like <source file>:<dest file>.
 # <dest file> is relative to $(PRODUCT_OUT), so it should look like,
 # e.g., "system/etc/file.xml".
+# The filter part means "only eval the copy-one-file rule if this
+# src:dest pair is the first one to match %:dest"
 $(foreach cf,$(PRODUCT_COPY_FILES), \
   $(eval _src := $(call word-colon,1,$(cf))) \
-  $(eval _dest := $(call \
-          append-path,$(PRODUCT_OUT),$(call word-colon,2,$(cf)))) \
-  $(eval $(call copy-one-file,$(_src),$(_dest))) \
-  $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_dest)) \
+  $(eval _dest := $(call word-colon,2,$(cf))) \
+  $(eval _fulldest := $(call append-path,$(PRODUCT_OUT),$(_dest))) \
+  $(if $(filter $(_src):$(_dest),$(firstword $(filter %:$(_dest),$(PRODUCT_COPY_FILES)))), \
+    $(eval $(call copy-one-file,$(_src),$(_fulldest))),) \
+  $(eval ALL_DEFAULT_INSTALLED_MODULES += $(_fulldest)) \
  )
 
 # -----------------------------------------------------------------
@@ -208,8 +211,11 @@
 	@mkdir -p $(dir $@)
 	@rm -f $@
 	$(hide) $(foreach p,$(PACKAGES),\
-	  echo 'name="$(p).apk" certificate="$(PACKAGES.$(p).CERTIFICATE)" \
-	       private_key="$(PACKAGES.$(p).PRIVATE_KEY)"' >> $@;)
+          $(if $(PACKAGES.$(p).EXTERNAL_KEY),\
+	    echo 'name="$(p).apk" certificate="EXTERNAL" \
+	         private_key=""' >> $@;,\
+	    echo 'name="$(p).apk" certificate="$(PACKAGES.$(p).CERTIFICATE)" \
+	         private_key="$(PACKAGES.$(p).PRIVATE_KEY)"' >> $@;))
 
 .PHONY: apkcerts-list
 apkcerts-list: $(APKCERTS_FILE)
@@ -242,6 +248,29 @@
 .PHONY: systemimage
 systemimage:
 
+# -----------------------------------------------------------------
+
+.PHONY: event-log-tags
+
+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 := \
+    $(sort $(foreach m,\
+      $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES) \
+      $(call module-names-for-tag-list,user), \
+      $(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)
+	$(hide) mkdir -p $(dir $@)
+	$(hide) build/tools/merge-event-log-tags.py -o $@ $(PRIVATE_SRC_FILES)
+
+event-log-tags: $(event_log_tags_file)
+
+ALL_DEFAULT_INSTALLED_MODULES += $(event_log_tags_file)
+
 ifneq ($(TARGET_SIMULATOR),true)
 
 # #################################################################
@@ -588,6 +617,13 @@
 .PHONY: recoveryimage
 recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET)
 
+ifneq ($(BOARD_NAND_PAGE_SIZE),)
+mkyaffs2_extra_flags := -c $(BOARD_NAND_PAGE_SIZE)
+else
+mkyaffs2_extra_flags :=
+endif
+
+
 # -----------------------------------------------------------------
 # system yaffs image
 #
@@ -619,7 +655,7 @@
 define build-systemimage-target
     @echo "Target system fs image: $(1)"
     @mkdir -p $(dir $(1))
-    $(hide) $(MKYAFFS2) -f $(TARGET_OUT) $(1)
+    $(hide) $(MKYAFFS2) -f $(mkyaffs2_extra_flags) $(TARGET_OUT) $(1)
 endef
 endif # TARGET_USERIMAGES_USE_EXT2
 
@@ -719,7 +755,7 @@
 define build-userdataimage-target
     $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
     @mkdir -p $(TARGET_OUT_DATA)
-    $(hide) $(MKYAFFS2) -f $(TARGET_OUT_DATA) $(INSTALLED_USERDATAIMAGE_TARGET)
+    $(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
@@ -833,6 +869,7 @@
 		$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
 		$(built_ota_tools) \
 		$(APKCERTS_FILE) \
+		$(HOST_OUT_EXECUTABLES)/fs_config \
 		| $(ACP)
 	@echo "Package target files: $@"
 	$(hide) rm -rf $@ $(zip_root)
@@ -898,6 +935,10 @@
 	$(hide) echo "$(tool_extensions)" > $(zip_root)/META/tool-extensions.txt
 	@# 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
+	$(hide) zipinfo -1 $@ | awk -F/ 'BEGIN { OFS="/" } /^SYSTEM\// {$$1 = "system"; print}' | $(HOST_OUT_EXECUTABLES)/fs_config > $(zip_root)/META/filesystem_config.txt
+	$(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/filesystem_config.txt)
+
 
 target-files-package: $(BUILT_TARGET_FILES_PACKAGE)
 
@@ -906,8 +947,7 @@
 
 ifneq ($(TARGET_SIMULATOR),true)
 ifneq ($(TARGET_PRODUCT),sdk)
-ifneq ($(TARGET_PRODUCT),generic)
-ifneq ($(TARGET_PRODUCT),aosp_emulator_us)
+ifneq ($(TARGET_DEVICE),generic)
 
 name := $(TARGET_PRODUCT)
 ifeq ($(TARGET_BUILD_TYPE),debug)
@@ -937,8 +977,7 @@
 .PHONY: otapackage
 otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
 
-endif    # TARGET_PRODUCT != aosp_emulator_us
-endif    # TARGET_PRODUCT != generic
+endif    # TARGET_DEVICE != generic
 endif    # TARGET_PRODUCT != sdk
 endif    # TARGET_SIMULATOR != true
 
@@ -1156,10 +1195,12 @@
 	$(target_notice_file_txt) \
 	$(tools_notice_file_txt) \
 	$(OUT_DOCS)/offline-sdk-timestamp \
+	$(SYMBOLS_ZIP) \
 	$(INSTALLED_SYSTEMIMAGE) \
 	$(INSTALLED_USERDATAIMAGE_TARGET) \
 	$(INSTALLED_RAMDISK_TARGET) \
 	$(INSTALLED_SDK_BUILD_PROP_TARGET) \
+	$(INSTALLED_BUILD_PROP_TARGET) \
 	$(ATREE_FILES) \
 	$(atree_dir)/sdk.atree \
 	$(HOST_OUT_EXECUTABLES)/atree \
@@ -1205,6 +1246,15 @@
 		cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME) \
 	) || ( rm -rf $(PRIVATE_DIR) $@ && exit 44 )
 
+
+# Is a Windows SDK requested? If so, we need some definitions from here
+# in order to find the Linux SDK used to create the Windows one.
+ifneq ($(filter win_sdk,$(MAKECMDGOALS)),)
+LINUX_SDK_NAME := $(sdk_name)
+LINUX_SDK_DIR  := $(sdk_dir)
+include $(TOPDIR)development/build/tools/windows_sdk.mk
+endif
+
 endif # !simulator
 
 # -----------------------------------------------------------------
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 64b74e7..3f343e2 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -62,6 +62,13 @@
 #$(warning default tags: $(lastword $(filter-out config/% out/%,$(MAKEFILE_LIST))))
 endif
 
+# Only the tags mentioned in this test are expected to be set by module
+# makefiles. Anything else is either a typo or a source of unexpected
+# behaviors.
+ifneq ($(filter-out user debug eng tests optional samples,$(LOCAL_MODULE_TAGS)),)
+$(warning unusual tags $(LOCAL_MODULE_TAGS) on $(LOCAL_MODULE) at $(LOCAL_PATH))
+endif
+
 # Add implicit tags.
 #
 # If the local directory or one of its parents contains a MODULE_LICENSE_GPL
@@ -94,9 +101,13 @@
   $(error $(LOCAL_PATH): LOCAL_MODULE_CLASS must contain exactly one word, not "$(LOCAL_MODULE_CLASS)")
 endif
 
-# Add a tag like "_class@APPS" to this module so that we can filter
-# based on the class.
-LOCAL_MODULE_TAGS += _class@$(LOCAL_MODULE_CLASS)
+# Those used to be implicitly ignored, but aren't any more.
+# As of 20100110 there are no apps with the user tag.
+ifeq ($(LOCAL_MODULE_CLASS),APPS)
+  ifneq ($(filter $(LOCAL_MODULE_TAGS),user),)
+    $(warning user tag on app $(LOCAL_MODULE) at $(LOCAL_PATH) - add your app to core.mk instead)
+  endif
+endif
 
 LOCAL_MODULE_PATH := $(strip $(LOCAL_MODULE_PATH))
 ifeq ($(LOCAL_MODULE_PATH),)
@@ -175,9 +186,18 @@
 aidl_java_sources := $(patsubst %.aidl,%.java,$(addprefix $(intermediates.COMMON)/src/, $(aidl_sources)))
 aidl_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(aidl_sources))
 
-$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES))
+aidl_preprocess_import :=
+LOCAL_SDK_VERSION:=$(strip $(LOCAL_SDK_VERSION))
+ifdef LOCAL_SDK_VERSION
+ifeq ($(LOCAL_SDK_VERSION),current)
+  aidl_preprocess_import := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
+else
+  aidl_preprocess_import := $(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_VERSION)/framework.aidl
+endif # !current
+endif # LOCAL_SDK_VERSION
+$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b $(addprefix -p,$(aidl_preprocess_import)) -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES))
 
-$(aidl_java_sources): $(intermediates.COMMON)/src/%.java: $(TOPDIR)$(LOCAL_PATH)/%.aidl $(PRIVATE_ADDITIONAL_DEPENDENCIES) $(AIDL)
+$(aidl_java_sources): $(intermediates.COMMON)/src/%.java: $(TOPDIR)$(LOCAL_PATH)/%.aidl $(PRIVATE_ADDITIONAL_DEPENDENCIES) $(AIDL) $(aidl_preprocess_import)
 	$(transform-aidl-to-java)
 -include $(aidl_java_sources:%.java=%.P)
 
@@ -186,11 +206,39 @@
 endif
 
 ###########################################################
+## logtags: Add .logtags files to global list, emit java source
+###########################################################
+
+logtags_sources := $(filter %.logtags,$(LOCAL_SRC_FILES))
+
+ifneq ($(strip $(logtags_sources)),)
+
+event_log_tags := $(addprefix $(LOCAL_PATH)/,$(logtags_sources))
+
+# Emit a java source file with constants for the tags, if
+# LOCAL_MODULE_CLASS is "APPS" or "JAVA_LIBRARIES".
+ifneq ($(strip $(filter $(LOCAL_MODULE_CLASS),APPS JAVA_LIBRARIES)),)
+
+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
+	$(transform-logtags-to-java)
+
+endif
+
+else
+logtags_java_sources :=
+event_log_tags :=
+endif
+
+###########################################################
 ## Java: Compile .java files to .class
 ###########################################################
 #TODO: pull this into java.make once host and target are combined
 
-java_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(filter %.java,$(LOCAL_SRC_FILES))) $(aidl_java_sources)
+java_sources := $(addprefix $(TOP_DIR)$(LOCAL_PATH)/, $(filter %.java,$(LOCAL_SRC_FILES))) $(aidl_java_sources) $(logtags_java_sources) \
+                $(filter %.java,$(LOCAL_GENERATED_SOURCES))
 all_java_sources := $(java_sources) $(addprefix $($(my_prefix)OUT_COMMON_INTERMEDIATES)/, $(filter %.java,$(LOCAL_INTERMEDIATE_SOURCES)))
 
 ## Java resources #########################################
@@ -274,8 +322,14 @@
 ifeq ($(my_prefix),TARGET_)
 ifeq ($(LOCAL_SDK_VERSION),)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,core)
-endif
-endif
+else
+ifeq ($(LOCAL_SDK_VERSION),current)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,android_stubs_current)
+else
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,sdk_v$(LOCAL_SDK_VERSION))
+endif # current
+endif # LOCAL_SDK_VERSION
+endif # TARGET_
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
@@ -292,9 +346,21 @@
 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))
+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
+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)
 
@@ -313,7 +379,8 @@
   link_instr_intermediates_dir.COMMON := $(call intermediates-dir-for, \
       APPS,$(LOCAL_INSTRUMENTATION_FOR),,COMMON)
 
-  full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes.jar
+  # 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.
@@ -352,6 +419,8 @@
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_POST_PROCESS_COMMAND:= $(LOCAL_POST_PROCESS_COMMAND)
 $(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_ALL_JAVA_LIBRARIES:= $(full_java_libs)
 $(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_IS_HOST_MODULE := $(LOCAL_IS_HOST_MODULE)
@@ -402,7 +471,9 @@
 # checked modules, use LOCAL_BUILT_MODULE.  This was old
 # behavior, so it should be a safe default.
 ifndef LOCAL_CHECKED_MODULE
-  LOCAL_CHECKED_MODULE := $(LOCAL_BUILT_MODULE)
+  ifndef LOCAL_SDK_VERSION
+    LOCAL_CHECKED_MODULE := $(LOCAL_BUILT_MODULE)
+  endif
 endif
 
 # If they request that this module not be checked, then don't.
@@ -432,6 +503,8 @@
     $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(LOCAL_INSTALLED_MODULE)
 ALL_MODULES.$(LOCAL_MODULE).REQUIRED := \
     $(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)
 
 ###########################################################
 ## Take care of LOCAL_MODULE_TAGS
diff --git a/core/binary.mk b/core/binary.mk
index 4413d47..d5528b1 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -9,6 +9,15 @@
 include $(BUILD_SYSTEM)/base_rules.mk
 #######################################
 
+####################################################
+## Add FDO flags if FDO is turned on and supported
+####################################################
+ifeq ($(strip $(LOCAL_NO_FDO_SUPPORT)),)
+  LOCAL_CFLAGS += $(TARGET_FDO_CFLAGS)
+  LOCAL_CPPFLAGS += $(TARGET_FDO_CFLAGS)
+  LOCAL_LDFLAGS += $(TARGET_FDO_CFLAGS)
+endif
+
 ###########################################################
 ## Define PRIVATE_ variables used by multiple module types
 ###########################################################
diff --git a/core/build-system.html b/core/build-system.html
index 43bae03..ce5e869 100644
--- a/core/build-system.html
+++ b/core/build-system.html
@@ -704,6 +704,11 @@
 See the <a href="#custom-tools">Custom Tools</a> template makefile for an
 example.</p>
 
+<h4>LOCAL_JAVACFLAGS</h4>
+<p>If you have additional flags to pass into the javac compiler, add
+them here.  For example:</p>
+<p><code>LOCAL_JAVACFLAGS += -Xlint:deprecation</code></p>
+
 <h4>LOCAL_JAVA_LIBRARIES</h4>
 <p>When linking Java apps and libraries, <code>LOCAL_JAVA_LIBRARIES</code>
 specifies which sets of java classes to include.  Currently there are
diff --git a/core/build_id.mk b/core/build_id.mk
index 4661aea..40bb35d 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -23,7 +23,7 @@
 # (like "TC1-RC5").  It must be a single word, and is
 # capitalized by convention.
 #
-BUILD_ID := ECLAIR
+BUILD_ID := MASTER
 
 # DISPLAY_BUILD_NUMBER should only be set for development branches,
 # If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index a753554..7e68d6f 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -16,28 +16,40 @@
 INTERNAL_CLEAN_STEPS :=
 
 # Builds up a list of clean steps.  Creates a unique
-# id for each step by taking INTERNAL_CLEAN_BUILD_VERSION
+# id for each step by taking makefile path, INTERNAL_CLEAN_BUILD_VERSION
 # and appending an increasing number of '@' characters.
 #
 # $(1): shell command to run
+# $(2): indicate to not use makefile path as part of step id if not empty.
+#       $(2) should only be used in build/core/cleanspec.mk: just for compatibility.
 define _add-clean-step
   $(if $(strip $(INTERNAL_CLEAN_BUILD_VERSION)),, \
       $(error INTERNAL_CLEAN_BUILD_VERSION not set))
-  $(eval _acs_id := $(strip $(lastword $(INTERNAL_CLEAN_STEPS))))
-  $(if $(_acs_id),,$(eval _acs_id := $(INTERNAL_CLEAN_BUILD_VERSION)))
-  $(eval _acs_id := $(_acs_id)@)
+  $(eval _acs_makefile_prefix := $(lastword $(MAKEFILE_LIST)))
+  $(eval _acs_makefile_prefix := $(subst /,_,$(_acs_makefile_prefix)))
+  $(eval _acs_makefile_prefix := $(subst .,-,$(_acs_makefile_prefix)))
+  $(eval _acs_makefile_prefix := $(_acs_makefile_prefix)_acs)
+  $(if $($(_acs_makefile_prefix)),,\
+      $(eval $(_acs_makefile_prefix) := $(INTERNAL_CLEAN_BUILD_VERSION)))
+  $(eval $(_acs_makefile_prefix) := $($(_acs_makefile_prefix))@)
+  $(if $(strip $(2)),$(eval _acs_id := $($(_acs_makefile_prefix))),\
+      $(eval _acs_id := $(_acs_makefile_prefix)$($(_acs_makefile_prefix))))
   $(eval INTERNAL_CLEAN_STEPS += $(_acs_id))
   $(eval INTERNAL_CLEAN_STEP.$(_acs_id) := $(1))
   $(eval _acs_id :=)
+  $(eval _acs_makefile_prefix :=)
 endef
 define add-clean-step
-$(if $(call _add-clean-step,$(1)),)
+$(eval # for build/core/cleanspec.mk, dont use makefile path as part of step id) \
+$(if $(filter %/cleanspec.mk,$(lastword $(MAKEFILE_LIST))),\
+    $(eval $(call _add-clean-step,$(1),true)),\
+    $(eval $(call _add-clean-step,$(1))))
 endef
 
 # Defines INTERNAL_CLEAN_BUILD_VERSION and the individual clean steps.
 # cleanspec.mk is outside of the core directory so that more people
 # can have permission to touch it.
-include build/cleanspec.mk
+include $(BUILD_SYSTEM)/cleanspec.mk
 INTERNAL_CLEAN_BUILD_VERSION := $(strip $(INTERNAL_CLEAN_BUILD_VERSION))
 
 # If the clean_steps.mk file is missing (usually after a clean build)
diff --git a/cleanspec.mk b/core/cleanspec.mk
similarity index 87%
rename from cleanspec.mk
rename to core/cleanspec.mk
index b40b5f2..c85c450 100644
--- a/cleanspec.mk
+++ b/core/cleanspec.mk
@@ -15,7 +15,11 @@
 
 # Just bump this if you want to force a clean build.
 # **********************************************************************
-# WHEN DOING SO, DELETE ANY "add-clean-step" ENTRIES THAT HAVE PILED UP.
+# WHEN DOING SO
+# 1. DELETE ANY "add-clean-step" ENTRIES THAT HAVE PILED UP IN THIS FILE.
+# 2. REMOVE ALL FILES NAMED CleanSpec.mk.
+# 3. BUMP THE VERSION.
+# IDEALLY, THOSE STEPS SHOULD BE DONE ATOMICALLY.
 # **********************************************************************
 #
 INTERNAL_CLEAN_BUILD_VERSION := 4
@@ -58,3 +62,8 @@
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
+
+subdir_cleanspecs := \
+    $(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git . CleanSpec.mk)
+include $(subdir_cleanspecs)
+subdir_cleanspecs :=
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index a7eba3f..0fe3c8b 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -19,6 +19,7 @@
 LOCAL_PACKAGE_NAME:=
 LOCAL_OVERRIDES_PACKAGES:=
 LOCAL_EXPORT_PACKAGE_RESOURCES:=
+LOCAL_MANIFEST_PACKAGE_NAME:=
 LOCAL_REQUIRED_MODULES:=
 LOCAL_ACP_UNAVAILABLE:=
 LOCAL_MODULE_TAGS:=
@@ -33,6 +34,7 @@
 LOCAL_CXX:=
 LOCAL_CPP_EXTENSION:=
 LOCAL_NO_DEFAULT_COMPILER_FLAGS:=
+LOCAL_NO_FDO_SUPPORT :=
 LOCAL_ARM_MODE:=
 LOCAL_YACCFLAGS:=
 LOCAL_ASFLAGS:=
@@ -49,6 +51,7 @@
 LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
 LOCAL_PREBUILT_STRIP_COMMENTS:=
 LOCAL_INTERMEDIATE_SOURCES:=
+LOCAL_JAVACFLAGS:=
 LOCAL_JAVA_LIBRARIES:=
 LOCAL_NO_STANDARD_LIBRARIES:=
 LOCAL_CLASSPATH:=
diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
new file mode 100644
index 0000000..f277ea5
--- /dev/null
+++ b/core/combo/HOST_darwin-x86.mk
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Configuration for Darwin (Mac OS X) on x86.
+# Included by combo/select.mk
+
+# We build everything in 32-bit, because some host tools are
+# 32-bit-only anyway (emulator, acc), and because it gives us
+# more consistency between the host tools and the target.
+HOST_GLOBAL_CFLAGS += -m32
+HOST_GLOBAL_LDFLAGS += -m32
+
+HOST_GLOBAL_CFLAGS += -fPIC
+HOST_NO_UNDEFINED_LDFLAGS := -Wl,-undefined,error
+
+HOST_CC := $(CC)
+HOST_CXX := $(CXX)
+HOST_AR := $(AR)
+
+HOST_SHLIB_SUFFIX := .dylib
+HOST_JNILIB_SUFFIX := .jnilib
+
+HOST_GLOBAL_CFLAGS += \
+	-include $(call select-android-config-h,darwin-x86)
+HOST_RUN_RANLIB_AFTER_COPYING := true
+HOST_GLOBAL_ARFLAGS := cqs
+
+HOST_CUSTOM_LD_COMMAND := true
+
+define transform-host-o-to-shared-lib-inner
+    $(HOST_CXX) \
+        -dynamiclib -single_module -read_only_relocs suppress \
+        $(HOST_GLOBAL_LD_DIRS) \
+        $(HOST_GLOBAL_LDFLAGS) \
+        $(PRIVATE_ALL_OBJECTS) \
+        $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+        $(PRIVATE_LDLIBS) \
+        -o $@ \
+        $(PRIVATE_LDFLAGS) \
+        $(HOST_LIBGCC)
+endef
+
+define transform-host-o-to-executable-inner
+$(HOST_CXX) \
+        -o $@ \
+        -Wl,-dynamic -headerpad_max_install_names \
+        $(HOST_GLOBAL_LD_DIRS) \
+        $(HOST_GLOBAL_LDFLAGS) \
+        $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+        $(PRIVATE_ALL_OBJECTS) \
+        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+        $(PRIVATE_LDFLAGS) \
+        $(PRIVATE_LDLIBS) \
+        $(HOST_LIBGCC)
+endef
+
+# $(1): The file to check
+define get-file-size
+stat -f "%z" $(1)
+endef
diff --git a/core/combo/HOST_linux-x86.mk b/core/combo/HOST_linux-x86.mk
new file mode 100644
index 0000000..26052d6
--- /dev/null
+++ b/core/combo/HOST_linux-x86.mk
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Configuration for builds hosted on linux-x86.
+# Included by combo/select.mk
+
+# $(1): The file to check
+define get-file-size
+stat --format "%s" "$(1)" | tr -d '\n'
+endef
+
+# We build everything in 32-bit, because some host tools are
+# 32-bit-only anyway (emulator, acc), and because it gives us
+# more consistency between the host tools and the target.
+# The exception is the host side of the simulator, which
+# requires to use the default size, as wxWidgets code otherwise
+# fails to build.
+ifneq ($(TARGET_SIMULATOR),true)
+HOST_GLOBAL_CFLAGS += -m32
+HOST_GLOBAL_LDFLAGS += -m32
+endif
+
+HOST_GLOBAL_CFLAGS += -fPIC
+HOST_GLOBAL_CFLAGS += \
+	-include $(call select-android-config-h,linux-x86)
+
+HOST_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
diff --git a/core/combo/HOST_windows-x86.mk b/core/combo/HOST_windows-x86.mk
new file mode 100644
index 0000000..9870998
--- /dev/null
+++ b/core/combo/HOST_windows-x86.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Configuration for Linux on x86.
+# Included by combo/select.make
+
+# right now we get these from the environment, but we should
+# pick them from the tree somewhere
+TOOLS_PREFIX := #prebuilt/windows/host/bin/
+TOOLS_EXE_SUFFIX := .exe
+
+# Settings to use MinGW has a cross-compiler under Linux
+ifneq ($(findstring Linux,$(UNAME)),)
+ifneq ($(strip $(USE_MINGW)),)
+HOST_ACP_UNAVAILABLE := true
+TOOLS_PREFIX := /usr/bin/i586-mingw32msvc-
+TOOLS_EXE_SUFFIX :=
+HOST_GLOBAL_CFLAGS += -DUSE_MINGW
+HOST_C_INCLUDES += /usr/lib/gcc/i586-mingw32msvc/3.4.4/include
+HOST_GLOBAL_LD_DIRS += -L/usr/i586-mingw32msvc/lib
+endif
+endif
+
+HOST_CC := $(TOOLS_PREFIX)gcc$(TOOLS_EXE_SUFFIX)
+HOST_CXX := $(TOOLS_PREFIX)g++$(TOOLS_EXE_SUFFIX)
+HOST_AR := $(TOOLS_PREFIX)ar$(TOOLS_EXE_SUFFIX)
+
+HOST_GLOBAL_CFLAGS += -include $(call select-android-config-h,windows)
+HOST_GLOBAL_LDFLAGS += --enable-stdcall-fixup
+
+# when building under Cygwin, ensure that we use Mingw compilation by default.
+# you can disable this (i.e. to generate Cygwin executables) by defining the
+# USE_CYGWIN variable in your environment, e.g.:
+#
+#   export USE_CYGWIN=1
+#
+# note that the -mno-cygwin flags are not needed when cross-compiling the
+# Windows host tools on Linux
+#
+ifneq ($(findstring CYGWIN,$(UNAME)),)
+ifeq ($(strip $(USE_CYGWIN)),)
+HOST_GLOBAL_CFLAGS += -mno-cygwin
+HOST_GLOBAL_LDFLAGS += -mno-cygwin -mconsole
+endif
+endif
+
+HOST_SHLIB_SUFFIX := .dll
+HOST_EXECUTABLE_SUFFIX := .exe
+
+# $(1): The file to check
+# TODO: find out what format cygwin's stat(1) uses
+define get-file-size
+999999999
+endef
diff --git a/core/combo/linux-arm.mk b/core/combo/TARGET_linux-arm.mk
similarity index 67%
rename from core/combo/linux-arm.mk
rename to core/combo/TARGET_linux-arm.mk
index 6011351..972b10c 100644
--- a/core/combo/linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -1,5 +1,21 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 # Configuration for Linux on ARM.
-# Included by combo/select.make
+# Included by combo/select.mk
 
 # You can set TARGET_ARCH_VARIANT to use an arch version other
 # than ARMv5TE. Each value should correspond to a file named
@@ -18,16 +34,6 @@
 TARGET_ARCH_VARIANT := armv5te
 endif
 
-# TARGET_ARCH_VARIANT used to be called TARGET_ARCH_VERSION
-# to avoid any weirdness, issue an error message if the latter
-# is defined.
-#
-ifneq ($(strip $(TARGET_ARCH_VERSION)),)
-$(info Definition for TARGET_ARCH_VERSION encountered !)
-$(info This variable has been renamed TARGET_ARCH_VARIANT, please update your build files !!)
-$(error Aborting the build.)
-endif
-
 TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
 ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
 $(error Unknown ARM architecture version: $(TARGET_ARCH_VARIANT))
@@ -36,18 +42,18 @@
 include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
-$(combo_target)TOOLS_PREFIX := \
+ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
+TARGET_TOOLS_PREFIX := \
 	prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
 endif
 
-$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)CXX := $($(combo_target)TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)AR := $($(combo_target)TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)OBJCOPY := $($(combo_target)TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)LD := $($(combo_target)TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
+TARGET_AR := $(TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
+TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
+TARGET_LD := $(TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
 
-$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
 TARGET_arm_CFLAGS :=    -O2 \
                         -fomit-frame-pointer \
@@ -86,7 +92,7 @@
 android_config_h := $(call select-android-config-h,linux-arm)
 arch_include_dir := $(dir $(android_config_h))
 
-$(combo_target)GLOBAL_CFLAGS += \
+TARGET_GLOBAL_CFLAGS += \
 			-msoft-float -fpic \
 			-ffunction-sections \
 			-funwind-tables \
@@ -96,7 +102,7 @@
 			-include $(android_config_h) \
 			-I $(arch_include_dir)
 
-$(combo_target)GLOBAL_LDFLAGS += \
+TARGET_GLOBAL_LDFLAGS += \
 			$(arch_variant_ldflags)
 
 # We only need thumb interworking in cases where thumb support
@@ -104,15 +110,15 @@
 # since sometimes thumb-interwork appears to be default), we
 # specifically disable when thumb support is unavailable.
 ifeq ($(ARCH_ARM_HAVE_THUMB_SUPPORT),true)
-$(combo_target)GLOBAL_CFLAGS +=	-mthumb-interwork
+TARGET_GLOBAL_CFLAGS +=	-mthumb-interwork
 else
-$(combo_target)GLOBAL_CFLAGS +=	-mno-thumb-interwork
+TARGET_GLOBAL_CFLAGS +=	-mno-thumb-interwork
 endif
 
-$(combo_target)GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
+TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
 
-$(combo_target)RELEASE_CFLAGS := \
-			-DSK_RELEASE -DNDEBUG \
+TARGET_RELEASE_CFLAGS := \
+			-DNDEBUG \
 			-g \
 			-Wstrict-aliasing=2 \
 			-finline-functions \
@@ -128,13 +134,44 @@
 
 
 ## on some hosts, the target cross-compiler is not available so do not run this command
-ifneq ($(wildcard $($(combo_target)CC)),)
+ifneq ($(wildcard $(TARGET_CC)),)
 # We compile with the global cflags to ensure that
 # any flags which affect libgcc are correctly taken
 # into account.
-$(combo_target)LIBGCC := $(shell $($(combo_target)CC) $($(combo_target)GLOBAL_CFLAGS) -print-libgcc-file-name)
+TARGET_LIBGCC := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) -print-libgcc-file-name)
 endif
 
+# Define FDO (Feedback Directed Optimization) options.
+
+TARGET_FDO_CFLAGS:=
+TARGET_FDO_LIB:=
+
+target_libgcov := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
+        --print-file-name=libgcov.a)
+ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
+  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
+  # The profile will be generated on /data/local/tmp/profile on the device.
+  TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
+  TARGET_FDO_LIB := $(target_libgcov)
+else
+  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
+  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
+  ifeq ($(strip $(TARGET_FDO_PROFILE_PATH)),)
+    TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT)
+  else
+    ifeq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
+      $(warning Custom TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
+    endif
+  endif
+
+  # If the FDO profile directory can't be found, then FDO is off.
+  ifneq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
+    TARGET_FDO_CFLAGS := -fprofile-use=$(TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
+    TARGET_FDO_LIB := $(target_libgcov)
+  endif
+endif
+
+
 # unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
 # symlinks located in out/ to point to the appropriate kernel
 # headers. see 'config/kernel_headers.make' for more details
@@ -148,7 +185,7 @@
 endif
 KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
 
-$(combo_target)C_INCLUDES := \
+TARGET_C_INCLUDES := \
 	$(libc_root)/arch-arm/include \
 	$(libc_root)/include \
 	$(libstdc++_root)/include \
@@ -163,9 +200,15 @@
 
 TARGET_STRIP_MODULE:=true
 
-$(combo_target)DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
 
-$(combo_target)CUSTOM_LD_COMMAND := true
+TARGET_CUSTOM_LD_COMMAND := true
+
+# Enable the Dalvik JIT compiler if not already specified.
+ifeq ($(strip $(WITH_JIT)),)
+    WITH_JIT := true
+endif
+
 define transform-o-to-shared-lib-inner
 $(TARGET_CXX) \
 	-nostdlib -Wl,-soname,$(notdir $@) -Wl,-T,$(BUILD_SYSTEM)/armelf.xsc \
@@ -181,6 +224,7 @@
 	-o $@ \
 	$(PRIVATE_LDFLAGS) \
 	$(TARGET_GLOBAL_LDFLAGS) \
+	$(TARGET_FDO_LIB) \
 	$(TARGET_LIBGCC)
 endef
 
@@ -198,6 +242,7 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(PRIVATE_LDFLAGS) \
 	$(TARGET_GLOBAL_LDFLAGS) \
+	$(TARGET_FDO_LIB) \
 	$(TARGET_LIBGCC) \
 	$(TARGET_CRTEND_O)
 endef
@@ -212,6 +257,7 @@
 	$(TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_ALL_OBJECTS) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(TARGET_FDO_LIB) \
 	$(TARGET_LIBGCC) \
 	$(TARGET_CRTEND_O)
 endef
diff --git a/core/combo/linux-sh.mk b/core/combo/TARGET_linux-sh.mk
similarity index 74%
rename from core/combo/linux-sh.mk
rename to core/combo/TARGET_linux-sh.mk
index 79cf49d..361fe2e 100644
--- a/core/combo/linux-sh.mk
+++ b/core/combo/TARGET_linux-sh.mk
@@ -1,19 +1,35 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 # Configuration for Linux on SuperH.
 # Included by combo/select.make
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
-$(combo_target)TOOLS_PREFIX := \
+ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
+TARGET_TOOLS_PREFIX := \
 	prebuilt/$(HOST_PREBUILT_TAG)/toolchain/sh-4.3.3/bin/sh-linux-gnu-
 endif
 
-$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)CXX := $($(combo_target)TOOLS_PREFIX)c++$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)AR := $($(combo_target)TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)OBJCOPY := $($(combo_target)TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)LD := $($(combo_target)TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CXX := $(TARGET_TOOLS_PREFIX)c++$(HOST_EXECUTABLE_SUFFIX)
+TARGET_AR := $(TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
+TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
+TARGET_LD := $(TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
 
-$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
 TARGET_sh_release_CFLAGS :=     -O2 \
                                 -fomit-frame-pointer \
@@ -24,18 +40,18 @@
 # When building for debug, compile everything as superh.
 TARGET_sh_debug_CFLAGS := $(TARGET_sh_release_CFLAGS) -fno-omit-frame-pointer -fno-strict-aliasing
 
-$(combo_target)GLOBAL_CFLAGS += \
+TARGET_GLOBAL_CFLAGS += \
 			-fpic \
 			-ffunction-sections \
 			-funwind-tables \
 			-fstack-protector \
 			-include $(call select-android-config-h,linux-sh)
 
-$(combo_target)GLOBAL_CPPFLAGS += \
+TARGET_GLOBAL_CPPFLAGS += \
 			-fno-use-cxa-atexit \
 			-fvisibility-inlines-hidden
 
-$(combo_target)RELEASE_CFLAGS := \
+TARGET_RELEASE_CFLAGS := \
 			-DSK_RELEASE -DNDEBUG \
 			-O2 -g \
 			-Wstrict-aliasing=2 \
@@ -53,13 +69,13 @@
 
 
 ## on some hosts, the target cross-compiler is not available so do not run this command
-ifneq ($(wildcard $($(combo_target)CC)),)
+ifneq ($(wildcard $(TARGET_CC)),)
 # We compile with the global cflags to ensure that
 # any flags which affect libgcc are correctly taken
 # into account.
-LIBGCC_FILENAME := $(shell $($(combo_target)CC) $($(combo_target)GLOBAL_CFLAGS) -print-libgcc-file-name)
+LIBGCC_FILENAME := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) -print-libgcc-file-name)
 LIBGCC_EH_FILENAME := $(subst libgcc,libgcc_eh,$(LIBGCC_FILENAME))
-$(combo_target)LIBGCC := $(LIBGCC_EH_FILENAME) $(LIBGCC_FILENAME)
+TARGET_LIBGCC := $(LIBGCC_EH_FILENAME) $(LIBGCC_FILENAME)
 endif
 
 # unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
@@ -75,7 +91,7 @@
 endif
 KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
 
-$(combo_target)C_INCLUDES := \
+TARGET_C_INCLUDES := \
 	$(libc_root)/arch-sh/include \
 	$(libc_root)/include \
 	$(libstdc++_root)/include \
@@ -92,9 +108,9 @@
 
 TARGET_STRIP_MODULE:=false
 
-$(combo_target)DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
 
-$(combo_target)CUSTOM_LD_COMMAND := true
+TARGET_CUSTOM_LD_COMMAND := true
 define transform-o-to-shared-lib-inner
 $(TARGET_CXX) \
 	-nostdlib -Wl,-soname,$(notdir $@) -Wl,-T,$(BUILD_SYSTEM)/shlelf.xsc \
diff --git a/core/combo/target_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
similarity index 60%
rename from core/combo/target_linux-x86.mk
rename to core/combo/TARGET_linux-x86.mk
index 2d359ff..cd7d4b3 100644
--- a/core/combo/target_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -1,25 +1,57 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 # Configuration for Linux on x86 as a target.
-# Included by combo/select.make
+# Included by combo/select.mk
+
+ifeq ($(TARGET_SIMULATOR),true)
+# When building for the simulator, use the HOST settings as TARGET settings
+TARGET_CC := $(HOST_CC)
+TARGET_CXX := $(HOST_CXX)
+TARGET_AR := $(HOST_AR)
+TARGET_GLOBAL_CFLAGS := $(HOST_GLOBAL_CFLAGS) -m32
+TARGET_GLOBAL_LDFLAGS := $(HOST_GLOBAL_LDFLAGS) -m32 -lpthread
+TARGET_NO_UNDEFINED_LDFLAGS := $(HOST_NO_UNDEFINED_LDFLAGS)
+TARGET_ARCH_VARIANT := x86
+else #simulator
+
+# Provide a default variant.
+ifeq ($(strip $(TARGET_ARCH_VARIANT)),)
+TARGET_ARCH_VARIANT := x86
+endif
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $($(combo_target)TOOLS_PREFIX)),)
-$(combo_target)TOOLS_PREFIX := \
+ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
+TARGET_TOOLS_PREFIX := \
 	prebuilt/$(HOST_PREBUILT_TAG)/toolchain/i686-unknown-linux-gnu-4.2.1/bin/i686-unknown-linux-gnu-
 endif
 
-$(combo_target)CC := $($(combo_target)TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)CXX := $($(combo_target)TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)AR := $($(combo_target)TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)OBJCOPY := $($(combo_target)TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-$(combo_target)LD := $($(combo_target)TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
+TARGET_AR := $(TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
+TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
+TARGET_LD := $(TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
 
-ifneq ($(wildcard $($(combo_target)CC)),)
-$(combo_target)LIBGCC := \
-	$(shell $($(combo_target)CC) -m32 -print-file-name=libgcc.a) \
-        $(shell $($(combo_target)CC) -m32 -print-file-name=libgcc_eh.a)
+ifneq ($(wildcard $(TARGET_CC)),)
+TARGET_LIBGCC := \
+	$(shell $(TARGET_CC) -m32 -print-file-name=libgcc.a) \
+        $(shell $(TARGET_CC) -m32 -print-file-name=libgcc_eh.a)
 endif
 
-$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
 libc_root := bionic/libc
 libm_root := bionic/libm
@@ -39,16 +71,16 @@
 endif
 KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
 
-$(combo_target)GLOBAL_CFLAGS += \
+TARGET_GLOBAL_CFLAGS += \
 			-march=i686 \
 			-m32 \
 			-fPIC \
 			-include $(call select-android-config-h,target_linux-x86)
 
-$(combo_target)GLOBAL_CPPFLAGS += \
+TARGET_GLOBAL_CPPFLAGS += \
 			-fno-use-cxa-atexit
 
-$(combo_target)C_INCLUDES := \
+TARGET_C_INCLUDES := \
 	$(libc_root)/arch-x86/include \
 	$(libc_root)/include \
 	$(libstdc++_root)/include \
@@ -67,9 +99,9 @@
 
 # TARGET_STRIP_MODULE:=true
 
-$(combo_target)DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
 
-$(combo_target)CUSTOM_LD_COMMAND := true
+TARGET_CUSTOM_LD_COMMAND := true
 define transform-o-to-shared-lib-inner
 $(TARGET_CXX) \
 	$(TARGET_GLOBAL_LDFLAGS) \
@@ -125,5 +157,7 @@
 	$(TARGET_CRTEND_O)
 endef
 
-$(combo_target)GLOBAL_CFLAGS += -m32
-$(combo_target)GLOBAL_LDFLAGS += -m32
+TARGET_GLOBAL_CFLAGS += -m32
+TARGET_GLOBAL_LDFLAGS += -m32
+
+endif #simulator
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
new file mode 100644
index 0000000..7b5b8ed
--- /dev/null
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -0,0 +1,24 @@
+# Configuration for Linux on ARM.
+# Generating binaries for the ARMv7-a architecture and higher with NEON
+#
+ARCH_ARM_HAVE_THUMB_SUPPORT     := true
+ARCH_ARM_HAVE_FAST_INTERWORKING := true
+ARCH_ARM_HAVE_64BIT_DATA        := true
+ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
+ARCH_ARM_HAVE_CLZ               := true
+ARCH_ARM_HAVE_FFS               := true
+ARCH_ARM_HAVE_ARMV7A            := true
+ARCH_ARM_HAVE_VFP               := true
+ARCH_ARM_HAVE_VFP_D32           := true
+ARCH_ARM_HAVE_NEON              := true
+
+# Note: Hard coding the 'tune' value here is probably not ideal,
+# and a better solution should be found in the future.
+#
+arch_variant_cflags := \
+    -march=armv7-a \
+    -mfloat-abi=softfp \
+    -mfpu=neon
+
+arch_variant_ldflags := \
+	-Wl,--fix-cortex-a8
diff --git a/core/combo/arch/arm/armv7-a.mk b/core/combo/arch/arm/armv7-a.mk
index 7a3ecc4..0ca3ec6 100644
--- a/core/combo/arch/arm/armv7-a.mk
+++ b/core/combo/arch/arm/armv7-a.mk
@@ -7,8 +7,8 @@
 ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
 ARCH_ARM_HAVE_CLZ               := true
 ARCH_ARM_HAVE_FFS               := true
+ARCH_ARM_HAVE_ARMV7A            := true
 ARCH_ARM_HAVE_VFP               := true
-ARCH_ARM_HAVE_NEON              := true
 
 # Note: Hard coding the 'tune' value here is probably not ideal,
 # and a better solution should be found in the future.
@@ -16,7 +16,7 @@
 arch_variant_cflags := \
     -march=armv7-a \
     -mfloat-abi=softfp \
-    -mfpu=neon
+    -mfpu=vfpv3-d16
 
 arch_variant_ldflags := \
-	-Wl,--fix-cortex-a8
\ No newline at end of file
+	-Wl,--fix-cortex-a8
diff --git a/core/combo/darwin-x86.mk b/core/combo/darwin-x86.mk
deleted file mode 100644
index ab474ba..0000000
--- a/core/combo/darwin-x86.mk
+++ /dev/null
@@ -1,107 +0,0 @@
-# Configuration for Darwin (Mac OS X) on PPC.
-# Included by combo/select.make
-
-# We build everything in 32-bit, because some host tools are
-# 32-bit-only anyway (emulator, acc), and because it gives us
-# more consistency between the host tools and the target.
-$(combo_target)GLOBAL_CFLAGS += -m32
-$(combo_target)GLOBAL_LDFLAGS += -m32
-
-$(combo_target)GLOBAL_CFLAGS += -fPIC
-$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,-undefined,error
-
-$(combo_target)CC := $(CC)
-$(combo_target)CXX := $(CXX)
-$(combo_target)AR := $(AR)
-
-$(combo_target)SHLIB_SUFFIX := .dylib
-$(combo_target)JNILIB_SUFFIX := .jnilib
-
-$(combo_target)GLOBAL_CFLAGS += \
-	-include $(call select-android-config-h,darwin-x86)
-$(combo_target)RUN_RANLIB_AFTER_COPYING := true
-
-ifeq ($(combo_target),TARGET_)
-$(combo_target)CUSTOM_LD_COMMAND := true
-define transform-o-to-shared-lib-inner
-    $(TARGET_CXX) \
-        -dynamiclib -single_module -read_only_relocs suppress \
-        $(TARGET_GLOBAL_LD_DIRS) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-        $(PRIVATE_LDLIBS) \
-        -o $@ \
-        $(PRIVATE_LDFLAGS) \
-        $(if $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES),-all_load) \
-        $(TARGET_LIBGCC)
-endef
-
-define transform-o-to-executable-inner
-	$(TARGET_CXX) \
-        -o $@ \
-        -Wl,-dynamic -headerpad_max_install_names \
-        $(TARGET_GLOBAL_LD_DIRS) \
-        $(TARGET_GLOBAL_LDFLAGS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(PRIVATE_LDLIBS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-        $(TARGET_LIBGCC)
-endef
-
-define transform-o-to-static-executable-inner
-    $(TARGET_CXX) \
-        -static \
-        -o $@ \
-        $(TARGET_GLOBAL_LD_DIRS) \
-        $(TARGET_GLOBAL_LDFLAGS) \
-        $(PRIVATE_LDFLAGS) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(PRIVATE_LDLIBS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-        $(TARGET_LIBGCC)
-endef
-
-else
-$(combo_target)CUSTOM_LD_COMMAND := true
-
-define transform-host-o-to-shared-lib-inner
-    $(HOST_CXX) \
-        -dynamiclib -single_module -read_only_relocs suppress \
-        $(HOST_GLOBAL_LD_DIRS) \
-        $(HOST_GLOBAL_LDFLAGS) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-        $(PRIVATE_LDLIBS) \
-        -o $@ \
-        $(PRIVATE_LDFLAGS) \
-        $(HOST_LIBGCC)
-endef
-
-define transform-host-o-to-executable-inner
-$(HOST_CXX) \
-        -o $@ \
-        -Wl,-dynamic -headerpad_max_install_names \
-        $(HOST_GLOBAL_LD_DIRS) \
-        $(HOST_GLOBAL_LDFLAGS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
-        $(PRIVATE_ALL_OBJECTS) \
-        $(PRIVATE_LDLIBS) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
-        $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-        $(HOST_LIBGCC)
-endef
-
-# $(1): The file to check
-define get-file-size
-stat -f "%z" $(1)
-endef
-
-endif
-
diff --git a/core/combo/linux-x86.mk b/core/combo/linux-x86.mk
deleted file mode 100644
index f466147..0000000
--- a/core/combo/linux-x86.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Configuration for Linux on x86.
-# Included by combo/select.make
-
-# right now we get these from the environment, but we should
-# pick them from the tree somewhere
-$(combo_target)CC := $(CC)
-$(combo_target)CXX := $(CXX)
-$(combo_target)AR := $(AR)
-
-ifeq ($(combo_target),HOST_)
-# $(1): The file to check
-define get-file-size
-stat --format "%s" "$(1)" | tr -d '\n'
-endef
-endif
-
-# On the sim, we build the "host" tools in 64 bit iff the compiler
-# does it for us automatically.  In other words, that means on 64 bit
-# system, they're 64 bit and on 32 bit systems, they're 32 bits.  In
-# all other cases, we build 32 bit, since this is what we release.
-ifneq ($(combo_target)$(TARGET_SIMULATOR),HOST_true)
-$(combo_target)GLOBAL_CFLAGS := $($(combo_target)GLOBAL_CFLAGS) -m32
-$(combo_target)GLOBAL_LDFLAGS := $($(combo_target)GLOBAL_LDFLAGS) -m32
-endif
-
-
-$(combo_target)GLOBAL_CFLAGS += -fPIC
-$(combo_target)GLOBAL_CFLAGS += \
-	-include $(call select-android-config-h,linux-x86)
-
-$(combo_target)NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-
diff --git a/core/combo/select.mk b/core/combo/select.mk
index 793b0a9..916320b 100644
--- a/core/combo/select.mk
+++ b/core/combo/select.mk
@@ -1,24 +1,33 @@
+#
+# Copyright (C) 2006 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 # Select a combo based on the compiler being used.
 #
 # Inputs:
 #	combo_target -- prefix for final variables (HOST_ or TARGET_)
 #
-# Outputs:
-#   $(combo_target)OS -- standard name for this host (LINUX, DARWIN, etc.)
-#   $(combo_target)ARCH -- standard name for process architecture (powerpc, x86, etc.)
-#   $(combo_target)GLOBAL_CFLAGS -- C compiler flags to use for everything
-#   $(combo_target)RELEASE_CFLAGS -- additional C compiler flags for release builds
-#   $(combo_target)GLOBAL_ARFLAGS -- flags to use for static linking everything
-#   $(combo_target)SHLIB_SUFFIX -- suffix of shared libraries
 
 # Build a target string like "linux-arm" or "darwin-x86".
 combo_os_arch := $($(combo_target)OS)-$($(combo_target)ARCH)
 
-# Set the defaults.
+# Set reasonable defaults for the various variables
 
-HOST_CC ?= $(CC)
-HOST_CXX ?= $(CXX)
-HOST_AR ?= $(AR)
+$(combo_target)CC := $(CC)
+$(combo_target)CXX := $(CXX)
+$(combo_target)AR := $(AR)
 
 $(combo_target)BINDER_MINI := 0
 
@@ -36,11 +45,10 @@
 $(combo_target)HAVE_STRLCAT := 0
 $(combo_target)HAVE_KERNEL_MODULES := 0
 
-# These flags might (will) be overridden by the target makefiles
 $(combo_target)GLOBAL_CFLAGS := -fno-exceptions -Wno-multichar
 $(combo_target)RELEASE_CFLAGS := -O2 -g -fno-strict-aliasing
 $(combo_target)GLOBAL_LDFLAGS :=
-$(combo_target)GLOBAL_ARFLAGS := crs
+$(combo_target)GLOBAL_ARFLAGS := crsP
 
 $(combo_target)EXECUTABLE_SUFFIX := 
 $(combo_target)SHLIB_SUFFIX := .so
@@ -49,28 +57,8 @@
 
 $(combo_target)PRELINKER_MAP := $(BUILD_SYSTEM)/prelink-$(combo_os_arch).map
 
-# We try to find a target or host specific file for the os/arch specified, and
-# default to just looking for the os/arch one. This will allow us to define
-# things separately for targets and hosts that have the same architecture
-# but need different defines. e.g. target_linux-x86 and host_linux-x86
-
-ifneq ($(TARGET_SIMULATOR),true)
-# Convert the combo_target string to lowercase
-combo_target_lc := $(shell echo $(combo_target) | tr '[A-Z]' '[a-z]')
-
-# form combo makefile name like "<path>/target_linux-x86.make",
-# "<path>/host_darwin-x86.make", etc.
-combo_target_os_arch := $(BUILD_COMBOS)/$(combo_target_lc)$(combo_os_arch).mk
-else
-combo_target_os_arch :=
-endif
-
 # Now include the combo for this specific target.
-ifneq ($(wildcard $(combo_target_os_arch)),)
-include $(combo_target_os_arch)
-else
-include $(BUILD_COMBOS)/$(combo_os_arch).mk
-endif
+include $(BUILD_COMBOS)/$(combo_target)$(combo_os_arch).mk
 
 ifneq ($(USE_CCACHE),)
   ccache := prebuilt/$(HOST_PREBUILT_TAG)/ccache/ccache
diff --git a/core/combo/windows-x86.mk b/core/combo/windows-x86.mk
deleted file mode 100644
index e32a077..0000000
--- a/core/combo/windows-x86.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Configuration for Linux on x86.
-# Included by combo/select.make
-
-# right now we get these from the environment, but we should
-# pick them from the tree somewhere
-TOOLS_PREFIX := #prebuilt/windows/host/bin/
-TOOLS_EXE_SUFFIX := .exe
-
-# Settings to use MinGW has a cross-compiler under Linux
-ifneq ($(findstring Linux,$(UNAME)),)
-ifneq ($(strip $(USE_MINGW)),)
-HOST_ACP_UNAVAILABLE := true
-TOOLS_PREFIX := /usr/bin/i586-mingw32msvc-
-TOOLS_EXE_SUFFIX :=
-$(combo_target)GLOBAL_CFLAGS += -DUSE_MINGW
-$(combo_target)C_INCLUDES += /usr/lib/gcc/i586-mingw32msvc/3.4.4/include
-$(combo_target)GLOBAL_LD_DIRS += -L/usr/i586-mingw32msvc/lib
-endif
-endif
-
-$(combo_target)CC := $(TOOLS_PREFIX)gcc$(TOOLS_EXE_SUFFIX)
-$(combo_target)CXX := $(TOOLS_PREFIX)g++$(TOOLS_EXE_SUFFIX)
-$(combo_target)AR := $(TOOLS_PREFIX)ar$(TOOLS_EXE_SUFFIX)
-
-$(combo_target)GLOBAL_CFLAGS += -include $(call select-android-config-h,windows)
-$(combo_target)GLOBAL_LDFLAGS += --enable-stdcall-fixup
-
-# when building under Cygwin, ensure that we use Mingw compilation by default.
-# you can disable this (i.e. to generate Cygwin executables) by defining the
-# USE_CYGWIN variable in your environment, e.g.:
-#
-#   export USE_CYGWIN=1
-#
-# note that the -mno-cygwin flags are not needed when cross-compiling the
-# Windows host tools on Linux
-#
-ifneq ($(findstring CYGWIN,$(UNAME)),)
-ifeq ($(strip $(USE_CYGWIN)),)
-$(combo_target)GLOBAL_CFLAGS += -mno-cygwin
-$(combo_target)GLOBAL_LDFLAGS += -mno-cygwin -mconsole
-endif
-endif
-
-$(combo_target)SHLIB_SUFFIX := .dll
-$(combo_target)EXECUTABLE_SUFFIX := .exe
-
-ifeq ($(combo_target),HOST_)
-# $(1): The file to check
-# TODO: find out what format cygwin's stat(1) uses
-define get-file-size
-999999999
-endef
-endif
diff --git a/core/config.mk b/core/config.mk
index 4662a38..2dcd876 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -3,10 +3,20 @@
 # current configuration and platform, which
 # are not specific to what is being built.
 
+# Only use ANDROID_BUILD_SHELL to wrap around bash.
+# DO NOT use other shells such as zsh.
+ifdef ANDROID_BUILD_SHELL
+SHELL := $(ANDROID_BUILD_SHELL)
+else
 # Use bash, not whatever shell somebody has installed as /bin/sh
 # This is repeated from main.mk, since envsetup.sh runs this file
 # directly.
 SHELL := /bin/bash
+endif
+
+# Tell python not to spam the source tree with .pyc files.  This
+# only has an effect on python 2.6 and above.
+export PYTHONDONTWRITEBYTECODE := 1
 
 # Standard source directories.
 SRC_DOCS:= $(TOPDIR)docs
@@ -185,7 +195,6 @@
 YACC:= bison -d
 DOXYGEN:= doxygen
 AAPT := $(HOST_OUT_EXECUTABLES)/aapt$(HOST_EXECUTABLE_SUFFIX)
-ACP := $(HOST_OUT_EXECUTABLES)/acp$(HOST_EXECUTABLE_SUFFIX)
 AIDL := $(HOST_OUT_EXECUTABLES)/aidl$(HOST_EXECUTABLE_SUFFIX)
 ICUDATA := $(HOST_OUT_EXECUTABLES)/icudata$(HOST_EXECUTABLE_SUFFIX)
 SIGNAPK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/signapk$(COMMON_JAVA_PACKAGE_SUFFIX)
@@ -202,6 +211,10 @@
 E2FSCK := e2fsck
 JARJAR := java -jar $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
 PROGUARD := external/proguard/bin/proguard.sh
+JAVATAGS := build/tools/java-event-log-tags.py
+
+# ACP is always for the build OS, not for the host OS
+ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX)
 
 # dx is java behind a shell script; no .exe necessary.
 DX := $(HOST_OUT_EXECUTABLES)/dx
@@ -296,31 +309,31 @@
 
 PREBUILT_IS_PRESENT := $(if $(wildcard prebuilt/Android.mk),true)
 
-
 # ###############################################################
 # Collect a list of the SDK versions that we could compile against
 # For use with the LOCAL_SDK_VERSION variable for include $(BUILD_PACKAGE)
 # ###############################################################
 
-# The files that we can convert into android.jars are are in config/api/*.xml
-# The 'current' version is whatever this source tree is.  Once the apicheck
-# tool can generate the stubs from the xml files, we'll use that to be
-# able to build back-versions.  In the meantime, 'current' is the only
-# one supported.
+HISTORICAL_SDK_VERSIONS_ROOT := $(TOPDIR)prebuilt/sdk
+
+# Historical SDK version N is stored in $(HISTORICAL_SDK_VERSIONS_ROOT)/N.
+# The 'current' version is whatever this source tree is.
 #
 # sgrax     is the opposite of xargs.  It takes the list of args and puts them
 #           on each line for sort to process.
 # sort -g   is a numeric sort, so 1 2 3 10 instead of 1 10 2 3.
-TARGET_AVAILABLE_SDK_VERSIONS := current \
-        $(shell function sgrax() { \
-                while [ -n "$$1" ] ; do echo $$1 ; shift ; done \
-            } ; \
-            ( sgrax $(patsubst $(SRC_API_DIR)/%.xml,%, \
-                $(filter-out $(SRC_API_DIR)/current.xml, \
-                $(shell find $(SRC_API_DIR) -name "*.xml"))) | sort -g ) )
 
+# Numerically sort a list of numbers
+# $(1): the list of numbers to be sorted
+define numerically_sort
+$(shell function sgrax() { \
+    while [ -n "$$1" ] ; do echo $$1 ; shift ; done \
+    } ; \
+    ( sgrax $(1) | sort -g ) )
+endef
+
+TARGET_AVAILABLE_SDK_VERSIONS := current $(call numerically_sort,\
+    $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/android.jar,%, \
+    $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/android.jar)))
 
 INTERNAL_PLATFORM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/public_api.xml
-
-
-
diff --git a/core/definitions.mk b/core/definitions.mk
index 27e38d3..c678f97 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -223,12 +223,38 @@
 endef
 
 ###########################################################
+## Find all of the logtags files under the named directories.
+## Meant to be used like:
+##    SRC_FILES := $(call all-logtags-files-under,src)
+###########################################################
+
+define all-logtags-files-under
+$(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find $(1) -name "*.logtags" -and -not -name ".*") \
+  )
+endef
+
+###########################################################
+## Find all of the html files under the named directories.
+## Meant to be used like:
+##    SRC_FILES := $(call all-html-files-under,src tests)
+###########################################################
+
+define all-html-files-under
+$(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find $(1) -name "*.html" -and -not -name ".*") \
+ )
+endef
+
+###########################################################
 ## Find all of the html files from here.  Meant to be used like:
 ##    SRC_FILES := $(call all-subdir-html-files)
 ###########################################################
 
 define all-subdir-html-files
-$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find . -name "*.html"))
+$(call all-html-files-under,.)
 endef
 
 ###########################################################
@@ -559,6 +585,7 @@
 # $(1): list of tags to accept
 # $(2): list of tags to reject
 #TODO(dbort): do $(if $(strip $(1)),$(1),$(ALL_MODULE_TAGS))
+#TODO(jbq): as of 20100106 nobody uses the second parameter
 define get-tagged-modules
 $(filter-out \
 	$(call modules-for-tag-list,$(2)), \
@@ -644,6 +671,7 @@
 @echo PRIVATE_ARFLAGS=$(PRIVATE_ARFLAGS);
 @echo PRIVATE_AAPT_FLAGS=$(PRIVATE_AAPT_FLAGS);
 @echo PRIVATE_DX_FLAGS=$(PRIVATE_DX_FLAGS);
+@echo PRIVATE_JAVACFLAGS=$(PRIVATE_JAVACFLAGS);
 @echo PRIVATE_JAVA_LIBRARIES=$(PRIVATE_JAVA_LIBRARIES);
 @echo PRIVATE_ALL_SHARED_LIBRARIES=$(PRIVATE_ALL_SHARED_LIBRARIES);
 @echo PRIVATE_ALL_STATIC_LIBRARIES=$(PRIVATE_ALL_STATIC_LIBRARIES);
@@ -717,6 +745,16 @@
 #$(AIDL) $(PRIVATE_AIDL_FLAGS) $< - | indent -nut -br -npcs -l1000 > $@
 
 
+###########################################################
+## Commands for running java-event-log-tags.py
+###########################################################
+
+define transform-logtags-to-java
+@mkdir -p $(dir $@)
+@echo "logtags: $@ <= $<"
+$(hide) $(JAVATAGS) -o $@ $^
+endef
+
 
 ###########################################################
 ## Commands for running gcc to compile a C++ file
@@ -727,11 +765,11 @@
 @echo "target $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
 $(hide) $(PRIVATE_CXX) \
 	$(foreach incdir, \
+	    $(PRIVATE_C_INCLUDES) \
 	    $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 		$(TARGET_PROJECT_INCLUDES) \
 		$(TARGET_C_INCLUDES) \
 	     ) \
-	    $(PRIVATE_C_INCLUDES) \
 	  , \
 	    -I $(incdir) \
 	 ) \
@@ -759,11 +797,11 @@
 @mkdir -p $(dir $@)
 $(hide) $(PRIVATE_CC) \
 	$(foreach incdir, \
+	    $(PRIVATE_C_INCLUDES) \
 	    $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 		$(TARGET_PROJECT_INCLUDES) \
 		$(TARGET_C_INCLUDES) \
 	     ) \
-	    $(PRIVATE_C_INCLUDES) \
 	  , \
 	    -I $(incdir) \
 	 ) \
@@ -823,11 +861,11 @@
 @echo "host C++: $(PRIVATE_MODULE) <= $<"
 $(hide) $(PRIVATE_CXX) \
 	$(foreach incdir, \
+	    $(PRIVATE_C_INCLUDES) \
 	    $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 		$(HOST_PROJECT_INCLUDES) \
 		$(HOST_C_INCLUDES) \
 	     ) \
-	    $(PRIVATE_C_INCLUDES) \
 	  , \
 	    -I $(incdir) \
 	 ) \
@@ -853,11 +891,11 @@
 @mkdir -p $(dir $@)
 $(hide) $(PRIVATE_CC) \
 	$(foreach incdir, \
+	    $(PRIVATE_C_INCLUDES) \
 	    $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
 		$(HOST_PROJECT_INCLUDES) \
 		$(HOST_C_INCLUDES) \
 	     ) \
-	    $(PRIVATE_C_INCLUDES) \
 	  , \
 	    -I $(incdir) \
 	 ) \
@@ -909,7 +947,7 @@
 ## Commands for running ar
 ###########################################################
 
-define extract-and-include-whole-static-libs
+define extract-and-include-target-whole-static-libs
 $(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
 	@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
 	ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(lib)))_objs;\
@@ -929,22 +967,39 @@
 define transform-o-to-static-lib
 @mkdir -p $(dir $@)
 @rm -f $@
-$(extract-and-include-whole-static-libs)
+$(extract-and-include-target-whole-static-libs)
 @echo "target StaticLib: $(PRIVATE_MODULE) ($@)"
-$(hide) $(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@ $^
+$(hide) echo $^ | xargs $(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@
 endef
 
 ###########################################################
 ## Commands for running host ar
 ###########################################################
 
+define extract-and-include-host-whole-static-libs
+$(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
+	@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
+	ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(lib)))_objs;\
+	rm -rf $$ldir; \
+	mkdir -p $$ldir; \
+	filelist=; \
+	for f in `$(HOST_AR) t $(lib) | grep '\.o$$'`; do \
+	    $(HOST_AR) p $(lib) $$f > $$ldir/$$f; \
+	    filelist="$$filelist $$ldir/$$f"; \
+	done ; \
+	$(HOST_AR) $(HOST_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@ $$filelist;\
+)
+endef
+
 # Explicitly delete the archive first so that ar doesn't
 # try to add to an existing archive.
 define transform-host-o-to-static-lib
 @mkdir -p $(dir $@)
-@echo "host StaticLib: $(PRIVATE_MODULE) ($@)"
 @rm -f $@
-$(HOST_AR) $(HOST_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@ $^
+$(extract-and-include-host-whole-static-libs)
+@echo "host StaticLib: $(PRIVATE_MODULE) ($@)"
+echo $(filter %.o, $^) | \
+	xargs $(HOST_AR) $(HOST_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@
 endef
 
 
@@ -1166,7 +1221,7 @@
 define create-resource-java-files
 @mkdir -p $(PRIVATE_SOURCE_INTERMEDIATES_DIR)
 @mkdir -p $(dir $(PRIVATE_RESOURCE_PUBLICS_OUTPUT))
-$(hide) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m -z \
+$(hide) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m \
     $(eval # PRODUCT_AAPT_CONFIG is intentionally missing-- see comment.) \
     $(addprefix -J , $(PRIVATE_SOURCE_INTERMEDIATES_DIR)) \
     $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
@@ -1178,7 +1233,9 @@
     $(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 --version-name , $(PLATFORM_VERSION)) \
+    $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
+    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME))
 endef
 
 ifeq ($(HOST_OS),windows)
@@ -1254,7 +1311,7 @@
 $(hide) $(TARGET_JAVAC) -encoding ascii $(PRIVATE_BOOTCLASSPATH) \
     $(addprefix -classpath ,$(strip \
         $(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES)))) \
-    $(strip $(PRIVATE_JAVAC_DEBUG_FLAGS)) $(xlint_unchecked) \
+    $(PRIVATE_JAVACFLAGS) $(strip $(PRIVATE_JAVAC_DEBUG_FLAGS)) $(xlint_unchecked) \
     -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) \
     \@$(dir $(PRIVATE_CLASS_INTERMEDIATES_DIR))/java-source-list-uniq \
     || ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 )
@@ -1311,7 +1368,7 @@
 #values; applications can override these by explicitly stating
 #them in their manifest.
 define add-assets-to-package
-$(hide) $(AAPT) package -z -u $(PRIVATE_AAPT_FLAGS) \
+$(hide) $(AAPT) package -u $(PRIVATE_AAPT_FLAGS) \
     $(addprefix -c , $(PRODUCT_AAPT_CONFIG)) \
     $(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
     $(addprefix -S , $(PRIVATE_RESOURCE_DIR)) \
@@ -1321,6 +1378,8 @@
     $(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(addprefix --version-code , $(PLATFORM_SDK_VERSION)) \
     $(addprefix --version-name , $(PLATFORM_VERSION)) \
+    $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
+    $(addprefix --rename-instrumentation-target-package , $(PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME)) \
     -F $@
 endef
 
@@ -1390,7 +1449,7 @@
 	$(PRIVATE_JAVA_SOURCES)),\
 	$(PRIVATE_INTERMEDIATES_DIR)/java-source-list-uniq)
 $(hide) $(HOST_JAVAC) -encoding ascii -g \
-	$(xlint_unchecked) \
+	$(PRIVATE_JAVACFLAGS) $(xlint_unchecked) \
 	$(addprefix -classpath ,$(strip \
 		$(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES)))) \
 	-extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR)\
@@ -1520,7 +1579,6 @@
 $(copy-file-to-target-strip-comments)
 endef
 
-
 ###########################################################
 ## On some platforms (MacOS), after copying a static
 ## library, ranlib must be run to update an internal
@@ -1549,6 +1607,37 @@
 
 
 ###########################################################
+## Commands to call Proguard
+###########################################################
+
+# Command to copy the file with acp, if proguard is disabled.
+define proguard-disabled-commands
+@echo Copying: $@
+$(hide) $(ACP) $< $@
+endef
+
+# Command to call Proguard
+# $(1): extra flags for instrumentation.
+define proguard-enabled-commands
+@echo Proguard: $@
+$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS) $(1)
+endef
+
+# Figure out the proguard dictionary file of the module that is instrumentationed for.
+define get-instrumentation-proguard-flags
+$(if $(PRIVATE_INSTRUMENTATION_FOR),$(if $(ALL_MODULES.$(PRIVATE_INSTRUMENTATION_FOR).PROGUARD_ENABLED),-applymapping $(call intermediates-dir-for,APPS,$(PRIVATE_INSTRUMENTATION_FOR),,COMMON)/proguard_dictionary))
+endef
+
+define transform-jar-to-proguard
+$(eval _instrumentation_proguard_flags:=$(call get-instrumentation-proguard-flags))
+$(eval _enable_proguard:=$(PRIVATE_PROGUARD_ENABLED)$(_instrumentation_proguard_flags))
+$(if $(_enable_proguard),$(call proguard-enabled-commands,$(_instrumentation_proguard_flags)),$(call proguard-disabled-commands))
+$(eval _instrumentation_proguard_flags:=)
+$(eval _enable_proguard:=)
+endef
+
+
+###########################################################
 ## Stuff source generated from one-off tools
 ###########################################################
 
@@ -1634,17 +1723,68 @@
 # INSTALLED_RADIOIMAGE_TARGET.
 # $(1): filename
 define add-radio-file
-  $(eval $(call add-radio-file-internal,$(1)))
+  $(eval $(call add-radio-file-internal,$(1),$(notdir $(1))))
 endef
 define add-radio-file-internal
-INSTALLED_RADIOIMAGE_TARGET += $$(PRODUCT_OUT)/$(1)
-ALL_PREBUILT += $$(PRODUCT_OUT)/$(1)
-$$(PRODUCT_OUT)/$(1) : $$(LOCAL_PATH)/$(1) | $$(ACP)
+INSTALLED_RADIOIMAGE_TARGET += $$(PRODUCT_OUT)/$(2)
+ALL_PREBUILT += $$(PRODUCT_OUT)/$(2)
+$$(PRODUCT_OUT)/$(2) : $$(LOCAL_PATH)/$(1) | $$(ACP)
 	$$(transform-prebuilt-to-target)
 endef
 
 
 ###########################################################
+# Override the package defined in $(1), setting the
+# variables listed below differently.
+#
+#  $(1): The makefile to override (relative to the source
+#        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.
+#
+# 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)))
+endef
+
+define inherit-package-internal
+  LOCAL_PACKAGE_OVERRIDES \
+      := $(strip $(1))||$(strip $(2))||$(strip $(3))||$(strip $(4))||&&$(strip $(5))||$(strip $(6)) $(LOCAL_PACKAGE_OVERRIDES)
+  include $(1)
+  LOCAL_PACKAGE_OVERRIDES \
+      := $(wordlist 1,$(words $(LOCAL_PACKAGE_OVERRIDES)), $(LOCAL_PACKAGE_OVERRIDES))
+endef
+
+# To be used with inherit-package above
+# Evalutes to true if the package was overridden
+define set-inherited-package-variables
+$(strip $(call set-inherited-package-variables-internal))
+endef
+
+define keep-or-override
+$(eval $(1) := $(if $(2),$(2),$($(1))))
+endef
+
+define set-inherited-package-variables-internal
+  $(eval _o := $(subst ||, ,$(lastword $(LOCAL_PACKAGE_OVERRIDES))))
+  $(eval _n := $(subst ||, ,$(firstword $(LOCAL_PACKAGE_OVERRIDES))))
+  $(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))) \
+    $(eval LOCAL_OVERRIDES_PACKAGES := $(sort $(LOCAL_OVERRIDES_PACKAGES) $(word 2,$(_o)))) \
+    true \
+  ,)
+endef
+
+
+###########################################################
 ## Other includes
 ###########################################################
 
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index f07cf2a..0818d87 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -91,6 +91,13 @@
 # around, so we have to use this version.
 prelink_output := $(LOCAL_UNSTRIPPED_PATH)/$(LOCAL_MODULE_SUBDIR)$(LOCAL_BUILT_MODULE_STEM)
 
+# Skip prelinker if it is FDO instrumentation build.
+ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
+ifneq ($(LOCAL_NO_FDO_SUPPORT),true)
+LOCAL_PRELINK_MODULE := false
+endif
+endif
+
 ifeq ($(LOCAL_PRELINK_MODULE),true)
 $(prelink_output): $(prelink_input) $(TARGET_PRELINKER_MAP) $(APRIORI)
 	$(transform-to-prelinked)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 6d14753..f8a2027 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -68,9 +68,17 @@
 ifneq (,$(findstring CYGWIN,$(UNAME)))
 	HOST_OS := windows
 endif
+
+# BUILD_OS is the real host doing the build.
+BUILD_OS := $(HOST_OS)
+
+# Under Linux, if USE_MINGW is set, we change HOST_OS to Windows to build the
+# Windows SDK. Only a subset of tools and SDK will manage to build properly.
+ifeq ($(HOST_OS),linux)
 ifneq ($(USE_MINGW),)
 	HOST_OS := windows
 endif
+endif
 
 ifeq ($(HOST_OS),)
 $(error Unable to determine HOST_OS from uname -sm: $(UNAME)!)
@@ -86,6 +94,8 @@
 	HOST_ARCH := ppc
 endif
 
+BUILD_ARCH := $(HOST_ARCH)
+
 ifeq ($(HOST_ARCH),)
 $(error Unable to determine HOST_ARCH from uname -sm: $(UNAME)!)
 endif
@@ -168,6 +178,8 @@
 HOST_OUT_debug := $(HOST_OUT_ROOT_debug)/$(HOST_OS)-$(HOST_ARCH)
 HOST_OUT := $(HOST_OUT_$(HOST_BUILD_TYPE))
 
+BUILD_OUT := $(OUT_DIR)/host/$(BUILD_OS)-$(BUILD_ARCH)
+
 ifeq ($(TARGET_SIMULATOR),true)
   # Any arch- or os-specific parts of the simulator (everything
   # under product/) are actually host-dependent.
@@ -185,6 +197,8 @@
 
 OUT_DOCS := $(TARGET_COMMON_OUT_ROOT)/docs
 
+BUILD_OUT_EXECUTABLES:= $(BUILD_OUT)/bin
+
 HOST_OUT_EXECUTABLES:= $(HOST_OUT)/bin
 HOST_OUT_SHARED_LIBRARIES:= $(HOST_OUT)/lib
 HOST_OUT_JAVA_LIBRARIES:= $(HOST_OUT)/framework
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index 92b5ff6..1977115 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -25,5 +25,6 @@
 
 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)
 	$(transform-host-java-to-package)
diff --git a/core/host_static_library.mk b/core/host_static_library.mk
index 237981f..39c99ee 100644
--- a/core/host_static_library.mk
+++ b/core/host_static_library.mk
@@ -1,5 +1,5 @@
 ###########################################################
-## Standard rules for building a static library.
+## Standard rules for building a static library for the host.
 ##
 ## Additional inputs from base_rules.make:
 ## None.
@@ -7,8 +7,6 @@
 ## LOCAL_MODULE_SUFFIX will be set for you.
 ###########################################################
 
-LOCAL_IS_HOST_MODULE := true
-
 ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 endif
@@ -17,7 +15,10 @@
 endif
 LOCAL_UNINSTALLABLE_MODULE := true
 
+LOCAL_IS_HOST_MODULE := true
+
 include $(BUILD_SYSTEM)/binary.mk
 
+$(LOCAL_BUILT_MODULE): $(built_whole_libraries)
 $(LOCAL_BUILT_MODULE): $(all_objects)
 	$(transform-host-o-to-static-lib)
diff --git a/core/java.mk b/core/java.mk
index ddb8737..baa83ee 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -20,7 +20,11 @@
       $(error $(LOCAL_PATH): Invalid LOCAL_SDK_VERSION '$(LOCAL_SDK_VERSION)' \
              Choices are: $(TARGET_AVAILABLE_SDK_VERSIONS))
     else
-      LOCAL_JAVA_LIBRARIES := android_stubs_$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES) 
+      ifeq ($(LOCAL_SDK_VERSION),current)
+        LOCAL_JAVA_LIBRARIES := android_stubs_$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
+      else
+        LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
+      endif
     endif
   endif
 else
@@ -70,6 +74,7 @@
 full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_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
 
@@ -77,6 +82,7 @@
     $(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)
@@ -135,6 +141,7 @@
 # This intentionally depends on java_sources, not all_java_sources.
 # 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)
 	$(transform-java-to-classes.jar)
 
@@ -147,7 +154,7 @@
 # be done after the inclusion of base_rules.mk.
 ALL_MODULES.$(LOCAL_MODULE).CHECKED := $(full_classes_compiled_jar)
 
-ifneq ($(LOCAL_NO_EMMA_COMPILE),true) 
+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.
@@ -155,7 +162,7 @@
 # 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 
+# when emma is off, compile with the default flags, which contain full debug
 # info
 $(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
 endif
@@ -171,9 +178,12 @@
 $(full_classes_emma_jar): PRIVATE_EMMA_INTERMEDIATES_DIR := $(emma_intermediates_dir)
 # this rule will generate both $(PRIVATE_EMMA_COVERAGE_FILE) and
 # $(full_classes_emma_jar)
-$(full_classes_emma_jar): $(full_classes_compiled_jar)
+$(full_classes_emma_jar): $(full_classes_compiled_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: $<
@@ -192,39 +202,55 @@
 	$(hide) $(ACP) $< $@
 endif
 
+# Keep a copy of the jar just before proguard processing.
+$(full_classes_full_names_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.
-ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),)
 proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary
-proguard_flags := $(addprefix -libraryjars ,$(full_java_libs)) \
+# 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))
+proguard_flags := $(addprefix -libraryjars ,$(proguard_full_java_libs)) \
                   -include $(BUILD_SYSTEM)/proguard.flags \
                   -forceprocessing \
                   -printmapping $(proguard_dictionary)
-ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),full)
+# If this is a test package, add proguard keep flags for tests.
+ifneq ($(strip $(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS))$(filter android.test.runner,$(LOCAL_JAVA_LIBRARIES))),)
+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
 else
-ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),optonly)
+ifeq ($(LOCAL_PROGUARD_ENABLED),optonly)
     # optonly
     proguard_flags += -dontobfuscate
 else
-ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom)
+ifeq ($(LOCAL_PROGUARD_ENABLED),custom)
     # custom
 else
     $(warning while processing: $(LOCAL_MODULE))
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
-endif
-endif
-endif
+endif # custom
+endif # optonly
+endif # full
+endif # LOCAL_PROGUARD_ENABLED
 
+$(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): $(full_classes_emma_jar) | $(PROGUARD)
-	@echo Proguard: $@
-	$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS)
-else
-$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(ACP)
-	@echo Copying: $@
-	$(hide) $(ACP) $< $@
-endif
+$(full_classes_proguard_jar): PRIVATE_INSTRUMENTATION_FOR:=$(strip $(LOCAL_INSTRUMENTATION_FOR))
+
+$(full_classes_proguard_jar): $(full_classes_full_names_jar) | $(ACP) $(PROGUARD)
+	$(call transform-jar-to-proguard)
+
+ALL_MODULES.$(LOCAL_MODULE).PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED)
 
 # Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
 # will work even when intermediates != intermediates.COMMON.
diff --git a/core/main.mk b/core/main.mk
index fdb1163..6eb167b 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1,8 +1,13 @@
-
+# Only use ANDROID_BUILD_SHELL to wrap around bash.
+# DO NOT use other shells such as zsh.
+ifdef ANDROID_BUILD_SHELL
+SHELL := $(ANDROID_BUILD_SHELL)
+else
 # Use bash, not whatever shell somebody has installed as /bin/sh
 # This is repeated in config.mk, since envsetup.sh runs that file
 # directly.
 SHELL := /bin/bash
+endif
 
 # this turns off the suffix rules built into make
 .SUFFIXES:
@@ -174,6 +179,9 @@
 ifneq ($(filter sdk,$(MAKECMDGOALS)),)
 is_sdk_build := true
 endif
+ifneq ($(filter win_sdk,$(MAKECMDGOALS)),)
+is_sdk_build := true
+endif
 ifneq ($(filter sdk_addon,$(MAKECMDGOALS)),)
 is_sdk_build := true
 endif
@@ -191,6 +199,9 @@
   ifeq ($(user_variant),userdebug)
     # Pick up some extra useful tools
     tags_to_install += debug
+
+    # Enable Dalvik lock contention logging for userdebug builds.
+    ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.lockprof.threshold=500
   else
     # Disable debugging in plain user builds.
     enable_target_debugging :=
@@ -246,6 +257,7 @@
 ifneq ($(words $(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS))),1)
 $(error The 'sdk' target may not be specified with any other targets)
 endif
+
 # TODO: this should be eng I think.  Since the sdk is built from the eng
 # variant.
 tags_to_install := user debug eng
@@ -254,6 +266,11 @@
 else # !sdk
 endif
 
+# build the full stagefright library
+ifneq ($(strip BUILD_WITH_FULL_STAGEFRIGHT),)
+BUILD_WITH_FULL_STAGEFRIGHT := true
+endif
+
 ## precise GC ##
 
 ifneq ($(filter dalvik.gc.type-precise,$(PRODUCT_TAGS)),)
@@ -286,13 +303,11 @@
 endif
 
 ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
-ADDITIONAL_BUILD_PROPERTIES += ro.config.sync=yes
 
 # enable vm tracing in files for now to help track
 # the cause of ANRs in the content process
 ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.stack-trace-file=/data/anr/traces.txt
 
-
 # ------------------------------------------------------------
 # Define a function that, given a list of module tags, returns
 # non-empty if that module should be installed in /system.
@@ -385,7 +400,7 @@
 subdirs += \
 	build/tools/signapk \
 	dalvik/dx \
-	dalvik/libcore \
+	libcore \
 	sdk/archquery \
 	sdk/androidprefs \
 	sdk/apkbuilder \
@@ -398,7 +413,6 @@
 	sdk/layoutopt \
 	development/apps \
 	development/tools/mkstubs \
-	external/googleclient \
 	packages
 else
 $(warning SDK_ONLY: javac not available.)
@@ -450,7 +464,7 @@
 # modules as a side-effect.  Do this after including ONE_SHOT_MAKEFILE
 # so that the modules will be installed in the same place they
 # would have been with a normal make.
-CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS),))
+CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))
 FULL_BUILD :=
 # Stub out the notice targets, which probably aren't defined
 # when using ONE_SHOT_MAKEFILE.
@@ -524,9 +538,6 @@
 
 # Of the modules defined by the component makefiles,
 # determine what we actually want to build.
-# If a module has the "restricted" tag on it, it
-# poisons the rest of the tags and shouldn't appear
-# on any list.
 Default_MODULES := $(sort $(ALL_DEFAULT_INSTALLED_MODULES) \
                           $(CUSTOM_MODULES))
 # TODO: Remove the 3 places in the tree that use
@@ -552,12 +563,12 @@
 endif
 # Use tags to get the non-APPS user modules.  Use the product
 # definition files to get the APPS user modules.
-user_MODULES := $(sort $(call get-tagged-modules,user,_class@APPS restricted))
+user_MODULES := $(sort $(call get-tagged-modules,user))
 user_MODULES := $(user_MODULES) $(user_PACKAGES)
 
-eng_MODULES := $(sort $(call get-tagged-modules,eng,restricted))
-debug_MODULES := $(sort $(call get-tagged-modules,debug,restricted))
-tests_MODULES := $(sort $(call get-tagged-modules,tests,restricted))
+eng_MODULES := $(sort $(call get-tagged-modules,eng))
+debug_MODULES := $(sort $(call get-tagged-modules,debug))
+tests_MODULES := $(sort $(call get-tagged-modules,tests))
 
 ifeq ($(strip $(tags_to_install)),)
 $(error ASSERTION FAILED: tags_to_install should not be empty)
@@ -676,8 +687,21 @@
 # The actual files built by the droidcore target changes depending
 # on the build variant.
 .PHONY: droid tests
-droid tests: droidcore
+ifeq ($(strip $(is_unbundled_app_build)),true)
+unbundled_build_modules :=
+ifdef UNBUNDLED_APPS
+unbundled_build_modules := $(UNBUNDLED_APPS)
+else # UNBUNDLED_APPS
+# Otherwise we build all modules in the source tree.
+unbundled_build_modules := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))
+endif # UNBUNDLED_APPS
+droid: $(unbundled_build_modules)
+else # is_unbundled_app_build
+droid: droidcore
+endif # is_unbundled_app_build
+tests: droidcore
 
+ifneq ($(strip $(is_unbundled_app_build)),true)
 $(call dist-for-goals, droid, \
 	$(INTERNAL_UPDATE_PACKAGE_TARGET) \
 	$(INTERNAL_OTA_PACKAGE_TARGET) \
@@ -688,6 +712,7 @@
 	$(INSTALLED_FILES_FILE) \
 	$(INSTALLED_BUILD_PROP_TARGET) \
 	$(BUILT_TARGET_FILES_PACKAGE) \
+	$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
  )
 
 # Tests are installed in userdata.img.  If we're building the tests
@@ -701,13 +726,25 @@
  )
 endif
 
+else # is_unbundled_app_build
+# dist the unbundled app.
+ifdef UNBUNDLED_APPS
+  $(call dist-for-goals,droid, \
+    $(foreach m,$(UNBUNDLED_APPS),$(ALL_MODULES.$(m).INSTALLED)) \
+  )
+endif # UNBUNDLED_APPS
+endif # is_unbundled_app_build
+
 .PHONY: docs
 docs: $(ALL_DOCS)
 
 .PHONY: sdk
 ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
 sdk: $(ALL_SDK_TARGETS)
-$(call dist-for-goals,sdk,$(ALL_SDK_TARGETS))
+$(call dist-for-goals,sdk, \
+	$(ALL_SDK_TARGETS) \
+	$(SYMBOLS_ZIP) \
+ )
 
 .PHONY: findbugs
 findbugs: $(INTERNAL_FINDBUGS_HTML_TARGET) $(INTERNAL_FINDBUGS_XML_TARGET)
@@ -742,4 +779,3 @@
 .PHONY: showcommands
 showcommands:
 	@echo >/dev/null
-
diff --git a/core/node_fns.mk b/core/node_fns.mk
index 5d2a669..38ecea7 100644
--- a/core/node_fns.mk
+++ b/core/node_fns.mk
@@ -162,8 +162,9 @@
           $(call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \
       $(eval ### "Expand the inherit tag") \
       $(eval $(_eiv_tv) := \
-          $(patsubst $(INHERIT_TAG)$(i),$($(1).$(i).$(v)), \
-              $($(_eiv_tv)))) \
+          $(strip \
+              $(patsubst $(INHERIT_TAG)$(i),$($(1).$(i).$(v)), \
+                  $($(_eiv_tv))))) \
       $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \
       $(eval $(1).$(i).$(v) :=) \
       $(eval ### "If we just inherited ourselves, it's a cycle.") \
@@ -187,7 +188,10 @@
   $(eval _include_stack := $(2) $$(_include_stack))
   $(call clear-var-list, $(3))
   $(eval LOCAL_PATH := $(patsubst %/,%,$(dir $(2))))
+  $(eval MAKEFILE_LIST :=)
   $(eval include $(2))
+  $(eval _included := $(filter-out $(2),$(MAKEFILE_LIST)))
+  $(eval MAKEFILE_LIST :=)
   $(eval LOCAL_PATH :=)
   $(call copy-var-list, $(1).$(2), $(3))
   $(call clear-var-list, $(3))
@@ -203,6 +207,13 @@
 endef
 
 #
+# This will generate a warning for _included above
+#  $(if $(_included), \
+#      $(eval $(warning product spec file: $(2)))\
+#      $(foreach _inc,$(_included),$(eval $(warning $(space)$(space)$(space)includes: $(_inc)))),)
+#
+
+#
 # $(1): context prefix
 # $(2): list of makefiles representing nodes to import
 # $(3): list of node variable names
diff --git a/core/package.mk b/core/package.mk
index d92a8b8..e7be05f 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -25,6 +25,19 @@
 ## be set for you.
 ###########################################################
 
+
+# If this makefile is being read from within an inheritance,
+# use the new values.
+skip_definition:=
+ifdef LOCAL_PACKAGE_OVERRIDES
+  package_overridden := $(call set-inherited-package-variables)
+  ifeq ($(strip $(package_overridden)),)
+    skip_definition := true
+  endif
+endif
+
+ifndef skip_definition
+
 LOCAL_PACKAGE_NAME := $(strip $(LOCAL_PACKAGE_NAME))
 ifeq ($(LOCAL_PACKAGE_NAME),)
 $(error $(LOCAL_PATH): Package modules must define LOCAL_PACKAGE_NAME)
@@ -61,6 +74,11 @@
 
 #$(warning $(LOCAL_PATH) $(LOCAL_PACKAGE_NAME) $(sort $(LOCAL_MODULE_TAGS)))
 
+ifeq ($(filter tests, $(LOCAL_MODULE_TAGS)),)
+# Force localization check if it's not tagged as tests.
+LOCAL_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) -z
+endif
+
 ifeq (,$(LOCAL_ASSET_DIR))
 LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
 endif
@@ -69,8 +87,10 @@
   LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 endif
 LOCAL_RESOURCE_DIR := \
-  $(wildcard $(addsuffix /$(LOCAL_RESOURCE_DIR), $(PRODUCT_PACKAGE_OVERLAYS))) \
-  $(wildcard $(addsuffix /$(LOCAL_RESOURCE_DIR), $(DEVICE_PACKAGE_OVERLAYS))) \
+  $(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
+    $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
+  $(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \
+    $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
   $(LOCAL_RESOURCE_DIR)
 
 # this is an app, so add the system libraries to the search path
@@ -111,10 +131,24 @@
 
 LOCAL_BUILT_MODULE_STEM := package.apk
 
-proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options
-ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom)
-    LOCAL_PROGUARD_FLAGS := -include $(proguard_options_file) $(LOCAL_PROGUARD_FLAGS)
+LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
+ifndef LOCAL_PROGUARD_ENABLED
+ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
+    # turn on Proguard by default for user & userdebug build
+    LOCAL_PROGUARD_ENABLED :=full
 endif
+endif
+ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
+    # the package explicitly request to disable proguard.
+    LOCAL_PROGUARD_ENABLED :=
+endif
+proguard_options_file :=
+ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
+ifneq ($(all_resources),)
+    proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options
+endif # all_resources
+endif # !custom
+LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
 
 # The dex files go in the package, so we don't
 # want to install them separately for this module.
@@ -210,17 +244,24 @@
 # Most packages should link against the resources defined by framework-res.
 # Even if they don't have their own resources, they may use framework
 # resources.
+ifneq ($(filter-out current,$(LOCAL_SDK_VERSION)),)
+# for released sdk versions, the platform resources were built into android.jar.
+framework_res_package_export := \
+	$(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_VERSION)/android.jar
+framework_res_package_export_deps := $(framework_res_package_export)
+else # LOCAL_SDK_VERSION
 framework_res_package_export := \
 	$(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
-$(LOCAL_INTERMEDIATE_TARGETS): \
-	PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
 # We can't depend directly on the export.apk file; it won't get its
 # PRIVATE_ vars set up correctly if we do.  Instead, depend on the
 # corresponding R.stamp file, which lists the export.apk as a dependency.
 framework_res_package_export_deps := \
 	$(dir $(framework_res_package_export))src/R.stamp
+endif # LOCAL_SDK_VERSION
 $(R_file_stamp): $(framework_res_package_export_deps)
-endif
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
+endif # LOCAL_NO_STANDARD_LIBRARIES
 
 ifneq ($(full_classes_jar),)
 $(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
@@ -244,6 +285,15 @@
 ifeq ($(LOCAL_CERTIFICATE),)
     LOCAL_CERTIFICATE := testkey
 endif
+
+ifeq ($(LOCAL_CERTIFICATE),EXTERNAL)
+  # The special value "EXTERNAL" means that we will sign it with the
+  # default testkey, apply predexopt, but then expect the final .apk
+  # (after dexopting) to be signed by an outside tool.
+  LOCAL_CERTIFICATE := testkey
+  PACKAGES.$(LOCAL_PACKAGE_NAME).EXTERNAL_KEY := 1
+endif
+
 # If this is not an absolute certificate, assign it to a generic one.
 ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
     LOCAL_CERTIFICATE := $(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE)
@@ -261,6 +311,10 @@
 # Define the rule to build the actual package.
 $(LOCAL_BUILT_MODULE): $(AAPT) | $(ZIPALIGN)
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries)
+ifeq ($(strip $(is_unbundled_app_build)),true)
+    # Include all resources for unbundled apps.
+    $(LOCAL_BUILT_MODULE): PRODUCT_AAPT_CONFIG :=
+endif
 $(LOCAL_BUILT_MODULE): $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
 	$(create-empty-package)
@@ -280,3 +334,5 @@
 PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_FILES := $(all_resources)
 
 PACKAGES := $(PACKAGES) $(LOCAL_PACKAGE_NAME)
+
+endif # skip_definition
diff --git a/core/pathmap.mk b/core/pathmap.mk
index 1ae663d..25de0ea 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -72,6 +72,11 @@
 # A list of all source roots under frameworks/base, which will be
 # built into the android.jar.
 #
+# Note - "common" is included here, even though it is also built
+# into a static library (android-common) for unbundled use.  This
+# is so common and the other framework libraries can have mutual
+# interdependencies.
+#
 FRAMEWORKS_BASE_SUBDIRS := \
 	$(addsuffix /java, \
 	    core \
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index b2bb07c..b03f2af 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -42,19 +42,40 @@
 endif
 endif
 
-ifeq ($(LOCAL_CERTIFICATE),)
-  # can't re-sign this package, so predexopt is not available.
-else
-
-# If this is not an absolute certificate, assign it to a generic one.
-ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
-    LOCAL_CERTIFICATE := $(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE)
+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
+  # package to be signed with a different key.
+  #
+  # This can be used for packages where we don't have access to the
+  # keys, but want the package to be predexopt'ed.
+  LOCAL_CERTIFICATE := testkey
+  PACKAGES.$(LOCAL_MODULE).EXTERNAL_KEY := 1
 endif
+ifeq ($(LOCAL_CERTIFICATE),)
+  ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
+    # It is now a build error to add a prebuilt .apk without
+    # specifying a key for it.
+    $(error No LOCAL_CERTIFICATE specified for prebuilt "$(LOCAL_SRC_FILES)")
+  endif
+else ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
+  # The magic string "PRESIGNED" means this package is already checked
+  # signed with its release key.
+  #
+  # By setting .CERTIFICATE but not .PRIVATE_KEY, this package will be
+  # mentioned in apkcerts.txt (with certificate set to "PRESIGNED")
+  # but the dexpreopt process will not try to re-sign the app.
+  PACKAGES.$(LOCAL_MODULE).CERTIFICATE := PRESIGNED
+  PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
+else
+  # If this is not an absolute certificate, assign it to a generic one.
+  ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
+      LOCAL_CERTIFICATE := $(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE)
+  endif
 
-PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
-PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
-PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
-
+  PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
+  PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+  PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
 endif
 
 ifneq ($(prebuilt_module_is_a_library),)
diff --git a/core/prelink-linux-arm.map b/core/prelink-linux-arm.map
index 64149bc..22f5f34 100644
--- a/core/prelink-linux-arm.map
+++ b/core/prelink-linux-arm.map
@@ -1,4 +1,3 @@
-
 # 0xC0000000 - 0xFFFFFFFF Kernel
 # 0xB0100000 - 0xBFFFFFFF Thread 0 Stack
 # 0xB0000000 - 0xB00FFFFF Linker
@@ -9,158 +8,200 @@
 # 0x10000000 - 0x3FFFFFFF Thread Stacks
 # 0x00000000 - 0x0FFFFFFF .text / .data / heap
 
+# Note: The general rule is that libraries should be aligned on 1MB
+# boundaries. For ease of updating this file, you will find a comment
+# on each line, indicating the observed size of the library, which is
+# one of:
+#
+#     [<64K] observed to be less than 64K
+#     [~1M] rounded up, one megabyte (similarly for other sizes)
+#     [???] no size observed, assumed to be one megabyte
+
 # core system libraries
-libdl.so                0xAFF00000
-libc.so                 0xAFE00000
-libstdc++.so            0xAFD00000
-libm.so                 0xAFC00000
-liblog.so               0xAFBC0000
-libcutils.so            0xAFB00000
-libthread_db.so         0xAFA00000
-libz.so                 0xAF900000
-libevent.so             0xAF800000
-libssl.so               0xAF700000
-libcrypto.so            0xAF500000
-libsysutils.so          0xAF400000
+libdl.so                0xAFF00000 # [<64K]
+libc.so                 0xAFD00000 # [~2M]
+libstdc++.so            0xAFC00000 # [<64K]
+libm.so                 0xAFB00000 # [~1M]
+liblog.so               0xAFA00000 # [<64K]
+libcutils.so            0xAF900000 # [~1M]
+libthread_db.so         0xAF800000 # [<64K]
+libz.so                 0xAF700000 # [~1M]
+libevent.so             0xAF600000 # [???]
+libssl.so               0xAF400000 # [~2M]
+libcrypto.so            0xAF000000 # [~4M]
+libsysutils.so          0xAEF00000 # [~1M]
 
 # bluetooth
-liba2dp.so              0xAEE00000
-audio.so                0xAED00000
-input.so                0xAEC00000
-libbluetoothd.so        0xAEB00000
-libbluedroid.so         0xAEA00000
-libbluetooth.so         0xAE900000
-libdbus.so              0xAE800000
+liba2dp.so              0xAEE00000 # [~1M]
+audio.so                0xAED00000 # [~1M]
+input.so                0xAEC00000 # [~1M]
+libbluetoothd.so        0xAEA00000 # [~2M]
+libbluedroid.so         0xAE900000 # [<64K]
+libbluetooth.so         0xAE800000 # [~1M]
+libdbus.so              0xAE700000 # [~1M]
 
 # extended system libraries
-libril.so               0xAE400000
-libreference-ril.so     0xAE000000
-libwpa_client.so        0xADC00000
-libnetutils.so          0xADB00000
+libril.so               0xAE600000 # [~1M]
+libreference-ril.so     0xAE500000 # [~1M]
+libwpa_client.so        0xAE400000 # [<64K]
+libnetutils.so          0xAE300000 # [~1M]
 
 # core dalvik runtime support
-libandroid_servers.so   0xAD900000
-#libicudata.so           0xAD600000
-libicuuc.so             0xAD500000
-libicui18n.so           0xAD400000
-libandroid_runtime.so   0xAD300000
-libnativehelper.so      0xAD200000
-libdvm-ARM.so           0xAD100000
-libdvm.so               0xAD000000
+libandroid_servers.so   0xAE200000 # [~1M]
+libicuuc.so             0xADE00000 # [~4M]
+libicui18n.so           0xAD900000 # [~5M]
+libandroid_runtime.so   0xAD300000 # [~6M]
+libnativehelper.so      0xAD100000 # [~2M]
+libdvm-ARM.so           0xAD000000 # [???]
+libdvm.so               0xACA00000 # [~6M]
+# Note: libicudata.so intentionally omitted
 
 # graphics
-libpixelflinger.so      0xACF00000
+libpixelflinger.so      0xAC900000 # [~1M]
 # libcorecg is for backward-compatibility with donut
-libcorecg.so            0xACE00000
-libsurfaceflinger.so    0xACD00000
-libGLES_android.so      0xACC80000
-libagl.so               0xACC00000
+libcorecg.so            0xAC800000 # [???]
+libsurfaceflinger_client.so 0xAC700000 # [~1M]
+libsurfaceflinger.so    0xAC500000 # [~2M]
+libGLES_android.so      0xAC400000 # [~1M]
+libagl.so               0xAC300000 # [???]
 
-libGLESv1_CM.so         0xACB00000
-libGLESv2.so            0xACA00000
-libOpenVG_CM.so         0xAC900000
-libOpenVGU_CM.so        0xAC800000
-libEGL.so               0xAC700000
+libGLESv1_CM.so         0xAC200000 # [~1M]
+libGLESv2.so            0xAC100000 # [~1M]
+libOpenVG_CM.so         0xAC000000 # [???]
+libOpenVGU_CM.so        0xABF00000 # [???]
+libEGL.so               0xABE00000 # [~1M]
+libETC1.so              0xABD00000 # [<64K]
 
-libacc.so               0xAC600000
+libacc.so               0xABC00000 # [~1M]
 
-libexif.so              0xAC500000
-libui.so                0xAC400000
+libexif.so              0xABB00000 # [~1M]
+libcamera_client.so     0xABA80000 # [~1M]
+libui.so                0xAB900000 # [~1M]
 # libsgl is for backward-compatibility with donut
-libsgl.so               0xAC200000
-libskia.so              0xAC000000
-librs_jni.so            0xABF00000
-libRS.so                0xAB900000
-
+libsgl.so               0xAB800000 # [???]
+libskia.so              0xAB100000 # [~7M]
+librs_jni.so            0xAB000000 # [~1M]
+libRS.so                0xA9E00000 # [~2M]
+libjnigraphics.so       0xA9D00000 # [<64K]
+libskiagl.so            0xA9C00000 # [~1M]
 
 # audio
-libFLAC.so              0xAB8A0000
-libaudiopolicy.so       0xAB880000
-libaudiopolicygeneric.so 0xAB800000
-libsoundpool.so         0xAB780000
-libaudio.so             0xAB700000
-libspeech.so            0xAB600000
-libsonivox.so           0xAB500000
-libvorbisidec.so        0xAB400000
-libmedia_jni.so         0xAB300000
-libmediaplayerservice.so 0xAB280000
-libmedia.so             0xAB200000
-libFFTEm.so             0xAB100000
-libaudioflinger.so      0xAB000000
+libFLAC.so              0xA9B00000 # [???]
+libaudiopolicy.so       0xA9A00000 # [~1M]
+libaudiopolicygeneric.so 0xA9900000 # [???]
+libsoundpool.so         0xA9800000 # [~1M]
+libaudio.so             0xA9700000 # [~1M]
+libspeech.so            0xA9600000 # [~1M]
+libsonivox.so           0xA9500000 # [~1M]
+libvorbisidec.so        0xA9400000 # [~1M]
+libmedia_jni.so         0xA9300000 # [~1M]
+libmediaplayerservice.so 0xA9200000 # [~1M]
+libmedia.so             0xA9000000 # [~2M]
+libFFTEm.so             0xA8F00000 # [~1M]
+libSR_AudioIn.so        0xA8E00000 # [~1M] for external/srec
+libaudioflinger.so      0xA8D00000 # [~1M]
 
 # assorted system libraries
-libsqlite.so            0xAAC00000
-libexpat.so             0xAAB00000
-libwebcore.so           0xAA000000
-libbinder.so            0xA9D80000
-libutils.so             0xA9D00000
-libcameraservice.so     0xA9C80000
-libhardware.so          0xA9C70000
-libhardware_legacy.so   0xA9C00000
-libapp_process.so       0xA9B00000
-libsystem_server.so     0xA9A00000
-libime.so               0xA9800000
-libgps.so               0xA9700000
-libcamera.so            0xA9680000
-liboemcamera.so         0xA9400000
+libsqlite.so            0xA8B00000 # [~2M]
+libexpat.so             0xA8A00000 # [~1M]
+libwebcore.so           0xA8300000 # [~7M]
+libbinder.so            0xA8200000 # [~1M]
+libutils.so             0xA8100000 # [~1M]
+libcameraservice.so     0xA8000000 # [~1M]
+libhardware.so          0xA7F00000 # [<64K]
+libhardware_legacy.so   0xA7E00000 # [~1M]
+libapp_process.so       0xA7D00000 # [???]
+libsystem_server.so     0xA7C00000 # [~1M]
+libime.so               0xA7B00000 # [???]
+libgps.so               0xA7A00000 # [~1M]
+libcamera.so            0xA7900000 # [~1M]
+liboemcamera.so         0xA7700000 # [~2M]
+libdiskconfig.so        0xA7600000 # [<64K]
+libemoji.so             0xA7500000 # [<64K]
+libjni_latinime.so      0xA7400000 # [~1M]
+libjni_pinyinime.so     0xA7300000 # [~1M]
+libttssynthproxy.so     0xA7200000 # [~1M] for frameworks/base
+libttspico.so           0xA7000000 # [~2M] for external/svox
 
 # pv libraries
-libpvasf.so                    0xA7C26000
-libpvasfreg.so                 0xA7C00000
-libomx_sharedlibrary.so        0xA7BA0000
-libopencore_download.so        0xA7B40000
-libopencore_downloadreg.so     0xA7B00000
-libopencore_net_support.so     0xA7A00000
-libopencore_rtsp.so            0xA7900000
-libopencore_rtspreg.so         0xA7890000
-libopencore_author.so          0xA7800000
-libomx_aacdec_sharedlibrary.so 0xA7700000
-libomx_amrdec_sharedlibrary.so 0xA76A0000
-libomx_amrenc_sharedlibrary.so 0xA7680000
-libomx_avcdec_sharedlibrary.so 0xA7660000
-libomx_avcenc_sharedlibrary.so 0xA7610000
-libomx_m4vdec_sharedlibrary.so 0xA75C0000
-libomx_m4venc_sharedlibrary.so 0xA7590000
-libomx_mp3dec_sharedlibrary.so 0xA7450000
-libopencore_mp4local.so        0xA7400000
-libopencore_mp4localreg.so     0xA7300000
-libopencore_player.so          0xA7000000
+libpvasf.so                    0xA6F00000 # [???]
+libpvasfreg.so                 0xA6E00000 # [???]
+libomx_sharedlibrary.so        0xA6D00000 # [~1M]
+libopencore_download.so        0xA6C00000 # [~1M]
+libopencore_downloadreg.so     0xA6B00000 # [~1M]
+libopencore_net_support.so     0xA6800000 # [~3M]
+libopencore_rtsp.so            0xA6200000 # [~6M]
+libopencore_rtspreg.so         0xA6100000 # [~1M]
+libopencore_author.so          0xA5D00000 # [~4M]
+libomx_aacdec_sharedlibrary.so 0xA5B00000 # [~2M]
+libomx_amrdec_sharedlibrary.so 0xA5A00000 # [~1M]
+libomx_amrenc_sharedlibrary.so 0xA5900000 # [~1M]
+libomx_avcdec_sharedlibrary.so 0xA5800000 # [~1M]
+libomx_avcenc_sharedlibrary.so 0xA5700000 # [???]
+libomx_m4vdec_sharedlibrary.so 0xA5600000 # [~1M]
+libomx_m4venc_sharedlibrary.so 0xA5500000 # [???]
+libomx_mp3dec_sharedlibrary.so 0xA5400000 # [~1M]
+libopencore_mp4local.so        0xA5200000 # [~2M]
+libopencore_mp4localreg.so     0xA5100000 # [~1M]
+libopencore_player.so          0xA4800000 # [~9M]
 
 # opencore hardware support
-libmm-adspsvc.so              0xA6FFD000
-libOmxCore.so                 0xA6FF0000
-libOmxMpeg4Dec.so             0xA6FC0000
-libOmxH264Dec.so              0xA6F90000
-libOmxVidEnc.so               0xA6F60000
-libopencorehw.so              0xA6F50000
+libmm-adspsvc.so              0xA4700000 # [<64K]
+libOmxCore.so                 0xA4600000 # [<64K]
+libOmxMpeg4Dec.so             0xA4500000 # [~1M]
+libOmxH264Dec.so              0xA4400000 # [~1M]
+libOmxVidEnc.so               0xA4300000 # [~1M]
+libopencorehw.so              0xA4200000 # [~1M]
+libOmxVdec.so                 0xA4100000 # [~1M]
+libmm-omxcore.so              0xA4000000 # [<64K]
 
 # pv libraries
-libopencore_common.so         0xA6000000
-libqcomm_omx.so               0xA5A00000
+libopencore_common.so         0xA3900000 # [~7M]
+libqcomm_omx.so               0xA3800000 # [<64K]
+
+# stagefright libraries
+libstagefright_amrnb_common.so     0xA3700000 # [~1M]
+libstagefright_avc_common.so       0xA3600000 # [~1M]
+libstagefright_color_conversion.so 0xA3500000 # [<64K]
+libstagefright_omx.so              0xA3400000 # [~1M]
+libstagefrighthw.so                0xA3300000 # [~1M]
+libstagefright.so                  0xA2F00000 # [~4M]
+
+# libraries for specific hardware
+libgsl.so               0xA2E00000 # [~1M]
+libhtc_acoustic.so      0xA2D00000 # [<64K]
+libhtc_ril.so           0xA2C00000 # [~1M]
+liblvmxipc.so           0xA2B00000 # [~1M] for vendor/nxp
+libreference-cdma-sms.so 0xA2A00000 # [<64K] for hardware/ril
 
 # libraries for specific apps or temporary libraries
-libcam_ipl.so           0x9F000000
-libwbxml.so             0x9E800000
-libwbxml_jni.so         0x9E400000
-libxml2wbxml.so         0x9E000000
-libaes.so               0x9DC00000
-libdrm1.so              0x9D800000
-libdrm1_jni.so          0x9D400000
-libwapcore.so           0x9D000000
-libstreetview.so        0x9CC00000
-libwapbrowsertest.so    0x9C800000
-libminiglobe.so         0x9C400000
-libearth.so             0x9C000000
-libembunit.so           0x9BC00000
-libneon.so              0x9B800000
-libjni_example.so       0x9B400000
-libjni_load_test.so     0x9B000000
-libjni_lib_test.so      0x9AC00000
-librunperf.so           0x9A800000
-libctest.so             0x9A700000
-libUAPI_jni.so          0x9A500000
-librpc.so               0x9A400000
-libtrace_test.so        0x9A300000
-libsrec_jni.so          0x9A200000
-libcerttool_jni.so      0x9A100000
-
+libcam_ipl.so           0x9F000000 # [???]
+libwbxml.so             0x9EF00000 # [???]
+libwbxml_jni.so         0x9EE00000 # [~1M]
+libxml2wbxml.so         0x9EB00000 # [~1M]
+libdrm1.so              0x9EA00000 # [~1M]
+libdrm1_jni.so          0x9E900000 # [<64K]
+libwapcore.so           0x9E800000 # [???]
+libstreetview.so        0x9E700000 # [???]
+libwapbrowsertest.so    0x9E600000 # [???]
+libminiglobe.so         0x9E500000 # [???]
+libearth.so             0x9E400000 # [???]
+libembunit.so           0x9E300000 # [<64K]
+libneon.so              0x9E200000 # [???]
+libjni_example.so       0x9E100000 # [???]
+libjni_load_test.so     0x9E000000 # [???]
+libjni_lib_test.so      0x9DF00000 # [???]
+librunperf.so           0x9DE00000 # [???]
+libctest.so             0x9DD00000 # [<64K]
+libUAPI_jni.so          0x9DC00000 # [???]
+librpc.so               0x9DB00000 # [~1M]
+libtrace_test.so        0x9DA00000 # [???]
+libsrec_jni.so          0x9D800000 # [~2M]
+libjpeg.so              0x9D700000 # [~1M]
+libiprouteutil.so       0x9D600000 # [~1M] for external/iproute2
+libnetlink.so           0x9D500000 # [<64K] for external/iproute2
+libpagemap.so           0x9D400000 # [<64K] for system/extras/libpagemap
+libstlport.so           0x9D100000 # [~3M] for external/stlport
+libzxing.so             0x9D000000 # [<64K] for goggles
+libinterstitial.so      0x9CF00000 # [<64K] for goggles
+liblept.so              0x9CA00000 # [~5M] for external/leptonica
diff --git a/core/product.mk b/core/product.mk
index 5417242..38d1148 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -29,13 +29,13 @@
 endef
 
 #
-# Returns the sorted concatenation of all PRODUCT_MAKEFILES
-# variables set in all AndroidProducts.mk files.
-# $(call ) isn't necessary.
+# Returns the sorted concatenation of PRODUCT_MAKEFILES
+# variables set in the given AndroidProducts.mk files.
+# $(1): the list of AndroidProducts.mk files.
 #
-define get-all-product-makefiles
+define get-product-makefiles
 $(sort \
-  $(foreach f,$(_find-android-products-files), \
+  $(foreach f,$(1), \
     $(eval PRODUCT_MAKEFILES :=) \
     $(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) \
     $(eval include $(f)) \
@@ -47,6 +47,15 @@
 endef
 
 #
+# Returns the sorted concatenation of all PRODUCT_MAKEFILES
+# variables set in all AndroidProducts.mk files.
+# $(call ) isn't necessary.
+#
+define get-all-product-makefiles
+$(call get-product-makefiles,$(_find-android-products-files))
+endef
+
+#
 # Functions for including product makefiles
 #
 
@@ -101,6 +110,14 @@
   $(eval ALL_PRODUCTS := $(sort $(ALL_PRODUCTS) $(word 1,$(_include_stack))))
 endef
 
+
+#
+# Do inherit-product only if $(1) exists
+#
+define inherit-product-if-exists
+  $(if $(wildcard $(1)),$(call inherit-product,$(1)),)
+endef
+
 #
 # $(1): product makefile list
 #
diff --git a/core/product_config.mk b/core/product_config.mk
index ffb8d27..e86b040 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -149,6 +149,27 @@
 # else: Use the value set in the environment or buildspec.mk.
 
 # ---------------------------------------------------------------
+# Provide "APP-<appname>" targets, which lets you build
+# an unbundled app.
+#
+unbundled_goals := $(strip $(filter APP-%,$(MAKECMDGOALS)))
+ifdef unbundled_goals
+  ifneq ($(words $(unbundled_goals)),1)
+    $(error Only one APP-* goal may be specified; saw "$(unbundled_goals)"))
+  endif
+  UNBUNDLED_APPS := $(strip $(subst -, ,$(patsubst APP-%,%,$(unbundled_goals))))
+  ifneq ($(filter $(DEFAULT_GOAL),$(MAKECMDGOALS)),)
+    MAKECMDGOALS := $(patsubst $(unbundled_goals),,$(MAKECMDGOALS))
+  else
+    MAKECMDGOALS := $(patsubst $(unbundled_goals),$(DEFAULT_GOAL),$(MAKECMDGOALS))
+  endif
+  is_unbundled_app_build := true
+
+.PHONY: $(unbundled_goals)
+$(unbundled_goals): $(MAKECMDGOALS)
+endif # unbundled_goals
+
+# ---------------------------------------------------------------
 # Include the product definitions.
 # We need to do this to translate TARGET_PRODUCT into its
 # underlying TARGET_DEVICE before we start defining any rules.
@@ -157,12 +178,18 @@
 include $(BUILD_SYSTEM)/product.mk
 include $(BUILD_SYSTEM)/device.mk
 
-# Read in all of the product definitions specified by the AndroidProducts.mk
-# files in the tree.
-#
-#TODO: when we start allowing direct pointers to product files,
-#    guarantee that they're in this list.
-$(call import-products, $(get-all-product-makefiles))
+ifeq ($(strip $(is_unbundled_app_build)),true)
+  # An unbundled app build needs only the core product makefiles.
+  $(call import-products,$(call get-product-makefiles,\
+      $(SRC_TARGET_DIR)/product/AndroidProducts.mk))
+else
+  # Read in all of the product definitions specified by the AndroidProducts.mk
+  # files in the tree.
+  #
+  #TODO: when we start allowing direct pointers to product files,
+  #    guarantee that they're in this list.
+  $(call import-products, $(get-all-product-makefiles))
+endif # is_unbundled_app_build
 $(check-all-products)
 #$(dump-products)
 #$(error done)
diff --git a/core/proguard.flags b/core/proguard.flags
index afd1548..06e32cc 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -1,7 +1,60 @@
 # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
 -optimizations !code/simplification/arithmetic
+-optimizations !code/simplification/cast
 -allowaccessmodification
 
+# To prevent name conflict in incremental obfuscation.
+-useuniqueclassmembernames
+
+# dex does not like code run through proguard optimize and preverify steps.
+-dontoptimize
+-dontpreverify
+
+# Don't obfuscate. We only need dead code striping.
+-dontobfuscate
+
+# Add this flag in your package's own configuration if it's needed.
+#-flattenpackagehierarchy
+
 # Some classes in the libraries extend package private classes to chare common functionality
 # that isn't explicitly part of the API
--dontskipnonpubliclibraryclasses
+-dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
+
+# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+# class$ methods are inserted by some compilers to implement .class construct,
+# see http://proguard.sourceforge.net/manual/examples.html#library
+-keepclassmembernames class * {
+    java.lang.Class class$(java.lang.String);
+    java.lang.Class class$(java.lang.String, boolean);
+}
+
+# Keep classes and methods that have the guava @VisibleForTesting annotation
+-keep @com.google.common.annotations.VisibleForTesting class *
+-keepclassmembers class * {
+@com.google.common.annotations.VisibleForTesting *;
+}
+
+# Please specify classes to be kept explicitly in your package's configuration.
+# -keep class * extends android.app.Activity
+# -keep class * extends android.view.View
+# -keep class * extends android.app.Service
+# -keep class * extends android.content.BroadcastReceiver
+# -keep class * extends android.content.ContentProvider
+# -keep class * extends android.preference.Preference
+# -keep class * extends android.app.BackupAgent
+
+#-keep class * implements android.os.Parcelable {
+#  public static final android.os.Parcelable$Creator *;
+#}
+
+
diff --git a/core/proguard_tests.flags b/core/proguard_tests.flags
new file mode 100644
index 0000000..f4063d6
--- /dev/null
+++ b/core/proguard_tests.flags
@@ -0,0 +1,21 @@
+# Keep everything for tests
+-dontshrink -dontobfuscate
+
+#-keep class * extends junit.framework.TestCase {
+#  public void test*();
+#}
+
+#-keepclasseswithmembers class * {
+#  public static void run();
+#  public static junit.framework.Test suite();
+#}
+
+# some AllTests don't include run().
+#-keepclasseswithmembers class * {
+#  public static junit.framework.Test suite();
+#}
+
+#-keep class * extends junit.framework.TestSuite
+#-keep class * extends android.app.Instrumentation
+#-keep class * extends android.test.TestSuiteProvider
+
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
index 044e4af..740668c 100644
--- a/core/tasks/apicheck.mk
+++ b/core/tasks/apicheck.mk
@@ -41,13 +41,18 @@
 # Run the checkapi rules by default.
 droidcore: checkapi
 
+last_released_sdk_version := $(lastword $(call numerically_sort,\
+    $(patsubst $(SRC_API_DIR)/%.xml,%, \
+    $(filter-out $(SRC_API_DIR)/current.xml, \
+    $(wildcard $(SRC_API_DIR)/*.xml)))))
+
 # INTERNAL_PLATFORM_API_FILE is the one build by droiddoc.
 
 # Check that the API we're building hasn't broken the last-released
 # SDK version.
 $(eval $(call check-api, \
 	checkapi-last, \
-	$(SRC_API_DIR)/$(lastword $(TARGET_AVAILABLE_SDK_VERSIONS)).xml, \
+	$(SRC_API_DIR)/$(last_released_sdk_version).xml, \
 	$(INTERNAL_PLATFORM_API_FILE), \
 	-hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 \
 	-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 9cc49c4..ec5dcd4 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -41,7 +41,7 @@
   # which is the version that we reveal to the end user.
   # Update this value when the platform version changes (rather
   # than overriding it somewhere else).  Can be an arbitrary string.
-  PLATFORM_VERSION := 2.1-update1
+  PLATFORM_VERSION := 2.2
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -53,7 +53,7 @@
   # intermediate builds).  During development, this number remains at the
   # SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
   # the code-name of the new development work.
-  PLATFORM_SDK_VERSION := 7
+  PLATFORM_SDK_VERSION := 8
 endif
 
 ifeq "" "$(PLATFORM_VERSION_CODENAME)"
diff --git a/envsetup.sh b/envsetup.sh
index 4eede33..9c6e695 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -625,7 +625,8 @@
             if [ -f $DIR/Android.mk ]; then
                 TO_CHOP=`echo $T | wc -c | tr -d ' '`
                 TO_CHOP=`expr $TO_CHOP + 1`
-                MFILE=`echo $PWD | cut -c${TO_CHOP}-`
+                START=`PWD= /bin/pwd`
+                MFILE=`echo $START | cut -c${TO_CHOP}-`
                 if [ "$MFILE" = "" ] ; then
                     MFILE=$DIR/Android.mk
                 else
@@ -770,7 +771,7 @@
 
 function cgrep()
 {
-    find . -type f -name "*\.c*" -print0 | xargs -0 grep --color -n "$@"
+    find . -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' \) -print0 | xargs -0 grep --color -n "$@"
 }
 
 function resgrep()
@@ -985,9 +986,10 @@
         echo "Usage: godir <regex>"
         return
     fi
+    T=$(gettop)
     if [[ ! -f $T/filelist ]]; then
         echo -n "Creating index..."
-        (cd $T; find . -wholename ./out -prune -o -type f > filelist)
+        (cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist)
         echo " Done"
         echo ""
     fi
@@ -1024,6 +1026,20 @@
     cd $T/$pathname
 }
 
+# Force JAVA_HOME to point to java 1.5 if it isn't already set
+if [ "$STAY_OFF_MY_LAWN" = "" ]; then
+    if [ ! "$JAVA_HOME" ]; then
+        case `uname -s` in
+            Darwin)
+                export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home
+                ;;
+            *)
+                export JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun
+                ;;
+        esac
+    fi
+fi
+
 # determine whether arrays are zero-based (bash) or one-based (zsh)
 _xarray=(a b c)
 if [ -z "${_xarray[${#_xarray[@]}]}" ]
@@ -1035,7 +1051,7 @@
 unset _xarray
 
 # Execute the contents of any vendorsetup.sh files we can find.
-for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh 2> /dev/null`
+for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh device/*/*/vendorsetup.sh 2> /dev/null`
 do
     echo "including $f"
     . $f
diff --git a/history/cupcake.txt b/history/cupcake.txt
deleted file mode 100644
index 7947f93..0000000
--- a/history/cupcake.txt
+++ /dev/null
@@ -1,1103 +0,0 @@
-Cupcake auto-import at change 127436, Jan 22 2009.
-
-(cd bionic && git checkout c2f23bb1cdea20fc5e8e5b8101d9d0bd6d14b74b)
-(cd bootable/bootloader/legacy && git checkout d08c9e9444e2fb688ca4d3c4d807ba69c680fb3c)
-(cd bootable/diskinstaller && git checkout a2bb8bf00fbd01859e2475fc36fc6fa070e6eaa9)
-(cd bootable/recovery && git checkout 6d12e0d6f8fe05ebd6b0210fed00e0ff874a3d70)
-(cd build && git checkout b33e7b0cb085a1937c1a2e5b81eb78d6059bf6bc)
-(cd dalvik && git checkout cd18d5743d1957b1c1f57c0abe7ea28187c63a9f)
-(cd development && git checkout 2f3ec0146063b7bed40ff4f41c73407cebdc71fc)
-(cd external/aes && git checkout 17e798f9d2c0a804b5dcac6ee4b2bc1eee66e3b2)
-(cd external/apache-http && git checkout 4e30c8f9f80e5bd40fd8f018760b01a80b16b8c3)
-(cd external/bison && git checkout b7f2b4d529ee03ee0e4172cc06e7cd973bd9bef5)
-(cd external/bluez && git checkout dbbd69e74e390449430a6c357a098fd345fde2ed)
-(cd external/bsdiff && git checkout 03874566c6f74e11d030fa2c534b3dd5a06721af)
-(cd external/bzip2 && git checkout d78fa13a44d08622d61d0df71e731de77021dcf1)
-(cd external/clearsilver && git checkout b651aeec8a719c9f639ef710423e29463123d4f6)
-(cd external/dbus && git checkout ed0821c6a30852d02d05ce85d4ad4a567ff8a3da)
-(cd external/dhcpcd && git checkout 4c5a5fb53bccceff331bae70f748bf9b4609fe0a)
-(cd external/dosfstools && git checkout c936fe75ee33b6cbc46e6124679d9a1d5d471663)
-(cd external/dropbear && git checkout 1abbfe5d373a44e7e0525fb7971ef0e00955f2e4)
-(cd external/e2fsprogs && git checkout 0bc54db4f9a9aab8225f5107a712c4bbbe34f79c)
-(cd external/elfcopy && git checkout 8d6d7ea32d2e40489fa8be26618167fb6e2dfb40)
-(cd external/elfutils && git checkout ee6008996aa701ad2a50d5d6b1529c9e2c2724c1)
-(cd external/embunit && git checkout 225a86217dd274aea51b1e442568e7aec43a74e9)
-(cd external/emma && git checkout 725ce5e17f431acc3b549f87464a7883f98adf66)
-(cd external/esd && git checkout 7ef614b2e0ad463c3454cd9ba1052c2964e14596)
-(cd external/expat && git checkout da44bf784a2b6acb5df7f40b32c0d4b563fba3ed)
-(cd external/fdlibm && git checkout 74aa530c6ca9c2f10a0e3635b4211f1438b972b2)
-(cd external/freetype && git checkout b36db06baca4c030538565e01b8264971c9b69f8)
-(cd external/gdata && git checkout e784ba4a104f64d1f57dad38ff76764b5718bea0)
-(cd external/genext2fs && git checkout f4a0b4d282a1718ac6e3fff10d02aa877e294324)
-(cd external/giflib && git checkout ff6a75e423d8333c6657e4a66494e0bc9ed34385)
-(cd external/googleclient && git checkout d3974b69b023cb38541d1870ad5c35e4b2ea2c35)
-(cd external/grub && git checkout 1650e5296608be8925d9831310c9ad3595fd6869)
-(cd external/icu4c && git checkout 80865003e90c51ddd5f1e5e1be5ebc1add6af188)
-(cd external/iptables && git checkout 10a1e8d1003257d408c77662fc5ce6470a19b245)
-(cd external/jdiff && git checkout 0e7cb56de28fb496d69a1dd1907388b2076224d6)
-(cd external/jhead && git checkout 9705c3e3c1b19598026449c303d54cdc485f35a9)
-(cd external/jpeg && git checkout 9175dba76b0c31e0870fe074d476650cf258071c)
-(cd external/libffi && git checkout 8c63892438fbb7ef754e55c60220dd02e7c8fd70)
-(cd external/libpcap && git checkout 23295e59cff9c04be154ede6afad16bc9fe385cf)
-(cd external/libpng && git checkout 78ac9384d6ca0067d77b843b70bbdd828bb738df)
-(cd external/libxml2 && git checkout 2c905f99793b8da7f02349aa69fc01cba533f935)
-(cd external/netcat && git checkout 6fc2e7182a81d3665e5233a6555fc6c1960b6b8a)
-(cd external/netperf && git checkout acbeb739a2260972afbd58233fc8939fe5014e3c)
-(cd external/neven && git checkout dfddd36f99a6e11ca3b0107b49f35c623203c8f2)
-(cd external/opencore && git checkout 7a7c607909568a2a1b561023be821919bdb9d578)
-(cd external/openssl && git checkout 499ee9f31d10290f510c2f3785b6abe1314993ec)
-(cd external/oprofile && git checkout b0a81c270584f10323634816b6e5e19711690233)
-(cd external/ping && git checkout 8a5b42ad26815061053bc553b2d04fcbbce5f9d0)
-(cd external/ppp && git checkout 9d869087afe63b8506a367aaeb2008459c823ecf)
-(cd external/protobuf && git checkout 2f1917b2d9754d6288e8de2739469bf719438388)
-(cd external/qemu && git checkout 7a5cb2bf2725afddd4ff9ede151063d23b849d94)
-(cd external/safe-iop && git checkout a625f2f303bd1e1eb8287d82075fa9a240296167)
-(cd external/skia && git checkout 07051704de661e1c4e0fffc4f486afb60110f7e6)
-(cd external/sonivox && git checkout 372b906dec9f897dc04ba3bbd00c908bb2304e95)
-(cd external/sqlite && git checkout 60a965a2f8a63d7704130d867458495a324801e1)
-(cd external/srec && git checkout 00743dcf9e86961f3867b81ef81022040c821f18)
-(cd external/strace && git checkout 67670f6420d064f0b0f54ab2cf2f07752dcc35c7)
-(cd external/tagsoup && git checkout 4bb395b502d0c2495f7a5d226ccf7f06f53dea38)
-(cd external/tcpdump && git checkout f3ccc4ec63431539743f1155a60192a40f6bec24)
-(cd external/tinyxml && git checkout 600ebb441039bcb8a0340df016c6685a688b7647)
-(cd external/tremor && git checkout 0ad0141e864cfbb130db4f22e279d421832e7336)
-(cd external/webkit && git checkout 3607268bbf57cd3af1bb2d67e956821fb8e3c9ec)
-(cd external/wpa_supplicant && git checkout 17800c6dac7ac53c2b348151274071a4cc6e4318)
-(cd external/xdelta3 && git checkout 65fb2b2df617551c42d9bdf7b5bc88168ce6f1ff)
-(cd external/yaffs2 && git checkout d333fc232d7e5ae3370080d5d6f7d88ea9c6b3a1)
-(cd external/zlib && git checkout e860c69e014c1dfed34cf4ee808d200648205f2a)
-(cd frameworks/base && git checkout 94cbba0933e50d593c1c462cff698dd3387ba95b)
-(cd frameworks/opt/com.google.android && git checkout 95252a12ffcf47582ab8b68a35a996ef50cdb523)
-(cd frameworks/opt/com.google.android.googlelogin && git checkout 8f1d2acbab346be5c40d06d24a07bc169ad9c60e)
-(cd frameworks/policies/base && git checkout 880754ac4766e622367a6d65304c0b4176260e0d)
-(cd hardware/libhardware && git checkout 37156b8db0bee9a0e77160a40483d0fad0409bd4)
-(cd hardware/libhardware_legacy && git checkout 5af6317f266c0f7792f6a2fa1c2061f61529aab7)
-(cd hardware/ril && git checkout 154a2efc9b75de255cf9c3916d9d778c445df2ae)
-(cd kernel && git checkout 3c625cce51fadd88b75db8b6766de38f4ce7deaf)
-(cd packages/apps/AlarmClock && git checkout c8208f9f6ff76479da3b1eb0cedbd5500b8be1f4)
-(cd packages/apps/Browser && git checkout c3996145a81b44e27b7fad251e460ccf9c4a5d61)
-(cd packages/apps/Calculator && git checkout d3f7cb4de21253fbeeec0cf4b680bd79e6e62e8a)
-(cd packages/apps/Calendar && git checkout 1c94a74857db16dec676dc16e1ff58f9a4d0385c)
-(cd packages/apps/Camera && git checkout bf1c107ea0bbe8d80769b70d8e9b50dbf8cfcc09)
-(cd packages/apps/Contacts && git checkout cbe59e173d0baf73e98b12ac889ca17172677121)
-(cd packages/apps/Email && git checkout 6f463987544260a770b9203bd412fb665c59d0f9)
-(cd packages/apps/GoogleSearch && git checkout 2134a0d22132a8e68b6914ce466aa2acf28c244a)
-(cd packages/apps/HTMLViewer && git checkout ae36e6ba1ad74a7eb844a41c6c0fc1ecd3c66467)
-(cd packages/apps/IM && git checkout ad1551cc24ebeffda11932c1d2cae0cf1b69a854)
-(cd packages/apps/Launcher && git checkout a3673051acdee1f88b68ffc3a39f0db8529009ff)
-(cd packages/apps/Mms && git checkout 2d9959fea0cfea5fca09d139b66b1fa2cd45bf49)
-(cd packages/apps/Music && git checkout fa0935a617742fe1545bb65202d2b93af8985b6a)
-(cd packages/apps/PackageInstaller && git checkout 3a1faab9685bd0fc39ea7bf5bdc7237805d09c58)
-(cd packages/apps/Phone && git checkout 4974565b48789d5b12c302a846fc090e67039647)
-(cd packages/apps/Settings && git checkout c0a8abbb4f423c0aaa66a1e09bafd4b845837537)
-(cd packages/apps/SoundRecorder && git checkout eb2e5e6a43c0756e9d3e149f46f6a504747175f2)
-(cd packages/apps/Stk && git checkout 4e63a901fb044d270868b4f3abc8abb20d011230)
-(cd packages/apps/Sync && git checkout d8aa470c7fea6a43e269da78e1a2b8c14fb40c70)
-(cd packages/apps/Updater && git checkout 9e0cd9b717f546609ec155f6be3764554ede6408)
-(cd packages/apps/VoiceDialer && git checkout 1ab735e15b6855beabd22f5b87d497f83b3b5b6a)
-(cd packages/providers/CalendarProvider && git checkout 3690a0259f2c62501a47c9a4ecd007f1c1cc599a)
-(cd packages/providers/ContactsProvider && git checkout ef7f8057050027ce57424b69dc697d4127ffc37d)
-(cd packages/providers/DownloadProvider && git checkout b7f50f86e1f424ab05dc8154c3fabbfb3ecd4c47)
-(cd packages/providers/DrmProvider && git checkout 7f08c3d1582a2195fd7b28a3157dedd975230d8b)
-(cd packages/providers/GoogleContactsProvider && git checkout 1a6c0f279fe754b041290768bfa753e5f58e43ad)
-(cd packages/providers/GoogleSubscribedFeedsProvider && git checkout 88f4be5460c130c048e5017999a80275d71a88d6)
-(cd packages/providers/ImProvider && git checkout 8d4eb986192e7682c770449e0695d23d954a5691)
-(cd packages/providers/MediaProvider && git checkout ef92b4dc14a5f8093cb1b58888c213a867504afa)
-(cd packages/providers/TelephonyProvider && git checkout 62f78e4e0ae991f0df285488a1af382bd5105483)
-(cd prebuilt && git checkout 4ef7c54fb1bdfbd5e93d631c7f76ea216ab2d375)
-(cd system/bluetooth && git checkout 36658369459e22152cce54bd1c0660d71a270947)
-(cd system/core && git checkout 4a4c9f6f98055918f1ebff06b3cc1ed622c058fe)
-(cd system/extras && git checkout 1d68e595e72f955a8cd12f59825943ea71daf7d5)
-(cd system/wlan/ti && git checkout 6ff408df1efe9981f20ab8ce6ec36d6ff6f034dc)
-
-Change 127102
-
-	Allow different "Settings > About phone > Contributors" for different products.  The product-specific contributors.{html,css} are copied to /system/etc, and the Contributors activity loads it from there.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/build/core/product.mk#4 edit
-... //branches/cupcake/android/build/core/product_config.mk#9 edit
-
---------
-
-Change 127106
-
-	This removes the patch intended to fix this webkit bug
-	http://bugs.webkit.org/show_bug.cgi?id=16512
-	(orginally reported by this bug: http://b/issue?id=954816)
-	
-	The original bug can no longer be reproduced in webkit.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLAppletElement.cpp#3 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLEmbedElement.cpp#3 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLFormElement.cpp#3 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLFormElement.h#3 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLImageElement.cpp#3 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLImageElement.h#2 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLObjectElement.cpp#3 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLPlugInElement.cpp#2 edit
-... //branches/cupcake/android/external/webkit/WebCore/html/HTMLPlugInElement.h#2 edit
-
---------
-
-Change 127112
-
-	Added RemoteViews.setOnClickPendingIntent() that connects onClick events to launch PendingIntents.  Also exposed un-@hide RemoteViews.setImageViewBitmap().  Also added @RemoteView annotation to Button and ImageButton to allow them across the RemoteView boundary, and added tests to verify this happens.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/api/current.xml#105 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/widget/Button.java#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/widget/ImageButton.java#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/widget/RemoteViews.java#2 edit
-... //branches/cupcake/android/frameworks/base/tests/FrameworkTest/res/layout/remote_view_test_good.xml#2 edit
-... //branches/cupcake/android/frameworks/base/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java#2 edit
-
---------
-
-Change 127115
-
-	Fix bug where UMS wouldn't enable properly
-	
-
-Affected files ...
-
-... //branches/cupcake/android/system/core/vold/volmgr.c#8 edit
-
---------
-
-Change 127120
-
-	Automated rollback of changelist 127102.
-
-
-Affected files ...
-
-... //branches/cupcake/android/build/core/product.mk#5 edit
-... //branches/cupcake/android/build/core/product_config.mk#10 edit
-
---------
-
-Change 127126
-
-	Add back auto space on candidate selection.
-	Delay key feedback display.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/inputmethodservice/KeyboardView.java#9 edit
-
---------
-
-Change 127129
-
-	Remove the call to is.reset(). This allows callers to embedded data after the encoded bitmap and be able to retrieve it.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/graphics/java/android/graphics/BitmapFactory.java#2 edit
-
---------
-
-Change 127134
-
-	add copyPixelsFromBuffer, to allow developers to write pixels values with no format or alpha transformations that accompany using setPixels.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/development/samples/ApiDemos/AndroidManifest.xml#7 edit
-... //branches/cupcake/android/development/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java#1 add
-... //branches/cupcake/android/frameworks/base/api/current.xml#106 edit
-... //branches/cupcake/android/frameworks/base/core/jni/android/graphics/Bitmap.cpp#4 edit
-... //branches/cupcake/android/frameworks/base/graphics/java/android/graphics/Bitmap.java#2 edit
-
---------
-
-Change 127136
-
-	Fix power consumption notification when driver is removed
-	
-
-Affected files ...
-
-... //branches/cupcake/android/system/wlan/ti/sta_dk_4_0_4_32/pform/linux/src/esta_drv.c#10 edit
-
---------
-
-Change 127138
-
-	Enable building dosfstools for all non simulator builds
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/dosfstools/src/Android.mk#2 edit
-
---------
-
-Change 127142
-
-	Use a single button for both the mode indicator and the recording indicator.
-	This makes for a smoother user experience when using the trackball, as the
-	focus highlight stays on the button when you start recording.
-	
-	(Bonus: the code's shorter too. We just switch the button's drawable rather than
-	hiding one button and showing another.)
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Camera/res/layout/video_camera.xml#8 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/VideoCamera.java#25 edit
-
---------
-
-Change 127144
-
-	Fix problem that would leave the "now playing" list empty when removing the currently playing song from it.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Music/src/com/android/music/TrackBrowserActivity.java#13 edit
-
---------
-
-Change 127146
-
-	Handle NPE when search is invoked but no suggestions are
-	provided.  Also, add a field
-	that was missing in the parceling of SearchableInfo.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/app/SearchDialog.java#20 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/server/search/SearchableInfo.java#6 edit
-
---------
-
-Change 127147
-
-	Bug fix - SET UP CALL - sending confirmation result twice. TERMINAL RESPONSE is not needed.
-	
-	When the user's confirmation result is handled by Telephony->StkService, returns immediately after calling CommandInterface.handleCallSetupRequestFromSim(). This will insure that the no termainl response is going to be send.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java#2 edit
-
---------
-
-Change 127155
-
-	Don't switch back to video preview mode when bringing up the menu, except if
-	we're recording.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/VideoCamera.java#26 edit
-
---------
-
-Change 127159
-
-	Change back button behavior when ping-ponging between the still-image camera and
-	the single-image gallery view. Now going from the gallery back to the still-image
-	camera acts like a "back" as far as the activity stack is concerned.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/MenuHelper.java#19 edit
-
---------
-
-Change 127165
-
-	Added a test that attempts to access a nonexistent static field.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/dalvik/tests/064-field-access/expected.txt#2 edit
-... //branches/cupcake/android/dalvik/tests/064-field-access/src/GetNonexistent.java#1 add
-... //branches/cupcake/android/dalvik/tests/064-field-access/src/Holder.java#1 add
-... //branches/cupcake/android/dalvik/tests/064-field-access/src/Main.java#2 edit
-... //branches/cupcake/android/dalvik/tests/064-field-access/src2/Holder.java#1 add
-
---------
-
-Change 127170
-
-	Setup a place to put IMF/IME sample activities. The idea is to try to
-	create situations that we want to test the IMF/IME against, that aren't
-	necessarily represented well by the existing applications. Include an
-	input type test for starters.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/Android.mk#1 add
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/AndroidManifest.xml#1 add
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/res/layout/sample_edit_text.xml#1 add
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/res/values/strings.xml#1 add
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java#1 add
-
---------
-
-Change 127176
-
-	Expose API in SDK to remove cache files
-	
-	Add a new public api to free cache in PackageManager. The call back is via a pending intent.
-	Rename the api to freeStorage and change usage in other places.
-	Add a new unit test.
-	Remove DeviceMemoryMonitor from code base.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/cmds/installd/commands.c#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/app/ApplicationContext.java#5 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/content/pm/IPackageManager.aidl#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/content/pm/PackageManager.java#4 edit
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/DeviceMemoryMonitor.java#2 delete
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/DeviceStorageMonitorService.java#2 edit
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/PackageManagerService.java#6 edit
-... //branches/cupcake/android/frameworks/base/test-runner/android/test/mock/MockPackageManager.java#3 edit
-... //branches/cupcake/android/frameworks/base/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java#3 edit
-... //branches/cupcake/android/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java#5 edit
-
---------
-
-Change 127180
-
-	Fix TextAppearanceSpan parceling to write in the same
-	order as it reads.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/text/TextUtils.java#7 edit
-
---------
-
-Change 127182
-
-	* General cleanup
-	* Switch to supporting split file (one for platform, one for product
-	  specific entries).
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Email/res/xml/providers.xml#7 edit
-... //branches/cupcake/android/packages/apps/Email/res/xml/providers_product.xml#1 branch
-... //branches/cupcake/android/packages/apps/Email/src/com/android/email/activity/setup/AccountSetupBasics.java#7 integrate
-
---------
-
-Change 127194
-
-	Fix bug (The camera preview is not in full screen after using the trackball to select the "capture" button).  Also clean up the transitions between fullscreen and non-fullscreen a bit by animating the status bar.
-	Still not perfect, of course. :(
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/view/WindowManagerPolicy.java#2 edit
-... //branches/cupcake/android/frameworks/base/core/res/res/anim/status_bar_enter.xml#1 add
-... //branches/cupcake/android/frameworks/base/core/res/res/anim/status_bar_exit.xml#1 add
-... //branches/cupcake/android/frameworks/base/core/res/res/values/styles.xml#9 edit
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/WindowManagerService.java#14 edit
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/status/StatusBarService.java#7 edit
-... //branches/cupcake/android/frameworks/policies/base/mid/com/android/internal/policy/impl/MidWindowManager.java#2 edit
-... //branches/cupcake/android/frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java#12 edit
-
---------
-
-Change 127197
-
-	Add broadcast intents for the following new external media events:
-	    - Volume is being disk checked
-	    - Volume is blank (no partition table or no supported filesystems)
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/content/Intent.java#11 edit
-
---------
-
-Change 127200
-
-	Camera work:
-	+ Define a standard, albeit currently @hidden, intent-extra for specifying that
-	  videos and/or pictures should be written to a given content URI.
-	  (This had been the hard-coded string "output". We kept the value the same so
-	  that any in-the-wild applications that use this extra will continue to work.)
-	
-	+ Add the ability to specify that a video is recorded to a given content URI.
-	  (Because we can't actually do this at the video camera level yet, we cheat
-	   and implement this feature using a copy-and-delete-the-original-video-file.)
-	
-	+ Add a test to the MarkTest scratch app to test out this new ability.
-	
-	+ Remove mention of the "pick" intent from the camera and video camera activities.
-	  (This was a copy-and-paste error from when the code was originally copied from
-	   the image gallery activities.)
-	
-	+ Wrap use of MediaMetadataRetriever in try / catch clauses because the
-	  media metadata retriever was observed to throw a runtime exception if it was
-	  given a garbage video file.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/provider/MediaStore.java#16 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/Camera.java#30 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/CropImage.java#4 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/ImageManager.java#13 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/MenuHelper.java#20 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/VideoCamera.java#27 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/Wallpaper.java#4 edit
-
---------
-
-Change 127225
-
-	Ensure that the fingerprint doesn't contain spaces.
-	
-	Strip the BoardConfig-defined variable.
-	
-	Fail if the fingerprint doesn't contain exactly one word.
-	
-	Remove an old check that is no longer necessary.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/build/core/Makefile#14 edit
-... //branches/cupcake/android/build/core/main.mk#18 edit
-
---------
-
-Change 127245
-
-	Temporarily disable A2DP and force audio hardware when any audio streams are ringtones, alarms or notifications.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/libs/audioflinger/AudioFlinger.cpp#18 edit
-... //branches/cupcake/android/frameworks/base/libs/audioflinger/AudioFlinger.h#10 edit
-
---------
-
-Change 127247
-
-	When the dom changes, preserve the focus unless the frame structure has
-	changed. The old test was too conservative, and required that the old and
-	new pointers match. With this change, only require that frame's position
-	in the parent hierarchy match.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/webkit/WebKit/android/nav/CachedFrame.cpp#3 edit
-... //branches/cupcake/android/external/webkit/WebKit/android/nav/CachedFrame.h#3 edit
-... //branches/cupcake/android/external/webkit/WebKit/android/nav/WebView.cpp#21 edit
-
---------
-
-Change 127249
-
-	Log a better message when rejecting a class because we're not able
-	to resolve a static field.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/dalvik/vm/analysis/CodeVerify.c#12 edit
-
---------
-
-Change 127250
-
-	Added a unique serial number to class objects.  This allows classes
-	to be uniquely identified in a world where the GC can move objects
-	around.
-	
-	This replaces the hprofSerialNumber that was included when
-	WITH_HPROF_STACK was defined.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/dalvik/vm/Globals.h#4 edit
-... //branches/cupcake/android/dalvik/vm/hprof/HprofClass.c#2 edit
-... //branches/cupcake/android/dalvik/vm/hprof/HprofStackFrame.c#2 edit
-... //branches/cupcake/android/dalvik/vm/mterp/common/asm-constants.h#3 edit
-... //branches/cupcake/android/dalvik/vm/oo/Array.c#3 edit
-... //branches/cupcake/android/dalvik/vm/oo/Class.c#5 edit
-... //branches/cupcake/android/dalvik/vm/oo/Class.h#2 edit
-... //branches/cupcake/android/dalvik/vm/oo/Object.h#3 edit
-... //branches/cupcake/android/dalvik/vm/reflect/Proxy.c#3 edit
-
---------
-
-Change 127253
-
-	Convert microseconds to milliseconds before formatting
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/os/BatteryStats.java#4 edit
-
---------
-
-Change 127254
-
-	Print a log message rather than a stack trace when the shared prefs file is unreadable
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/app/ApplicationContext.java#6 edit
-
---------
-
-Change 127259
-
-	Integration of the latest EAS and JET engine updates from Sonivox.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/sonivox/arm-wt-22k/host_src/jet.h#3 edit
-... //branches/cupcake/android/external/sonivox/arm-wt-22k/lib_src/eas_midi.c#2 edit
-... //branches/cupcake/android/external/sonivox/arm-wt-22k/lib_src/jet.c#3 edit
-... //branches/cupcake/android/external/sonivox/arm-wt-22k/lib_src/jet_data.h#2 edit
-
---------
-
-Change 127263
-
-	Adds the User dictionary settings, available via Settings > Locale and text > User dictionary, allowing you to see or add words to the user dictionary.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Settings/AndroidManifest.xml#14 edit
-... //branches/cupcake/android/packages/apps/Settings/res/drawable/ic_menu_add.png#1 add
-... //branches/cupcake/android/packages/apps/Settings/res/layout/dialog_edittext.xml#1 add
-... //branches/cupcake/android/packages/apps/Settings/res/layout/list_content_with_empty_view.xml#1 add
-... //branches/cupcake/android/packages/apps/Settings/res/values/strings.xml#26 edit
-... //branches/cupcake/android/packages/apps/Settings/res/xml/language_settings.xml#3 edit
-... //branches/cupcake/android/packages/apps/Settings/src/com/android/settings/UserDictionarySettings.java#1 add
-
---------
-
-Change 127270
-
-	Buffer the response data even for redirects. If the redirect turns out
-	to be null, use the buffered data in webcore.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/webkit/LoadListener.java#5 edit
-
---------
-
-Change 127272
-
-	This removes the quarter second delay when passing a set focus message from
-	WebView to WebCore. 
-	
-	The delay was originally added in March of 2008 to help reduce the burden
-	on WebCore when moving across several items with the trackball in quick secession.
-	By delaying the event, it is easier to detect if there are subsequent events
-	before the first is executed, allowing intermediate JavaScript, layout, and 
-	display list builds to be deferred until the user is finished navigating.
-	
-	Since March, JavaScript and display list building are substantially faster.
-	The old design makes it difficult to keep items in order since not all events
-	(e.g. resizing the window) are delayed the same.
-	
-	This change preserves the code that discards navigation events as WebCore
-	falls behind -- the change causes only the first trackball movement to make
-	it to WebCore, where with the delay, the first movement may be ignored.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/webkit/WebView.java#29 edit
-
---------
-
-Change 127273
-
-	Pass the mouse click through to webkit, even if the node hit isn't valid.
-	
-	The node and frame are captured when the nav cache is built. They may not
-	still be around when a later mouse click is processed. If either are not
-	valid, skip special code that deals with image maps and menu lists, but
-	still pass the mouse click to the main frame.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/webkit/WebKit/android/jni/WebViewCore.cpp#16 edit
-
---------
-
-Change 127274
-
-	Overhaul bonding API.
-	
-	- listBondings() is now listBonds() and uses cached values in the system
-	  server
-	- hasBonding() is now getBondState() and uses cached values in the system
-	  server. It also returns an integer state code now to include the
-	  in-progress state (BOND_BONDING)
-	- createBonding() is now createBond() and no longer has an async callback.
-	  Use intents instead.
-	- BONDING_CREATED_ACTION / BONDING_REMOVED_ACTION are now
-	  BOND_STATE_CHANGED_ACTION with state codes, and result codes.
-	- Introduced BluetoothDevice.BOND_RESULT_* result codes so the UI can pick
-	  a nicer error message. TODO(jasonparekh): update the UI to use these result codes.
-	- Removed Setttings App PAIRING_STATUS in favor of BluetoothDevice.BOND_*
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/bluetooth/BluetoothDevice.java#4 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/bluetooth/BluetoothIntent.java#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/bluetooth/IBluetoothDevice.aidl#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/server/BluetoothA2dpService.java#9 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/server/BluetoothDeviceService.java#6 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/server/BluetoothEventLoop.java#4 edit
-... //branches/cupcake/android/frameworks/base/core/jni/android_server_BluetoothDeviceService.cpp#2 edit
-... //branches/cupcake/android/frameworks/base/core/jni/android_server_BluetoothEventLoop.cpp#6 edit
-... //branches/cupcake/android/packages/apps/Phone/src/com/android/phone/BluetoothHeadsetService.java#6 edit
-... //branches/cupcake/android/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEventRedirector.java#3 edit
-... //branches/cupcake/android/packages/apps/Settings/src/com/android/settings/bluetooth/LocalBluetoothDevice.java#8 edit
-... //branches/cupcake/android/packages/apps/Settings/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java#6 edit
-... //branches/cupcake/android/packages/apps/Settings/src/com/android/settings/bluetooth/LocalBluetoothManager.java#5 edit
-... //branches/cupcake/android/packages/apps/Settings/src/com/android/settings/bluetooth/SettingsBtStatus.java#2 edit
-
---------
-
-Change 127275
-
-	Added class name to "pure-abstract" warning.  Added a test case that
-	exercises "conversion" of the superclass declaration from concrete to
-	abstract.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/expected.txt#2 edit
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/info.txt#2 edit
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/src/AbstractBase.java#2 edit
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/src/ConcreteSub.java#2 edit
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/src/ConcreteSub2.java#1 add
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/src/Main.java#2 edit
-... //branches/cupcake/android/dalvik/tests/032-concrete-sub/src2/AbstractBase.java#2 edit
-... //branches/cupcake/android/dalvik/vm/analysis/DexOptimize.c#5 edit
-
---------
-
-Change 127278
-
-	Bug 1555561: Make the EditTexts in the "Add Bookmark" dialog
-	single-line so they don't stretch and mess up the layout.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Browser/res/layout/browser_add_bookmark.xml#2 edit
-
---------
-
-Change 127282
-
-	   Fix build.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/tests/AndroidTests/src/com/android/unit_tests/BluetoothTest.java#3 edit
-
---------
-
-Change 127283
-
-	   Clean up some old cruft.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/system/core/init/devices.c#7 edit
-
---------
-
-Change 127285
-
-	sync with demetrius r75
-	allow to build with scalar==fixed again
-	remove some unneeded SK_BUILD_FOR_MAC tests
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/skia/include/core/SkBitmap.h#2 edit
-... //branches/cupcake/android/external/skia/src/core/SkFloatBits.cpp#2 edit
-... //branches/cupcake/android/external/skia/src/core/SkGraphics.cpp#4 edit
-... //branches/cupcake/android/external/skia/src/core/SkMath.cpp#3 edit
-... //branches/cupcake/android/external/skia/src/ports/SkFontHost_mac.cpp#3 edit
-
---------
-
-Change 127289
-
-	Increase MMS size to 1MB.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/core/java/android/provider/Settings.java#28 edit
-... //branches/cupcake/android/packages/apps/Mms/src/com/android/mms/model/CarrierContentRestriction.java#2 edit
-... //branches/cupcake/android/packages/apps/Mms/src/com/android/mms/model/ContentRestriction.java#2 edit
-... //branches/cupcake/android/packages/apps/Mms/src/com/android/mms/model/SlideshowModel.java#2 edit
-
---------
-
-Change 127297
-
-	Fixing Socket Spec
-	Fixing a Bug where SecurityManager.checkConnect is called with the
-	host name instead of the host address as it is specified and
-	implemented by the RI.
-	Reenabling comented out code in InetAddress.getLocalHost()
-	Fixed an error in InetAddress.equals() where we were not adhering to the spec.
-	Applied some fixes copied from harmony to not have to deal with dem later.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/dalvik/libcore/luni/src/main/java/java/net/InetAddress.java#5 edit
-... //branches/cupcake/android/dalvik/libcore/luni/src/main/java/java/net/NegCacheElement.java#3 edit
-... //branches/cupcake/android/dalvik/libcore/luni/src/main/java/java/net/NegativeCache.java#3 edit
-... //branches/cupcake/android/dalvik/libcore/luni/src/main/java/java/net/Socket.java#3 edit
-
---------
-
-Change 127310
-
-	Fix ToggleButton. A previous change I made was based on a false assumption about how LayerDrawable works. A LayerDrawable *adds* the padding of all of its layers, each layer being translated by the padding of the layer below it. Surprising, but necessary to make widgets like ToggleButton work.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/graphics/java/android/graphics/drawable/LayerDrawable.java#4 edit
-
---------
-
-Change 127315
-
-	Implement "IME: Add transactions to InputConnection".  Also change the background dim amount, which I forgot to include with my previous check-in. :)
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/api/current.xml#107 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/view/inputmethod/InputConnection.java#11 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/view/inputmethod/InputConnectionWrapper.java#9 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java#22 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/widget/TextView.java#23 edit
-... //branches/cupcake/android/frameworks/base/core/java/com/android/internal/view/IInputConnectionWrapper.java#11 edit
-... //branches/cupcake/android/frameworks/base/core/java/com/android/internal/view/IInputContext.aidl#10 edit
-... //branches/cupcake/android/frameworks/base/core/java/com/android/internal/view/InputConnectionWrapper.java#10 edit
-... //branches/cupcake/android/frameworks/base/core/java/com/android/internal/widget/EditableInputConnection.java#11 edit
-... //branches/cupcake/android/frameworks/base/core/res/res/values/themes.xml#6 edit
-
---------
-
-Change 127338
-
-	Reset variables in bluetooth_start() to fix intermittent glitches resuming A2DP after standby.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/bluez/utils/audio/liba2dp.c#12 edit
-
---------
-
-Change 127341
-
-	ButtonActivity - test to see if softkeyboard responds correctly to button activity.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/AndroidManifest.xml#2 edit
-... //branches/cupcake/android/frameworks/base/tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java#1 add
-
---------
-
-Change 127342
-
-	   Make GadgetService get the list of gadgets by querying the package
-	   manager, and having a configuration xml file instead of hard coding
-	   it.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/api/current.xml#108 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/gadget/GadgetManager.java#2 edit
-... //branches/cupcake/android/frameworks/base/core/java/com/android/internal/gadget/IGadgetService.aidl#2 edit
-... //branches/cupcake/android/frameworks/base/core/res/res/values/attrs.xml#32 edit
-... //branches/cupcake/android/frameworks/base/core/res/res/values/public.xml#32 edit
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/GadgetService.java#2 edit
-... //branches/cupcake/android/frameworks/base/tests/GadgetHost/AndroidManifest.xml#2 edit
-... //branches/cupcake/android/frameworks/base/tests/GadgetHost/src/com/android/gadgethost/GadgetHostActivity.java#2 edit
-... //branches/cupcake/android/frameworks/base/tests/GadgetHost/src/com/android/gadgethost/GadgetPickActivity.java#2 edit
-
---------
-
-Change 127344
-
-	Make sure the music service also stops itself if it got killed and restarted by the system.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Music/src/com/android/music/MediaPlaybackService.java#10 edit
-
---------
-
-Change 127347
-
-	   add the gadget_info xml file
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/tests/GadgetHost/res/xml/gadget_info.xml#1 add
-
---------
-
-Change 127356
-
-	Submit rightly signed 64-bit driver
-	
-
-Affected files ...
-
-... //branches/cupcake/android/development/host/windows/prebuilt/usb/driver_amd_64/androidusb.sys#3 edit
-... //branches/cupcake/android/development/host/windows/prebuilt/usb/driver_amd_64/androidusba64.cat#3 edit
-
---------
-
-Change 127362
-
-	Use mmap to load speech model files.  Use const.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/srec/srec/clib/log_add.h#2 edit
-... //branches/cupcake/android/external/srec/srec/clib/swimodel.c#2 edit
-... //branches/cupcake/android/external/srec/srec/clib/voc_read.c#2 edit
-... //branches/cupcake/android/external/srec/srec/crec/c47mulsp.c#2 edit
-... //branches/cupcake/android/external/srec/srec/crec/get_fram.c#2 edit
-... //branches/cupcake/android/external/srec/srec/crec/srec.c#2 edit
-... //branches/cupcake/android/external/srec/srec/include/c42mul.h#2 edit
-... //branches/cupcake/android/external/srec/srec/include/hmmlib.h#2 edit
-... //branches/cupcake/android/external/srec/srec/include/simapi.h#2 edit
-... //branches/cupcake/android/external/srec/srec/include/srec.h#2 edit
-... //branches/cupcake/android/external/srec/srec/include/swimodel.h#2 edit
-... //branches/cupcake/android/external/srec/tools/grxmlcompile/grph.h#2 edit
-
---------
-
-Change 127363
-
-	Bug 1547138: Add copyright headers to translated strings files.
-	Don't generate files that don't actually contain any translations.
-	Check in code for generating translation console flat-file format.
-	
-
-Affected files ...
-
-[list deleted]
-
---------
-
-Change 127371
-
-	Clean up termination of the GPS network thread.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/location/java/com/android/internal/location/GpsLocationProvider.java#6 edit
-
---------
-
-Change 127377
-
-	Introduce a new Activity callback, onUserLeaving(), that is invoked whenever the user initiates an action that causes the activity to be moved away from being frontmost.
-	
-	Any code that starts activities "silently," without the user having prompted the action, should supply the new Intent.FLAG_ACTIVITY_NO_USER_ACTION flag when calling startActivity().  This instructs the Activity Manager that this focus change is not due to user activity, suppressing the onUserLeaving() callback.  This is important to preserve the reliability of the onUserLeaving() callback indicating a specific user choice to navigate to the new activity.
-	
-	The two known apps in the tree that forcibly start activities without user activity have also been updated to use this new Intent flag:  Phone and AlarmClock.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/frameworks/base/api/current.xml#109 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/app/Activity.java#9 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/app/ActivityThread.java#6 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/app/ApplicationThreadNative.java#3 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/app/IApplicationThread.java#3 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/app/Instrumentation.java#3 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/content/Intent.java#12 edit
-... //branches/cupcake/android/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java#11 edit
-... //branches/cupcake/android/packages/apps/AlarmClock/src/com/android/alarmclock/AlarmReceiver.java#4 edit
-... //branches/cupcake/android/packages/apps/Phone/src/com/android/phone/PhoneApp.java#6 edit
-
---------
-
-Change 127385
-
-	marking bookmarks as untranslatable
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Browser/res/values/strings.xml#15 integrate
-
---------
-
-Change 127387
-
-	Test case to make sure we don't reuse the "this" register in
-	instance methods.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/dalvik/dx/tests/110-dex-preserve-this/Blort.java#1 add
-... //branches/cupcake/android/dalvik/dx/tests/110-dex-preserve-this/expected.txt#1 add
-... //branches/cupcake/android/dalvik/dx/tests/110-dex-preserve-this/info.txt#1 add
-... //branches/cupcake/android/dalvik/dx/tests/110-dex-preserve-this/run#1 add
-
---------
-
-Change 127392
-
-	update the 'update-audio.sh' script that is used to upload a new prebuilt version
-	of the QEMU audio sub-system for Linux.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/qemu/Makefile.android#10 integrate
-... //branches/cupcake/android/external/qemu/distrib/update-audio.sh#2 edit
-... //branches/cupcake/android/prebuilt/linux-x86/emulator/libqemu-audio.a#2 edit
-
---------
-
-Change 127400
-
-	Fix the problem where the build would break looking for "@".
-	
-	built_ota_tools should have been a list of files, not a list
-	of commands to build those files.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/build/core/Makefile#15 edit
-
---------
-
-Change 127406
-
-	Fix bug (Bottom/Menu portion of the screen is appearing black).  There were a bunch of issues with deciding when to show the IME window, and a big issue in the sample keyboard IME with when it was handing starting of input (it would only work if the keyboard view had been created).
-	
-
-Affected files ...
-
-... //branches/cupcake/android/development/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java#6 edit
-... //branches/cupcake/android/frameworks/base/core/java/android/inputmethodservice/InputMethodService.java#21 edit
-
---------
-
-Change 127412
-
-	   Fix timer subtraction when there is > 1 second difference.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/bluez/utils/audio/liba2dp.c#13 edit
-
---------
-
-Change 127433
-
-	Fix Mac build of the emulator
-	
-
-Affected files ...
-
-... //branches/cupcake/android/external/qemu/Makefile.android#11 edit
-
---------
-
-Change 127436
-
-	 Camera: Create a subclass of ImageView that can be used as a camera button.
-	+ Clients can register for notification when the button is pressed, optionally clicked,
-	and released.
-	     - note that you can press a button, then move your finger off of it before releasing,
-	       in which case ther would be a pressed and a released notification, but no clicked
-	       notification.
-	     - The reason we want to do this is so we can emulate the physical camera button, which
-	       has focus down, optional camera down-and-up, and focus up events.
-	+ The pressed, clicked, and released notifications are delivered in that order, both for
-	  touch presses and for trackball/dpad presses. (This was tricky because the UI
-	  framework delivers the underlying notifications in a different order for the two
-	  types of input.)
-	+ Use the new shutter button in the still-image camera. We don't yet need it in the
-	  video camera, but it could be used there as well.
-	
-
-Affected files ...
-
-... //branches/cupcake/android/packages/apps/Camera/res/layout/camera.xml#16 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/Camera.java#31 edit
-... //branches/cupcake/android/packages/apps/Camera/src/com/android/camera/ShutterButton.java#1 add
-
---------
-
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index e241cde..df2fca1 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -25,10 +25,17 @@
 # it includes.
 #
 
+ifeq ($(strip $(is_unbundled_app_build)),true)
+# An unbundled app build needs only generic.mk.
 PRODUCT_MAKEFILES := \
+    $(LOCAL_DIR)/core.mk \
+    $(LOCAL_DIR)/generic.mk
+else
+PRODUCT_MAKEFILES := \
+    $(LOCAL_DIR)/core.mk \
     $(LOCAL_DIR)/generic.mk \
-    $(LOCAL_DIR)/min_dev.mk \
-    $(LOCAL_DIR)/sdk.mk \
-    $(LOCAL_DIR)/sim.mk \
     $(LOCAL_DIR)/generic_x86.mk \
-    $(LOCAL_DIR)/generic_with_google.mk
+    $(LOCAL_DIR)/full.mk \
+    $(LOCAL_DIR)/sdk.mk \
+    $(LOCAL_DIR)/sim.mk
+endif
diff --git a/target/product/core.mk b/target/product/core.mk
index a93ba7c..a35df85 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -1,7 +1,25 @@
-PRODUCT_BRAND :=
-PRODUCT_NAME :=
-PRODUCT_DEVICE :=
+#
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PRODUCT_BRAND := generic
+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
@@ -9,14 +27,14 @@
 PRODUCT_PACKAGES := \
     framework-res \
     Browser \
+    CarHomeLauncher \
     Contacts \
-    Launcher \
+    Home \
     HTMLViewer \
     Phone \
     ApplicationsProvider \
     ContactsProvider \
     DownloadProvider \
-    GoogleSearch \
     MediaProvider \
     PicoTts \
     SettingsProvider \
@@ -25,4 +43,11 @@
     VpnServices \
     UserDictionaryProvider \
     PackageInstaller \
+    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
diff --git a/target/product/full.mk b/target/product/full.mk
new file mode 100644
index 0000000..8725804
--- /dev/null
+++ b/target/product/full.mk
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is a build configuration for a full-featured build of the
+# Open-Source part of the tree. It's geared toward a US-centric
+# build of the emulator, but all those aspects can be overridden
+# in inherited configurations.
+
+PRODUCT_PACKAGES := \
+    OpenWnn \
+    PinyinIME \
+    VoiceDialer \
+    libWnnEngDic \
+    libWnnJpnDic \
+    libwnndict
+
+# Additional settings used in all AOSP builds
+PRODUCT_PROPERTY_OVERRIDES := \
+    keyguard.no_require_sim=true \
+    ro.com.android.dateformat=MM-dd-yyyy \
+    ro.com.android.dataroaming=true \
+    ro.ril.hsxpa=1 \
+    ro.ril.gprsclass=10
+
+PRODUCT_COPY_FILES := \
+    development/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
+    development/data/etc/vold.conf:system/etc/vold.conf
+
+# Pick up some sounds - stick with the short list to save space
+# on smaller devices.
+$(call inherit-product, frameworks/base/data/sounds/OriginalAudio.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)
+
+$(call inherit-product, build/target/product/generic.mk)
+
+# Overrides
+PRODUCT_NAME := full
+PRODUCT_BRAND := generic
+PRODUCT_DEVICE := generic
+PRODUCT_MODEL := Full Android
+
diff --git a/target/product/generic.mk b/target/product/generic.mk
index a2050c0..f05c441 100644
--- a/target/product/generic.mk
+++ b/target/product/generic.mk
@@ -1,9 +1,25 @@
+#
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 # This is a generic product that isn't specialized for a specific device.
-# It includes the base Android platform. If you need Google-specific features,
-# you should derive from generic_with_google.mk
+# It includes the base Android platform.
 
 PRODUCT_PACKAGES := \
     AccountAndSyncSettings \
+    CarHome \
     DeskClock \
     AlarmProvider \
     Bluetooth \
@@ -13,11 +29,14 @@
     CertInstaller \
     DrmProvider \
     Email \
-    Gallery \
+    Gallery3D \
     LatinIME \
+    Launcher2 \
     Mms \
     Music \
     Provision \
+    Protips \
+    QuickSearchBox \
     Settings \
     Sync \
     Updater \
diff --git a/target/product/generic_with_google.mk b/target/product/generic_with_google.mk
deleted file mode 100644
index ba30f15..0000000
--- a/target/product/generic_with_google.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# This is a generic product that isn't specialized for a specific device.
-# It includes the base Android platform including some Google-specific features.
-# If you do not want to include Google specific features, you should derive 
-# from generic.mk
-
-PRODUCT_PACKAGES := \
-    ContactsProvider \
-    GoogleContactsSyncAdapter \
-    GoogleSubscribedFeedsProvider \
-    com.google.android.gtalkservice \
-    com.google.android.datamessaging \
-    com.google.android.maps
-
-PRODUCT_COPY_FILES := \
-    vendor/google/frameworks/maps/com.google.android.maps.xml:system/etc/permissions/com.google.android.maps.xml \
-    vendor/google/frameworks/datamessaging/com.google.android.datamessaging.xml:system/etc/permissions/com.google.android.datamessaging.xml \
-    vendor/google/apps/GTalkService/com.google.android.gtalkservice.xml:system/etc/permissions/com.google.android.gtalkservice.xml
-
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
-
-# Overrides
-PRODUCT_NAME := generic_with_google
diff --git a/target/product/languages_full.mk b/target/product/languages_full.mk
new file mode 100644
index 0000000..6c49c79
--- /dev/null
+++ b/target/product/languages_full.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is a build configuration that just contains a list of languages.
+# It helps in situations where laugnages must come first in the list,
+# mostly because screen densities interfere with the list of locales and
+# the system misbehaves when a density is the first locale.
+
+# Those are all the locales that have translations.
+PRODUCT_LOCALES := en_US en_GB fr_FR it_IT es_ES es_US de_DE nl_NL cs_CZ pl_PL zh_TW zh_CN ru_RU ko_KR nb_NO pt_PT pt_BR da_DK el_GR sv_SE tr_TR ja_JP
diff --git a/target/product/languages_small.mk b/target/product/languages_small.mk
new file mode 100644
index 0000000..d695ca8
--- /dev/null
+++ b/target/product/languages_small.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is a build configuration that just contains a list of languages.
+# It helps in situations where laugnages must come first in the list,
+# mostly because screen densities interfere with the list of locales and
+# the system misbehaves when a density is the first locale.
+
+# This is the list of languages that originally shipped on ADP1
+
+PRODUCT_LOCALES := en_US en_GB fr_FR it_IT de_DE es_ES
diff --git a/target/product/min_dev.mk b/target/product/min_dev.mk
deleted file mode 100644
index 92ba973..0000000
--- a/target/product/min_dev.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-
-PRODUCT_POLICY := android.policy_phone
-PRODUCT_PROPERTY_OVERRIDES := \
-    ro.config.notification_sound=OnTheHunt.ogg \
-    ro.config.alarm_alert=Alarm_Classic.ogg
-PRODUCT_BRAND := generic
-PRODUCT_NAME := min_dev
-PRODUCT_DEVICE := generic
-
-PRODUCT_PACKAGES := \
-    DownloadProvider \
-    GoogleSearch \
-    MediaProvider \
-    SettingsProvider \
-    PackageInstaller \
-    Bugreport \
-    Launcher \
-    Settings \
-    sqlite3
-
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index e571f9e..be41486 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -1,3 +1,19 @@
+#
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 PRODUCT_PROPERTY_OVERRIDES :=
 
 PRODUCT_PACKAGES := \
@@ -5,13 +21,15 @@
 	AlarmClock \
 	Camera \
 	Calculator \
+	CarHome \
 	Development \
 	DrmProvider \
 	Email \
 	Fallback \
 	Gallery \
 	GPSEnable \
-	Launcher \
+	Launcher2 \
+	Protips \
 	Music \
 	Mms \
 	Settings \
@@ -30,12 +48,15 @@
 	ApiDemos \
 	GestureBuilder \
 	SoftKeyboard \
-	CubeLiveWallpapers
+	CubeLiveWallpapers \
+	QuickSearchBox
 
 PRODUCT_PACKAGE_OVERLAYS := development/sdk_overlay
 
 PRODUCT_COPY_FILES := \
-	development/data/etc/vold.conf:system/etc/vold.conf \
+	system/core/rootdir/etc/vold.fstab:system/etc/vold.fstab \
+	frameworks/base/data/sounds/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	frameworks/base/data/sounds/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	frameworks/base/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
diff --git a/target/product/security/README b/target/product/security/README
index b92693d..24f984c 100644
--- a/target/product/security/README
+++ b/target/product/security/README
@@ -1,13 +1,9 @@
-The following commands were used to generate the test key pair:
+The following commands were used to generate the test key pairs:
 
-  openssl genrsa -3 -out testkey.pem 2048
-
-  openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000 \
-    -subj '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
-
-  openssl pkcs8 -in testkey.pem -topk8 -outform DER -out testkey.pk8 -nocrypt
-
-Alternatively you can use the "mkkey.sh" command included in this directory.
+  development/tools/make_key testkey  '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
+  development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
+  development/tools/make_key shared   '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
+  development/tools/make_key media    '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
 
 The following standard test keys are currently included:
 
@@ -28,11 +24,11 @@
    % openssl pkcs8 -inform DER -nocrypt -in testkey.pk8 -out testkey.pem
 
 2. create a signature using the pem format key
-   % openssl dgst -binary -sha1 -sign testkey.pem FILE > FILE.sig 
+   % openssl dgst -binary -sha1 -sign testkey.pem FILE > FILE.sig
 
 extracting public keys for embedding
 ------------------------------------
 it's a Java tool
 but it generates C code
 take a look at commands/recovery/Android.mk
-you'll see it running $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar
\ No newline at end of file
+you'll see it running $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar
diff --git a/target/product/security/mkkey.sh b/target/product/security/mkkey.sh
deleted file mode 100644
index 86744f6..0000000
--- a/target/product/security/mkkey.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-if ["$1" == ""]; then
-	echo "Create a test certificate key."
-	echo "Usage: $0 NAME"
-	echo "Will generate NAME.pk8 and NAME.x509.pem"
-	echo "  /C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com"
-	return
-fi
-
-openssl genrsa -3 -out $1.pem 2048
-
-openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 \
-    -subj '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
-
-openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -nocrypt
-
diff --git a/target/product/sim.mk b/target/product/sim.mk
index 4403e46..51b3676 100644
--- a/target/product/sim.mk
+++ b/target/product/sim.mk
@@ -1,6 +1,3 @@
-PRODUCT_PACKAGES := \
-	IM
-
 $(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
 
 # Overrides
diff --git a/tools/Android.mk b/tools/Android.mk
new file mode 100644
index 0000000..aea2785
--- /dev/null
+++ b/tools/Android.mk
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(my-dir)
+
+ifeq ($(strip $(is_unbundled_app_build)),true)
+include $(LOCAL_PATH)/signapk/Android.mk
+else
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/tools/adbs b/tools/adbs
index 8b1fac6..815ae10 100755
--- a/tools/adbs
+++ b/tools/adbs
@@ -217,6 +217,7 @@
       SymbolTranslation(groups)
     else:
       print line
+      sys.stdout.flush()
 
   # adb itself aborts
   stream.close()
diff --git a/tools/apicheck/src/com/android/apicheck/ApiInfo.java b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
index 01d8f9e..c237814 100644
--- a/tools/apicheck/src/com/android/apicheck/ApiInfo.java
+++ b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
@@ -26,8 +26,19 @@
         mPackages = new HashMap<String, PackageInfo>();
         mAllClasses = new HashMap<String, ClassInfo>();
     }
+
+    public ClassInfo findClass(String name) {
+        return mAllClasses.get(name);
+    }
+
+    private void resolveInterfaces() {
+        for (ClassInfo c : mAllClasses.values()) {
+            c.resolveInterfaces(this);
+        }
+    }
     
     public boolean isConsistent(ApiInfo otherApi) {
+        resolveInterfaces();
         boolean consistent = true;
         for (PackageInfo pInfo : mPackages.values()) {
             if (otherApi.getPackages().containsKey(pInfo.name())) {
diff --git a/tools/apicheck/src/com/android/apicheck/ClassInfo.java b/tools/apicheck/src/com/android/apicheck/ClassInfo.java
index 5405ad2..e62a3d0 100644
--- a/tools/apicheck/src/com/android/apicheck/ClassInfo.java
+++ b/tools/apicheck/src/com/android/apicheck/ClassInfo.java
@@ -26,7 +26,8 @@
     private boolean mIsFinal;
     private String mDeprecated;
     private String mScope;
-    private List<String> mInterfaces;
+    private List<String> mInterfaceNames;
+    private List<ClassInfo> mInterfaces;
     private HashMap<String, MethodInfo> mMethods;
     private HashMap<String, FieldInfo> mFields;
     private HashMap<String, ConstructorInfo> mConstructors;
@@ -48,7 +49,8 @@
         mIsFinal = isFinal;
         mDeprecated = deprecated;
         mScope = visibility;
-        mInterfaces = new ArrayList<String>();
+        mInterfaceNames = new ArrayList<String>();
+        mInterfaces = new ArrayList<ClassInfo>();
         mMethods = new HashMap<String, MethodInfo>();
         mFields = new HashMap<String, FieldInfo>();
         mConstructors = new HashMap<String, ConstructorInfo>();
@@ -109,6 +111,18 @@
         return null;
     }
     
+    // Find a superinterface declaration of the given method.
+    public MethodInfo interfaceMethod(MethodInfo candidate) {
+        for (ClassInfo interfaceInfo : mInterfaces) {
+            for (MethodInfo mi : interfaceInfo.mMethods.values()) {
+                if (mi.matches(candidate)) {
+                    return mi;
+                }
+            }
+        }
+        return (mSuperClass != null) ? mSuperClass.interfaceMethod(candidate) : null;
+    }
+
     public boolean isConsistent(ClassInfo cl) {
         cl.mExistsInBoth = true;
         mExistsInBoth = true;
@@ -120,14 +134,18 @@
                     + " changed class/interface declaration");
             consistent = false;
         }
-        for (String iface : mInterfaces) {
-            if (!cl.mInterfaces.contains(iface)) {
+        for (String iface : mInterfaceNames) {
+            boolean found = false;
+            for (ClassInfo c = cl; c != null && !found; c = c.mSuperClass) {
+                found = c.mInterfaceNames.contains(iface);
+            }
+            if (!found) {
                 Errors.error(Errors.REMOVED_INTERFACE, cl.position(),
                         "Class " + qualifiedName() + " no longer implements " + iface);
             }
         }
-        for (String iface : cl.mInterfaces) {
-          if (!mInterfaces.contains(iface)) {
+        for (String iface : cl.mInterfaceNames) {
+          if (!mInterfaceNames.contains(iface)) {
               Errors.error(Errors.ADDED_INTERFACE, cl.position(),
                       "Added interface " + iface + " to class "
                       + qualifiedName());
@@ -147,6 +165,9 @@
                  */
                 MethodInfo mi = mInfo.containingClass().overriddenMethod(mInfo);
                 if (mi == null) {
+                    mi = mInfo.containingClass().interfaceMethod(mInfo);
+                }
+                if (mi == null) {
                     Errors.error(Errors.REMOVED_METHOD, mInfo.position(),
                             "Removed public method " + mInfo.qualifiedName());
                     consistent = false;
@@ -252,9 +273,15 @@
         
         return consistent;
     }
+
+    public void resolveInterfaces(ApiInfo apiInfo) {
+        for (String interfaceName : mInterfaceNames) {
+            mInterfaces.add(apiInfo.findClass(interfaceName));
+        }
+    }
     
     public void addInterface(String name) {
-        mInterfaces.add(name);
+        mInterfaceNames.add(name);
     }
     
     public void addMethod(MethodInfo mInfo) {
diff --git a/tools/applypatch/Android.mk b/tools/applypatch/Android.mk
deleted file mode 100644
index f09223e..0000000
--- a/tools/applypatch/Android.mk
+++ /dev/null
@@ -1,61 +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)
-
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := applypatch.c bspatch.c freecache.c imgpatch.c utils.c
-LOCAL_MODULE := libapplypatch
-LOCAL_MODULE_TAGS := eng
-LOCAL_C_INCLUDES += external/bzip2 external/zlib bootable/recovery
-LOCAL_STATIC_LIBRARIES += libmtdutils libmincrypt libbz libz
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := main.c
-LOCAL_MODULE := applypatch
-LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
-LOCAL_SHARED_LIBRARIES += libz libcutils libstdc++ libc
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := main.c
-LOCAL_MODULE := applypatch_static
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE_TAGS := eng
-LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
-LOCAL_STATIC_LIBRARIES += libz libcutils libstdc++ libc
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := imgdiff.c utils.c bsdiff.c
-LOCAL_MODULE := imgdiff
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE_TAGS := eng
-LOCAL_C_INCLUDES += external/zlib external/bzip2
-LOCAL_STATIC_LIBRARIES += libz libbz
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif   # TARGET_ARCH == arm
-endif  # !TARGET_SIMULATOR
diff --git a/tools/applypatch/applypatch.c b/tools/applypatch/applypatch.c
deleted file mode 100644
index e69a2fb..0000000
--- a/tools/applypatch/applypatch.c
+++ /dev/null
@@ -1,895 +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 <errno.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "mincrypt/sha.h"
-#include "applypatch.h"
-#include "mtdutils/mtdutils.h"
-
-int SaveFileContents(const char* filename, FileContents file);
-int LoadMTDContents(const char* filename, FileContents* file);
-int ParseSha1(const char* str, uint8_t* digest);
-size_t FileSink(unsigned char* data, size_t len, void* token);
-
-static int mtd_partitions_scanned = 0;
-
-// Read a file into memory; store it and its associated metadata in
-// *file.  Return 0 on success.
-int LoadFileContents(const char* filename, FileContents* file) {
-  file->data = NULL;
-
-  // A special 'filename' beginning with "MTD:" means to load the
-  // contents of an MTD partition.
-  if (strncmp(filename, "MTD:", 4) == 0) {
-    return LoadMTDContents(filename, file);
-  }
-
-  if (stat(filename, &file->st) != 0) {
-    printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
-    return -1;
-  }
-
-  file->size = file->st.st_size;
-  file->data = malloc(file->size);
-
-  FILE* f = fopen(filename, "rb");
-  if (f == NULL) {
-    printf("failed to open \"%s\": %s\n", filename, strerror(errno));
-    free(file->data);
-    file->data = NULL;
-    return -1;
-  }
-
-  size_t bytes_read = fread(file->data, 1, file->size, f);
-  if (bytes_read != file->size) {
-    printf("short read of \"%s\" (%d bytes of %d)\n",
-            filename, bytes_read, file->size);
-    free(file->data);
-    file->data = NULL;
-    return -1;
-  }
-  fclose(f);
-
-  SHA(file->data, file->size, file->sha1);
-  return 0;
-}
-
-static size_t* size_array;
-// comparison function for qsort()ing an int array of indexes into
-// size_array[].
-static int compare_size_indices(const void* a, const void* b) {
-  int aa = *(int*)a;
-  int bb = *(int*)b;
-  if (size_array[aa] < size_array[bb]) {
-    return -1;
-  } else if (size_array[aa] > size_array[bb]) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-// Load the contents of an MTD partition into the provided
-// FileContents.  filename should be a string of the form
-// "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:...".
-// The smallest size_n bytes for which that prefix of the mtd contents
-// has the corresponding sha1 hash will be loaded.  It is acceptable
-// for a size value to be repeated with different sha1s.  Will return
-// 0 on success.
-//
-// This complexity is needed because if an OTA installation is
-// interrupted, the partition might contain either the source or the
-// target data, which might be of different lengths.  We need to know
-// the length in order to read from MTD (there is no "end-of-file"
-// marker), so the caller must specify the possible lengths and the
-// hash of the data, and we'll do the load expecting to find one of
-// those hashes.
-int LoadMTDContents(const char* filename, FileContents* file) {
-  char* copy = strdup(filename);
-  const char* magic = strtok(copy, ":");
-  if (strcmp(magic, "MTD") != 0) {
-    printf("LoadMTDContents called with bad filename (%s)\n",
-            filename);
-    return -1;
-  }
-  const char* partition = strtok(NULL, ":");
-
-  int i;
-  int colons = 0;
-  for (i = 0; filename[i] != '\0'; ++i) {
-    if (filename[i] == ':') {
-      ++colons;
-    }
-  }
-  if (colons < 3 || colons%2 == 0) {
-    printf("LoadMTDContents called with bad filename (%s)\n",
-            filename);
-  }
-
-  int pairs = (colons-1)/2;     // # of (size,sha1) pairs in filename
-  int* index = malloc(pairs * sizeof(int));
-  size_t* size = malloc(pairs * sizeof(size_t));
-  char** sha1sum = malloc(pairs * sizeof(char*));
-
-  for (i = 0; i < pairs; ++i) {
-    const char* size_str = strtok(NULL, ":");
-    size[i] = strtol(size_str, NULL, 10);
-    if (size[i] == 0) {
-      printf("LoadMTDContents called with bad size (%s)\n", filename);
-      return -1;
-    }
-    sha1sum[i] = strtok(NULL, ":");
-    index[i] = i;
-  }
-
-  // sort the index[] array so it indexes the pairs in order of
-  // increasing size.
-  size_array = size;
-  qsort(index, pairs, sizeof(int), compare_size_indices);
-
-  if (!mtd_partitions_scanned) {
-    mtd_scan_partitions();
-    mtd_partitions_scanned = 1;
-  }
-
-  const MtdPartition* mtd = mtd_find_partition_by_name(partition);
-  if (mtd == NULL) {
-    printf("mtd partition \"%s\" not found (loading %s)\n",
-            partition, filename);
-    return -1;
-  }
-
-  MtdReadContext* ctx = mtd_read_partition(mtd);
-  if (ctx == NULL) {
-    printf("failed to initialize read of mtd partition \"%s\"\n",
-            partition);
-    return -1;
-  }
-
-  SHA_CTX sha_ctx;
-  SHA_init(&sha_ctx);
-  uint8_t parsed_sha[SHA_DIGEST_SIZE];
-
-  // allocate enough memory to hold the largest size.
-  file->data = malloc(size[index[pairs-1]]);
-  char* p = (char*)file->data;
-  file->size = 0;                // # bytes read so far
-
-  for (i = 0; i < pairs; ++i) {
-    // Read enough additional bytes to get us up to the next size
-    // (again, we're trying the possibilities in order of increasing
-    // size).
-    size_t next = size[index[i]] - file->size;
-    size_t read = 0;
-    if (next > 0) {
-      read = mtd_read_data(ctx, p, next);
-      if (next != read) {
-        printf("short read (%d bytes of %d) for partition \"%s\"\n",
-                read, next, partition);
-        free(file->data);
-        file->data = NULL;
-        return -1;
-      }
-      SHA_update(&sha_ctx, p, read);
-      file->size += read;
-    }
-
-    // Duplicate the SHA context and finalize the duplicate so we can
-    // check it against this pair's expected hash.
-    SHA_CTX temp_ctx;
-    memcpy(&temp_ctx, &sha_ctx, sizeof(SHA_CTX));
-    const uint8_t* sha_so_far = SHA_final(&temp_ctx);
-
-    if (ParseSha1(sha1sum[index[i]], parsed_sha) != 0) {
-      printf("failed to parse sha1 %s in %s\n",
-              sha1sum[index[i]], filename);
-      free(file->data);
-      file->data = NULL;
-      return -1;
-    }
-
-    if (memcmp(sha_so_far, parsed_sha, SHA_DIGEST_SIZE) == 0) {
-      // we have a match.  stop reading the partition; we'll return
-      // the data we've read so far.
-      printf("mtd read matched size %d sha %s\n",
-             size[index[i]], sha1sum[index[i]]);
-      break;
-    }
-
-    p += read;
-  }
-
-  mtd_read_close(ctx);
-
-  if (i == pairs) {
-    // Ran off the end of the list of (size,sha1) pairs without
-    // finding a match.
-    printf("contents of MTD partition \"%s\" didn't match %s\n",
-            partition, filename);
-    free(file->data);
-    file->data = NULL;
-    return -1;
-  }
-
-  const uint8_t* sha_final = SHA_final(&sha_ctx);
-  for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
-    file->sha1[i] = sha_final[i];
-  }
-
-  // Fake some stat() info.
-  file->st.st_mode = 0644;
-  file->st.st_uid = 0;
-  file->st.st_gid = 0;
-
-  free(copy);
-  free(index);
-  free(size);
-  free(sha1sum);
-
-  return 0;
-}
-
-
-// Save the contents of the given FileContents object under the given
-// filename.  Return 0 on success.
-int SaveFileContents(const char* filename, FileContents file) {
-  int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
-  if (fd < 0) {
-    printf("failed to open \"%s\" for write: %s\n",
-            filename, strerror(errno));
-    return -1;
-  }
-
-  size_t bytes_written = FileSink(file.data, file.size, &fd);
-  if (bytes_written != file.size) {
-    printf("short write of \"%s\" (%d bytes of %d) (%s)\n",
-           filename, bytes_written, file.size, strerror(errno));
-    close(fd);
-    return -1;
-  }
-  fsync(fd);
-  close(fd);
-
-  if (chmod(filename, file.st.st_mode) != 0) {
-    printf("chmod of \"%s\" failed: %s\n", filename, strerror(errno));
-    return -1;
-  }
-  if (chown(filename, file.st.st_uid, file.st.st_gid) != 0) {
-    printf("chown of \"%s\" failed: %s\n", filename, strerror(errno));
-    return -1;
-  }
-
-  return 0;
-}
-
-// Write a memory buffer to target_mtd partition, a string of the form
-// "MTD:<partition>[:...]".  Return 0 on success.
-int WriteToMTDPartition(unsigned char* data, size_t len,
-                        const char* target_mtd) {
-  char* partition = strchr(target_mtd, ':');
-  if (partition == NULL) {
-    printf("bad MTD target name \"%s\"\n", target_mtd);
-    return -1;
-  }
-  ++partition;
-  // Trim off anything after a colon, eg "MTD:boot:blah:blah:blah...".
-  // We want just the partition name "boot".
-  partition = strdup(partition);
-  char* end = strchr(partition, ':');
-  if (end != NULL)
-    *end = '\0';
-
-  if (!mtd_partitions_scanned) {
-    mtd_scan_partitions();
-    mtd_partitions_scanned = 1;
-  }
-
-  const MtdPartition* mtd = mtd_find_partition_by_name(partition);
-  if (mtd == NULL) {
-    printf("mtd partition \"%s\" not found for writing\n", partition);
-    return -1;
-  }
-
-  MtdWriteContext* ctx = mtd_write_partition(mtd);
-  if (ctx == NULL) {
-    printf("failed to init mtd partition \"%s\" for writing\n",
-            partition);
-    return -1;
-  }
-
-  size_t written = mtd_write_data(ctx, (char*)data, len);
-  if (written != len) {
-    printf("only wrote %d of %d bytes to MTD %s\n",
-            written, len, partition);
-    mtd_write_close(ctx);
-    return -1;
-  }
-
-  if (mtd_erase_blocks(ctx, -1) < 0) {
-    printf("error finishing mtd write of %s\n", partition);
-    mtd_write_close(ctx);
-    return -1;
-  }
-
-  if (mtd_write_close(ctx)) {
-    printf("error closing mtd write of %s\n", partition);
-    return -1;
-  }
-
-  free(partition);
-  return 0;
-}
-
-
-// Take a string 'str' of 40 hex digits and parse it into the 20
-// byte array 'digest'.  'str' may contain only the digest or be of
-// the form "<digest>:<anything>".  Return 0 on success, -1 on any
-// error.
-int ParseSha1(const char* str, uint8_t* digest) {
-  int i;
-  const char* ps = str;
-  uint8_t* pd = digest;
-  for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) {
-    int digit;
-    if (*ps >= '0' && *ps <= '9') {
-      digit = *ps - '0';
-    } else if (*ps >= 'a' && *ps <= 'f') {
-      digit = *ps - 'a' + 10;
-    } else if (*ps >= 'A' && *ps <= 'F') {
-      digit = *ps - 'A' + 10;
-    } else {
-      return -1;
-    }
-    if (i % 2 == 0) {
-      *pd = digit << 4;
-    } else {
-      *pd |= digit;
-      ++pd;
-    }
-  }
-  if (*ps != '\0' && *ps != ':') return -1;
-  return 0;
-}
-
-// Parse arguments (which should be of the form "<sha1>" or
-// "<sha1>:<filename>" into the array *patches, returning the number
-// of Patch objects in *num_patches.  Return 0 on success.
-int ParseShaArgs(int argc, char** argv, Patch** patches, int* num_patches) {
-  *num_patches = argc;
-  *patches = malloc(*num_patches * sizeof(Patch));
-
-  int i;
-  for (i = 0; i < *num_patches; ++i) {
-    if (ParseSha1(argv[i], (*patches)[i].sha1) != 0) {
-      printf("failed to parse sha1 \"%s\"\n", argv[i]);
-      return -1;
-    }
-    if (argv[i][SHA_DIGEST_SIZE*2] == '\0') {
-      (*patches)[i].patch_filename = NULL;
-    } else if (argv[i][SHA_DIGEST_SIZE*2] == ':') {
-      (*patches)[i].patch_filename = argv[i] + (SHA_DIGEST_SIZE*2+1);
-    } else {
-      printf("failed to parse filename \"%s\"\n", argv[i]);
-      return -1;
-    }
-  }
-
-  return 0;
-}
-
-// Search an array of Patch objects for one matching the given sha1.
-// Return the Patch object on success, or NULL if no match is found.
-const Patch* FindMatchingPatch(uint8_t* sha1, Patch* patches, int num_patches) {
-  int i;
-  for (i = 0; i < num_patches; ++i) {
-    if (memcmp(patches[i].sha1, sha1, SHA_DIGEST_SIZE) == 0) {
-      return patches+i;
-    }
-  }
-  return NULL;
-}
-
-// Returns 0 if the contents of the file (argv[2]) or the cached file
-// match any of the sha1's on the command line (argv[3:]).  Returns
-// nonzero otherwise.
-int CheckMode(int argc, char** argv) {
-  if (argc < 3) {
-    printf("no filename given\n");
-    return 2;
-  }
-
-  int num_patches;
-  Patch* patches;
-  if (ParseShaArgs(argc-3, argv+3, &patches, &num_patches) != 0) { return 1; }
-
-  FileContents file;
-  file.data = NULL;
-
-  // It's okay to specify no sha1s; the check will pass if the
-  // LoadFileContents is successful.  (Useful for reading MTD
-  // partitions, where the filename encodes the sha1s; no need to
-  // check them twice.)
-  if (LoadFileContents(argv[2], &file) != 0 ||
-      (num_patches > 0 &&
-       FindMatchingPatch(file.sha1, patches, num_patches) == NULL)) {
-    printf("file \"%s\" doesn't have any of expected "
-            "sha1 sums; checking cache\n", argv[2]);
-
-    free(file.data);
-
-    // If the source file is missing or corrupted, it might be because
-    // we were killed in the middle of patching it.  A copy of it
-    // should have been made in CACHE_TEMP_SOURCE.  If that file
-    // exists and matches the sha1 we're looking for, the check still
-    // passes.
-
-    if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) {
-      printf("failed to load cache file\n");
-      return 1;
-    }
-
-    if (FindMatchingPatch(file.sha1, patches, num_patches) == NULL) {
-      printf("cache bits don't match any sha1 for \"%s\"\n",
-              argv[2]);
-      return 1;
-    }
-  }
-
-  free(file.data);
-  return 0;
-}
-
-int ShowLicenses() {
-  ShowBSDiffLicense();
-  return 0;
-}
-
-size_t FileSink(unsigned char* data, size_t len, void* token) {
-  int fd = *(int *)token;
-  ssize_t done = 0;
-  ssize_t wrote;
-  while (done < (ssize_t) len) {
-    wrote = write(fd, data+done, len-done);
-    if (wrote <= 0) {
-      printf("error writing %d bytes: %s\n", (int)(len-done), strerror(errno));
-      return done;
-    }
-    done += wrote;
-  }
-  printf("wrote %d bytes to output\n", (int)done);
-  return done;
-}
-
-typedef struct {
-  unsigned char* buffer;
-  size_t size;
-  size_t pos;
-} MemorySinkInfo;
-
-size_t MemorySink(unsigned char* data, size_t len, void* token) {
-  MemorySinkInfo* msi = (MemorySinkInfo*)token;
-  if (msi->size - msi->pos < len) {
-    return -1;
-  }
-  memcpy(msi->buffer + msi->pos, data, len);
-  msi->pos += len;
-  return len;
-}
-
-// Return the amount of free space (in bytes) on the filesystem
-// containing filename.  filename must exist.  Return -1 on error.
-size_t FreeSpaceForFile(const char* filename) {
-  struct statfs sf;
-  if (statfs(filename, &sf) != 0) {
-    printf("failed to statfs %s: %s\n", filename, strerror(errno));
-    return -1;
-  }
-  return sf.f_bsize * sf.f_bfree;
-}
-
-// This program applies binary patches to files in a way that is safe
-// (the original file is not touched until we have the desired
-// replacement for it) and idempotent (it's okay to run this program
-// multiple times).
-//
-// - if the sha1 hash of <tgt-file> is <tgt-sha1>, does nothing and exits
-//   successfully.
-//
-// - otherwise, if the sha1 hash of <src-file> is <src-sha1>, applies the
-//   bsdiff <patch> to <src-file> to produce a new file (the type of patch
-//   is automatically detected from the file header).  If that new
-//   file has sha1 hash <tgt-sha1>, moves it to replace <tgt-file>, and
-//   exits successfully.  Note that if <src-file> and <tgt-file> are
-//   not the same, <src-file> is NOT deleted on success.  <tgt-file>
-//   may be the string "-" to mean "the same as src-file".
-//
-// - otherwise, or if any error is encountered, exits with non-zero
-//   status.
-//
-// <src-file> (or <file> in check mode) may refer to an MTD partition
-// to read the source data.  See the comments for the
-// LoadMTDContents() function above for the format of such a filename.
-//
-//
-// As you might guess from the arguments, this function used to be
-// main(); it was split out this way so applypatch could be built as a
-// static library and linked into other executables as well.  In the
-// future only the library form will exist; we will not need to build
-// this as a standalone executable.
-//
-// The arguments to this function are just the command-line of the
-// standalone executable:
-//
-// <src-file> <tgt-file> <tgt-sha1> <tgt-size> [<src-sha1>:<patch> ...]
-//    to apply a patch.  Returns 0 on success, 1 on failure.
-//
-// "-c" <file> [<sha1> ...]
-//    to check a file's contents against zero or more sha1s.  Returns
-//    0 if it matches any of them, 1 if it doesn't.
-//
-// "-s" <bytes>
-//    returns 0 if enough free space is available on /cache; 1 if it
-//    does not.
-//
-// "-l"
-//    shows open-source license information and returns 0.
-//
-// This function returns 2 if the arguments are not understood (in the
-// standalone executable, this causes the usage message to be
-// printed).
-//
-// TODO: make the interface more sensible for use as a library.
-
-int applypatch(int argc, char** argv) {
-  if (argc < 2) {
-    return 2;
-  }
-
-  if (strncmp(argv[1], "-l", 3) == 0) {
-    return ShowLicenses();
-  }
-
-  if (strncmp(argv[1], "-c", 3) == 0) {
-    return CheckMode(argc, argv);
-  }
-
-  if (strncmp(argv[1], "-s", 3) == 0) {
-    if (argc != 3) {
-      return 2;
-    }
-    size_t bytes = strtol(argv[2], NULL, 10);
-    if (MakeFreeSpaceOnCache(bytes) < 0) {
-      printf("unable to make %ld bytes available on /cache\n", (long)bytes);
-      return 1;
-    } else {
-      return 0;
-    }
-  }
-
-  uint8_t target_sha1[SHA_DIGEST_SIZE];
-
-  const char* source_filename = argv[1];
-  const char* target_filename = argv[2];
-  if (target_filename[0] == '-' &&
-      target_filename[1] == '\0') {
-    target_filename = source_filename;
-  }
-
-  printf("\napplying patch to %s\n", source_filename);
-
-  if (ParseSha1(argv[3], target_sha1) != 0) {
-    printf("failed to parse tgt-sha1 \"%s\"\n", argv[3]);
-    return 1;
-  }
-
-  unsigned long target_size = strtoul(argv[4], NULL, 0);
-
-  int num_patches;
-  Patch* patches;
-  if (ParseShaArgs(argc-5, argv+5, &patches, &num_patches) < 0) { return 1; }
-
-  FileContents copy_file;
-  FileContents source_file;
-  const char* source_patch_filename = NULL;
-  const char* copy_patch_filename = NULL;
-  int made_copy = 0;
-
-  // We try to load the target file into the source_file object.
-  if (LoadFileContents(target_filename, &source_file) == 0) {
-    if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
-      // The early-exit case:  the patch was already applied, this file
-      // has the desired hash, nothing for us to do.
-      printf("\"%s\" is already target; no patch needed\n",
-              target_filename);
-      return 0;
-    }
-  }
-
-  if (source_file.data == NULL ||
-      (target_filename != source_filename &&
-       strcmp(target_filename, source_filename) != 0)) {
-    // Need to load the source file:  either we failed to load the
-    // target file, or we did but it's different from the source file.
-    free(source_file.data);
-    LoadFileContents(source_filename, &source_file);
-  }
-
-  if (source_file.data != NULL) {
-    const Patch* to_use =
-        FindMatchingPatch(source_file.sha1, patches, num_patches);
-    if (to_use != NULL) {
-      source_patch_filename = to_use->patch_filename;
-    }
-  }
-
-  if (source_patch_filename == NULL) {
-    free(source_file.data);
-    printf("source file is bad; trying copy\n");
-
-    if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file) < 0) {
-      // fail.
-      printf("failed to read copy file\n");
-      return 1;
-    }
-
-    const Patch* to_use =
-        FindMatchingPatch(copy_file.sha1, patches, num_patches);
-    if (to_use != NULL) {
-      copy_patch_filename = to_use->patch_filename;
-    }
-
-    if (copy_patch_filename == NULL) {
-      // fail.
-      printf("copy file doesn't match source SHA-1s either\n");
-      return 1;
-    }
-  }
-
-  int retry = 1;
-  SHA_CTX ctx;
-  int output;
-  MemorySinkInfo msi;
-  FileContents* source_to_use;
-  char* outname;
-
-  // assume that target_filename (eg "/system/app/Foo.apk") is located
-  // on the same filesystem as its top-level directory ("/system").
-  // We need something that exists for calling statfs().
-  char target_fs[strlen(target_filename)+1];
-  char* slash = strchr(target_filename+1, '/');
-  if (slash != NULL) {
-    int count = slash - target_filename;
-    strncpy(target_fs, target_filename, count);
-    target_fs[count] = '\0';
-  } else {
-    strcpy(target_fs, target_filename);
-  }
-
-  do {
-    // Is there enough room in the target filesystem to hold the patched
-    // file?
-
-    if (strncmp(target_filename, "MTD:", 4) == 0) {
-      // If the target is an MTD partition, we're actually going to
-      // write the output to /tmp and then copy it to the partition.
-      // statfs() always returns 0 blocks free for /tmp, so instead
-      // we'll just assume that /tmp has enough space to hold the file.
-
-      // We still write the original source to cache, in case the MTD
-      // write is interrupted.
-      if (MakeFreeSpaceOnCache(source_file.size) < 0) {
-        printf("not enough free space on /cache\n");
-        return 1;
-      }
-      if (SaveFileContents(CACHE_TEMP_SOURCE, source_file) < 0) {
-        printf("failed to back up source file\n");
-        return 1;
-      }
-      made_copy = 1;
-      retry = 0;
-    } else {
-      int enough_space = 0;
-      if (retry > 0) {
-        size_t free_space = FreeSpaceForFile(target_fs);
-        int enough_space =
-          (free_space > (target_size * 3 / 2));  // 50% margin of error
-        printf("target %ld bytes; free space %ld bytes; retry %d; enough %d\n",
-               (long)target_size, (long)free_space, retry, enough_space);
-      }
-
-      if (!enough_space) {
-        retry = 0;
-      }
-
-      if (!enough_space && source_patch_filename != NULL) {
-        // Using the original source, but not enough free space.  First
-        // copy the source file to cache, then delete it from the original
-        // location.
-
-        if (strncmp(source_filename, "MTD:", 4) == 0) {
-          // It's impossible to free space on the target filesystem by
-          // deleting the source if the source is an MTD partition.  If
-          // we're ever in a state where we need to do this, fail.
-          printf("not enough free space for target but source is MTD\n");
-          return 1;
-        }
-
-        if (MakeFreeSpaceOnCache(source_file.size) < 0) {
-          printf("not enough free space on /cache\n");
-          return 1;
-        }
-
-        if (SaveFileContents(CACHE_TEMP_SOURCE, source_file) < 0) {
-          printf("failed to back up source file\n");
-          return 1;
-        }
-        made_copy = 1;
-        unlink(source_filename);
-
-        size_t free_space = FreeSpaceForFile(target_fs);
-        printf("(now %ld bytes free for target)\n", (long)free_space);
-      }
-    }
-
-    const char* patch_filename;
-    if (source_patch_filename != NULL) {
-      source_to_use = &source_file;
-      patch_filename = source_patch_filename;
-    } else {
-      source_to_use = &copy_file;
-      patch_filename = copy_patch_filename;
-    }
-
-    SinkFn sink = NULL;
-    void* token = NULL;
-    output = -1;
-    outname = NULL;
-    if (strncmp(target_filename, "MTD:", 4) == 0) {
-      // We store the decoded output in memory.
-      msi.buffer = malloc(target_size);
-      if (msi.buffer == NULL) {
-        printf("failed to alloc %ld bytes for output\n",
-               (long)target_size);
-        return 1;
-      }
-      msi.pos = 0;
-      msi.size = target_size;
-      sink = MemorySink;
-      token = &msi;
-    } else {
-      // We write the decoded output to "<tgt-file>.patch".
-      outname = (char*)malloc(strlen(target_filename) + 10);
-      strcpy(outname, target_filename);
-      strcat(outname, ".patch");
-
-      output = open(outname, O_WRONLY | O_CREAT | O_TRUNC);
-      if (output < 0) {
-        printf("failed to open output file %s: %s\n",
-               outname, strerror(errno));
-        return 1;
-      }
-      sink = FileSink;
-      token = &output;
-    }
-
-#define MAX_HEADER_LENGTH 8
-    unsigned char header[MAX_HEADER_LENGTH];
-    FILE* patchf = fopen(patch_filename, "rb");
-    if (patchf == NULL) {
-      printf("failed to open patch file %s: %s\n",
-             patch_filename, strerror(errno));
-      return 1;
-    }
-    int header_bytes_read = fread(header, 1, MAX_HEADER_LENGTH, patchf);
-    fclose(patchf);
-
-    SHA_init(&ctx);
-
-    int result;
-
-    if (header_bytes_read >= 4 &&
-        header[0] == 0xd6 && header[1] == 0xc3 &&
-        header[2] == 0xc4 && header[3] == 0) {
-      // xdelta3 patches begin "VCD" (with the high bits set) followed
-      // by a zero byte (the version number).
-      printf("error:  xdelta3 patches no longer supported\n");
-      return 1;
-    } else if (header_bytes_read >= 8 &&
-               memcmp(header, "BSDIFF40", 8) == 0) {
-      result = ApplyBSDiffPatch(source_to_use->data, source_to_use->size,
-                                    patch_filename, 0, sink, token, &ctx);
-    } else if (header_bytes_read >= 8 &&
-               memcmp(header, "IMGDIFF", 7) == 0 &&
-               (header[7] == '1' || header[7] == '2')) {
-      result = ApplyImagePatch(source_to_use->data, source_to_use->size,
-                                   patch_filename, sink, token, &ctx);
-    } else {
-      printf("Unknown patch file format\n");
-      return 1;
-    }
-
-    if (output >= 0) {
-      fsync(output);
-      close(output);
-    }
-
-    if (result != 0) {
-      if (retry == 0) {
-        printf("applying patch failed\n");
-        return result;
-      } else {
-        printf("applying patch failed; retrying\n");
-      }
-      if (outname != NULL) {
-        unlink(outname);
-      }
-    } else {
-      // succeeded; no need to retry
-      break;
-    }
-  } while (retry-- > 0);
-
-  const uint8_t* current_target_sha1 = SHA_final(&ctx);
-  if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) {
-    printf("patch did not produce expected sha1\n");
-    return 1;
-  }
-
-  if (output < 0) {
-    // Copy the temp file to the MTD partition.
-    if (WriteToMTDPartition(msi.buffer, msi.pos, target_filename) != 0) {
-      printf("write of patched data to %s failed\n", target_filename);
-      return 1;
-    }
-    free(msi.buffer);
-  } else {
-    // Give the .patch file the same owner, group, and mode of the
-    // original source file.
-    if (chmod(outname, source_to_use->st.st_mode) != 0) {
-      printf("chmod of \"%s\" failed: %s\n", outname, strerror(errno));
-      return 1;
-    }
-    if (chown(outname, source_to_use->st.st_uid,
-              source_to_use->st.st_gid) != 0) {
-      printf("chown of \"%s\" failed: %s\n", outname, strerror(errno));
-      return 1;
-    }
-
-    // Finally, rename the .patch file to replace the target file.
-    if (rename(outname, target_filename) != 0) {
-      printf("rename of .patch to \"%s\" failed: %s\n",
-              target_filename, strerror(errno));
-      return 1;
-    }
-  }
-
-  // If this run of applypatch created the copy, and we're here, we
-  // can delete it.
-  if (made_copy) unlink(CACHE_TEMP_SOURCE);
-
-  // Success!
-  return 0;
-}
diff --git a/tools/applypatch/applypatch.h b/tools/applypatch/applypatch.h
deleted file mode 100644
index 3701087..0000000
--- a/tools/applypatch/applypatch.h
+++ /dev/null
@@ -1,65 +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.
- */
-
-#ifndef _APPLYPATCH_H
-#define _APPLYPATCH_H
-
-#include <sys/stat.h>
-#include "mincrypt/sha.h"
-
-typedef struct _Patch {
-  uint8_t sha1[SHA_DIGEST_SIZE];
-  const char* patch_filename;
-} Patch;
-
-typedef struct _FileContents {
-  uint8_t sha1[SHA_DIGEST_SIZE];
-  unsigned char* data;
-  size_t size;
-  struct stat st;
-} FileContents;
-
-// When there isn't enough room on the target filesystem to hold the
-// patched version of the file, we copy the original here and delete
-// it to free up space.  If the expected source file doesn't exist, or
-// is corrupted, we look to see if this file contains the bits we want
-// and use it as the source instead.
-#define CACHE_TEMP_SOURCE "/cache/saved.file"
-
-typedef size_t (*SinkFn)(unsigned char*, size_t, void*);
-
-// applypatch.c
-size_t FreeSpaceForFile(const char* filename);
-int applypatch(int argc, char** argv);
-
-// bsdiff.c
-void ShowBSDiffLicense();
-int ApplyBSDiffPatch(const unsigned char* old_data, ssize_t old_size,
-                     const char* patch_filename, ssize_t offset,
-                     SinkFn sink, void* token, SHA_CTX* ctx);
-int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size,
-                        const char* patch_filename, ssize_t patch_offset,
-                        unsigned char** new_data, ssize_t* new_size);
-
-// imgpatch.c
-int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
-                    const char* patch_filename,
-                    SinkFn sink, void* token, SHA_CTX* ctx);
-
-// freecache.c
-int MakeFreeSpaceOnCache(size_t bytes_needed);
-
-#endif
diff --git a/tools/applypatch/applypatch.sh b/tools/applypatch/applypatch.sh
deleted file mode 100755
index 88f3025..0000000
--- a/tools/applypatch/applypatch.sh
+++ /dev/null
@@ -1,345 +0,0 @@
-#!/bin/bash
-#
-# A test suite for applypatch.  Run in a client where you have done
-# envsetup, choosecombo, etc.
-#
-# DO NOT RUN THIS ON A DEVICE YOU CARE ABOUT.  It will mess up your
-# system partition.
-#
-#
-# TODO: find some way to get this run regularly along with the rest of
-# the tests.
-
-EMULATOR_PORT=5580
-DATA_DIR=$ANDROID_BUILD_TOP/build/tools/applypatch/testdata
-
-# This must be the filename that applypatch uses for its copies.
-CACHE_TEMP_SOURCE=/cache/saved.file
-
-# Put all binaries and files here.  We use /cache because it's a
-# temporary filesystem in the emulator; it's created fresh each time
-# the emulator starts.
-WORK_DIR=/system
-
-# partition that WORK_DIR is located on, without the leading slash
-WORK_FS=system
-
-# set to 0 to use a device instead
-USE_EMULATOR=1
-
-# ------------------------
-
-tmpdir=$(mktemp -d)
-
-if [ "$USE_EMULATOR" == 1 ]; then
-  emulator -wipe-data -noaudio -no-window -port $EMULATOR_PORT &
-  pid_emulator=$!
-  ADB="adb -s emulator-$EMULATOR_PORT "
-else
-  ADB="adb -d "
-fi
-
-echo "waiting to connect to device"
-$ADB wait-for-device
-echo "device is available"
-$ADB remount
-# free up enough space on the system partition for the test to run.
-$ADB shell rm -r /system/media
-
-# run a command on the device; exit with the exit status of the device
-# command.
-run_command() {
-  $ADB shell "$@" \; echo \$? | awk '{if (b) {print a}; a=$0; b=1} END {exit a}'
-}
-
-testname() {
-  echo
-  echo "$1"...
-  testname="$1"
-}
-
-fail() {
-  echo
-  echo FAIL: $testname
-  echo
-  [ "$open_pid" == "" ] || kill $open_pid
-  [ "$pid_emulator" == "" ] || kill $pid_emulator
-  exit 1
-}
-
-sha1() {
-  sha1sum $1 | awk '{print $1}'
-}
-
-free_space() {
-  run_command df | awk "/$1/ {print gensub(/K/, \"\", \"g\", \$6)}"
-}
-
-cleanup() {
-  # not necessary if we're about to kill the emulator, but nice for
-  # running on real devices or already-running emulators.
-  testname "removing test files"
-  run_command rm $WORK_DIR/bloat.dat
-  run_command rm $WORK_DIR/old.file
-  run_command rm $WORK_DIR/patch.bsdiff
-  run_command rm $WORK_DIR/applypatch
-  run_command rm $CACHE_TEMP_SOURCE
-  run_command rm /cache/bloat*.dat
-
-  [ "$pid_emulator" == "" ] || kill $pid_emulator
-
-  rm -rf $tmpdir
-}
-
-cleanup
-
-$ADB push $ANDROID_PRODUCT_OUT/system/bin/applypatch $WORK_DIR/applypatch
-
-BAD1_SHA1=$(printf "%040x" $RANDOM)
-BAD2_SHA1=$(printf "%040x" $RANDOM)
-OLD_SHA1=$(sha1 $DATA_DIR/old.file)
-NEW_SHA1=$(sha1 $DATA_DIR/new.file)
-NEW_SIZE=$(stat -c %s $DATA_DIR/new.file)
-
-# --------------- basic execution ----------------------
-
-testname "usage message"
-run_command $WORK_DIR/applypatch && fail
-
-testname "display license"
-run_command $WORK_DIR/applypatch -l | grep -q -i copyright || fail
-
-
-# --------------- check mode ----------------------
-
-$ADB push $DATA_DIR/old.file $WORK_DIR
-
-testname "check mode single"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $OLD_SHA1 || fail
-
-testname "check mode multiple"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $BAD1_SHA1 $OLD_SHA1 $BAD2_SHA1|| fail
-
-testname "check mode failure"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $BAD2_SHA1 $BAD1_SHA1 && fail
-
-$ADB push $DATA_DIR/old.file $CACHE_TEMP_SOURCE
-# put some junk in the old file
-run_command dd if=/dev/urandom of=$WORK_DIR/old.file count=100 bs=1024 || fail
-
-testname "check mode cache (corrupted) single"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $OLD_SHA1 || fail
-
-testname "check mode cache (corrupted) multiple"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $BAD1_SHA1 $OLD_SHA1 $BAD2_SHA1|| fail
-
-testname "check mode cache (corrupted) failure"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $BAD2_SHA1 $BAD1_SHA1 && fail
-
-# remove the old file entirely
-run_command rm $WORK_DIR/old.file
-
-testname "check mode cache (missing) single"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $OLD_SHA1 || fail
-
-testname "check mode cache (missing) multiple"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $BAD1_SHA1 $OLD_SHA1 $BAD2_SHA1|| fail
-
-testname "check mode cache (missing) failure"
-run_command $WORK_DIR/applypatch -c $WORK_DIR/old.file $BAD2_SHA1 $BAD1_SHA1 && fail
-
-
-# --------------- apply patch ----------------------
-
-$ADB push $DATA_DIR/old.file $WORK_DIR
-$ADB push $DATA_DIR/patch.bsdiff $WORK_DIR
-
-# Check that the partition has enough space to apply the patch without
-# copying.  If it doesn't, we'll be testing the low-space condition
-# when we intend to test the not-low-space condition.
-testname "apply patches (with enough space)"
-free_kb=$(free_space $WORK_FS)
-echo "${free_kb}kb free on /$WORK_FS."
-if (( free_kb * 1024 < NEW_SIZE * 3 / 2 )); then
-  echo "Not enough space on /$WORK_FS to patch test file."
-  echo
-  echo "This doesn't mean that applypatch is necessarily broken;"
-  echo "just that /$WORK_FS doesn't have enough free space to"
-  echo "properly run this test."
-  exit 1
-fi
-
-testname "apply bsdiff patch"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-testname "reapply bsdiff patch"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-
-# --------------- apply patch in new location ----------------------
-
-$ADB push $DATA_DIR/old.file $WORK_DIR
-$ADB push $DATA_DIR/patch.bsdiff $WORK_DIR
-
-# Check that the partition has enough space to apply the patch without
-# copying.  If it doesn't, we'll be testing the low-space condition
-# when we intend to test the not-low-space condition.
-testname "apply patch to new location (with enough space)"
-free_kb=$(free_space $WORK_FS)
-echo "${free_kb}kb free on /$WORK_FS."
-if (( free_kb * 1024 < NEW_SIZE * 3 / 2 )); then
-  echo "Not enough space on /$WORK_FS to patch test file."
-  echo
-  echo "This doesn't mean that applypatch is necessarily broken;"
-  echo "just that /$WORK_FS doesn't have enough free space to"
-  echo "properly run this test."
-  exit 1
-fi
-
-run_command rm $WORK_DIR/new.file
-run_command rm $CACHE_TEMP_SOURCE
-
-testname "apply bsdiff patch to new location"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file $WORK_DIR/new.file $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/new.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-testname "reapply bsdiff patch to new location"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file $WORK_DIR/new.file $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/new.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-$ADB push $DATA_DIR/old.file $CACHE_TEMP_SOURCE
-# put some junk in the old file
-run_command dd if=/dev/urandom of=$WORK_DIR/old.file count=100 bs=1024 || fail
-
-testname "apply bsdiff patch to new location with corrupted source"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file $WORK_DIR/new.file $NEW_SHA1 $NEW_SIZE $OLD_SHA1:$WORK_DIR/patch.bsdiff $BAD1_SHA1:$WORK_DIR/foo || fail
-$ADB pull $WORK_DIR/new.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-# put some junk in the cache copy, too
-run_command dd if=/dev/urandom of=$CACHE_TEMP_SOURCE count=100 bs=1024 || fail
-
-run_command rm $WORK_DIR/new.file
-testname "apply bsdiff patch to new location with corrupted source and copy (no new file)"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file $WORK_DIR/new.file $NEW_SHA1 $NEW_SIZE $OLD_SHA1:$WORK_DIR/patch.bsdiff $BAD1_SHA1:$WORK_DIR/foo && fail
-
-# put some junk in the new file
-run_command dd if=/dev/urandom of=$WORK_DIR/new.file count=100 bs=1024 || fail
-
-testname "apply bsdiff patch to new location with corrupted source and copy (bad new file)"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file $WORK_DIR/new.file $NEW_SHA1 $NEW_SIZE $OLD_SHA1:$WORK_DIR/patch.bsdiff $BAD1_SHA1:$WORK_DIR/foo && fail
-
-# --------------- apply patch with low space on /system ----------------------
-
-$ADB push $DATA_DIR/old.file $WORK_DIR
-$ADB push $DATA_DIR/patch.bsdiff $WORK_DIR
-
-free_kb=$(free_space $WORK_FS)
-echo "${free_kb}kb free on /$WORK_FS; we'll soon fix that."
-echo run_command dd if=/dev/zero of=$WORK_DIR/bloat.dat count=$((free_kb-512)) bs=1024 || fail
-run_command dd if=/dev/zero of=$WORK_DIR/bloat.dat count=$((free_kb-512)) bs=1024 || fail
-free_kb=$(free_space $WORK_FS)
-echo "${free_kb}kb free on /$WORK_FS now."
-
-testname "apply bsdiff patch with low space"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-testname "reapply bsdiff patch with low space"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-# --------------- apply patch with low space on /system and /cache ----------------------
-
-$ADB push $DATA_DIR/old.file $WORK_DIR
-$ADB push $DATA_DIR/patch.bsdiff $WORK_DIR
-
-free_kb=$(free_space $WORK_FS)
-echo "${free_kb}kb free on /$WORK_FS"
-
-run_command mkdir /cache/subdir
-run_command 'echo > /cache/subdir/a.file'
-run_command 'echo > /cache/a.file'
-run_command mkdir /cache/recovery /cache/recovery/otatest
-run_command 'echo > /cache/recovery/otatest/b.file'
-run_command "echo > $CACHE_TEMP_SOURCE"
-free_kb=$(free_space cache)
-echo "${free_kb}kb free on /cache; we'll soon fix that."
-run_command dd if=/dev/zero of=/cache/bloat_small.dat count=128 bs=1024 || fail
-run_command dd if=/dev/zero of=/cache/bloat_large.dat count=$((free_kb-640)) bs=1024 || fail
-free_kb=$(free_space cache)
-echo "${free_kb}kb free on /cache now."
-
-testname "apply bsdiff patch with low space, full cache, can't delete enough"
-$ADB shell 'cat >> /cache/bloat_large.dat' & open_pid=$!
-echo "open_pid is $open_pid"
-
-# size check should fail even though it deletes some stuff
-run_command $WORK_DIR/applypatch -s $NEW_SIZE && fail
-run_command ls /cache/bloat_small.dat && fail          # was deleted
-run_command ls /cache/a.file && fail                   # was deleted
-run_command ls /cache/recovery/otatest/b.file && fail  # was deleted
-run_command ls /cache/bloat_large.dat || fail          # wasn't deleted because it was open
-run_command ls /cache/subdir/a.file || fail            # wasn't deleted because it's in a subdir
-run_command ls $CACHE_TEMP_SOURCE || fail              # wasn't deleted because it's the source file copy
-
-# should fail; not enough files can be deleted
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff && fail
-run_command ls /cache/bloat_large.dat || fail   # wasn't deleted because it was open
-run_command ls /cache/subdir/a.file || fail     # wasn't deleted because it's in a subdir
-run_command ls $CACHE_TEMP_SOURCE || fail       # wasn't deleted because it's the source file copy
-
-kill $open_pid   # /cache/bloat_large.dat is no longer open
-
-testname "apply bsdiff patch with low space, full cache, can delete enough"
-
-# should succeed after deleting /cache/bloat_large.dat
-run_command $WORK_DIR/applypatch -s $NEW_SIZE || fail
-run_command ls /cache/bloat_large.dat && fail   # was deleted
-run_command ls /cache/subdir/a.file || fail     # still wasn't deleted because it's in a subdir
-run_command ls $CACHE_TEMP_SOURCE || fail       # wasn't deleted because it's the source file copy
-
-# should succeed
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-run_command ls /cache/subdir/a.file || fail     # still wasn't deleted because it's in a subdir
-run_command ls $CACHE_TEMP_SOURCE && fail       # was deleted because patching overwrote it, then deleted it
-
-# --------------- apply patch from cache ----------------------
-
-$ADB push $DATA_DIR/old.file $CACHE_TEMP_SOURCE
-# put some junk in the old file
-run_command dd if=/dev/urandom of=$WORK_DIR/old.file count=100 bs=1024 || fail
-
-testname "apply bsdiff patch from cache (corrupted source) with low space"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-$ADB push $DATA_DIR/old.file $CACHE_TEMP_SOURCE
-# remove the old file entirely
-run_command rm $WORK_DIR/old.file
-
-testname "apply bsdiff patch from cache (missing source) with low space"
-run_command $WORK_DIR/applypatch $WORK_DIR/old.file - $NEW_SHA1 $NEW_SIZE $BAD1_SHA1:$WORK_DIR/foo $OLD_SHA1:$WORK_DIR/patch.bsdiff || fail
-$ADB pull $WORK_DIR/old.file $tmpdir/patched
-diff -q $DATA_DIR/new.file $tmpdir/patched || fail
-
-
-# --------------- cleanup ----------------------
-
-cleanup
-
-echo
-echo PASS
-echo
-
diff --git a/tools/applypatch/bsdiff.c b/tools/applypatch/bsdiff.c
deleted file mode 100644
index b6d342b..0000000
--- a/tools/applypatch/bsdiff.c
+++ /dev/null
@@ -1,410 +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.
- */
-
-/*
- * Most of this code comes from bsdiff.c from the bsdiff-4.3
- * distribution, which is:
- */
-
-/*-
- * Copyright 2003-2005 Colin Percival
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted providing that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <bzlib.h>
-#include <err.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define MIN(x,y) (((x)<(y)) ? (x) : (y))
-
-static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
-{
-	off_t i,j,k,x,tmp,jj,kk;
-
-	if(len<16) {
-		for(k=start;k<start+len;k+=j) {
-			j=1;x=V[I[k]+h];
-			for(i=1;k+i<start+len;i++) {
-				if(V[I[k+i]+h]<x) {
-					x=V[I[k+i]+h];
-					j=0;
-				};
-				if(V[I[k+i]+h]==x) {
-					tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
-					j++;
-				};
-			};
-			for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
-			if(j==1) I[k]=-1;
-		};
-		return;
-	};
-
-	x=V[I[start+len/2]+h];
-	jj=0;kk=0;
-	for(i=start;i<start+len;i++) {
-		if(V[I[i]+h]<x) jj++;
-		if(V[I[i]+h]==x) kk++;
-	};
-	jj+=start;kk+=jj;
-
-	i=start;j=0;k=0;
-	while(i<jj) {
-		if(V[I[i]+h]<x) {
-			i++;
-		} else if(V[I[i]+h]==x) {
-			tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
-			j++;
-		} else {
-			tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
-			k++;
-		};
-	};
-
-	while(jj+j<kk) {
-		if(V[I[jj+j]+h]==x) {
-			j++;
-		} else {
-			tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
-			k++;
-		};
-	};
-
-	if(jj>start) split(I,V,start,jj-start,h);
-
-	for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
-	if(jj==kk-1) I[jj]=-1;
-
-	if(start+len>kk) split(I,V,kk,start+len-kk,h);
-}
-
-static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
-{
-	off_t buckets[256];
-	off_t i,h,len;
-
-	for(i=0;i<256;i++) buckets[i]=0;
-	for(i=0;i<oldsize;i++) buckets[old[i]]++;
-	for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
-	for(i=255;i>0;i--) buckets[i]=buckets[i-1];
-	buckets[0]=0;
-
-	for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
-	I[0]=oldsize;
-	for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
-	V[oldsize]=0;
-	for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
-	I[0]=-1;
-
-	for(h=1;I[0]!=-(oldsize+1);h+=h) {
-		len=0;
-		for(i=0;i<oldsize+1;) {
-			if(I[i]<0) {
-				len-=I[i];
-				i-=I[i];
-			} else {
-				if(len) I[i-len]=-len;
-				len=V[I[i]]+1-i;
-				split(I,V,i,len,h);
-				i+=len;
-				len=0;
-			};
-		};
-		if(len) I[i-len]=-len;
-	};
-
-	for(i=0;i<oldsize+1;i++) I[V[i]]=i;
-}
-
-static off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
-{
-	off_t i;
-
-	for(i=0;(i<oldsize)&&(i<newsize);i++)
-		if(old[i]!=new[i]) break;
-
-	return i;
-}
-
-static off_t search(off_t *I,u_char *old,off_t oldsize,
-		u_char *new,off_t newsize,off_t st,off_t en,off_t *pos)
-{
-	off_t x,y;
-
-	if(en-st<2) {
-		x=matchlen(old+I[st],oldsize-I[st],new,newsize);
-		y=matchlen(old+I[en],oldsize-I[en],new,newsize);
-
-		if(x>y) {
-			*pos=I[st];
-			return x;
-		} else {
-			*pos=I[en];
-			return y;
-		}
-	};
-
-	x=st+(en-st)/2;
-	if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) {
-		return search(I,old,oldsize,new,newsize,x,en,pos);
-	} else {
-		return search(I,old,oldsize,new,newsize,st,x,pos);
-	};
-}
-
-static void offtout(off_t x,u_char *buf)
-{
-	off_t y;
-
-	if(x<0) y=-x; else y=x;
-
-		buf[0]=y%256;y-=buf[0];
-	y=y/256;buf[1]=y%256;y-=buf[1];
-	y=y/256;buf[2]=y%256;y-=buf[2];
-	y=y/256;buf[3]=y%256;y-=buf[3];
-	y=y/256;buf[4]=y%256;y-=buf[4];
-	y=y/256;buf[5]=y%256;y-=buf[5];
-	y=y/256;buf[6]=y%256;y-=buf[6];
-	y=y/256;buf[7]=y%256;
-
-	if(x<0) buf[7]|=0x80;
-}
-
-// This is main() from bsdiff.c, with the following changes:
-//
-//    - old, oldsize, new, newsize are arguments; we don't load this
-//      data from files.  old and new are owned by the caller; we
-//      don't free them at the end.
-//
-//    - the "I" block of memory is owned by the caller, who passes a
-//      pointer to *I, which can be NULL.  This way if we call
-//      bsdiff() multiple times with the same 'old' data, we only do
-//      the qsufsort() step the first time.
-//
-int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* new, off_t newsize,
-           const char* patch_filename)
-{
-	int fd;
-	off_t *I;
-	off_t scan,pos,len;
-	off_t lastscan,lastpos,lastoffset;
-	off_t oldscore,scsc;
-	off_t s,Sf,lenf,Sb,lenb;
-	off_t overlap,Ss,lens;
-	off_t i;
-	off_t dblen,eblen;
-	u_char *db,*eb;
-	u_char buf[8];
-	u_char header[32];
-	FILE * pf;
-	BZFILE * pfbz2;
-	int bz2err;
-
-        if (*IP == NULL) {
-            off_t* V;
-            *IP = malloc((oldsize+1) * sizeof(off_t));
-            V = malloc((oldsize+1) * sizeof(off_t));
-            qsufsort(*IP, V, old, oldsize);
-            free(V);
-        }
-        I = *IP;
-
-	if(((db=malloc(newsize+1))==NULL) ||
-		((eb=malloc(newsize+1))==NULL)) err(1,NULL);
-	dblen=0;
-	eblen=0;
-
-	/* Create the patch file */
-	if ((pf = fopen(patch_filename, "w")) == NULL)
-              err(1, "%s", patch_filename);
-
-	/* Header is
-		0	8	 "BSDIFF40"
-		8	8	length of bzip2ed ctrl block
-		16	8	length of bzip2ed diff block
-		24	8	length of new file */
-	/* File is
-		0	32	Header
-		32	??	Bzip2ed ctrl block
-		??	??	Bzip2ed diff block
-		??	??	Bzip2ed extra block */
-	memcpy(header,"BSDIFF40",8);
-	offtout(0, header + 8);
-	offtout(0, header + 16);
-	offtout(newsize, header + 24);
-	if (fwrite(header, 32, 1, pf) != 1)
-		err(1, "fwrite(%s)", patch_filename);
-
-	/* Compute the differences, writing ctrl as we go */
-	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
-		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
-	scan=0;len=0;
-	lastscan=0;lastpos=0;lastoffset=0;
-	while(scan<newsize) {
-		oldscore=0;
-
-		for(scsc=scan+=len;scan<newsize;scan++) {
-			len=search(I,old,oldsize,new+scan,newsize-scan,
-					0,oldsize,&pos);
-
-			for(;scsc<scan+len;scsc++)
-			if((scsc+lastoffset<oldsize) &&
-				(old[scsc+lastoffset] == new[scsc]))
-				oldscore++;
-
-			if(((len==oldscore) && (len!=0)) ||
-				(len>oldscore+8)) break;
-
-			if((scan+lastoffset<oldsize) &&
-				(old[scan+lastoffset] == new[scan]))
-				oldscore--;
-		};
-
-		if((len!=oldscore) || (scan==newsize)) {
-			s=0;Sf=0;lenf=0;
-			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
-				if(old[lastpos+i]==new[lastscan+i]) s++;
-				i++;
-				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
-			};
-
-			lenb=0;
-			if(scan<newsize) {
-				s=0;Sb=0;
-				for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
-					if(old[pos-i]==new[scan-i]) s++;
-					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
-				};
-			};
-
-			if(lastscan+lenf>scan-lenb) {
-				overlap=(lastscan+lenf)-(scan-lenb);
-				s=0;Ss=0;lens=0;
-				for(i=0;i<overlap;i++) {
-					if(new[lastscan+lenf-overlap+i]==
-					   old[lastpos+lenf-overlap+i]) s++;
-					if(new[scan-lenb+i]==
-					   old[pos-lenb+i]) s--;
-					if(s>Ss) { Ss=s; lens=i+1; };
-				};
-
-				lenf+=lens-overlap;
-				lenb-=lens;
-			};
-
-			for(i=0;i<lenf;i++)
-				db[dblen+i]=new[lastscan+i]-old[lastpos+i];
-			for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
-				eb[eblen+i]=new[lastscan+lenf+i];
-
-			dblen+=lenf;
-			eblen+=(scan-lenb)-(lastscan+lenf);
-
-			offtout(lenf,buf);
-			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
-			if (bz2err != BZ_OK)
-				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-
-			offtout((scan-lenb)-(lastscan+lenf),buf);
-			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
-			if (bz2err != BZ_OK)
-				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-
-			offtout((pos-lenb)-(lastpos+lenf),buf);
-			BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
-			if (bz2err != BZ_OK)
-				errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-
-			lastscan=scan-lenb;
-			lastpos=pos-lenb;
-			lastoffset=pos-scan;
-		};
-	};
-	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
-	if (bz2err != BZ_OK)
-		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
-
-	/* Compute size of compressed ctrl data */
-	if ((len = ftello(pf)) == -1)
-		err(1, "ftello");
-	offtout(len-32, header + 8);
-
-	/* Write compressed diff data */
-	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
-		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
-	BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
-	if (bz2err != BZ_OK)
-		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
-	if (bz2err != BZ_OK)
-		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
-
-	/* Compute size of compressed diff data */
-	if ((newsize = ftello(pf)) == -1)
-		err(1, "ftello");
-	offtout(newsize - len, header + 16);
-
-	/* Write compressed extra data */
-	if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
-		errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
-	BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
-	if (bz2err != BZ_OK)
-		errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-	BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
-	if (bz2err != BZ_OK)
-		errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
-
-	/* Seek to the beginning, write the header, and close the file */
-	if (fseeko(pf, 0, SEEK_SET))
-		err(1, "fseeko");
-	if (fwrite(header, 32, 1, pf) != 1)
-		err(1, "fwrite(%s)", patch_filename);
-	if (fclose(pf))
-		err(1, "fclose");
-
-	/* Free the memory we used */
-	free(db);
-	free(eb);
-
-	return 0;
-}
diff --git a/tools/applypatch/bspatch.c b/tools/applypatch/bspatch.c
deleted file mode 100644
index d5cd617..0000000
--- a/tools/applypatch/bspatch.c
+++ /dev/null
@@ -1,252 +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.
- */
-
-// This file is a nearly line-for-line copy of bspatch.c from the
-// bsdiff-4.3 distribution; the primary differences being how the
-// input and output data are read and the error handling.  Running
-// applypatch with the -l option will display the bsdiff license
-// notice.
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <bzlib.h>
-
-#include "mincrypt/sha.h"
-#include "applypatch.h"
-
-void ShowBSDiffLicense() {
-  puts("The bsdiff library used herein is:\n"
-       "\n"
-       "Copyright 2003-2005 Colin Percival\n"
-       "All rights reserved\n"
-       "\n"
-       "Redistribution and use in source and binary forms, with or without\n"
-       "modification, are permitted providing that the following conditions\n"
-       "are met:\n"
-       "1. Redistributions of source code must retain the above copyright\n"
-       "   notice, this list of conditions and the following disclaimer.\n"
-       "2. Redistributions in binary form must reproduce the above copyright\n"
-       "   notice, this list of conditions and the following disclaimer in the\n"
-       "   documentation and/or other materials provided with the distribution.\n"
-       "\n"
-       "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n"
-       "IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
-       "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
-       "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n"
-       "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
-       "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
-       "OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
-       "HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n"
-       "STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\n"
-       "IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n"
-       "POSSIBILITY OF SUCH DAMAGE.\n"
-       "\n------------------\n\n"
-       "This program uses Julian R Seward's \"libbzip2\" library, available\n"
-       "from http://www.bzip.org/.\n"
-       );
-}
-
-static off_t offtin(u_char *buf)
-{
-  off_t y;
-
-  y=buf[7]&0x7F;
-  y=y*256;y+=buf[6];
-  y=y*256;y+=buf[5];
-  y=y*256;y+=buf[4];
-  y=y*256;y+=buf[3];
-  y=y*256;y+=buf[2];
-  y=y*256;y+=buf[1];
-  y=y*256;y+=buf[0];
-
-  if(buf[7]&0x80) y=-y;
-
-  return y;
-}
-
-
-int ApplyBSDiffPatch(const unsigned char* old_data, ssize_t old_size,
-                     const char* patch_filename, ssize_t patch_offset,
-                     SinkFn sink, void* token, SHA_CTX* ctx) {
-
-  unsigned char* new_data;
-  ssize_t new_size;
-  if (ApplyBSDiffPatchMem(old_data, old_size, patch_filename, patch_offset,
-                          &new_data, &new_size) != 0) {
-    return -1;
-  }
-
-  if (sink(new_data, new_size, token) < new_size) {
-    fprintf(stderr, "short write of output: %d (%s)\n", errno, strerror(errno));
-    return 1;
-  }
-  if (ctx) {
-    SHA_update(ctx, new_data, new_size);
-  }
-  free(new_data);
-
-  return 0;
-}
-
-int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size,
-                        const char* patch_filename, ssize_t patch_offset,
-                        unsigned char** new_data, ssize_t* new_size) {
-
-  FILE* f;
-  if ((f = fopen(patch_filename, "rb")) == NULL) {
-    fprintf(stderr, "failed to open patch file\n");
-    return 1;
-  }
-
-  // File format:
-  //   0       8       "BSDIFF40"
-  //   8       8       X
-  //   16      8       Y
-  //   24      8       sizeof(newfile)
-  //   32      X       bzip2(control block)
-  //   32+X    Y       bzip2(diff block)
-  //   32+X+Y  ???     bzip2(extra block)
-  // with control block a set of triples (x,y,z) meaning "add x bytes
-  // from oldfile to x bytes from the diff block; copy y bytes from the
-  // extra block; seek forwards in oldfile by z bytes".
-
-  fseek(f, patch_offset, SEEK_SET);
-
-  unsigned char header[32];
-  if (fread(header, 1, 32, f) < 32) {
-    fprintf(stderr, "failed to read patch file header\n");
-    return 1;
-  }
-
-  if (memcmp(header, "BSDIFF40", 8) != 0) {
-    fprintf(stderr, "corrupt bsdiff patch file header (magic number)\n");
-    return 1;
-  }
-
-  ssize_t ctrl_len, data_len;
-  ctrl_len = offtin(header+8);
-  data_len = offtin(header+16);
-  *new_size = offtin(header+24);
-
-  if (ctrl_len < 0 || data_len < 0 || *new_size < 0) {
-    fprintf(stderr, "corrupt patch file header (data lengths)\n");
-    return 1;
-  }
-
-  fclose(f);
-
-  int bzerr;
-
-#define OPEN_AT(f, bzf, offset)                                          \
-  FILE* f;                                                               \
-  BZFILE* bzf;                                                           \
-  if ((f = fopen(patch_filename, "rb")) == NULL) {                       \
-    fprintf(stderr, "failed to open patch file\n");                      \
-    return 1;                                                            \
-  }                                                                      \
-  if (fseeko(f, offset+patch_offset, SEEK_SET)) {                        \
-    fprintf(stderr, "failed to seek in patch file\n");                   \
-    return 1;                                                            \
-  }                                                                      \
-  if ((bzf = BZ2_bzReadOpen(&bzerr, f, 0, 0, NULL, 0)) == NULL) {        \
-    fprintf(stderr, "failed to bzReadOpen in patch file (%d)\n", bzerr); \
-    return 1;                                                            \
-  }
-
-  OPEN_AT(cpf, cpfbz2, 32);
-  OPEN_AT(dpf, dpfbz2, 32+ctrl_len);
-  OPEN_AT(epf, epfbz2, 32+ctrl_len+data_len);
-
-#undef OPEN_AT
-
-  *new_data = malloc(*new_size);
-  if (*new_data == NULL) {
-    fprintf(stderr, "failed to allocate %d bytes of memory for output file\n",
-            (int)*new_size);
-    return 1;
-  }
-
-  off_t oldpos = 0, newpos = 0;
-  off_t ctrl[3];
-  off_t len_read;
-  int i;
-  unsigned char buf[8];
-  while (newpos < *new_size) {
-    // Read control data
-    for (i = 0; i < 3; ++i) {
-      len_read = BZ2_bzRead(&bzerr, cpfbz2, buf, 8);
-      if (len_read < 8 || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
-        fprintf(stderr, "corrupt patch (read control)\n");
-        return 1;
-      }
-      ctrl[i] = offtin(buf);
-    }
-
-    // Sanity check
-    if (newpos + ctrl[0] > *new_size) {
-      fprintf(stderr, "corrupt patch (new file overrun)\n");
-      return 1;
-    }
-
-    // Read diff string
-    len_read = BZ2_bzRead(&bzerr, dpfbz2, *new_data + newpos, ctrl[0]);
-    if (len_read < ctrl[0] || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
-      fprintf(stderr, "corrupt patch (read diff)\n");
-      return 1;
-    }
-
-    // Add old data to diff string
-    for (i = 0; i < ctrl[0]; ++i) {
-      if ((oldpos+i >= 0) && (oldpos+i < old_size)) {
-        (*new_data)[newpos+i] += old_data[oldpos+i];
-      }
-    }
-
-    // Adjust pointers
-    newpos += ctrl[0];
-    oldpos += ctrl[0];
-
-    // Sanity check
-    if (newpos + ctrl[1] > *new_size) {
-      fprintf(stderr, "corrupt patch (new file overrun)\n");
-      return 1;
-    }
-
-    // Read extra string
-    len_read = BZ2_bzRead(&bzerr, epfbz2, *new_data + newpos, ctrl[1]);
-    if (len_read < ctrl[1] || !(bzerr == BZ_OK || bzerr == BZ_STREAM_END)) {
-      fprintf(stderr, "corrupt patch (read extra)\n");
-      return 1;
-    }
-
-    // Adjust pointers
-    newpos += ctrl[1];
-    oldpos += ctrl[2];
-  }
-
-  BZ2_bzReadClose(&bzerr, cpfbz2);
-  BZ2_bzReadClose(&bzerr, dpfbz2);
-  BZ2_bzReadClose(&bzerr, epfbz2);
-  fclose(cpf);
-  fclose(dpf);
-  fclose(epf);
-
-  return 0;
-}
diff --git a/tools/applypatch/freecache.c b/tools/applypatch/freecache.c
deleted file mode 100644
index 9827fda..0000000
--- a/tools/applypatch/freecache.c
+++ /dev/null
@@ -1,172 +0,0 @@
-#include <errno.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <ctype.h>
-
-#include "applypatch.h"
-
-static int EliminateOpenFiles(char** files, int file_count) {
-  DIR* d;
-  struct dirent* de;
-  d = opendir("/proc");
-  if (d == NULL) {
-    printf("error opening /proc: %s\n", strerror(errno));
-    return -1;
-  }
-  while ((de = readdir(d)) != 0) {
-    int i;
-    for (i = 0; de->d_name[i] != '\0' && isdigit(de->d_name[i]); ++i);
-    if (de->d_name[i]) continue;
-
-    // de->d_name[i] is numeric
-
-    char path[FILENAME_MAX];
-    strcpy(path, "/proc/");
-    strcat(path, de->d_name);
-    strcat(path, "/fd/");
-
-    DIR* fdd;
-    struct dirent* fdde;
-    fdd = opendir(path);
-    if (fdd == NULL) {
-      printf("error opening %s: %s\n", path, strerror(errno));
-      continue;
-    }
-    while ((fdde = readdir(fdd)) != 0) {
-      char fd_path[FILENAME_MAX];
-      char link[FILENAME_MAX];
-      strcpy(fd_path, path);
-      strcat(fd_path, fdde->d_name);
-
-      int count;
-      count = readlink(fd_path, link, sizeof(link)-1);
-      if (count >= 0) {
-        link[count] = '\0';
-
-        // This is inefficient, but it should only matter if there are
-        // lots of files in /cache, and lots of them are open (neither
-        // of which should be true, especially in recovery).
-        if (strncmp(link, "/cache/", 7) == 0) {
-          int j;
-          for (j = 0; j < file_count; ++j) {
-            if (files[j] && strcmp(files[j], link) == 0) {
-              printf("%s is open by %s\n", link, de->d_name);
-              free(files[j]);
-              files[j] = NULL;
-            }
-          }
-        }
-      }
-    }
-    closedir(fdd);
-  }
-  closedir(d);
-
-  return 0;
-}
-
-int FindExpendableFiles(char*** names, int* entries) {
-  DIR* d;
-  struct dirent* de;
-  int size = 32;
-  *entries = 0;
-  *names = malloc(size * sizeof(char*));
-
-  char path[FILENAME_MAX];
-
-  // We're allowed to delete unopened regular files in any of these
-  // directories.
-  const char* dirs[2] = {"/cache", "/cache/recovery/otatest"};
-
-  unsigned int i;
-  for (i = 0; i < sizeof(dirs)/sizeof(dirs[0]); ++i) {
-    d = opendir(dirs[i]);
-    if (d == NULL) {
-      printf("error opening %s: %s\n", dirs[i], strerror(errno));
-      continue;
-    }
-
-    // Look for regular files in the directory (not in any subdirectories).
-    while ((de = readdir(d)) != 0) {
-      strcpy(path, dirs[i]);
-      strcat(path, "/");
-      strcat(path, de->d_name);
-
-      // We can't delete CACHE_TEMP_SOURCE; if it's there we might have
-      // restarted during installation and could be depending on it to
-      // be there.
-      if (strcmp(path, CACHE_TEMP_SOURCE) == 0) continue;
-
-      struct stat st;
-      if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
-        if (*entries >= size) {
-          size *= 2;
-          *names = realloc(*names, size * sizeof(char*));
-        }
-        (*names)[(*entries)++] = strdup(path);
-      }
-    }
-
-    closedir(d);
-  }
-
-  printf("%d regular files in deletable directories\n", *entries);
-
-  if (EliminateOpenFiles(*names, *entries) < 0) {
-    return -1;
-  }
-
-  return 0;
-}
-
-int MakeFreeSpaceOnCache(size_t bytes_needed) {
-  size_t free_now = FreeSpaceForFile("/cache");
-  printf("%ld bytes free on /cache (%ld needed)\n",
-         (long)free_now, (long)bytes_needed);
-
-  if (free_now >= bytes_needed) {
-    return 0;
-  }
-
-  char** names;
-  int entries;
-
-  if (FindExpendableFiles(&names, &entries) < 0) {
-    return -1;
-  }
-
-  if (entries == 0) {
-    // nothing we can delete to free up space!
-    printf("no files can be deleted to free space on /cache\n");
-    return -1;
-  }
-
-  // We could try to be smarter about which files to delete:  the
-  // biggest ones?  the smallest ones that will free up enough space?
-  // the oldest?  the newest?
-  //
-  // Instead, we'll be dumb.
-
-  int i;
-  for (i = 0; i < entries && free_now < bytes_needed; ++i) {
-    if (names[i]) {
-      unlink(names[i]);
-      free_now = FreeSpaceForFile("/cache");
-      printf("deleted %s; now %ld bytes free\n", names[i], (long)free_now);
-      free(names[i]);
-    }
-  }
-
-  for (; i < entries; ++i) {
-    free(names[i]);
-  }
-  free(names);
-
-  return (free_now >= bytes_needed) ? 0 : -1;
-}
diff --git a/tools/applypatch/imgdiff.c b/tools/applypatch/imgdiff.c
deleted file mode 100644
index 6b9ebee..0000000
--- a/tools/applypatch/imgdiff.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This program constructs binary patches for images -- such as boot.img
- * and recovery.img -- that consist primarily of large chunks of gzipped
- * data interspersed with uncompressed data.  Doing a naive bsdiff of
- * these files is not useful because small changes in the data lead to
- * large changes in the compressed bitstream; bsdiff patches of gzipped
- * data are typically as large as the data itself.
- *
- * To patch these usefully, we break the source and target images up into
- * chunks of two types: "normal" and "gzip".  Normal chunks are simply
- * patched using a plain bsdiff.  Gzip chunks are first expanded, then a
- * bsdiff is applied to the uncompressed data, then the patched data is
- * gzipped using the same encoder parameters.  Patched chunks are
- * concatenated together to create the output file; the output image
- * should be *exactly* the same series of bytes as the target image used
- * originally to generate the patch.
- *
- * To work well with this tool, the gzipped sections of the target
- * image must have been generated using the same deflate encoder that
- * is available in applypatch, namely, the one in the zlib library.
- * In practice this means that images should be compressed using the
- * "minigzip" tool included in the zlib distribution, not the GNU gzip
- * program.
- *
- * An "imgdiff" patch consists of a header describing the chunk structure
- * of the file and any encoding parameters needed for the gzipped
- * chunks, followed by N bsdiff patches, one per chunk.
- *
- * For a diff to be generated, the source and target images must have the
- * same "chunk" structure: that is, the same number of gzipped and normal
- * chunks in the same order.  Android boot and recovery images currently
- * consist of five chunks:  a small normal header, a gzipped kernel, a
- * small normal section, a gzipped ramdisk, and finally a small normal
- * footer.
- *
- * Caveats:  we locate gzipped sections within the source and target
- * images by searching for the byte sequence 1f8b0800:  1f8b is the gzip
- * magic number; 08 specifies the "deflate" encoding [the only encoding
- * supported by the gzip standard]; and 00 is the flags byte.  We do not
- * currently support any extra header fields (which would be indicated by
- * a nonzero flags byte).  We also don't handle the case when that byte
- * sequence appears spuriously in the file.  (Note that it would have to
- * occur spuriously within a normal chunk to be a problem.)
- *
- *
- * The imgdiff patch header looks like this:
- *
- *    "IMGDIFF1"                  (8)   [magic number and version]
- *    chunk count                 (4)
- *    for each chunk:
- *        chunk type              (4)   [CHUNK_{NORMAL, GZIP, DEFLATE, RAW}]
- *        if chunk type == CHUNK_NORMAL:
- *           source start         (8)
- *           source len           (8)
- *           bsdiff patch offset  (8)   [from start of patch file]
- *        if chunk type == CHUNK_GZIP:      (version 1 only)
- *           source start         (8)
- *           source len           (8)
- *           bsdiff patch offset  (8)   [from start of patch file]
- *           source expanded len  (8)   [size of uncompressed source]
- *           target expected len  (8)   [size of uncompressed target]
- *           gzip level           (4)
- *                method          (4)
- *                windowBits      (4)
- *                memLevel        (4)
- *                strategy        (4)
- *           gzip header len      (4)
- *           gzip header          (gzip header len)
- *           gzip footer          (8)
- *        if chunk type == CHUNK_DEFLATE:   (version 2 only)
- *           source start         (8)
- *           source len           (8)
- *           bsdiff patch offset  (8)   [from start of patch file]
- *           source expanded len  (8)   [size of uncompressed source]
- *           target expected len  (8)   [size of uncompressed target]
- *           gzip level           (4)
- *                method          (4)
- *                windowBits      (4)
- *                memLevel        (4)
- *                strategy        (4)
- *        if chunk type == RAW:             (version 2 only)
- *           target len           (4)
- *           data                 (target len)
- *
- * All integers are little-endian.  "source start" and "source len"
- * specify the section of the input image that comprises this chunk,
- * including the gzip header and footer for gzip chunks.  "source
- * expanded len" is the size of the uncompressed source data.  "target
- * expected len" is the size of the uncompressed data after applying
- * the bsdiff patch.  The next five parameters specify the zlib
- * parameters to be used when compressing the patched data, and the
- * next three specify the header and footer to be wrapped around the
- * compressed data to create the output chunk (so that header contents
- * like the timestamp are recreated exactly).
- *
- * After the header there are 'chunk count' bsdiff patches; the offset
- * of each from the beginning of the file is specified in the header.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "zlib.h"
-#include "imgdiff.h"
-#include "utils.h"
-
-typedef struct {
-  int type;             // CHUNK_NORMAL, CHUNK_DEFLATE
-  size_t start;         // offset of chunk in original image file
-
-  size_t len;
-  unsigned char* data;  // data to be patched (uncompressed, for deflate chunks)
-
-  size_t source_start;
-  size_t source_len;
-
-  off_t* I;             // used by bsdiff
-
-  // --- for CHUNK_DEFLATE chunks only: ---
-
-  // original (compressed) deflate data
-  size_t deflate_len;
-  unsigned char* deflate_data;
-
-  char* filename;       // used for zip entries
-
-  // deflate encoder parameters
-  int level, method, windowBits, memLevel, strategy;
-
-  size_t source_uncompressed_len;
-} ImageChunk;
-
-typedef struct {
-  int data_offset;
-  int deflate_len;
-  int uncomp_len;
-  char* filename;
-} ZipFileEntry;
-
-static int fileentry_compare(const void* a, const void* b) {
-  int ao = ((ZipFileEntry*)a)->data_offset;
-  int bo = ((ZipFileEntry*)b)->data_offset;
-  if (ao < bo) {
-    return -1;
-  } else if (ao > bo) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-// from bsdiff.c
-int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* new, off_t newsize,
-           const char* patch_filename);
-
-unsigned char* ReadZip(const char* filename,
-                       int* num_chunks, ImageChunk** chunks,
-                       int include_pseudo_chunk) {
-  struct stat st;
-  if (stat(filename, &st) != 0) {
-    printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
-    return NULL;
-  }
-
-  unsigned char* img = malloc(st.st_size);
-  FILE* f = fopen(filename, "rb");
-  if (fread(img, 1, st.st_size, f) != st.st_size) {
-    printf("failed to read \"%s\" %s\n", filename, strerror(errno));
-    fclose(f);
-    return NULL;
-  }
-  fclose(f);
-
-  // look for the end-of-central-directory record.
-
-  int i;
-  for (i = st.st_size-20; i >= 0 && i > st.st_size - 65600; --i) {
-    if (img[i] == 0x50 && img[i+1] == 0x4b &&
-        img[i+2] == 0x05 && img[i+3] == 0x06) {
-      break;
-    }
-  }
-  // double-check: this archive consists of a single "disk"
-  if (!(img[i+4] == 0 && img[i+5] == 0 && img[i+6] == 0 && img[i+7] == 0)) {
-    printf("can't process multi-disk archive\n");
-    return NULL;
-  }
-
-  int cdcount = Read2(img+i+8);
-  int cdoffset = Read4(img+i+16);
-
-  ZipFileEntry* temp_entries = malloc(cdcount * sizeof(ZipFileEntry));
-  int entrycount = 0;
-
-  unsigned char* cd = img+cdoffset;
-  for (i = 0; i < cdcount; ++i) {
-    if (!(cd[0] == 0x50 && cd[1] == 0x4b && cd[2] == 0x01 && cd[3] == 0x02)) {
-      printf("bad central directory entry %d\n", i);
-      return NULL;
-    }
-
-    int clen = Read4(cd+20);   // compressed len
-    int ulen = Read4(cd+24);   // uncompressed len
-    int nlen = Read2(cd+28);   // filename len
-    int xlen = Read2(cd+30);   // extra field len
-    int mlen = Read2(cd+32);   // file comment len
-    int hoffset = Read4(cd+42);   // local header offset
-
-    char* filename = malloc(nlen+1);
-    memcpy(filename, cd+46, nlen);
-    filename[nlen] = '\0';
-
-    int method = Read2(cd+10);
-
-    cd += 46 + nlen + xlen + mlen;
-
-    if (method != 8) {  // 8 == deflate
-      free(filename);
-      continue;
-    }
-
-    unsigned char* lh = img + hoffset;
-
-    if (!(lh[0] == 0x50 && lh[1] == 0x4b && lh[2] == 0x03 && lh[3] == 0x04)) {
-      printf("bad local file header entry %d\n", i);
-      return NULL;
-    }
-
-    if (Read2(lh+26) != nlen || memcmp(lh+30, filename, nlen) != 0) {
-      printf("central dir filename doesn't match local header\n");
-      return NULL;
-    }
-
-    xlen = Read2(lh+28);   // extra field len; might be different from CD entry?
-
-    temp_entries[entrycount].data_offset = hoffset+30+nlen+xlen;
-    temp_entries[entrycount].deflate_len = clen;
-    temp_entries[entrycount].uncomp_len = ulen;
-    temp_entries[entrycount].filename = filename;
-    ++entrycount;
-  }
-
-  qsort(temp_entries, entrycount, sizeof(ZipFileEntry), fileentry_compare);
-
-#if 0
-  printf("found %d deflated entries\n", entrycount);
-  for (i = 0; i < entrycount; ++i) {
-    printf("off %10d  len %10d unlen %10d   %p %s\n",
-           temp_entries[i].data_offset,
-           temp_entries[i].deflate_len,
-           temp_entries[i].uncomp_len,
-           temp_entries[i].filename,
-           temp_entries[i].filename);
-  }
-#endif
-
-  *num_chunks = 0;
-  *chunks = malloc((entrycount*2+2) * sizeof(ImageChunk));
-  ImageChunk* curr = *chunks;
-
-  if (include_pseudo_chunk) {
-    curr->type = CHUNK_NORMAL;
-    curr->start = 0;
-    curr->len = st.st_size;
-    curr->data = img;
-    curr->filename = NULL;
-    curr->I = NULL;
-    ++curr;
-    ++*num_chunks;
-  }
-
-  int pos = 0;
-  int nextentry = 0;
-
-  while (pos < st.st_size) {
-    if (nextentry < entrycount && pos == temp_entries[nextentry].data_offset) {
-      curr->type = CHUNK_DEFLATE;
-      curr->start = pos;
-      curr->deflate_len = temp_entries[nextentry].deflate_len;
-      curr->deflate_data = img + pos;
-      curr->filename = temp_entries[nextentry].filename;
-      curr->I = NULL;
-
-      curr->len = temp_entries[nextentry].uncomp_len;
-      curr->data = malloc(curr->len);
-
-      z_stream strm;
-      strm.zalloc = Z_NULL;
-      strm.zfree = Z_NULL;
-      strm.opaque = Z_NULL;
-      strm.avail_in = curr->deflate_len;
-      strm.next_in = curr->deflate_data;
-
-      // -15 means we are decoding a 'raw' deflate stream; zlib will
-      // not expect zlib headers.
-      int ret = inflateInit2(&strm, -15);
-
-      strm.avail_out = curr->len;
-      strm.next_out = curr->data;
-      ret = inflate(&strm, Z_NO_FLUSH);
-      if (ret != Z_STREAM_END) {
-        printf("failed to inflate \"%s\"; %d\n", curr->filename, ret);
-        return NULL;
-      }
-
-      inflateEnd(&strm);
-
-      pos += curr->deflate_len;
-      ++nextentry;
-      ++*num_chunks;
-      ++curr;
-      continue;
-    }
-
-    // use a normal chunk to take all the data up to the start of the
-    // next deflate section.
-
-    curr->type = CHUNK_NORMAL;
-    curr->start = pos;
-    if (nextentry < entrycount) {
-      curr->len = temp_entries[nextentry].data_offset - pos;
-    } else {
-      curr->len = st.st_size - pos;
-    }
-    curr->data = img + pos;
-    curr->filename = NULL;
-    curr->I = NULL;
-    pos += curr->len;
-
-    ++*num_chunks;
-    ++curr;
-  }
-
-  free(temp_entries);
-  return img;
-}
-
-/*
- * Read the given file and break it up into chunks, putting the number
- * of chunks and their info in *num_chunks and **chunks,
- * respectively.  Returns a malloc'd block of memory containing the
- * contents of the file; various pointers in the output chunk array
- * will point into this block of memory.  The caller should free the
- * return value when done with all the chunks.  Returns NULL on
- * failure.
- */
-unsigned char* ReadImage(const char* filename,
-                         int* num_chunks, ImageChunk** chunks) {
-  struct stat st;
-  if (stat(filename, &st) != 0) {
-    printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
-    return NULL;
-  }
-
-  unsigned char* img = malloc(st.st_size + 4);
-  FILE* f = fopen(filename, "rb");
-  if (fread(img, 1, st.st_size, f) != st.st_size) {
-    printf("failed to read \"%s\" %s\n", filename, strerror(errno));
-    fclose(f);
-    return NULL;
-  }
-  fclose(f);
-
-  // append 4 zero bytes to the data so we can always search for the
-  // four-byte string 1f8b0800 starting at any point in the actual
-  // file data, without special-casing the end of the data.
-  memset(img+st.st_size, 0, 4);
-
-  size_t pos = 0;
-
-  *num_chunks = 0;
-  *chunks = NULL;
-
-  while (pos < st.st_size) {
-    unsigned char* p = img+pos;
-
-    if (st.st_size - pos >= 4 &&
-        p[0] == 0x1f && p[1] == 0x8b &&
-        p[2] == 0x08 &&    // deflate compression
-        p[3] == 0x00) {    // no header flags
-      // 'pos' is the offset of the start of a gzip chunk.
-
-      *num_chunks += 3;
-      *chunks = realloc(*chunks, *num_chunks * sizeof(ImageChunk));
-      ImageChunk* curr = *chunks + (*num_chunks-3);
-
-      // create a normal chunk for the header.
-      curr->start = pos;
-      curr->type = CHUNK_NORMAL;
-      curr->len = GZIP_HEADER_LEN;
-      curr->data = p;
-      curr->I = NULL;
-
-      pos += curr->len;
-      p += curr->len;
-      ++curr;
-
-      curr->type = CHUNK_DEFLATE;
-      curr->filename = NULL;
-      curr->I = NULL;
-
-      // We must decompress this chunk in order to discover where it
-      // ends, and so we can put the uncompressed data and its length
-      // into curr->data and curr->len.
-
-      size_t allocated = 32768;
-      curr->len = 0;
-      curr->data = malloc(allocated);
-      curr->start = pos;
-      curr->deflate_data = p;
-
-      z_stream strm;
-      strm.zalloc = Z_NULL;
-      strm.zfree = Z_NULL;
-      strm.opaque = Z_NULL;
-      strm.avail_in = st.st_size - pos;
-      strm.next_in = p;
-
-      // -15 means we are decoding a 'raw' deflate stream; zlib will
-      // not expect zlib headers.
-      int ret = inflateInit2(&strm, -15);
-
-      do {
-        strm.avail_out = allocated - curr->len;
-        strm.next_out = curr->data + curr->len;
-        ret = inflate(&strm, Z_NO_FLUSH);
-        curr->len = allocated - strm.avail_out;
-        if (strm.avail_out == 0) {
-          allocated *= 2;
-          curr->data = realloc(curr->data, allocated);
-        }
-      } while (ret != Z_STREAM_END);
-
-      curr->deflate_len = st.st_size - strm.avail_in - pos;
-      inflateEnd(&strm);
-      pos += curr->deflate_len;
-      p += curr->deflate_len;
-      ++curr;
-
-      // create a normal chunk for the footer
-
-      curr->type = CHUNK_NORMAL;
-      curr->start = pos;
-      curr->len = GZIP_FOOTER_LEN;
-      curr->data = img+pos;
-      curr->I = NULL;
-
-      pos += curr->len;
-      p += curr->len;
-      ++curr;
-
-      // The footer (that we just skipped over) contains the size of
-      // the uncompressed data.  Double-check to make sure that it
-      // matches the size of the data we got when we actually did
-      // the decompression.
-      size_t footer_size = Read4(p-4);
-      if (footer_size != curr[-2].len) {
-        printf("Error: footer size %d != decompressed size %d\n",
-                footer_size, curr[-2].len);
-        free(img);
-        return NULL;
-      }
-    } else {
-      // Reallocate the list for every chunk; we expect the number of
-      // chunks to be small (5 for typical boot and recovery images).
-      ++*num_chunks;
-      *chunks = realloc(*chunks, *num_chunks * sizeof(ImageChunk));
-      ImageChunk* curr = *chunks + (*num_chunks-1);
-      curr->start = pos;
-      curr->I = NULL;
-
-      // 'pos' is not the offset of the start of a gzip chunk, so scan
-      // forward until we find a gzip header.
-      curr->type = CHUNK_NORMAL;
-      curr->data = p;
-
-      for (curr->len = 0; curr->len < (st.st_size - pos); ++curr->len) {
-        if (p[curr->len] == 0x1f &&
-            p[curr->len+1] == 0x8b &&
-            p[curr->len+2] == 0x08 &&
-            p[curr->len+3] == 0x00) {
-          break;
-        }
-      }
-      pos += curr->len;
-    }
-  }
-
-  return img;
-}
-
-#define BUFFER_SIZE 32768
-
-/*
- * Takes the uncompressed data stored in the chunk, compresses it
- * using the zlib parameters stored in the chunk, and checks that it
- * matches exactly the compressed data we started with (also stored in
- * the chunk).  Return 0 on success.
- */
-int TryReconstruction(ImageChunk* chunk, unsigned char* out) {
-  size_t p = 0;
-
-#if 0
-  printf("trying %d %d %d %d %d\n",
-          chunk->level, chunk->method, chunk->windowBits,
-          chunk->memLevel, chunk->strategy);
-#endif
-
-  z_stream strm;
-  strm.zalloc = Z_NULL;
-  strm.zfree = Z_NULL;
-  strm.opaque = Z_NULL;
-  strm.avail_in = chunk->len;
-  strm.next_in = chunk->data;
-  int ret;
-  ret = deflateInit2(&strm, chunk->level, chunk->method, chunk->windowBits,
-                     chunk->memLevel, chunk->strategy);
-  do {
-    strm.avail_out = BUFFER_SIZE;
-    strm.next_out = out;
-    ret = deflate(&strm, Z_FINISH);
-    size_t have = BUFFER_SIZE - strm.avail_out;
-
-    if (memcmp(out, chunk->deflate_data+p, have) != 0) {
-      // mismatch; data isn't the same.
-      deflateEnd(&strm);
-      return -1;
-    }
-    p += have;
-  } while (ret != Z_STREAM_END);
-  deflateEnd(&strm);
-  if (p != chunk->deflate_len) {
-    // mismatch; ran out of data before we should have.
-    return -1;
-  }
-  return 0;
-}
-
-/*
- * Verify that we can reproduce exactly the same compressed data that
- * we started with.  Sets the level, method, windowBits, memLevel, and
- * strategy fields in the chunk to the encoding parameters needed to
- * produce the right output.  Returns 0 on success.
- */
-int ReconstructDeflateChunk(ImageChunk* chunk) {
-  if (chunk->type != CHUNK_DEFLATE) {
-    printf("attempt to reconstruct non-deflate chunk\n");
-    return -1;
-  }
-
-  size_t p = 0;
-  unsigned char* out = malloc(BUFFER_SIZE);
-
-  // We only check two combinations of encoder parameters:  level 6
-  // (the default) and level 9 (the maximum).
-  for (chunk->level = 6; chunk->level <= 9; chunk->level += 3) {
-    chunk->windowBits = -15;  // 32kb window; negative to indicate a raw stream.
-    chunk->memLevel = 8;      // the default value.
-    chunk->method = Z_DEFLATED;
-    chunk->strategy = Z_DEFAULT_STRATEGY;
-
-    if (TryReconstruction(chunk, out) == 0) {
-      free(out);
-      return 0;
-    }
-  }
-
-  free(out);
-  return -1;
-}
-
-/*
- * Given source and target chunks, compute a bsdiff patch between them
- * by running bsdiff in a subprocess.  Return the patch data, placing
- * its length in *size.  Return NULL on failure.  We expect the bsdiff
- * program to be in the path.
- */
-unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
-  if (tgt->type == CHUNK_NORMAL) {
-    if (tgt->len <= 160) {
-      tgt->type = CHUNK_RAW;
-      *size = tgt->len;
-      return tgt->data;
-    }
-  }
-
-  char ptemp[] = "/tmp/imgdiff-patch-XXXXXX";
-  mkstemp(ptemp);
-
-  int r = bsdiff(src->data, src->len, &(src->I), tgt->data, tgt->len, ptemp);
-  if (r != 0) {
-    printf("bsdiff() failed: %d\n", r);
-    return NULL;
-  }
-
-  struct stat st;
-  if (stat(ptemp, &st) != 0) {
-    printf("failed to stat patch file %s: %s\n",
-            ptemp, strerror(errno));
-    return NULL;
-  }
-
-  unsigned char* data = malloc(st.st_size);
-
-  if (tgt->type == CHUNK_NORMAL && tgt->len <= st.st_size) {
-    unlink(ptemp);
-
-    tgt->type = CHUNK_RAW;
-    *size = tgt->len;
-    return tgt->data;
-  }
-
-  *size = st.st_size;
-
-  FILE* f = fopen(ptemp, "rb");
-  if (f == NULL) {
-    printf("failed to open patch %s: %s\n", ptemp, strerror(errno));
-    return NULL;
-  }
-  if (fread(data, 1, st.st_size, f) != st.st_size) {
-    printf("failed to read patch %s: %s\n", ptemp, strerror(errno));
-    return NULL;
-  }
-  fclose(f);
-
-  unlink(ptemp);
-
-  tgt->source_start = src->start;
-  switch (tgt->type) {
-    case CHUNK_NORMAL:
-      tgt->source_len = src->len;
-      break;
-    case CHUNK_DEFLATE:
-      tgt->source_len = src->deflate_len;
-      tgt->source_uncompressed_len = src->len;
-      break;
-  }
-
-  return data;
-}
-
-/*
- * Cause a gzip chunk to be treated as a normal chunk (ie, as a blob
- * of uninterpreted data).  The resulting patch will likely be about
- * as big as the target file, but it lets us handle the case of images
- * where some gzip chunks are reconstructible but others aren't (by
- * treating the ones that aren't as normal chunks).
- */
-void ChangeDeflateChunkToNormal(ImageChunk* ch) {
-  if (ch->type != CHUNK_DEFLATE) return;
-  ch->type = CHUNK_NORMAL;
-  free(ch->data);
-  ch->data = ch->deflate_data;
-  ch->len = ch->deflate_len;
-}
-
-/*
- * Return true if the data in the chunk is identical (including the
- * compressed representation, for gzip chunks).
- */
-int AreChunksEqual(ImageChunk* a, ImageChunk* b) {
-    if (a->type != b->type) return 0;
-
-    switch (a->type) {
-        case CHUNK_NORMAL:
-            return a->len == b->len && memcmp(a->data, b->data, a->len) == 0;
-
-        case CHUNK_DEFLATE:
-            return a->deflate_len == b->deflate_len &&
-                memcmp(a->deflate_data, b->deflate_data, a->deflate_len) == 0;
-
-        default:
-            printf("unknown chunk type %d\n", a->type);
-            return 0;
-    }
-}
-
-/*
- * Look for runs of adjacent normal chunks and compress them down into
- * a single chunk.  (Such runs can be produced when deflate chunks are
- * changed to normal chunks.)
- */
-void MergeAdjacentNormalChunks(ImageChunk* chunks, int* num_chunks) {
-  int out = 0;
-  int in_start = 0, in_end;
-  while (in_start < *num_chunks) {
-    if (chunks[in_start].type != CHUNK_NORMAL) {
-      in_end = in_start+1;
-    } else {
-      // in_start is a normal chunk.  Look for a run of normal chunks
-      // that constitute a solid block of data (ie, each chunk begins
-      // where the previous one ended).
-      for (in_end = in_start+1;
-           in_end < *num_chunks && chunks[in_end].type == CHUNK_NORMAL &&
-             (chunks[in_end].start ==
-              chunks[in_end-1].start + chunks[in_end-1].len &&
-              chunks[in_end].data ==
-              chunks[in_end-1].data + chunks[in_end-1].len);
-           ++in_end);
-    }
-
-    if (in_end == in_start+1) {
-#if 0
-      printf("chunk %d is now %d\n", in_start, out);
-#endif
-      if (out != in_start) {
-        memcpy(chunks+out, chunks+in_start, sizeof(ImageChunk));
-      }
-    } else {
-#if 0
-      printf("collapse normal chunks %d-%d into %d\n", in_start, in_end-1, out);
-#endif
-
-      // Merge chunks [in_start, in_end-1] into one chunk.  Since the
-      // data member of each chunk is just a pointer into an in-memory
-      // copy of the file, this can be done without recopying (the
-      // output chunk has the first chunk's start location and data
-      // pointer, and length equal to the sum of the input chunk
-      // lengths).
-      chunks[out].type = CHUNK_NORMAL;
-      chunks[out].start = chunks[in_start].start;
-      chunks[out].data = chunks[in_start].data;
-      chunks[out].len = chunks[in_end-1].len +
-        (chunks[in_end-1].start - chunks[in_start].start);
-    }
-
-    ++out;
-    in_start = in_end;
-  }
-  *num_chunks = out;
-}
-
-ImageChunk* FindChunkByName(const char* name,
-                            ImageChunk* chunks, int num_chunks) {
-  int i;
-  for (i = 0; i < num_chunks; ++i) {
-    if (chunks[i].type == CHUNK_DEFLATE && chunks[i].filename &&
-        strcmp(name, chunks[i].filename) == 0) {
-      return chunks+i;
-    }
-  }
-  return NULL;
-}
-
-void DumpChunks(ImageChunk* chunks, int num_chunks) {
-    int i;
-    for (i = 0; i < num_chunks; ++i) {
-        printf("chunk %d: type %d start %d len %d\n",
-               i, chunks[i].type, chunks[i].start, chunks[i].len);
-    }
-}
-
-int main(int argc, char** argv) {
-  if (argc != 4 && argc != 5) {
-    usage:
-    printf("usage: %s [-z] <src-img> <tgt-img> <patch-file>\n",
-            argv[0]);
-    return 2;
-  }
-
-  int zip_mode = 0;
-
-  if (strcmp(argv[1], "-z") == 0) {
-    zip_mode = 1;
-    --argc;
-    ++argv;
-  }
-
-
-  int num_src_chunks;
-  ImageChunk* src_chunks;
-  int num_tgt_chunks;
-  ImageChunk* tgt_chunks;
-  int i;
-
-  if (zip_mode) {
-    if (ReadZip(argv[1], &num_src_chunks, &src_chunks, 1) == NULL) {
-      printf("failed to break apart source zip file\n");
-      return 1;
-    }
-    if (ReadZip(argv[2], &num_tgt_chunks, &tgt_chunks, 0) == NULL) {
-      printf("failed to break apart target zip file\n");
-      return 1;
-    }
-  } else {
-    if (ReadImage(argv[1], &num_src_chunks, &src_chunks) == NULL) {
-      printf("failed to break apart source image\n");
-      return 1;
-    }
-    if (ReadImage(argv[2], &num_tgt_chunks, &tgt_chunks) == NULL) {
-      printf("failed to break apart target image\n");
-      return 1;
-    }
-
-    // Verify that the source and target images have the same chunk
-    // structure (ie, the same sequence of deflate and normal chunks).
-
-    if (!zip_mode) {
-        // Merge the gzip header and footer in with any adjacent
-        // normal chunks.
-        MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
-        MergeAdjacentNormalChunks(src_chunks, &num_src_chunks);
-    }
-
-    if (num_src_chunks != num_tgt_chunks) {
-      printf("source and target don't have same number of chunks!\n");
-      printf("source chunks:\n");
-      DumpChunks(src_chunks, num_src_chunks);
-      printf("target chunks:\n");
-      DumpChunks(tgt_chunks, num_tgt_chunks);
-      return 1;
-    }
-    for (i = 0; i < num_src_chunks; ++i) {
-      if (src_chunks[i].type != tgt_chunks[i].type) {
-        printf("source and target don't have same chunk "
-                "structure! (chunk %d)\n", i);
-        printf("source chunks:\n");
-        DumpChunks(src_chunks, num_src_chunks);
-        printf("target chunks:\n");
-        DumpChunks(tgt_chunks, num_tgt_chunks);
-        return 1;
-      }
-    }
-  }
-
-  for (i = 0; i < num_tgt_chunks; ++i) {
-    if (tgt_chunks[i].type == CHUNK_DEFLATE) {
-      // Confirm that given the uncompressed chunk data in the target, we
-      // can recompress it and get exactly the same bits as are in the
-      // input target image.  If this fails, treat the chunk as a normal
-      // non-deflated chunk.
-      if (ReconstructDeflateChunk(tgt_chunks+i) < 0) {
-        printf("failed to reconstruct target deflate chunk %d [%s]; "
-               "treating as normal\n", i, tgt_chunks[i].filename);
-        ChangeDeflateChunkToNormal(tgt_chunks+i);
-        if (zip_mode) {
-          ImageChunk* src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks);
-          if (src) {
-            ChangeDeflateChunkToNormal(src);
-          }
-        } else {
-          ChangeDeflateChunkToNormal(src_chunks+i);
-        }
-        continue;
-      }
-
-      // If two deflate chunks are identical (eg, the kernel has not
-      // changed between two builds), treat them as normal chunks.
-      // This makes applypatch much faster -- it can apply a trivial
-      // patch to the compressed data, rather than uncompressing and
-      // recompressing to apply the trivial patch to the uncompressed
-      // data.
-      ImageChunk* src;
-      if (zip_mode) {
-        src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks);
-      } else {
-        src = src_chunks+i;
-      }
-
-      if (src == NULL || AreChunksEqual(tgt_chunks+i, src)) {
-        ChangeDeflateChunkToNormal(tgt_chunks+i);
-        if (src) {
-          ChangeDeflateChunkToNormal(src);
-        }
-      }
-    }
-  }
-
-  // Merging neighboring normal chunks.
-  if (zip_mode) {
-    // For zips, we only need to do this to the target:  deflated
-    // chunks are matched via filename, and normal chunks are patched
-    // using the entire source file as the source.
-    MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
-  } else {
-    // For images, we need to maintain the parallel structure of the
-    // chunk lists, so do the merging in both the source and target
-    // lists.
-    MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
-    MergeAdjacentNormalChunks(src_chunks, &num_src_chunks);
-    if (num_src_chunks != num_tgt_chunks) {
-      // This shouldn't happen.
-      printf("merging normal chunks went awry\n");
-      return 1;
-    }
-  }
-
-  // Compute bsdiff patches for each chunk's data (the uncompressed
-  // data, in the case of deflate chunks).
-
-  printf("Construct patches for %d chunks...\n", num_tgt_chunks);
-  unsigned char** patch_data = malloc(num_tgt_chunks * sizeof(unsigned char*));
-  size_t* patch_size = malloc(num_tgt_chunks * sizeof(size_t));
-  for (i = 0; i < num_tgt_chunks; ++i) {
-    if (zip_mode) {
-      ImageChunk* src;
-      if (tgt_chunks[i].type == CHUNK_DEFLATE &&
-          (src = FindChunkByName(tgt_chunks[i].filename, src_chunks,
-                                 num_src_chunks))) {
-        patch_data[i] = MakePatch(src, tgt_chunks+i, patch_size+i);
-      } else {
-        patch_data[i] = MakePatch(src_chunks, tgt_chunks+i, patch_size+i);
-      }
-    } else {
-      patch_data[i] = MakePatch(src_chunks+i, tgt_chunks+i, patch_size+i);
-    }
-    printf("patch %3d is %d bytes (of %d)\n",
-           i, patch_size[i], tgt_chunks[i].source_len);
-  }
-
-  // Figure out how big the imgdiff file header is going to be, so
-  // that we can correctly compute the offset of each bsdiff patch
-  // within the file.
-
-  size_t total_header_size = 12;
-  for (i = 0; i < num_tgt_chunks; ++i) {
-    total_header_size += 4;
-    switch (tgt_chunks[i].type) {
-      case CHUNK_NORMAL:
-        total_header_size += 8*3;
-        break;
-      case CHUNK_DEFLATE:
-        total_header_size += 8*5 + 4*5;
-        break;
-      case CHUNK_RAW:
-        total_header_size += 4 + patch_size[i];
-        break;
-    }
-  }
-
-  size_t offset = total_header_size;
-
-  FILE* f = fopen(argv[3], "wb");
-
-  // Write out the headers.
-
-  fwrite("IMGDIFF2", 1, 8, f);
-  Write4(num_tgt_chunks, f);
-  for (i = 0; i < num_tgt_chunks; ++i) {
-    Write4(tgt_chunks[i].type, f);
-
-    switch (tgt_chunks[i].type) {
-      case CHUNK_NORMAL:
-        printf("chunk %3d: normal   (%10d, %10d)  %10d\n", i,
-               tgt_chunks[i].start, tgt_chunks[i].len, patch_size[i]);
-        Write8(tgt_chunks[i].source_start, f);
-        Write8(tgt_chunks[i].source_len, f);
-        Write8(offset, f);
-        offset += patch_size[i];
-        break;
-
-      case CHUNK_DEFLATE:
-        printf("chunk %3d: deflate  (%10d, %10d)  %10d  %s\n", i,
-               tgt_chunks[i].start, tgt_chunks[i].deflate_len, patch_size[i],
-               tgt_chunks[i].filename);
-        Write8(tgt_chunks[i].source_start, f);
-        Write8(tgt_chunks[i].source_len, f);
-        Write8(offset, f);
-        Write8(tgt_chunks[i].source_uncompressed_len, f);
-        Write8(tgt_chunks[i].len, f);
-        Write4(tgt_chunks[i].level, f);
-        Write4(tgt_chunks[i].method, f);
-        Write4(tgt_chunks[i].windowBits, f);
-        Write4(tgt_chunks[i].memLevel, f);
-        Write4(tgt_chunks[i].strategy, f);
-        offset += patch_size[i];
-        break;
-
-      case CHUNK_RAW:
-        printf("chunk %3d: raw      (%10d, %10d)\n", i,
-               tgt_chunks[i].start, tgt_chunks[i].len);
-        Write4(patch_size[i], f);
-        fwrite(patch_data[i], 1, patch_size[i], f);
-        break;
-    }
-  }
-
-  // Append each chunk's bsdiff patch, in order.
-
-  for (i = 0; i < num_tgt_chunks; ++i) {
-    if (tgt_chunks[i].type != CHUNK_RAW) {
-      fwrite(patch_data[i], 1, patch_size[i], f);
-    }
-  }
-
-  fclose(f);
-
-  return 0;
-}
diff --git a/tools/applypatch/imgdiff.h b/tools/applypatch/imgdiff.h
deleted file mode 100644
index f2069b4..0000000
--- a/tools/applypatch/imgdiff.h
+++ /dev/null
@@ -1,30 +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.
- */
-
-// Image patch chunk types
-#define CHUNK_NORMAL   0
-#define CHUNK_GZIP     1   // version 1 only
-#define CHUNK_DEFLATE  2   // version 2 only
-#define CHUNK_RAW      3   // version 2 only
-
-// The gzip header size is actually variable, but we currently don't
-// support gzipped data with any of the optional fields, so for now it
-// will always be ten bytes.  See RFC 1952 for the definition of the
-// gzip format.
-#define GZIP_HEADER_LEN   10
-
-// The gzip footer size really is fixed.
-#define GZIP_FOOTER_LEN   8
diff --git a/tools/applypatch/imgdiff_test.sh b/tools/applypatch/imgdiff_test.sh
deleted file mode 100755
index dcdb922..0000000
--- a/tools/applypatch/imgdiff_test.sh
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/bash
-#
-# A script for testing imgdiff/applypatch.  It takes two full OTA
-# packages as arguments.  It generates (on the host) patches for all
-# the zip/jar/apk files they have in common, as well as boot and
-# recovery images.  It then applies the patches on the device (or
-# emulator) and checks that the resulting file is correct.
-
-EMULATOR_PORT=5580
-
-# set to 0 to use a device instead
-USE_EMULATOR=0
-
-# where on the device to do all the patching.
-WORK_DIR=/data/local/tmp
-
-START_OTA_PACKAGE=$1
-END_OTA_PACKAGE=$2
-
-# ------------------------
-
-tmpdir=$(mktemp -d)
-
-if [ "$USE_EMULATOR" == 1 ]; then
-  emulator -wipe-data -noaudio -no-window -port $EMULATOR_PORT &
-  pid_emulator=$!
-  ADB="adb -s emulator-$EMULATOR_PORT "
-else
-  ADB="adb -d "
-fi
-
-echo "waiting to connect to device"
-$ADB wait-for-device
-
-# run a command on the device; exit with the exit status of the device
-# command.
-run_command() {
-  $ADB shell "$@" \; echo \$? | awk '{if (b) {print a}; a=$0; b=1} END {exit a}'
-}
-
-testname() {
-  echo
-  echo "$1"...
-  testname="$1"
-}
-
-fail() {
-  echo
-  echo FAIL: $testname
-  echo
-  [ "$open_pid" == "" ] || kill $open_pid
-  [ "$pid_emulator" == "" ] || kill $pid_emulator
-  exit 1
-}
-
-sha1() {
-  sha1sum $1 | awk '{print $1}'
-}
-
-size() {
-  stat -c %s $1 | tr -d '\n'
-}
-
-cleanup() {
-  # not necessary if we're about to kill the emulator, but nice for
-  # running on real devices or already-running emulators.
-  testname "removing test files"
-  run_command rm $WORK_DIR/applypatch
-  run_command rm $WORK_DIR/source
-  run_command rm $WORK_DIR/target
-  run_command rm $WORK_DIR/patch
-
-  [ "$pid_emulator" == "" ] || kill $pid_emulator
-
-  rm -rf $tmpdir
-}
-
-$ADB push $ANDROID_PRODUCT_OUT/system/bin/applypatch $WORK_DIR/applypatch
-
-patch_and_apply() {
-  local fn=$1
-  shift
-
-  unzip -p $START_OTA_PACKAGE $fn > $tmpdir/source
-  unzip -p $END_OTA_PACKAGE $fn > $tmpdir/target
-  imgdiff "$@" $tmpdir/source $tmpdir/target $tmpdir/patch
-  bsdiff $tmpdir/source $tmpdir/target $tmpdir/patch.bs
-  echo "patch for $fn is $(size $tmpdir/patch) [of $(size $tmpdir/target)] ($(size $tmpdir/patch.bs) with bsdiff)"
-  echo "$fn $(size $tmpdir/patch) of $(size $tmpdir/target) bsdiff $(size $tmpdir/patch.bs)" >> /tmp/stats.txt
-  $ADB push $tmpdir/source $WORK_DIR/source || fail "source push failed"
-  run_command rm /data/local/tmp/target
-  $ADB push $tmpdir/patch $WORK_DIR/patch || fail "patch push failed"
-  run_command /data/local/tmp/applypatch /data/local/tmp/source \
-    /data/local/tmp/target $(sha1 $tmpdir/target) $(size $tmpdir/target) \
-    $(sha1 $tmpdir/source):/data/local/tmp/patch \
-    || fail "applypatch of $fn failed"
-  $ADB pull /data/local/tmp/target $tmpdir/result
-  diff -q $tmpdir/target $tmpdir/result || fail "patch output not correct!"
-}
-
-# --------------- basic execution ----------------------
-
-for i in $((zipinfo -1 $START_OTA_PACKAGE; zipinfo -1 $END_OTA_PACKAGE) | \
-           sort | uniq -d | egrep -e '[.](apk|jar|zip)$'); do
-  patch_and_apply $i -z
-done
-patch_and_apply boot.img
-patch_and_apply system/recovery.img
-
-
-# --------------- cleanup ----------------------
-
-cleanup
-
-echo
-echo PASS
-echo
-
diff --git a/tools/applypatch/imgpatch.c b/tools/applypatch/imgpatch.c
deleted file mode 100644
index 5322817..0000000
--- a/tools/applypatch/imgpatch.c
+++ /dev/null
@@ -1,364 +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.
- */
-
-// See imgdiff.c in this directory for a description of the patch file
-// format.
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "zlib.h"
-#include "mincrypt/sha.h"
-#include "applypatch.h"
-#include "imgdiff.h"
-#include "utils.h"
-
-/*
- * Apply the patch given in 'patch_filename' to the source data given
- * by (old_data, old_size).  Write the patched output to the 'output'
- * file, and update the SHA context with the output data as well.
- * Return 0 on success.
- */
-int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
-                    const char* patch_filename,
-                    SinkFn sink, void* token, SHA_CTX* ctx) {
-  FILE* f;
-  if ((f = fopen(patch_filename, "rb")) == NULL) {
-    printf("failed to open patch file\n");
-    return -1;
-  }
-
-  unsigned char header[12];
-  if (fread(header, 1, 12, f) != 12) {
-    printf("failed to read patch file header\n");
-    return -1;
-  }
-
-  // IMGDIFF1 uses CHUNK_NORMAL and CHUNK_GZIP.
-  // IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW.
-  if (memcmp(header, "IMGDIFF", 7) != 0 ||
-      (header[7] != '1' && header[7] != '2')) {
-    printf("corrupt patch file header (magic number)\n");
-    return -1;
-  }
-
-  int num_chunks = Read4(header+8);
-
-  int i;
-  for (i = 0; i < num_chunks; ++i) {
-    // each chunk's header record starts with 4 bytes.
-    unsigned char chunk[4];
-    if (fread(chunk, 1, 4, f) != 4) {
-      printf("failed to read chunk %d record\n", i);
-      return -1;
-    }
-
-    int type = Read4(chunk);
-
-    if (type == CHUNK_NORMAL) {
-      unsigned char normal_header[24];
-      if (fread(normal_header, 1, 24, f) != 24) {
-        printf("failed to read chunk %d normal header data\n", i);
-        return -1;
-      }
-
-      size_t src_start = Read8(normal_header);
-      size_t src_len = Read8(normal_header+8);
-      size_t patch_offset = Read8(normal_header+16);
-
-      printf("CHUNK %d:  normal   patch offset %d\n", i, patch_offset);
-
-      ApplyBSDiffPatch(old_data + src_start, src_len,
-                       patch_filename, patch_offset,
-                       sink, token, ctx);
-    } else if (type == CHUNK_GZIP) {
-      // This branch is basically a duplicate of the CHUNK_DEFLATE
-      // branch, with a bit of extra processing for the gzip header
-      // and footer.  I've avoided factoring the common code out since
-      // this branch will just be deleted when we drop support for
-      // IMGDIFF1.
-
-      // gzip chunks have an additional 64 + gzip_header_len + 8 bytes
-      // in their chunk header.
-      unsigned char* gzip = malloc(64);
-      if (fread(gzip, 1, 64, f) != 64) {
-        printf("failed to read chunk %d initial gzip header data\n",
-                i);
-        return -1;
-      }
-      size_t gzip_header_len = Read4(gzip+60);
-      gzip = realloc(gzip, 64 + gzip_header_len + 8);
-      if (fread(gzip+64, 1, gzip_header_len+8, f) != gzip_header_len+8) {
-        printf("failed to read chunk %d remaining gzip header data\n",
-                i);
-        return -1;
-      }
-
-      size_t src_start = Read8(gzip);
-      size_t src_len = Read8(gzip+8);
-      size_t patch_offset = Read8(gzip+16);
-
-      size_t expanded_len = Read8(gzip+24);
-      size_t target_len = Read8(gzip+32);
-      int gz_level = Read4(gzip+40);
-      int gz_method = Read4(gzip+44);
-      int gz_windowBits = Read4(gzip+48);
-      int gz_memLevel = Read4(gzip+52);
-      int gz_strategy = Read4(gzip+56);
-
-      printf("CHUNK %d:  gzip     patch offset %d\n", i, patch_offset);
-
-      // Decompress the source data; the chunk header tells us exactly
-      // how big we expect it to be when decompressed.
-
-      unsigned char* expanded_source = malloc(expanded_len);
-      if (expanded_source == NULL) {
-        printf("failed to allocate %d bytes for expanded_source\n",
-                expanded_len);
-        return -1;
-      }
-
-      z_stream strm;
-      strm.zalloc = Z_NULL;
-      strm.zfree = Z_NULL;
-      strm.opaque = Z_NULL;
-      strm.avail_in = src_len - (gzip_header_len + 8);
-      strm.next_in = (unsigned char*)(old_data + src_start + gzip_header_len);
-      strm.avail_out = expanded_len;
-      strm.next_out = expanded_source;
-
-      int ret;
-      ret = inflateInit2(&strm, -15);
-      if (ret != Z_OK) {
-        printf("failed to init source inflation: %d\n", ret);
-        return -1;
-      }
-
-      // Because we've provided enough room to accommodate the output
-      // data, we expect one call to inflate() to suffice.
-      ret = inflate(&strm, Z_SYNC_FLUSH);
-      if (ret != Z_STREAM_END) {
-        printf("source inflation returned %d\n", ret);
-        return -1;
-      }
-      // We should have filled the output buffer exactly.
-      if (strm.avail_out != 0) {
-        printf("source inflation short by %d bytes\n", strm.avail_out);
-        return -1;
-      }
-      inflateEnd(&strm);
-
-      // Next, apply the bsdiff patch (in memory) to the uncompressed
-      // data.
-      unsigned char* uncompressed_target_data;
-      ssize_t uncompressed_target_size;
-      if (ApplyBSDiffPatchMem(expanded_source, expanded_len,
-                              patch_filename, patch_offset,
-                              &uncompressed_target_data,
-                              &uncompressed_target_size) != 0) {
-        return -1;
-      }
-
-      // Now compress the target data and append it to the output.
-
-      // start with the gzip header.
-      sink(gzip+64, gzip_header_len, token);
-      SHA_update(ctx, gzip+64, gzip_header_len);
-
-      // we're done with the expanded_source data buffer, so we'll
-      // reuse that memory to receive the output of deflate.
-      unsigned char* temp_data = expanded_source;
-      ssize_t temp_size = expanded_len;
-      if (temp_size < 32768) {
-        // ... unless the buffer is too small, in which case we'll
-        // allocate a fresh one.
-        free(temp_data);
-        temp_data = malloc(32768);
-        temp_size = 32768;
-      }
-
-      // now the deflate stream
-      strm.zalloc = Z_NULL;
-      strm.zfree = Z_NULL;
-      strm.opaque = Z_NULL;
-      strm.avail_in = uncompressed_target_size;
-      strm.next_in = uncompressed_target_data;
-      ret = deflateInit2(&strm, gz_level, gz_method, gz_windowBits,
-                         gz_memLevel, gz_strategy);
-      do {
-        strm.avail_out = temp_size;
-        strm.next_out = temp_data;
-        ret = deflate(&strm, Z_FINISH);
-        size_t have = temp_size - strm.avail_out;
-
-        if (sink(temp_data, have, token) != have) {
-          printf("failed to write %d compressed bytes to output\n",
-                  have);
-          return -1;
-        }
-        SHA_update(ctx, temp_data, have);
-      } while (ret != Z_STREAM_END);
-      deflateEnd(&strm);
-
-      // lastly, the gzip footer.
-      sink(gzip+64+gzip_header_len, 8, token);
-      SHA_update(ctx, gzip+64+gzip_header_len, 8);
-
-      free(temp_data);
-      free(uncompressed_target_data);
-      free(gzip);
-    } else if (type == CHUNK_RAW) {
-      unsigned char raw_header[4];
-      if (fread(raw_header, 1, 4, f) != 4) {
-        printf("failed to read chunk %d raw header data\n", i);
-        return -1;
-      }
-
-      size_t data_len = Read4(raw_header);
-
-      printf("CHUNK %d:  raw      data %d\n", i, data_len);
-
-      unsigned char* temp = malloc(data_len);
-      if (fread(temp, 1, data_len, f) != data_len) {
-          printf("failed to read chunk %d raw data\n", i);
-          return -1;
-      }
-      SHA_update(ctx, temp, data_len);
-      if (sink(temp, data_len, token) != data_len) {
-          printf("failed to write chunk %d raw data\n", i);
-          return -1;
-      }
-    } else if (type == CHUNK_DEFLATE) {
-      // deflate chunks have an additional 60 bytes in their chunk header.
-      unsigned char deflate_header[60];
-      if (fread(deflate_header, 1, 60, f) != 60) {
-        printf("failed to read chunk %d deflate header data\n", i);
-        return -1;
-      }
-
-      size_t src_start = Read8(deflate_header);
-      size_t src_len = Read8(deflate_header+8);
-      size_t patch_offset = Read8(deflate_header+16);
-      size_t expanded_len = Read8(deflate_header+24);
-      size_t target_len = Read8(deflate_header+32);
-      int level = Read4(deflate_header+40);
-      int method = Read4(deflate_header+44);
-      int windowBits = Read4(deflate_header+48);
-      int memLevel = Read4(deflate_header+52);
-      int strategy = Read4(deflate_header+56);
-
-      printf("CHUNK %d:  deflate  patch offset %d\n", i, patch_offset);
-
-      // Decompress the source data; the chunk header tells us exactly
-      // how big we expect it to be when decompressed.
-
-      unsigned char* expanded_source = malloc(expanded_len);
-      if (expanded_source == NULL) {
-        printf("failed to allocate %d bytes for expanded_source\n",
-                expanded_len);
-        return -1;
-      }
-
-      z_stream strm;
-      strm.zalloc = Z_NULL;
-      strm.zfree = Z_NULL;
-      strm.opaque = Z_NULL;
-      strm.avail_in = src_len;
-      strm.next_in = (unsigned char*)(old_data + src_start);
-      strm.avail_out = expanded_len;
-      strm.next_out = expanded_source;
-
-      int ret;
-      ret = inflateInit2(&strm, -15);
-      if (ret != Z_OK) {
-        printf("failed to init source inflation: %d\n", ret);
-        return -1;
-      }
-
-      // Because we've provided enough room to accommodate the output
-      // data, we expect one call to inflate() to suffice.
-      ret = inflate(&strm, Z_SYNC_FLUSH);
-      if (ret != Z_STREAM_END) {
-        printf("source inflation returned %d\n", ret);
-        return -1;
-      }
-      // We should have filled the output buffer exactly.
-      if (strm.avail_out != 0) {
-        printf("source inflation short by %d bytes\n", strm.avail_out);
-        return -1;
-      }
-      inflateEnd(&strm);
-
-      // Next, apply the bsdiff patch (in memory) to the uncompressed
-      // data.
-      unsigned char* uncompressed_target_data;
-      ssize_t uncompressed_target_size;
-      if (ApplyBSDiffPatchMem(expanded_source, expanded_len,
-                              patch_filename, patch_offset,
-                              &uncompressed_target_data,
-                              &uncompressed_target_size) != 0) {
-        return -1;
-      }
-
-      // Now compress the target data and append it to the output.
-
-      // we're done with the expanded_source data buffer, so we'll
-      // reuse that memory to receive the output of deflate.
-      unsigned char* temp_data = expanded_source;
-      ssize_t temp_size = expanded_len;
-      if (temp_size < 32768) {
-        // ... unless the buffer is too small, in which case we'll
-        // allocate a fresh one.
-        free(temp_data);
-        temp_data = malloc(32768);
-        temp_size = 32768;
-      }
-
-      // now the deflate stream
-      strm.zalloc = Z_NULL;
-      strm.zfree = Z_NULL;
-      strm.opaque = Z_NULL;
-      strm.avail_in = uncompressed_target_size;
-      strm.next_in = uncompressed_target_data;
-      ret = deflateInit2(&strm, level, method, windowBits, memLevel, strategy);
-      do {
-        strm.avail_out = temp_size;
-        strm.next_out = temp_data;
-        ret = deflate(&strm, Z_FINISH);
-        size_t have = temp_size - strm.avail_out;
-
-        if (sink(temp_data, have, token) != have) {
-          printf("failed to write %d compressed bytes to output\n",
-                  have);
-          return -1;
-        }
-        SHA_update(ctx, temp_data, have);
-      } while (ret != Z_STREAM_END);
-      deflateEnd(&strm);
-
-      free(temp_data);
-      free(uncompressed_target_data);
-    } else {
-      printf("patch chunk %d is unknown type %d\n", i, type);
-      return -1;
-    }
-  }
-
-  return 0;
-}
diff --git a/tools/applypatch/main.c b/tools/applypatch/main.c
deleted file mode 100644
index e08f5c1..0000000
--- a/tools/applypatch/main.c
+++ /dev/null
@@ -1,60 +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.
- */
-
-#include <stdio.h>
-
-extern int applypatch(int argc, char** argv);
-
-// This program applies binary patches to files in a way that is safe
-// (the original file is not touched until we have the desired
-// replacement for it) and idempotent (it's okay to run this program
-// multiple times).
-//
-// - if the sha1 hash of <tgt-file> is <tgt-sha1>, does nothing and exits
-//   successfully.
-//
-// - otherwise, if the sha1 hash of <src-file> is <src-sha1>, applies the
-//   bsdiff <patch> to <src-file> to produce a new file (the type of patch
-//   is automatically detected from the file header).  If that new
-//   file has sha1 hash <tgt-sha1>, moves it to replace <tgt-file>, and
-//   exits successfully.  Note that if <src-file> and <tgt-file> are
-//   not the same, <src-file> is NOT deleted on success.  <tgt-file>
-//   may be the string "-" to mean "the same as src-file".
-//
-// - otherwise, or if any error is encountered, exits with non-zero
-//   status.
-//
-// <src-file> (or <file> in check mode) may refer to an MTD partition
-// to read the source data.  See the comments for the
-// LoadMTDContents() function above for the format of such a filename.
-
-int main(int argc, char** argv) {
-  int result = applypatch(argc, argv);
-  if (result == 2) {
-    printf(
-            "usage: %s <src-file> <tgt-file> <tgt-sha1> <tgt-size> "
-            "[<src-sha1>:<patch> ...]\n"
-            "   or  %s -c <file> [<sha1> ...]\n"
-            "   or  %s -s <bytes>\n"
-            "   or  %s -l\n"
-            "\n"
-            "Filenames may be of the form\n"
-            "  MTD:<partition>:<len_1>:<sha1_1>:<len_2>:<sha1_2>:...\n"
-            "to specify reading from or writing to an MTD partition.\n\n",
-            argv[0], argv[0], argv[0], argv[0]);
-  }
-  return result;
-}
diff --git a/tools/applypatch/testdata/new.file b/tools/applypatch/testdata/new.file
deleted file mode 100644
index cdeb8fd..0000000
--- a/tools/applypatch/testdata/new.file
+++ /dev/null
Binary files differ
diff --git a/tools/applypatch/testdata/old.file b/tools/applypatch/testdata/old.file
deleted file mode 100644
index 166c873..0000000
--- a/tools/applypatch/testdata/old.file
+++ /dev/null
Binary files differ
diff --git a/tools/applypatch/testdata/patch.bsdiff b/tools/applypatch/testdata/patch.bsdiff
deleted file mode 100644
index b78d385..0000000
--- a/tools/applypatch/testdata/patch.bsdiff
+++ /dev/null
Binary files differ
diff --git a/tools/applypatch/utils.c b/tools/applypatch/utils.c
deleted file mode 100644
index 912229b..0000000
--- a/tools/applypatch/utils.c
+++ /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.
- */
-
-#include <stdio.h>
-
-#include "utils.h"
-
-/** Write a 4-byte value to f in little-endian order. */
-void Write4(int value, FILE* f) {
-  fputc(value & 0xff, f);
-  fputc((value >> 8) & 0xff, f);
-  fputc((value >> 16) & 0xff, f);
-  fputc((value >> 24) & 0xff, f);
-}
-
-/** Write an 8-byte value to f in little-endian order. */
-void Write8(long long value, FILE* f) {
-  fputc(value & 0xff, f);
-  fputc((value >> 8) & 0xff, f);
-  fputc((value >> 16) & 0xff, f);
-  fputc((value >> 24) & 0xff, f);
-  fputc((value >> 32) & 0xff, f);
-  fputc((value >> 40) & 0xff, f);
-  fputc((value >> 48) & 0xff, f);
-  fputc((value >> 56) & 0xff, f);
-}
-
-int Read2(unsigned char* p) {
-  return (int)(((unsigned int)p[1] << 8) |
-               (unsigned int)p[0]);
-}
-
-int Read4(unsigned char* p) {
-  return (int)(((unsigned int)p[3] << 24) |
-               ((unsigned int)p[2] << 16) |
-               ((unsigned int)p[1] << 8) |
-               (unsigned int)p[0]);
-}
-
-long long Read8(unsigned char* p) {
-  return (long long)(((unsigned long long)p[7] << 56) |
-                     ((unsigned long long)p[6] << 48) |
-                     ((unsigned long long)p[5] << 40) |
-                     ((unsigned long long)p[4] << 32) |
-                     ((unsigned long long)p[3] << 24) |
-                     ((unsigned long long)p[2] << 16) |
-                     ((unsigned long long)p[1] << 8) |
-                     (unsigned long long)p[0]);
-}
diff --git a/tools/applypatch/utils.h b/tools/applypatch/utils.h
deleted file mode 100644
index d6d6f1d..0000000
--- a/tools/applypatch/utils.h
+++ /dev/null
@@ -1,30 +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.
- */
-
-#ifndef _BUILD_TOOLS_APPLYPATCH_UTILS_H
-#define _BUILD_TOOLS_APPLYPATCH_UTILS_H
-
-#include <stdio.h>
-
-// Read and write little-endian values of various sizes.
-
-void Write4(int value, FILE* f);
-void Write8(long long value, FILE* f);
-int Read2(unsigned char* p);
-int Read4(unsigned char* p);
-long long Read8(unsigned char* p);
-
-#endif //  _BUILD_TOOLS_APPLYPATCH_UTILS_H
diff --git a/tools/dexpreopt/Config.mk b/tools/dexpreopt/Config.mk
index 443b8c9..b2b32c6 100644
--- a/tools/dexpreopt/Config.mk
+++ b/tools/dexpreopt/Config.mk
@@ -78,7 +78,7 @@
 endif
 
 # The kernel used for ARMv7 system images is different
-ifeq ($(TARGET_ARCH_VARIANT),armv7-a)
+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
diff --git a/tools/dexpreopt/dexpreopt.py b/tools/dexpreopt/dexpreopt.py
index 5dde642..376f135 100755
--- a/tools/dexpreopt/dexpreopt.py
+++ b/tools/dexpreopt/dexpreopt.py
@@ -125,6 +125,10 @@
   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'):
diff --git a/tools/droiddoc/src/Errors.java b/tools/droiddoc/src/Errors.java
index 77852f8..7ba5623 100644
--- a/tools/droiddoc/src/Errors.java
+++ b/tools/droiddoc/src/Errors.java
@@ -115,7 +115,7 @@
     public static Error DEPRECATION_MISMATCH = new Error(13, WARNING);
     public static Error MISSING_COMMENT = new Error(14, WARNING);
     public static Error IO_ERROR = new Error(15, HIDDEN);
-    public static Error NO_SINCE_DATA = new Error(16, WARNING);
+    public static Error NO_SINCE_DATA = new Error(16, HIDDEN);
 
     public static Error[] ERRORS = {
             UNRESOLVED_LINK,
diff --git a/tools/droiddoc/src/LinkReference.java b/tools/droiddoc/src/LinkReference.java
index bbcd4db..b1f998a 100644
--- a/tools/droiddoc/src/LinkReference.java
+++ b/tools/droiddoc/src/LinkReference.java
@@ -59,6 +59,12 @@
                               Pattern.CASE_INSENSITIVE);
 
     /**
+     * regex pattern to use when matching double-quoted reference text
+     */
+    private static final Pattern QUOTE_PATTERN
+            = Pattern.compile("^\"([^\"]*)\"[ \n\r\t]*$");
+
+    /**
      * Parse and resolve a link string.
      *
      * @param text the original text
@@ -321,15 +327,15 @@
 
         if (text.startsWith("\"")) {
             // literal quoted reference (e.g., a book title)
-            result.label = text.substring(1);
-            skipHref = true;
-            if (!result.label.endsWith("\"")) {
+            Matcher matcher = QUOTE_PATTERN.matcher(text);
+            if (! matcher.matches()) {
                 Errors.error(Errors.UNRESOLVED_LINK, pos,
                         "unbalanced quoted link/see tag: " + text.trim());
                 result.makeError();
                 return result;
             }
-            result.label = result.label.substring(0, result.label.length() - 1);
+            skipHref = true;
+            result.label = matcher.group(1);
             result.kind = "@seeJustLabel";
         }
         else if (text.startsWith("<")) {
diff --git a/tools/droiddoc/src/MethodInfo.java b/tools/droiddoc/src/MethodInfo.java
index 3211038..7f96b80 100644
--- a/tools/droiddoc/src/MethodInfo.java
+++ b/tools/droiddoc/src/MethodInfo.java
@@ -363,8 +363,17 @@
     public String getHashableName() {
         StringBuilder result = new StringBuilder();
         result.append(name());
-        for (ParameterInfo pInfo : mParameters) {
-            result.append(":").append(pInfo.type().fullName());
+        for (int p = 0; p < mParameters.length; p++) {
+            result.append(":");
+            if (p == mParameters.length - 1 && isVarArgs()) {
+                // TODO: note that this does not attempt to handle hypothetical
+                // vararg methods whose last parameter is a list of arrays, e.g.
+                // "Object[]...".
+                result.append(mParameters[p].type().fullNameNoDimension(typeVariables()))
+                        .append("...");
+            } else {
+                result.append(mParameters[p].type().fullName(typeVariables()));
+            }
         }
         return result.toString();
     }
diff --git a/tools/droiddoc/src/SinceTagger.java b/tools/droiddoc/src/SinceTagger.java
index fb69c04..a1bce55 100644
--- a/tools/droiddoc/src/SinceTagger.java
+++ b/tools/droiddoc/src/SinceTagger.java
@@ -1,8 +1,13 @@
 // Copyright 2009 Google Inc. All Rights Reserved.
 
-import com.android.apicheck.*;
+import com.android.apicheck.ApiCheck;
+import com.android.apicheck.ApiInfo;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Collections;
 
 import org.clearsilver.HDF;
 
@@ -165,31 +170,68 @@
      */
     private void warnForMissingVersions(ClassInfo[] classDocs) {
         for (ClassInfo claz : classDocs) {
+            if (!checkLevelRecursive(claz)) {
+                continue;
+            }
+
             if (claz.getSince() == null) {
                 Errors.error(Errors.NO_SINCE_DATA, claz.position(),
                         "XML missing class " + claz.qualifiedName());
             }
-            for (FieldInfo field : claz.fields()) {
-                if (field.getSince() == null) {
-                    Errors.error(Errors.NO_SINCE_DATA, field.position(),
-                            "XML missing field "
-                                    + claz.qualifiedName() + "#" + field .name());
-                }
+            
+            for (FieldInfo field : missingVersions(claz.fields())) {
+                Errors.error(Errors.NO_SINCE_DATA, field.position(),
+                        "XML missing field " + claz.qualifiedName()
+                                + "#" + field.name());
             }
-            for (MethodInfo constructor : claz.constructors()) {
-                if (constructor.getSince() == null) {
-                    Errors.error(Errors.NO_SINCE_DATA, constructor.position(),
-                            "XML missing constructor "
-                                    + claz.qualifiedName() + "#" + constructor.getHashableName());
-                }
+
+            for (MethodInfo constructor : missingVersions(claz.constructors())) {
+                Errors.error(Errors.NO_SINCE_DATA, constructor.position(),
+                        "XML missing constructor " + claz.qualifiedName()
+                                + "#" + constructor.getHashableName());
             }
-            for (MethodInfo method : claz.methods()) {
-                if (method.getSince() == null) {
-                    Errors.error(Errors.NO_SINCE_DATA, method.position(),
-                            "XML missing method "
-                                    + claz.qualifiedName() + "#" + method .getHashableName());
-                }
+
+            for (MethodInfo method : missingVersions(claz.methods())) {
+                Errors.error(Errors.NO_SINCE_DATA, method.position(),
+                        "XML missing method " + claz.qualifiedName()
+                                + "#" + method.getHashableName());
             }
         }
     }
+
+    /**
+     * Returns the DocInfos in {@code all} that are documented but do not have
+     * since tags.
+     */
+    private <T extends MemberInfo> Iterable<T> missingVersions(T[] all) {
+        List<T> result = Collections.emptyList();
+        for (T t : all) {
+            // if this member has version info or isn't documented, skip it
+            if (t.getSince() != null
+                    || t.isHidden()
+                    || !checkLevelRecursive(t.realContainingClass())) {
+                continue;
+            }
+
+            if (result.isEmpty()) {
+                result = new ArrayList<T>(); // lazily construct a mutable list
+            }
+            result.add(t);
+        }
+        return result;
+    }
+
+    /**
+     * Returns true if {@code claz} and all containing classes are documented.
+     * The result may be used to filter out members that exist in the API
+     * data structure but aren't a part of the API.
+     */
+    private boolean checkLevelRecursive(ClassInfo claz) {
+        for (ClassInfo c = claz; c != null; c = c.containingClass()) {
+            if (!c.checkLevel()) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/tools/droiddoc/templates-pdk/assets/android-developer-core.css b/tools/droiddoc/templates-pdk/assets/android-developer-core.css
new file mode 100644
index 0000000..bb4f806
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/assets/android-developer-core.css
@@ -0,0 +1,1297 @@
+/* file: android-developer-core.css
+   author: smain
+   date: september 2008
+   info: core developer styles (developer.android.com)
+*/
+
+
+/* RESET STYLES */
+
+html,body,div,h1,h2,h3,h4,h5,h6,p,img,
+dl,dt,dd,ol,ul,li,table,caption,tbody,
+tfoot,thead,tr,th,td,form,fieldset,
+embed,object,applet {
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+
+.rebox {
+  background:#daf3fc;
+  margin-bottom:1.5em;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+}
+.rebox.lil p img {
+  display:block;
+  margin-bottom:2em;
+}
+
+.rebox .p {
+  padding:1.5em;
+  line-height:1.25em;
+}
+
+.p-r {
+  padding-right:1.5em;
+}
+
+.rebox h2, .rebox h3 {
+  font-size:16px;
+  color:#fff;
+  display:block;
+  background:url('/assets/images/rebox-gradient.gif') no-repeat center bottom #95c0d0;
+  padding:.5em .5em .5em .75em;
+  -moz-border-radius-topright:5px;
+  -moz-border-radius-topleft:5px;
+  -webkit-border-top-right-radius:5px;
+  -webkit-border-top-left-radius:5px;
+}
+
+.rebox.lil {
+}
+.rebox.lil img {
+  float:left;
+  margin:0 1em 0 0;
+  padding:0 0 3em 0;
+}
+
+.rebox.green {
+  background:#d4e9a9;
+}
+
+.rebox.green h2, .rebox.green h3 {
+  background:url('images/rebox-gradient-green.gif') no-repeat center bottom #aaca46;
+  font-weight:bold;
+}
+
+.rebox.green a:link, .rebox.green a:visited {
+  color:#360;
+}
+
+/* BASICS */
+
+html, body {
+  overflow:hidden; /* keeps scrollbar off IE */
+  background-color:#fff;
+}
+
+body {
+  font-family:arial,sans-serif;
+  color:#000;
+  font-size:13px;
+  color:#333;
+  background-image:url(images/bg_fade.jpg); 
+  background-repeat:repeat-x;
+}
+
+a, a code { 
+  color:#006699;
+} 
+
+
+a:active,
+a:active code { 
+  color:#f00;
+} 
+
+a:visited,
+a:visited code { 
+  color:#006699;
+}
+
+input, select,
+textarea, option {
+  font-family:inherit;
+  font-size:inherit;
+  padding:0;
+  margin:0;
+}
+
+option {
+  padding:0 4px;
+}
+
+p {
+  padding:0;
+  margin:0 0 1em;
+}
+
+code, pre {
+  color:#007000;
+  font-family:monospace;
+  line-height:1em;
+}
+
+var {
+  color:#007000;
+  font-style:italic;
+}
+
+pre {
+  border:1px solid #ccc;
+  background-color:#fafafa;
+  padding:10px;
+  margin:0 0 1em 1em;
+  overflow:auto;
+  line-height:inherit; /* fixes vertical scrolling in webkit */
+}
+
+h1,h2,h3,h4,h5 {
+  margin:1em 0;
+  padding:0;
+}
+
+p,ul,ol,dl,dd,dt,li {
+  line-height:1.3em;
+}
+
+ul,ol {
+  margin:0 0 .8em;
+  padding:0 0 0 2em;
+}
+
+li {
+  padding:0 0 .5em;
+}
+
+dl {
+  margin:0 0 1em 0;
+  padding:0;
+}
+
+dt {  
+  margin:0;
+  padding:0;
+}
+
+dd {
+  margin:0 0 1em;
+  padding:0 0 0 2em;
+}
+
+li p {
+  margin:.5em 0 0;
+}
+
+dd p {
+  margin:1em 0 0;
+}
+
+li pre, li table, li img {
+  margin:.5em 0 0 1em;
+}
+
+dd pre, dd table, dd img {
+  margin:1em 0 0 1em;
+}
+
+li ul,
+li ol,
+dd ul,
+dd ol {
+  margin:0;
+  padding: 0 0 0 2em;
+}
+
+li li,
+dd li {
+  margin:0;
+  padding:.5em 0 0;
+}
+
+dl dl,
+ol dl,
+ul dl {
+  margin:0 0 1em;
+  padding:0;
+}
+
+table {
+  font-size:1em;
+  margin:0 0 1em;
+  padding:0;
+  border-collapse:collapse;
+  border-width:0;
+  empty-cells:show;
+}
+
+td,th {
+  border:1px solid #ccc;
+  padding:6px 12px;
+  text-align:left;
+  vertical-align:top;
+  background-color:inherit;
+}
+
+th {
+  background-color:#dee8f1;
+}
+
+hr.blue {
+  background-color:#DDF0F2;
+  border:none;
+  height:5px;
+  margin:20px 0 10px;
+}
+
+/* LAYOUT */
+#body-content {
+  /* "Preliminary" watermark for preview releases and interim builds.
+  background:transparent url(images/preliminary.png) repeat scroll 0 0;  */
+  margin:0;
+  position:relative;
+  width:100%;
+}
+
+#header {
+  height: 114px;
+  position:relative;
+  z-index:100;
+  min-width:576px;
+  padding:0 10px;
+  border-bottom:3px solid #94b922;
+}
+
+#headerLeft{
+  padding: 25px 0 0;
+}
+
+#headerLeft img{
+  height:50px;
+  width:349px;
+}
+
+#headerRight {
+  position:absolute;
+  right:0;
+  top:0;
+  text-align:right;
+}
+
+/* Tabs in the header */
+#header ul {
+  list-style: none;
+  margin: 7px 0 0;  
+  padding: 0;
+  height: 29px;
+}
+
+#header li {
+  float: left;
+  margin: 0px 2px 0px 0px;
+  padding:0;
+}
+
+#header li a {
+  text-decoration: none;
+  display: block;
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 -58px;
+  background-repeat: no-repeat;
+  color: #666;
+  font-size: 13px;
+  font-weight: bold;
+  width: 94px;
+  height: 29px;
+  text-align: center;
+  margin: 0px;
+}
+
+#header li a:hover {
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 -29px;
+  background-repeat: no-repeat;
+}
+
+#header li a span {
+  position:relative;
+  top:7px;
+}
+
+#header li a span+span {
+  display:none;
+}
+
+/* TAB HIGHLIGHTING */
+.home #home-link a,
+.community #community-link a,
+.porting #porting-link a,
+.source #source-link a,
+.about #about-link a,
+.downloads #downloads-link a,
+.compatibility #compatibility-link a,
+.videos #videos-link a {
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 0;
+  background-repeat: no-repeat;
+  color: #fff;
+  font-weight: bold;
+  cursor:default;
+}
+
+.home #home-link a:hover,
+.community #community-link a:hover,
+.home #home-link a:hover,
+.community #community-link a:hover,
+.porting #porting-link a:hover,
+.source #source-link a:hover,
+.about #about-link a:hover,
+.downloads #downloads-link a:hover,
+.compatibility #compatibility-link a:hover,
+.videos #videos-link  a:hover {
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 0;
+}
+
+#headerLinks {
+  margin:10px 10px 0 0;
+  height:13px;
+  font-size: 11px;
+  vertical-align: top;
+}
+
+#headerLinks a {
+  color: #7FA9B5;
+}
+
+#headerLinks img {
+  vertical-align:middle;
+}
+
+#language {
+  margin:0 10px 0 4px;
+}
+
+#search {
+  height:45px;
+  margin:15px 10px 0 0;
+}
+
+/* main */
+
+#mainBodyFluid {
+  margin: 20px 10px;
+  color:#333;
+}
+
+#mainBodyFixed {
+  margin: 20px 10px;
+  color: #333;
+  width:930px;
+  position:relative;
+}
+
+#mainBodyFixed h3,
+#mainBodyFluid h3 {
+  color:#336666;
+  font-size:1.25em;
+  margin: 0em 0em 0em 0em;
+  padding-bottom:.5em;
+}
+
+#mainBodyFixed h2,
+#mainBodyFluid h2 { 
+  color:#336666;
+  font-size:1.25em;
+  margin: 0;
+  padding-bottom:.5em;
+}
+
+#mainBodyFixed h1,
+#mainBodyFluid h1 { 
+  color:#435A6E;
+  font-size:1.7em;
+  margin: 1em 0;
+}
+
+#mainBodyFixed .green,
+#mainBodyFluid .green,
+#jd-content .green { 
+  color:#7BB026;
+  background-color:none;
+}
+
+#mainBodyLeft {
+  float: left;
+  width: 600px;
+  margin-right: 20px;  
+  color: #333;
+  position:relative;
+}
+
+div.indent {
+  margin-left: 40px;  
+  margin-right: 70px;
+}
+
+#mainBodyLeft p {
+  color: #333;
+  font-size: 13px;
+}
+
+#mainBodyLeft p.blue {
+  color: #669999;
+}
+
+#mainBodyLeft #communityDiv {
+  float: left;
+  background-image:url(images/bg_community_leftDiv.jpg);
+  background-repeat: no-repeat;
+  width: 581px;
+  height: 347px;
+  padding: 20px 0px 0px 20px;
+}
+
+#mainBodyRight {
+  float: left;
+  width: 300px;
+  color: #333;
+}
+
+#mainBodyRight p {
+  padding-right: 50px;
+  color: #333;
+}
+
+#mainBodyRight table {
+  width: 100%;
+}
+
+#mainBodyRight td {
+  border:0px solid #666;
+  padding:0px 5px;
+  text-align:left;
+}
+
+#mainBodyRight .blueBorderBox {
+  border:5px solid #ddf0f2;
+  padding:18px 18px 18px 18px;
+  text-align:left;
+}
+
+#mainBodyFixed .seperator {
+  background-image:url(images/hr_gray_side.jpg);
+  background-repeat:no-repeat;
+  width: 100%;
+  float: left;
+  clear: both;
+}
+
+#mainBodyBottom {
+  float: left;
+  width: 100%;
+  clear:both;
+  color: #333;
+}
+
+#mainBodyBottom .seperator {
+  background-image:url(images/hr_gray_main.jpg);
+  background-repeat:no-repeat;
+  width: 100%;
+  float: left;
+  clear: both;
+}
+
+/* Footer */
+#footer {
+  float: left;
+  width:90%;
+  margin: 20px;
+  color: #aaa;
+  font-size: 11px;
+}
+
+#footer a {
+  color: #aaa;
+  font-size: 11px;
+}
+
+#footer a:hover {
+  text-decoration: underline;
+  color:#aaa;
+}
+
+#footerlinks {
+  margin-top:2px;
+}
+
+#footerlinks a,
+#footerlinks a:visited {
+  color:#006699;
+}
+
+#homeBottom td {
+  border:0px solid #666;
+  padding: 8px 18px 8px 18px;
+}
+
+#homeBottom table {
+  width: 100%;
+}
+
+
+#homeBottom {
+  padding: 0px 0px 0px 0px;
+  float: left;
+  width: 585px;
+  height: 165px;
+  background-image:url(images/home/bg_home_bottom.jpg);
+  background-repeat: no-repeat;
+}
+
+.groupTable {
+  width: 100%;
+}
+
+.groupTable th {
+  padding: 10px;
+  color: #ffffff;
+  background-color: #6D8293;
+  border: 2px solid #fff;
+}
+
+.groupTable td {
+  padding: 10px;
+  color: #333333;
+  background-color: #d9d9d9;
+  border: 2px solid #fff;
+}
+
+.groupTable .evenRow td {  
+  background-color: #ededed;
+}
+
+span.BigBlue {
+  color:#336666;
+  font-size:1.25em;
+  margin: 0em 0em 0em 0em;
+  padding-bottom:.5em;
+  font-weight: bold;
+}
+
+span.emBlue {
+  color: #336666;
+  font-style:italic;
+}
+
+.pageTable {
+  width: 95%;
+  border: none;
+}
+
+.pageTable img {
+vertical-align: bottom;
+}
+
+.pageTable td {
+  border: none;
+}
+
+.pageTable td.leftNav {
+  width: 100px;
+}
+
+.greenBox {
+  margin: 10px 30px 10px 30px;
+  padding: 10px 20px 10px 20px;
+  background-color: #EBF3DB;
+  width: 75%;
+}
+
+.blueBox {
+  margin: 10px 30px 10px 30px;
+  padding: 10px 20px 10px 20px;
+  background-color: #DDF0F2;
+  width: 75%;
+}
+
+.blueHR {
+  margin: 10px 30px 10px 30px;
+  height: 5px;
+  background-color: #DDF0F2;
+  width: 75%;
+}
+
+/* SEARCH FILTER */
+#search_autocomplete {
+  color:#aaa;
+}
+
+#search-button {
+  display:inline;
+}
+
+#search_filtered_div {
+  position:absolute;
+  margin-top:-1px;
+  z-index:101;
+  border:1px solid #BCCDF0;
+  background-color:#fff;
+}
+
+#search_filtered {
+  min-width:100%;
+}
+#search_filtered td{
+  background-color:#fff;
+  border-bottom: 1px solid #669999;
+  line-height:1.5em;
+}
+
+#search_filtered .jd-selected {
+  background-color: #94b922;
+  cursor:pointer;
+}
+#search_filtered .jd-selected,
+#search_filtered .jd-selected a {
+  color:#fff;
+}
+
+.no-display {
+  display: none;
+}
+
+.jd-autocomplete {
+  font-family: Arial, sans-serif;
+  padding-left: 6px;
+  padding-right: 6px;
+  padding-top: 1px;
+  padding-bottom: 1px;
+  font-size: .8em;
+  border: none;
+  margin: 0;
+  line-height: 1.05em;
+}
+
+.show-row {
+  display: table-row;
+}
+.hide-row {
+  display: hidden;
+}
+
+/* SEARCH */
+
+/* restrict global search form width */
+#searchForm {
+  width:350px;
+}
+
+#searchTxt {
+  width:200px;
+}
+
+/* disable twiddle and size selectors for left column */
+#leftSearchControl div {
+  width: 100%;
+}
+
+#leftSearchControl .gsc-twiddle {
+  background-image : none;
+}
+
+#leftSearchControl td, #searchForm td {
+  border: 0px solid #000;
+}
+
+#leftSearchControl .gsc-resultsHeader .gsc-title {
+  padding-left : 0px;
+  font-weight : bold;
+  font-size : 13px;
+  color:#006699;
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsHeader div.gsc-results-selector {
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsRoot {
+  padding-top : 6px;
+}
+
+#leftSearchControl div.gs-visibleUrl-long {
+  display : block;
+  color:#006699;
+}
+
+.gsc-webResult div.gs-visibleUrl-short,
+table.gsc-branding,
+.gsc-clear-button {
+  display : none;
+}
+
+.gsc-cursor-box .gsc-cursor div.gsc-cursor-page,
+.gsc-cursor-box .gsc-trailing-more-results a.gsc-trailing-more-results,
+#leftSearchControl a, 
+#leftSearchControl a b {
+  color:#006699;
+}
+
+.gsc-resultsHeader {
+  display: none;
+}
+
+/* Disable built in search forms */
+.gsc-control form.gsc-search-box {
+  display : none;
+}
+table.gsc-search-box {
+  margin:6px 0 0 0;
+  border-collapse:collapse;
+}
+
+td.gsc-input {
+  padding:0 2px;
+  width:100%;
+  vertical-align:middle;
+}
+
+input.gsc-input {
+  border:1px solid #BCCDF0;
+  width:99%;
+  padding-left:2px;
+  font-size:.95em;
+}
+
+td.gsc-search-button {
+  text-align: right;
+  padding:0;
+  vertical-align:top;
+}
+
+#search-button {
+  margin:0 0 0 2px;
+  font-size:11px;
+}
+
+/* search result tabs */
+
+#doc-content .gsc-control {
+  position:relative;
+}
+
+#doc-content .gsc-tabsArea {
+  position:relative;
+  white-space:nowrap;
+}
+
+#doc-content .gsc-tabHeader {
+  padding: 3px 6px;
+  position:relative;
+}
+
+#doc-content .gsc-tabHeader.gsc-tabhActive {
+  border-top: 2px solid #94B922;
+}
+
+#doc-content h2#searchTitle {
+  padding:0;
+}
+
+#doc-content .gsc-resultsbox-visible {
+  padding:1em 0 0 6px;
+}
+
+/* CAROUSEL */
+
+#homeMiddle {
+  padding: 0px 0px 0px 0px;
+  float: left;
+  width: 584px;
+  height: 580px;
+  position:relative;
+}
+
+#topAnnouncement {
+  background:url(images/home/bg_home_announcement.png) no-repeat 0 0;
+}
+  
+#homeTitle {
+  padding:15px 15px 0;
+  height:30px;  
+}
+
+#homeTitle h2 {
+  padding:0;
+}
+
+#announcement-block {
+  padding:0 15px 0;
+  overflow:hidden;
+  background: url(images/hr_gray_side.jpg) no-repeat 15px 0;
+  zoom:1;
+}
+
+#announcement-block>* {
+  padding:15px 0 0;
+}
+
+#announcement-block img {
+  float:left;
+  margin:0 30px 0 0;
+}
+
+#announcement {
+  float:left;
+  margin:0;
+}
+
+#carousel {
+  background:url(images/home/bg_home_carousel.png) no-repeat 0 0;
+  position:relative;
+  height:400px;
+}
+
+#carouselMain {
+	background: url(images/home/bg_home_carousel_board.png) 0 0 no-repeat;
+	height:auto;
+  padding: 25px 21px 0;
+  overflow:hidden;
+  position:relative;
+  zoom:1; /*IE6*/
+}
+
+#carouselMain img {
+  margin:0;
+}
+
+#carouselMain .bulletinDesc h3 {
+	margin:0;
+	padding:0;
+}
+
+#carouselMain .bulletinDesc p {
+	margin:0;
+	padding:0.7em 0 0;
+}
+
+#carouselWheel {
+	background: url(images/home/bg_home_carousel_wheel.png) 0 0 no-repeat;
+	padding-top:40px;
+	height:150px;
+}
+
+.clearer { clear:both; }
+
+a#arrow-left, a#arrow-right {
+  float:left;
+  width:42px;
+  height:42px;
+  background-image:url(images/home/carousel_buttons_sprite.png);
+  background-repeat:no-repeat;
+}
+a#arrow-left {
+  margin:35px 3px 0 10px;
+}
+a#arrow-right {
+  margin:35px 10px 0 0;
+}
+a.arrow-left-off,
+a#arrow-left.arrow-left-off:hover { 
+  background-position:0 0;
+}
+a.arrow-right-off, 
+a#arrow-right.arrow-right-off:hover { 
+  background-position:-42px 0;
+}
+a#arrow-left:hover { 
+  background-position:0 -42px;
+}
+a#arrow-right:hover { 
+  background-position:-42px -42px;
+}
+a.arrow-left-on {
+  background-position:0 0;
+}
+a.arrow-right-on {
+  background-position:-42px 0;
+}
+a.arrow-right-off,
+a.arrow-left-off {
+  cursor:default;
+}
+
+.app-list-container {
+  margin:0 20px;
+  position:relative;
+  width:100%;
+}
+
+div#list-clip { 
+  height:110px; 
+  width:438px;
+  overflow:hidden; 
+  position:relative; 
+  float:left; 
+}
+
+div#app-list { 
+  left:0; 
+  z-index:1; 
+  position:absolute;
+  margin:11px 0 0;
+  _margin-top:13px;
+  width:1000%;
+}
+
+#app-list a {
+  display:block;
+  float:left;
+  height:90px;
+  width:90px;
+  margin:0 24px 0;
+  padding:3px;
+  background:#99cccc;
+  -webkit-border-radius:7px;
+  -moz-border-radius:7px;
+  border-radius:7px;
+  text-decoration:none;
+  text-align:center;
+  font-size:11px;
+  line-height:11px;
+}
+
+#app-list a span {
+  position:relative;
+  top:-4px;
+}
+
+#app-list img {  
+  width:90px;
+  height:70px;
+  margin:0;
+}
+
+#app-list a.selected, 
+#app-list a:active.selected, 
+#app-list a:hover.selected {
+  background:#A4C639;
+  color:#fff;
+  cursor:default;
+  text-decoration:none;
+}
+
+#app-list a:hover, 
+#app-list a:active {
+  background:#ff9900;
+}
+
+#app-list a:hover span, 
+#app-list a:active span {
+  text-decoration:underline;
+}
+
+#droid-name {
+  padding-top:.5em;
+  color:#666;
+  padding-bottom:.25em;
+}
+
+/*IE6*/
+* html #app-list a { zoom: 1; margin:0 24px 0 15px;}
+
+* html #list-clip { 
+  width:430px !important;
+}
+
+/*carousel bulletin layouts*/
+/*460px width*/
+/*185px height*/
+.img-left {
+  float:left;
+  width:230px;
+  overflow:hidden;
+  padding:8px 0 8px 8px;
+}
+.desc-right {
+  float:left;
+  width:270px;
+  padding:10px;
+}
+.img-right {
+  float:right;
+  width:220px;
+  overflow:hidden;
+  padding:8px 8px 8px 0;
+}
+.desc-left {
+  float:right;
+  width:280px;
+  padding:10px;
+  text-align:right;
+}
+.img-top {
+  padding:20px 20px 0;
+}
+.desc-bottom {
+  padding:10px;
+}
+
+
+/* VIDEO PAGE */
+
+#mainBodyLeft.videoPlayer {
+  width:570px;
+}
+
+#mainBodyRight.videoPlayer {
+  width:330px;
+}
+
+/* player */
+
+#videoPlayerBox {
+  background-color: #DAF3FC;
+  border-radius:7px;
+  -moz-border-radius:7px;
+  -webkit-border-radius:7px;
+  width:530px;
+  padding:20px;
+  border:1px solid #d3ecf5;
+  box-shadow:2px 3px 1px #eee;
+  -moz-box-shadow:2px 3px 1px #eee;
+  -webkit-box-shadow:2px 3px 1px #eee;
+}
+
+#videoBorder {
+  background-color: #FFF;
+  min-height:399px;
+  height:auto !important;
+  border:1px solid #ccdada;
+  border-radius:7px 7px 0 0;
+  -moz-border-radius:7px 7px 0 0;
+  -webkit-border-top-left-radius:7px;
+  -webkit-border-top-right-radius:7px;
+}
+
+#videoPlayerTitle {
+  width:500px;
+  padding:15px 15px 0;
+}
+
+#videoPlayerTitle h2 {
+  font-weight:bold;
+  font-size:1.2em;
+  color:#336666;
+  margin:0;
+  padding:0;
+}
+
+#objectWrapper {
+  padding:15px 15px;
+  height:334px;
+  width:500px;
+}
+
+/* playlist tabs */
+
+ul#videoTabs {
+  list-style-type:none;
+  padding:0;
+  clear:both;
+  margin:0;
+  padding: 20px 0 0 15px;
+  zoom:1; /* IE7/8, otherwise top-padding is double */
+}
+
+ul#videoTabs li {
+  display:inline;
+  padding:0;
+  margin:0 3px 0 0;
+  line-height:2em;
+}
+
+ul#videoTabs li a {
+  border-radius:7px 7px 0 0;
+  -moz-border-radius:7px 7px 0 0;
+  -webkit-border-top-left-radius:7px;
+  -webkit-border-top-right-radius:7px;
+  background:#95c0d0;
+  color:#fff;
+  text-decoration:none;
+  padding:.45em 1.5em;
+  font-weight:bold;
+}
+
+ul#videoTabs li.selected a {
+  font-weight:bold;
+  text-decoration:none;
+  color:#555;
+  background:#daf3fc;
+  border-bottom:1px solid #daf3fc;
+}
+
+ul#videoTabs li:hover a {
+  background:#85acba;
+}
+
+ul#videoTabs li.selected:hover a {
+  background:#daf3fc;
+}
+
+/* playlists */
+
+#videos {
+  background:#daf3fc;
+  margin-bottom:1.5em;
+  padding:15px;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+  box-shadow:2px 3px 1px #eee;
+  -moz-box-shadow:2px 3px 1px #eee;
+  -webkit-box-shadow:2px 3px 1px #eee;
+}
+
+#videos div {
+  display:none;
+}
+
+#videos div.selected {
+  display:block;
+}
+
+ul.videoPreviews {
+  list-style:none;
+  padding:0;
+  margin:0;
+  zoom:1; /* IE, otherwise, layout doesn't update when showing 'more' */
+}
+
+ul.videoPreviews li {
+  margin:0 0 5px;
+  padding:0;
+  overflow:hidden;
+  position:relative;
+}
+
+#mainBodyFixed ul.videoPreviews h3 {
+  font-size: 12px;
+  margin:0 0 1em 130px;
+  padding:0;
+  font-weight:bold;
+  color:inherit;
+}
+
+ul.videoPreviews a {
+  margin:1px;
+  padding:10px;
+  text-decoration:none;
+  height:90px;
+  display:block;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+  background-color:transparent;
+}
+
+ul.videoPreviews a:hover {
+  background-color:#FFF;
+  border:none; /* IE8, otherwise, bg doesn't work */
+}
+
+ul.videoPreviews a.selected {
+  background-color: #FF9900;
+}
+
+ul.videoPreviews img {
+  float:left;
+  clear:left;
+  margin:0;
+}
+
+ul.videoPreviews h3 {
+  font-size:12px;
+  font-weight:bold;
+  text-decoration:none;
+  margin:0 0 1em 130px;
+  padding:0;
+}
+
+ul.videoPreviews p {
+  font-size: 12px;
+  text-decoration:none;
+  margin:0 0 1.2em 130px;
+}
+
+ul.videoPreviews p.full {
+  display:none;
+}
+
+ul.videoPreviews span.more {
+  padding:0 0 0 12px;
+  background:url(images/arrow_bluelink_down.png) 0 2px no-repeat;
+}
+
+ul.videoPreviews span.less {
+  padding:0 0 0 12px;
+  background:url(images/arrow_bluelink_up.png) 0 2px no-repeat;
+  display:none;
+}
+
+ul.videoPreviews p.toggle {
+  position:absolute;
+  margin:0;
+  margin-top:-23px; /* instead of bottom:23px, because IE won't do it correctly */
+  left:140px;
+}
+
+ul.videoPreviews p.toggle a {
+  height:auto;
+  margin:0;
+  padding:0;
+  zoom:1; /* IE6, otherwise the margin considers the img on redraws */
+}
+
+ul.videoPreviews p.toggle a:hover {
+  text-decoration:underline;
+  background:transparent; /* IE6, otherwise it inherits white */
+}
+
+/* featured videos */
+
+#mainBodyRight h2 {
+  padding:0 0 5px;
+}
+
+#mainBodyRight ul.videoPreviews {
+  margin:10px 0 0;
+}
+
+#mainBodyRight ul.videoPreviews li {
+  font-size:11px;
+  line-height:13px;
+  margin:0 0 5px;
+  padding:0;
+}
+
+#mainBodyRight ul.videoPreviews h3 {
+  padding:0;
+  margin:0;
+}
+
+#mainBodyRight ul.videoPreviews a {
+  text-decoration:none;
+  height:108px;
+  border:1px solid #FFF;
+}
+
+#mainBodyRight ul.videoPreviews a:hover {
+  border:1px solid #CCDADA;
+}
+
+#mainBodyRight ul.videoPreviews a.selected {
+  border:1px solid #FFF;
+}
+
+#mainBodyRight ul.videoPreviews p {
+	line-height:1.2em;
+  padding:0;
+  margin:4px 0 0 130px;
+}
+
+#mainBodyRight ul.videoPreviews img {
+	margin-top:5px;
+}
diff --git a/tools/droiddoc/templates-pdk/assets/android-developer-docs.js b/tools/droiddoc/templates-pdk/assets/android-developer-docs.js
new file mode 100644
index 0000000..59c4192
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/assets/android-developer-docs.js
@@ -0,0 +1,464 @@
+var resizePackagesNav;
+var classesNav;
+var devdocNav;
+var sidenav;
+var content;
+var HEADER_HEIGHT = 117;
+var cookie_namespace = 'android_developer';
+var NAV_PREF_TREE = "tree";
+var NAV_PREF_PANELS = "panels";
+var nav_pref;
+var toRoot;
+var isMobile = false; // true if mobile, so we can adjust some layout
+
+function addLoadEvent(newfun) {
+  var current = window.onload;
+  if (typeof window.onload != 'function') {
+    window.onload = newfun;
+  } else {
+    window.onload = function() {
+      current();
+      newfun();
+    }
+  }
+}
+
+var agent = navigator['userAgent'];
+if ((agent.indexOf("Mobile") != -1) || 
+    (agent.indexOf("BlackBerry") != -1) || 
+    (agent.indexOf("Mini") != -1)) {
+  isMobile = true;
+  addLoadEvent(mobileSetup);
+}
+
+addLoadEvent(function() {
+window.onresize = resizeAll;
+});
+
+function mobileSetup() {
+  $("body").css({'overflow':'auto'});
+  $("html").css({'overflow':'auto'});
+  $("#body-content").css({'position':'relative', 'top':'0'});
+  $("#doc-content").css({'overflow':'visible', 'border-left':'3px solid #DDD'});
+  $("#side-nav").css({'padding':'0'});
+  $("#nav-tree").css({'overflow-y': 'auto'});
+}
+
+/* loads the lists.js file to the page.
+Loading this in the head was slowing page load time */
+addLoadEvent( function() {
+  var lists = document.createElement("script");
+  lists.setAttribute("type","text/javascript");
+  lists.setAttribute("src", toRoot+"reference/lists.js");
+  document.getElementsByTagName("head")[0].appendChild(lists);
+} );
+
+function setToRoot(root) {
+  toRoot = root;
+  // note: toRoot also used by carousel.js
+}
+
+function restoreWidth(navWidth) {
+  var windowWidth = $(window).width() + "px";
+  content.css({marginLeft:parseInt(navWidth) + 6 + "px", //account for 6px-wide handle-bar
+               width:parseInt(windowWidth) - parseInt(navWidth) - 6 + "px"});
+  sidenav.css({width:navWidth});
+  resizePackagesNav.css({width:navWidth});
+  classesNav.css({width:navWidth});
+  $("#packages-nav").css({width:navWidth});
+}
+
+function restoreHeight(packageHeight) {
+  var windowHeight = ($(window).height() - HEADER_HEIGHT);
+  var swapperHeight = windowHeight - 13;
+  $("#swapper").css({height:swapperHeight + "px"});
+  sidenav.css({height:windowHeight + "px"});
+  content.css({height:windowHeight + "px"});
+  resizePackagesNav.css({maxHeight:swapperHeight + "px", height:packageHeight});
+  classesNav.css({height:swapperHeight - parseInt(packageHeight) + "px"});
+  $("#packages-nav").css({height:parseInt(packageHeight) - 6 + "px"}); //move 6px to give space for the resize handle
+  devdocNav.css({height:sidenav.css("height")});
+  $("#nav-tree").css({height:swapperHeight + "px"});
+}
+
+function readCookie(cookie) {
+  var myCookie = cookie_namespace+"_"+cookie+"=";
+  if (document.cookie) {
+    var index = document.cookie.indexOf(myCookie);
+    if (index != -1) {
+      var valStart = index + myCookie.length;
+      var valEnd = document.cookie.indexOf(";", valStart);
+      if (valEnd == -1) {
+        valEnd = document.cookie.length;
+      }
+      var val = document.cookie.substring(valStart, valEnd);
+      return val;
+    }
+  }
+  return 0;
+}
+
+function writeCookie(cookie, val, section, expiration) {
+  if (!val) return;  
+  section = section == null ? "_" : "_"+section+"_";
+  if (expiration == null) {
+    var date = new Date();
+    date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
+    expiration = date.toGMTString();
+  }
+  document.cookie = cookie_namespace+section+cookie+"="+val+"; expires="+expiration+"; path=/";
+} 
+
+function init() {
+  $("#side-nav").css({position:"absolute",left:0});
+  content = $("#doc-content");
+  resizePackagesNav = $("#resize-packages-nav");
+  classesNav = $("#classes-nav");
+  sidenav = $("#side-nav");
+  devdocNav = $("#devdoc-nav");
+
+  if (location.href.indexOf("/reference/") != -1) {
+    var cookiePath = "reference_";
+  } else if (location.href.indexOf("/guide/") != -1) {
+    var cookiePath = "guide_";
+  }
+
+  if (!isMobile) {
+    $("#resize-packages-nav").resizable({handles: "s", resize: function(e, ui) { resizeHeight(); } });
+    $(".side-nav-resizable").resizable({handles: "e", resize: function(e, ui) { resizeWidth(); } });
+    var cookieWidth = readCookie(cookiePath+'width');
+    var cookieHeight = readCookie(cookiePath+'height');
+    if (cookieWidth) {
+      restoreWidth(cookieWidth);
+    } else if ($(".side-nav-resizable").length) {
+      resizeWidth();
+    }
+    if (cookieHeight) {
+      restoreHeight(cookieHeight);
+    } else {
+      resizeHeight();
+    }
+  }
+
+  if (devdocNav.length) { // only dev guide and sdk 
+    highlightNav(location.href); 
+  }
+}
+
+function highlightNav(fullPageName) {
+  fullPageName = fullPageName.replace(/^https?:\/\//, '');
+  var lastSlashPos = fullPageName.lastIndexOf("/");
+  var firstSlashPos = fullPageName.indexOf("/"); 
+  if (lastSlashPos == (fullPageName.length - 1)) { // if the url ends in slash (add 'index.html')
+    fullPageName = fullPageName + "index.html";
+  }
+  var htmlPos = fullPageName.lastIndexOf(".html", fullPageName.length);
+  var pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5);
+  var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
+  if ((link.length == 0) && (fullPageName.indexOf("/guide/") != -1)) { 
+// if there's no match, then let's backstep through the directory until we find an index.html page that matches our ancestor directories (only for dev guide)
+    lastBackstep = pathPageName.lastIndexOf("/");
+    while (link.length == 0) {
+      backstepDirectory = pathPageName.lastIndexOf("/", lastBackstep);
+      link = $("#devdoc-nav a[href$='"+ pathPageName.slice(0, backstepDirectory + 1)+"index.html']");
+      lastBackstep = pathPageName.lastIndexOf("/", lastBackstep - 1);
+      if (lastBackstep == 0) break;
+    }
+  }
+  link.parent().addClass('selected');
+  if (link.parent().parent().is(':hidden')) {
+    toggle(link.parent().parent().parent(), false);
+  } else if (link.parent().parent().hasClass('toggle-list')) {
+    toggle(link.parent().parent(), false);
+  }
+}
+
+function resizeHeight() {
+  var windowHeight = ($(window).height() - HEADER_HEIGHT);
+  var swapperHeight = windowHeight - 13;
+  $("#swapper").css({height:swapperHeight + "px"});
+  sidenav.css({height:windowHeight + "px"});
+  content.css({height:windowHeight + "px"});
+  resizePackagesNav.css({maxHeight:swapperHeight + "px"});
+  classesNav.css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
+  $("#packages-nav").css({height:parseInt(resizePackagesNav.css("height")) - 6 + "px"}); //move 6px for handle
+  devdocNav.css({height:sidenav.css("height")});
+  $("#nav-tree").css({height:swapperHeight + "px"});
+  
+  var basePath = getBaseUri(location.pathname);
+  var section = basePath.substring(1,basePath.indexOf("/",1));
+  writeCookie("height", resizePackagesNav.css("height"), section, null);
+}
+
+function resizeWidth() {
+  var windowWidth = $(window).width() + "px";
+  if (sidenav.length) {
+    var sidenavWidth = sidenav.css("width");
+  } else {
+    var sidenavWidth = 0;
+  }
+  content.css({marginLeft:parseInt(sidenavWidth) + 6 + "px", //account for 6px-wide handle-bar
+               width:parseInt(windowWidth) - parseInt(sidenavWidth) - 6 + "px"});
+  resizePackagesNav.css({width:sidenavWidth});
+  classesNav.css({width:sidenavWidth});
+  $("#packages-nav").css({width:sidenavWidth});
+  
+  var basePath = getBaseUri(location.pathname);
+  var section = basePath.substring(1,basePath.indexOf("/",1));
+  writeCookie("width", sidenavWidth, section, null);
+}
+
+function resizeAll() {
+  if (!isMobile) {
+    resizeHeight();
+    if ($(".side-nav-resizable").length) {
+      resizeWidth();
+    }
+  }
+}
+
+function getBaseUri(uri) {
+  var intlUrl = (uri.substring(0,6) == "/intl/");
+  if (intlUrl) {
+    base = uri.substring(uri.indexOf('intl/')+5,uri.length);
+    base = base.substring(base.indexOf('/')+1, base.length);
+      //alert("intl, returning base url: /" + base);
+    return ("/" + base);
+  } else {
+      //alert("not intl, returning uri as found.");
+    return uri;
+  }
+}
+
+function requestAppendHL(uri) {
+//append "?hl=<lang> to an outgoing request (such as to blog)
+  var lang = getLangPref();
+  if (lang) {
+    var q = 'hl=' + lang;
+    uri += '?' + q;
+    window.location = uri;
+    return false;
+  } else {
+    return true;
+  }
+}
+
+function loadLast(cookiePath) {
+  var location = window.location.href;
+  if (location.indexOf("/"+cookiePath+"/") != -1) {
+    return true;
+  }
+  var lastPage = readCookie(cookiePath + "_lastpage");
+  if (lastPage) {
+    window.location = lastPage;
+    return false;
+  }
+  return true;
+}
+
+$(window).unload(function(){
+  var path = getBaseUri(location.pathname);
+  if (path.indexOf("/reference/") != -1) {
+    writeCookie("lastpage", path, "reference", null);
+  } else if (path.indexOf("/guide/") != -1) {
+    writeCookie("lastpage", path, "guide", null);
+  }
+});
+
+function toggle(obj, slide) {
+  var ul = $("ul", obj);
+  var li = ul.parent();
+  if (li.hasClass("closed")) {
+    if (slide) {
+      ul.slideDown("fast");
+    } else {
+      ul.show();
+    }
+    li.removeClass("closed");
+    li.addClass("open");
+    $(".toggle-img", li).attr("title", "hide pages");
+  } else {
+    ul.slideUp("fast");
+    li.removeClass("open");
+    li.addClass("closed");
+    $(".toggle-img", li).attr("title", "show pages");
+  }
+}
+
+function buildToggleLists() {
+  $(".toggle-list").each(
+    function(i) {
+      $("div", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
+      $(this).addClass("closed");
+    });
+}
+
+function getNavPref() {
+  var v = readCookie('reference_nav');
+  if (v != NAV_PREF_TREE) {
+    v = NAV_PREF_PANELS;
+  }
+  return v;
+}
+
+function chooseDefaultNav() {
+  nav_pref = getNavPref();
+  if (nav_pref == NAV_PREF_TREE) {
+    $("#nav-panels").toggle();
+    $("#panel-link").toggle();
+    $("#nav-tree").toggle();
+    $("#tree-link").toggle();
+  }
+}
+
+function swapNav() {
+  if (nav_pref == NAV_PREF_TREE) {
+    nav_pref = NAV_PREF_PANELS;
+  } else {
+    nav_pref = NAV_PREF_TREE;
+    init_default_navtree(toRoot);
+  }
+  var date = new Date();
+  date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
+  writeCookie("nav", nav_pref, "reference", date.toGMTString());
+
+  $("#nav-panels").toggle();
+  $("#panel-link").toggle();
+  $("#nav-tree").toggle();
+  $("#tree-link").toggle();
+
+  if ($("#nav-tree").is(':visible')) scrollIntoView("nav-tree");
+  else {
+    scrollIntoView("packages-nav");
+    scrollIntoView("classes-nav");
+  }
+}
+
+function scrollIntoView(nav) {
+  var navObj = $("#"+nav);
+  if (navObj.is(':visible')) {
+    var selected = $(".selected", navObj);
+    if (selected.length == 0) return;
+    if (selected.is("div")) selected = selected.parent();
+
+    var scrolling = document.getElementById(nav);
+    var navHeight = navObj.height();
+    var offsetTop = selected.position().top;
+    if (selected.parent().parent().is(".toggle-list")) offsetTop += selected.parent().parent().position().top;
+    if(offsetTop > navHeight - 92) {
+      scrolling.scrollTop = offsetTop - navHeight + 92;
+    }
+  }
+}
+
+function toggleAllInherited(linkObj, expand) {
+  var a = $(linkObj);
+  var table = $(a.parent().parent().parent());
+  var expandos = $(".jd-expando-trigger", table);
+  if ( (expand == null && a.text() == "[Expand]") || expand ) {
+    expandos.each(function(i) {
+      toggleInherited(this, true);
+    });
+    a.text("[Collapse]");
+  } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
+    expandos.each(function(i) {
+      toggleInherited(this, false);
+    });
+    a.text("[Expand]");
+  }
+  return false;
+}
+
+function toggleAllSummaryInherited(linkObj) {
+  var a = $(linkObj);
+  var content = $(a.parent().parent().parent());
+  var toggles = $(".toggle-all", content);
+  if (a.text() == "[Expand All]") {
+    toggles.each(function(i) {
+      toggleAllInherited(this, true);
+    });
+    a.text("[Collapse All]");
+  } else {
+    toggles.each(function(i) {
+      toggleAllInherited(this, false);
+    });
+    a.text("[Expand All]");
+  }
+  return false;
+}
+
+
+function changeTabLang(lang) {
+  var nodes = $("#header-tabs").find("."+lang);
+  for (i=0; i < nodes.length; i++) { // for each node in this language 
+    var node = $(nodes[i]);
+    node.siblings().css("display","none"); // hide all siblings 
+    if (node.not(":empty").length != 0) { //if this languages node has a translation, show it 
+      node.css("display","inline");
+    } else { //otherwise, show English instead 
+      node.css("display","none");
+      node.siblings().filter(".en").css("display","inline");
+    }
+  }
+}
+
+function changeNavLang(lang) {
+  var nodes = $("#side-nav").find("."+lang);
+  for (i=0; i < nodes.length; i++) { // for each node in this language 
+    var node = $(nodes[i]);
+    node.siblings().css("display","none"); // hide all siblings 
+    if (node.not(":empty").length != 0) { // if this languages node has a translation, show it 
+      node.css("display","inline");
+    } else { // otherwise, show English instead 
+      node.css("display","none");
+      node.siblings().filter(".en").css("display","inline");
+    }
+  }
+}
+
+function changeDocLang(lang) {
+  changeTabLang(lang);
+  changeNavLang(lang);
+}
+
+function changeLangPref(lang, refresh) {
+  var date = new Date();
+  expires = date.toGMTString(date.setTime(date.getTime()+(10*365*24*60*60*1000))); // keep this for 50 years
+  //alert("expires: " + expires)
+  writeCookie("pref_lang", lang, null, expires);
+  //changeDocLang(lang);
+  if (refresh) {
+    l = getBaseUri(location.pathname);
+    window.location = l;
+  }
+}
+
+function loadLangPref() {
+  var lang = readCookie("pref_lang");
+  if (lang != 0) {
+    $("#language").find("option[value='"+lang+"']").attr("selected",true);
+  }
+}
+
+function getLangPref() {
+  var lang = $("#language").find(":selected").attr("value");
+  if (!lang) {
+    lang = readCookie("pref_lang");
+  }
+  return (lang != 0) ? lang : 'en';
+}
+
+
+function toggleContent(obj) {
+  var button = $(obj);
+  var div = $(obj.parentNode);
+  var toggleMe = $(".toggle-content-toggleme",div);
+  if (button.hasClass("show")) {
+    toggleMe.slideDown();
+    button.removeClass("show").addClass("hide");
+  } else {
+    toggleMe.slideUp();
+    button.removeClass("hide").addClass("show");
+  }
+  $("span", button).toggle();
+}
diff --git a/tools/droiddoc/templates-pdk/assets-pdk/favicon.ico b/tools/droiddoc/templates-pdk/assets/favicon.ico
similarity index 100%
rename from tools/droiddoc/templates-pdk/assets-pdk/favicon.ico
rename to tools/droiddoc/templates-pdk/assets/favicon.ico
Binary files differ
diff --git a/tools/droiddoc/templates-pdk/assets/images/rebox-gradient.gif b/tools/droiddoc/templates-pdk/assets/images/rebox-gradient.gif
new file mode 100644
index 0000000..124e844
--- /dev/null
+++ b/tools/droiddoc/templates-pdk/assets/images/rebox-gradient.gif
Binary files differ
diff --git a/tools/droiddoc/templates-pdk/assets-pdk/placeholder b/tools/droiddoc/templates-pdk/assets/placeholder
similarity index 100%
rename from tools/droiddoc/templates-pdk/assets-pdk/placeholder
rename to tools/droiddoc/templates-pdk/assets/placeholder
diff --git a/tools/droiddoc/templates-pdk/customization.cs b/tools/droiddoc/templates-pdk/customization.cs
index dfebb12..3e9be06 100644
--- a/tools/droiddoc/templates-pdk/customization.cs
+++ b/tools/droiddoc/templates-pdk/customization.cs
@@ -5,23 +5,28 @@
 def:custom_masthead() ?>
   <div id="header">
       <div id="headerLeft">
-          <a href="http://source.android.com" tabindex="-1"><img
-              src="<?cs var:toroot ?>assets/images/open_source.png" alt="Open Source Project: Platform Development Kit" /></a>
-          <ul class="<?cs 
-                  if:releases ?> releases<?cs
-                  elif:guide ?> guide<?cs
-                  elif:licenses ?>licenses <?cs
-                  elif:home ?>home <?cs
-                  elif:community ?>community <?cs /if ?>">
+          <a href="<?cs var:toroot?>" tabindex="-1"><img
+              src="<?cs var:toroot ?>assets/images/open_source.png" alt="Android Open Source Project" /></a>
+          <ul class="<?cs if:home ?>home<?cs
+                      elif:doc.type == "source" ?>source<?cs
+                      elif:doc.type == "porting" ?>porting<?cs
+                      elif:doc.type == "compatibility" ?>compatibility<?cs
+                      elif:doc.type == "downloads" ?>downloads<?cs
+                      elif:doc.type == "community" ?>community<?cs
+                      elif:doc.type == "about" ?>about<?cs /if ?>">
               <li id="home-link"><a href="<?cs var:toroot ?>index.html"><span>Home</span></a></li>
-              <li id="guide-link"><a href="<?cs var:toroot ?>guide/index.html"
-                                  onClick="return loadLast('guide)'"><span>Guide</span></a></li>
-              <li id="releases-ink"><a href="<?cs var:toroot ?>releases/index.html"
-                                  onClick="return loadLast('releases)'"><span>Releases</span></a></li>
-              <li id="licenses-link"><a href="<?cs var:toroot ?>licenses/index.html"
-                                  onClick="return loadLast('licenses)'"><span>Licenses</span></a></li>
+              <li id="source-link"><a href="<?cs var:toroot ?>source/index.html"
+                                  onClick="return loadLast('source')"><span>Source</span></a></li>
+              <li id="porting-link"><a href="<?cs var:toroot ?>porting/index.html"
+                                  onClick="return loadLast('porting')"><span>Porting</span></a></li>
+              <li id="compatibility-link"><a href="<?cs var:toroot ?>compatibility/index.html"
+                                  onClick="return loadLast('compatibility')"><span>Compatibility</span></a></li>
               <li id="community-link"><a href="<?cs var:toroot ?>community/index.html"
-                                  onClick="return loadLast('community)'"><span>Community</span></a></li>
+                                  onClick="return loadLast('community')"><span>Community</span></a></li>
+              <li id="downloads-link"><a href="<?cs var:toroot ?>downloads/index.html"
+                                  onClick="return loadLast('downloads')"><span>Downloads</span></a></li>
+              <li id="about-link"><a href="<?cs var:toroot ?>about/index.html"
+                                  onClick="return loadLast('about')"><span>About</span></a></li>
           </ul> 
       </div>
       <div id="headerRight">
@@ -37,12 +42,11 @@
 /def ?><?cs # custom_masthead ?>
 
 
-<?cs 
-def:guide_nav() ?>
+<?cs def:community_nav() ?>
   <div class="g-section g-tpl-240" id="body-content">
     <div class="g-unit g-first side-nav-resizable" id="side-nav">
       <div id="devdoc-nav"><?cs 
-        include:"../../../../development/pdk/docs/guide/pdk_toc.cs" ?>
+        include:"../../../../development/pdk/docs/community/community_toc.cs" ?>
       </div>
     </div> <!-- end side-nav -->
     <script>
@@ -50,14 +54,14 @@
         scrollIntoView("devdoc-nav");
         });
     </script>
+  </div>
 <?cs /def ?>
 
-<?cs
-def:licenses_nav() ?>
+<?cs def:about_nav() ?>
   <div class="g-section g-tpl-240" id="body-content">
     <div class="g-unit g-first side-nav-resizable" id="side-nav">
       <div id="devdoc-nav"><?cs
-        include:"../../../../development/pdk/docs/licenses/licenses_toc.cs" ?>
+        include:"../../../../development/pdk/docs/about/about_toc.cs" ?>
       </div>
     </div> <!-- end side-nav -->
     <script>
@@ -65,14 +69,14 @@
         scrollIntoView("devdoc-nav");
         });
     </script>
+  </div>
 <?cs /def ?>
 
-<?cs
-def:releases_nav() ?>
+<?cs def:porting_nav() ?>
   <div class="g-section g-tpl-240" id="body-content">
     <div class="g-unit g-first side-nav-resizable" id="side-nav">
       <div id="devdoc-nav"><?cs
-        include:"../../../../development/pdk/docs/releases/releases_toc.cs" ?>
+        include:"../../../../development/pdk/docs/porting/porting_toc.cs" ?>
       </div>
     </div> <!-- end side-nav -->
     <script>
@@ -80,18 +84,71 @@
         scrollIntoView("devdoc-nav");
         });
     </script>
+  </div>
 <?cs /def ?>
 
-<?cs 
-def:custom_left_nav() ?><?cs
-  if:doc.type == "guide" ?><?cs
-    call:guide_nav() ?><?cs
-  elif:doc.type == "licenses" ?><?cs
-    call:licenses_nav() ?><?cs
-  elif:doc.type == "releases" ?><?cs
-    call:releases_nav() ?><?cs
-  /if ?><?cs
-/def ?>
+<?cs def:source_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first side-nav-resizable" id="side-nav">
+      <div id="devdoc-nav"><?cs
+        include:"../../../../development/pdk/docs/source/source_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      addLoadEvent(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+  </div>
+<?cs /def ?>
+
+<?cs def:downloads_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first side-nav-resizable" id="side-nav">
+      <div id="devdoc-nav"><?cs
+        include:"../../../../development/pdk/docs/downloads/downloads_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      addLoadEvent(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+  </div>
+<?cs /def ?>
+
+<?cs def:compatibility_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first side-nav-resizable" id="side-nav">
+      <div id="devdoc-nav"><?cs
+        include:"../../../../development/pdk/docs/compatibility/compatibility_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      addLoadEvent(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+  </div>
+<?cs /def ?>
+
+<?cs def:custom_left_nav() ?>
+  <?cs if:doc.hidenav != "true" ?>
+    <?cs if:doc.type == "source" ?>
+      <?cs call:source_nav() ?>
+    <?cs elif:doc.type == "porting" ?>
+      <?cs call:porting_nav() ?>
+    <?cs elif:doc.type == "compatibility" ?>
+      <?cs call:compatibility_nav() ?>
+    <?cs elif:doc.type == "downloads" ?>
+      <?cs call:downloads_nav() ?>
+    <?cs elif:doc.type == "community" ?>
+      <?cs call:community_nav() ?>
+    <?cs elif:doc.type == "about" ?>
+      <?cs call:about_nav() ?>
+    <?cs /if ?>
+  <?cs /if ?>
+<?cs /def ?>
 
 <?cs # appears at the bottom of every page ?><?cs 
 def:custom_cc_copyright() ?>
diff --git a/tools/droiddoc/templates-pdk/head_tag.cs b/tools/droiddoc/templates-pdk/head_tag.cs
index 47b332a..915dc0e 100644
--- a/tools/droiddoc/templates-pdk/head_tag.cs
+++ b/tools/droiddoc/templates-pdk/head_tag.cs
@@ -11,7 +11,6 @@
 <link href="<?cs var:toroot ?>assets/android-developer-docs-devguide.css" rel="stylesheet" type="text/css" />
 <link href="<?cs var:toroot ?>assets-pdk/pdk-local.css" rel="stylesheet" type="text/css" />
 <script src="<?cs var:toroot ?>assets/search_autocomplete.js" type="text/javascript"></script>
-<script src="<?cs var:toroot ?>reference/lists.js" type="text/javascript"></script>
 <script src="<?cs var:toroot ?>assets/jquery-resizable.min.js" type="text/javascript"></script>
 <script src="<?cs var:toroot ?>assets/android-developer-docs.js" type="text/javascript"></script>
 <script type="text/javascript">
diff --git a/tools/droiddoc/templates-sdk/sdkpage.cs b/tools/droiddoc/templates-sdk/sdkpage.cs
index 604b5ee..0823db4 100644
--- a/tools/droiddoc/templates-sdk/sdkpage.cs
+++ b/tools/droiddoc/templates-sdk/sdkpage.cs
@@ -6,7 +6,7 @@
     <title>Redirecting...</title>
     <meta http-equiv="refresh" content="0;url=<?cs var:toroot ?>sdk/<?cs 
       if:sdk.redirect.path ?><?cs var:sdk.redirect.path ?><?cs 
-      else ?><?cs var:sdk.current ?>/index.html<?cs /if ?>">
+      else ?>index.html<?cs /if ?>">
     <link href="<?cs var:toroot ?>assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
   </head>
 <?cs else ?>
@@ -38,8 +38,7 @@
 
   <div id="jd-content">
     <?cs 
-    if:ndk ?><p><em><?cs 
-      var:ndk.date ?></em></p><?cs 
+    if:ndk ?><?cs 
     else ?><?cs 
       if:android.whichdoc == "online" ?><p><em><?cs 
       var:sdk.date ?></em></p><?cs 
@@ -120,7 +119,8 @@
 <?cs /if ?> 
 <?cs # end if NDK ... the following is for the SDK ?>
 
-  <div class="toggle-content special">
+<?cs #  
+    <div class="toggle-content special">
     <p>The Android SDK has changed! If you've worked with the Android SDK before, 
     you will notice several important differences:</p>
     
@@ -146,10 +146,18 @@
     href="adding-components.html">Adding SDK Components</a>.</p>
     </div>
     
-    <a href='#' class='toggle-content-button show' onclick="toggleContent(this);return false;">
+    <a href='#' class='toggle-content-button show' onclick="toggleContent(this,true);return false;">
       <span>show more</span><span style='display:none'>show less</span>
     </a>
   </div>
+?>
+  <p>Welcome Developers! If you are new to the Android SDK, please read the <a
+href="#quickstart">Quick Start</a>, below, for an overview of how to install and
+set up the SDK. </p>
+
+  <p>If you are already using the Android SDK and would like to update to the
+latest tools or platforms, please use the <em>Android SDK and AVD Manager</em>
+to get the components, rather than downloading a new SDK package.</p>
 
   <table class="download">
     <tr>
@@ -200,14 +208,17 @@
 
 <?cs if:android.whichdoc != "online" && sdk.preview ?>
   <p>Welcome developers! The next release of the Android platform will be
-  Android 1.6 and we are pleased to announce the availability of an early look SDK
-  to give you a head-start on developing applications for it. </p>
+Android <?cs var:sdk.preview.version ?> and we are pleased to announce the
+availability of an early look SDK to give you a head-start on developing
+applications for it. </p>
 
-  <p>The Android 1.6 platform includes a variety of improvements and new features
-  for users and developers. Additionally, the SDK itself introduces several new
-  capabilities that enable you to develop applications more efficiently.
-  See the <a href="http://developer.android.com/sdk/preview/features.html">
-  Android 1.6 Highlights</a> document for a list of highlights.</p>
+  <p>The Android <?cs var:sdk.preview.version ?> platform includes a variety of
+improvements and new features for users and developers. Additionally, the SDK
+itself introduces several new capabilities that enable you to develop
+applications more efficiently. See the <a
+href="http://developer.android.com/sdk/preview/features.html">Android 
+<?cs var:sdk.preview.version ?> Highlights</a> document for a list of
+highlights.</p>
 <?cs /if ?>
 
       <?cs call:tag_list(root.descr) ?>
diff --git a/tools/droiddoc/templates/assets/android-developer-core.css b/tools/droiddoc/templates/assets/android-developer-core.css
index 2d1708a..40ab2fd 100644
--- a/tools/droiddoc/templates/assets/android-developer-core.css
+++ b/tools/droiddoc/templates/assets/android-developer-core.css
@@ -28,21 +28,21 @@
   color:#000;
   font-size:13px;
   color:#333;
-  background-image:url(images/bg_fade.jpg); 
+  background-image:url(images/bg_fade.jpg);
   background-repeat:repeat-x;
 }
 
-a, a code { 
+a, a code {
   color:#006699;
 }
 
 a:active,
-a:active code { 
+a:active code {
   color:#f00;
 } 
 
 a:visited,
-a:visited code { 
+a:visited code {
   color:#006699;
 }
 
@@ -107,7 +107,7 @@
   padding:0;
 }
 
-dt {  
+dt {
   margin:0;
   padding:0;
 }
@@ -129,7 +129,9 @@
   margin:.5em 0 0 1em;
 }
 
-dd pre, dd table, dd img {
+dd pre,
+#jd-content dd table,
+#jd-content dd img {
   margin:1em 0 0 1em;
 }
 
@@ -175,6 +177,10 @@
   background-color:#dee8f1;
 }
 
+td > p:last-child {
+  margin:0;
+}
+
 hr.blue {
   background-color:#DDF0F2;
   border:none;
@@ -226,7 +232,7 @@
 
 #header ul {
   list-style: none;
-  margin: 7px 0 0;  
+  margin: 7px 0 0;
   padding: 0;
   height: 29px;
 }
@@ -340,7 +346,7 @@
 }
 
 #mainBodyFixed h2,
-#mainBodyFluid h2 { 
+#mainBodyFluid h2 {
   color:#336666;
   font-size:1.25em;
   margin: 0;
@@ -348,7 +354,7 @@
 }
 
 #mainBodyFixed h1,
-#mainBodyFluid h1 { 
+#mainBodyFluid h1 {
   color:#435A6E;
   font-size:1.7em;
   margin: 1em 0;
@@ -356,7 +362,7 @@
 
 #mainBodyFixed .green,
 #mainBodyFluid .green,
-#jd-content .green { 
+#jd-content .green {
   color:#7BB026;
   background-color:none;
 }
@@ -364,13 +370,13 @@
 #mainBodyLeft {
   float: left;
   width: 600px;
-  margin-right: 20px;  
+  margin-right: 20px;
   color: #333;
   position:relative;
 }
 
 div.indent {
-  margin-left: 40px;  
+  margin-left: 40px;
   margin-right: 70px;
 }
 
@@ -413,6 +419,10 @@
   text-align:left;
 }
 
+#mainBodyRight td p {
+  margin:0 0 1em 0;
+}
+
 #mainBodyRight .blueBorderBox {
   border:5px solid #ddf0f2;
   padding:18px 18px 18px 18px;
@@ -517,7 +527,7 @@
   padding-right: 6px;
   padding-top: 1px;
   padding-bottom: 1px;
-  font-size: .8em;
+  font-size: 0.81em;
   border: none;
   margin: 0;
   line-height: 1.05em;
@@ -583,7 +593,7 @@
 
 .gsc-cursor-box .gsc-cursor div.gsc-cursor-page,
 .gsc-cursor-box .gsc-trailing-more-results a.gsc-trailing-more-results,
-#leftSearchControl a, 
+#leftSearchControl a,
 #leftSearchControl a b {
   color:#006699;
 }
@@ -669,7 +679,7 @@
   
 #homeTitle {
   padding:15px 15px 0;
-  height:30px;  
+  height:30px;
 }
 
 #homeTitle h2 {
@@ -704,8 +714,8 @@
 }
 
 #carouselMain {
-	background: url(images/home/bg_home_carousel_board.png) 0 0 no-repeat;
-	height:auto;
+  background: url(images/home/bg_home_carousel_board.png) 0 0 no-repeat;
+  height:auto;
   padding: 25px 21px 0;
   overflow:hidden;
   position:relative;
@@ -717,19 +727,19 @@
 }
 
 #carouselMain .bulletinDesc h3 {
-	margin:0;
-	padding:0;
+  margin:0;
+  padding:0;
 }
 
 #carouselMain .bulletinDesc p {
-	margin:0;
-	padding:0.7em 0 0;
+  margin:0;
+  padding:0.7em 0 0;
 }
 
 #carouselWheel {
-	background: url(images/home/bg_home_carousel_wheel.png) 0 0 no-repeat;
-	padding-top:40px;
-	height:150px;
+  background: url(images/home/bg_home_carousel_wheel.png) 0 0 no-repeat;
+  padding-top:40px;
+  height:150px;
 }
 
 .clearer { clear:both; }
@@ -748,17 +758,17 @@
   margin:35px 10px 0 0;
 }
 a.arrow-left-off,
-a#arrow-left.arrow-left-off:hover { 
+a#arrow-left.arrow-left-off:hover {
   background-position:0 0;
 }
-a.arrow-right-off, 
-a#arrow-right.arrow-right-off:hover { 
+a.arrow-right-off,
+a#arrow-right.arrow-right-off:hover {
   background-position:-42px 0;
 }
-a#arrow-left:hover { 
+a#arrow-left:hover {
   background-position:0 -42px;
 }
-a#arrow-right:hover { 
+a#arrow-right:hover {
   background-position:-42px -42px;
 }
 a.arrow-left-on {
@@ -778,17 +788,17 @@
   width:100%;
 }
 
-div#list-clip { 
-  height:110px; 
+div#list-clip {
+  height:110px;
   width:438px;
-  overflow:hidden; 
-  position:relative; 
-  float:left; 
+  overflow:hidden;
+  position:relative;
+  float:left;
 }
 
-div#app-list { 
-  left:0; 
-  z-index:1; 
+div#app-list {
+  left:0;
+  z-index:1;
   position:absolute;
   margin:11px 0 0;
   _margin-top:13px;
@@ -817,14 +827,14 @@
   top:-4px;
 }
 
-#app-list img {  
+#app-list img {
   width:90px;
   height:70px;
   margin:0;
 }
 
-#app-list a.selected, 
-#app-list a:active.selected, 
+#app-list a.selected,
+#app-list a:active.selected,
 #app-list a:hover.selected {
   background:#A4C639;
   color:#fff;
@@ -832,12 +842,12 @@
   text-decoration:none;
 }
 
-#app-list a:hover, 
+#app-list a:hover,
 #app-list a:active {
   background:#ff9900;
 }
 
-#app-list a:hover span, 
+#app-list a:hover span,
 #app-list a:active span {
   text-decoration:underline;
 }
@@ -851,7 +861,7 @@
 /*IE6*/
 * html #app-list a { zoom: 1; margin:0 24px 0 15px;}
 
-* html #list-clip { 
+* html #list-clip {
   width:430px !important;
 }
 
@@ -1146,13 +1156,13 @@
 }
 
 #mainBodyRight ul.videoPreviews p {
-	line-height:1.2em;
+  line-height:1.2em;
   padding:0;
   margin:4px 0 0 130px;
 }
 
 #mainBodyRight ul.videoPreviews img {
-	margin-top:5px;
+  margin-top:5px;
 }
 
 /* Pretty printing styles. Used with prettify.js. */
@@ -1164,8 +1174,10 @@
 .lit { color: #066; }
 .pun { color: #660; }
 .pln { color: #000; }
+dl.tag-list dt code,
 .tag { color: #008; }
-.atn { color: #606; }
+dl.atn-list dt code,
+.atn { color: #828; }
 .atv { color: #080; }
 .dec { color: #606; }
 
diff --git a/tools/droiddoc/templates/assets/android-developer-docs.css b/tools/droiddoc/templates/assets/android-developer-docs.css
index 0ab7aab..a3bab76 100644
--- a/tools/droiddoc/templates/assets/android-developer-docs.css
+++ b/tools/droiddoc/templates/assets/android-developer-docs.css
@@ -100,11 +100,14 @@
 #side-nav li a+a {
   padding: 0;
 }
-
-#side-nav li li li a { 
-/*sdk lists*/
+/*second level (nested) list*/
+#side-nav li li li a {
   padding: 0 0 0 28px;
-} 
+}
+/*third level (nested) list*/
+#side-nav li li li li a {
+  padding: 0 0 0 38px;
+}
 
 #side-nav .selected {
   background-color: #435a6e;
@@ -121,7 +124,7 @@
   display:block;
 }
 
-#side-nav .toggle-img {
+#side-nav .toggle-list .toggle-img {
   margin:0;
   padding:0;
   position:absolute;
@@ -131,8 +134,13 @@
   width:15px;
   outline-style:none;
 }
+/* second-level toggle */
+#side-nav .toggle-list .toggle-list .toggle-img {
+  left:10px;
+}
 
-#side-nav .closed .toggle-img {
+#side-nav .closed .toggle-img,
+#side-nav .open .closed .toggle-img {
   background:url('images/triangle-closed-small.png') 7px 4px no-repeat;
 }
 #side-nav .open .toggle-img {
@@ -226,7 +234,7 @@
 #doc-content {
   overflow:auto;
 }
-	
+
 #jd-header {
   background-color: #E2E2E2;
   padding: 7px 15px;
@@ -348,7 +356,7 @@
   color:#999;
 }
 
-div.api-level { 
+div.api-level {
   font-size:.8em;
   font-weight:normal;
   color:#999;
@@ -357,7 +365,7 @@
   margin-top:-25px;
 }
 
-#api-info-block div.api-level { 
+#api-info-block div.api-level {
   font-size:1.3em;
   font-weight:bold;
   float:none;
@@ -491,6 +499,8 @@
 
 hr {
   background-color:#ccc;
+  border-color:#fff;
+  margin:2em 0 1em;
 }
 
 /* DOC CLASSES */
@@ -507,8 +517,7 @@
   color:#111;
   border-top:2px solid #ccc;
   padding: .5em 0 0;
-  margin: 1.5em 0 1em 0;
-  max-width:968px;
+  margin: 2em 0 1em 0;
 }
 
 #jd-content h3 {
@@ -534,6 +543,10 @@
   position:inherit;
 }
 
+#jd-content table {
+  margin: 0 0 1em 1em;
+}
+
 #jd-content img {
   margin: 0 0 1em 1em;
 }
@@ -559,6 +572,15 @@
   font-weight:normal;
 }
 
+.caps {
+  font-variant:small-caps;
+  font-size:1.2em;
+}
+
+dl.tag-list dl.atn-list {
+  padding:0 0 0 2em;
+}
+
 .jd-details {
 /*  border:1px solid #669999;
   padding:4px; */
@@ -573,7 +595,7 @@
   margin:.5em .25em;
 }
 
-/* API reference: a block containing 
+/* API reference: a block containing
 a detailed description, a params table,
 seealso list, etc */
 .jd-tagdata {
@@ -737,7 +759,7 @@
 }
 
 li p.note, li p.warning {
-  margin: .5em 0 0 0;  
+  margin: .5em 0 0 0;
   padding: .2em .5em .2em .9em;
 }
 
@@ -772,7 +794,7 @@
 .new {
   font-size: .78em;
   font-weight: bold;
-  color: red;
+  color: #ff3d3d;
   text-decoration: none;
   vertical-align:top;
   line-height:.9em;
@@ -784,22 +806,37 @@
   padding:0;
 }
 
+p.img-caption {
+  margin: -0.5em 0 1em 1em; /* matches default img left-margin */
+}
+
 div.figure {
   float:right;
-  padding:0 0 20px 20px;
+  clear:right;
+  margin:1em 0 0 3em;
+  padding:0;
+  background-color:#fff;
   /* width must be defined w/ an inline style matching the image width */
 }
 
-#jd-content div.figure img {
-  display:block;
-  margin:0 0 10px 0;
+#jd-content
+div.figure img {
+  margin: 0 0 1em;
+}
+
+div.figure p.img-caption {
+  margin: -0.5em 0 1em 0;
+}
+
+p.table-caption {
+  margin: 0 0 0.5em 1em; /* matches default table left-margin */
 }
 
 /* BEGIN quickview sidebar element styles */
 
 #qv-wrapper {
   float: right;
-  width:310px;
+  width:310px; /* +35px padding */
   background-color:#fff;
   margin:-48px 0 2px 0;
   padding:0 0 20px 35px;
@@ -809,8 +846,8 @@
   background-color:#fff;
   border:4px solid #dee8f1;
   margin:0;
-  padding:0 6px 6px;
-  width:270px;
+  padding:0 5px 5px;
+  width:292px; /* +10px padding; +8px border */
   font-size:.9em;
 }
 
@@ -887,66 +924,53 @@
 /* Begin sidebox sidebar element styles */
 
 .sidebox-wrapper {
-  float: right;
-  width:280px;
+  float:right;
+  clear:right;
+  width:310px; /* +35px padding */
   background-color:#fff;
-  margin: 0;
-  padding: 20px 0 20px 20px;
-}
-
-.sidebox-inner {
-  border-left:1px solid #dee8f1;
-  background-color:#ffffee;
-  padding:5px 8px 5px 12px;
-  font-size:90%;
-  width:260px;
+  margin:0;
+  padding:0 0 20px 35px;
 }
 
 .sidebox {
-  float: right;
-  width:260px;
-  background-color:#ffffee;
   border-left:1px solid #dee8f1;
-  margin: 12px 0 0 15px;
-  padding:5px 8px 0 12px;
-  font-size:90%;
-}	
+  background-color:#ffffee;
+  margin:0;
+  padding:8px 12px;
+  font-size:0.9em;
+  width:285px; /* +24px padding; +1px border */
+}
 
-.sidebox p,
-.sidebox-inner p {
+.sidebox p {
   margin-bottom: .25em;
 }
 
-.sidebox ul,
-.sidebox-inner ul {
+.sidebox ul {
   padding: 0 0 0 1.5em;
 }
 
-.sidebox li ul,
-.sidebox-inner li ul {
+.sidebox li ul {
   margin-top:0;
   margin-bottom:.1em;
 }
 
-.sidebox li,
-.sidebox-inner li {
+.sidebox li {
 padding:0 0 0 0em;
 }
 
 #jd-content .sidebox h2,
 #jd-content .sidebox h3,
-#jd-content .sidebox-inner h2,
-#jd-content .sidebox-inner h3 {
+#jd-content .sidebox h4,
+#jd-content .sidebox h5 {
   border:none;
   font-size:1em;
   margin:0;
-  padding:4px 0 4px;
+  padding:0 0 8px;
   left:0;
   z-index:0;
 }
 
-.sidebox hr,
-.sidebox-inner hr {
+.sidebox hr {
   background-color:#ccc;
   border:none;
 }
@@ -963,7 +987,7 @@
 
 td.image-caption-i {
   font-size:92%;
-  padding:0;
+  padding:0 5px;
   margin:0;
   border:0;
 }
@@ -978,10 +1002,6 @@
   text-align:center;
 }
 
-.image-list .caption {
-  margin:0 2px;
-}
-
 td.image-caption-c {
   font-size:92%;
   padding:1em 2px 2px 2px;
@@ -1126,8 +1146,8 @@
 
 /* INLAY 180 COPY and 240PX EXTENSION */
 /* modified to 43px so that all browsers eliminate the package panel h-scroll */
-.g-tpl-240 .g-unit, 
-.g-unit .g-tpl-240 .g-unit, 
+.g-tpl-240 .g-unit,
+.g-unit .g-tpl-240 .g-unit,
 .g-unit .g-unit .g-tpl-240 .g-unit {
   display: block;
   margin: 0 0 0 243px;
@@ -1143,8 +1163,8 @@
   float: left;
 }
 /* 240px alt */
-.g-tpl-240-alt .g-unit, 
-.g-unit .g-tpl-240-alt .g-unit, 
+.g-tpl-240-alt .g-unit,
+.g-unit .g-tpl-240-alt .g-unit,
 .g-unit .g-unit .g-tpl-240-alt .g-unit {
   display: block;
   margin: 0 243px 0 0;
@@ -1161,8 +1181,8 @@
 }
 
 /* 180px */
-.g-tpl-180 .g-unit, 
-.g-unit .g-tpl-180 .g-unit, 
+.g-tpl-180 .g-unit,
+.g-unit .g-tpl-180 .g-unit,
 .g-unit .g-unit .g-tpl-180 .g-unit {
   display: block;
   margin: 0 0 0 180px;
@@ -1178,8 +1198,8 @@
   float: left;
 }
 /* 180px alt */
-.g-tpl-180-alt .g-unit, 
-.g-unit .g-tpl-180-alt .g-unit, 
+.g-tpl-180-alt .g-unit,
+.g-unit .g-tpl-180-alt .g-unit,
 .g-unit .g-unit .g-tpl-180-alt .g-unit {
   display: block;
   margin: 0 180px 0 0;
@@ -1200,10 +1220,12 @@
 .ui-resizable { position: relative; }
 .ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; z-index:1; }
 .ui-resizable .ui-resizable-handle { display: block; }
-body .ui-resizable-disabled .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
-body .ui-resizable-autohide .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
-.ui-resizable-s { cursor: s-resize; height: 6px; width: 100%; bottom: 0px; left: 0px; background: transparent url("images/resizable-s2.gif") repeat scroll center top; }
-.ui-resizable-e { cursor: e-resize; width: 6px; right: 0px; top: 0px; height: 100%; background: transparent url("images/resizable-e2.gif") repeat scroll right center; }
+body .ui-resizable-disabled .ui-resizable-handle { display: none; }
+body .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-s { cursor: s-resize; height: 6px; width: 100%; bottom: 0px; left: 0px;
+  background: transparent url("images/resizable-s2.gif") repeat scroll center top; }
+.ui-resizable-e { cursor: e-resize; width: 6px; right: 0px; top: 0px; height: 100%;
+  background: transparent url("images/resizable-e2.gif") repeat scroll right center; }
 
 @media print {
 
@@ -1266,7 +1288,7 @@
     word-wrap: break-word; /* IE 5.5+ */
   }
 
-  h1, h2, h3, h4, h5, h6 { 
+  h1, h2, h3, h4, h5, h6 {
     page-break-after: avoid;
   }
 
diff --git a/tools/droiddoc/templates/assets/android-developer-docs.js b/tools/droiddoc/templates/assets/android-developer-docs.js
index dfe8fa1..4c59dd6 100644
--- a/tools/droiddoc/templates/assets/android-developer-docs.js
+++ b/tools/droiddoc/templates/assets/android-developer-docs.js
@@ -193,11 +193,25 @@
       if (lastBackstep == 0) break;
     }
   }
+
+  // add 'selected' to the <li> or <div> that wraps this <a>
   link.parent().addClass('selected');
-  if (link.parent().parent().is(':hidden')) {
-    toggle(link.parent().parent().parent(), false);
-  } else if (link.parent().parent().hasClass('toggle-list')) {
-    toggle(link.parent().parent(), false);
+
+  // if we're in a toggleable root link (<li class=toggle-list><div><a>)
+  if (link.parent().parent().hasClass('toggle-list')) {
+    toggle(link.parent().parent(), false); // open our own list
+    // then also check if we're in a third-level nested list that's toggleable
+    if (link.parent().parent().parent().is(':hidden')) {
+      toggle(link.parent().parent().parent().parent(), false); // open the super parent list
+    }
+  }
+  // if we're in a normal nav link (<li><a>) and the parent <ul> is hidden
+  else if (link.parent().parent().is(':hidden')) {
+    toggle(link.parent().parent().parent(), false); // open the parent list
+    // then also check if the parent list is also nested in a hidden list
+    if (link.parent().parent().parent().parent().is(':hidden')) {
+      toggle(link.parent().parent().parent().parent().parent(), false); // open the super parent list
+    }
   }
 }
 
@@ -335,7 +349,7 @@
 });
 
 function toggle(obj, slide) {
-  var ul = $("ul", obj);
+  var ul = $("ul:first", obj);
   var li = ul.parent();
   if (li.hasClass("closed")) {
     if (slide) {
@@ -357,7 +371,7 @@
 function buildToggleLists() {
   $(".toggle-list").each(
     function(i) {
-      $("div", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
+      $("div:first", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
       $(this).addClass("closed");
     });
 }
@@ -420,43 +434,6 @@
   }
 }
 
-function toggleAllInherited(linkObj, expand) {
-  var a = $(linkObj);
-  var table = $(a.parent().parent().parent());
-  var expandos = $(".jd-expando-trigger", table);
-  if ( (expand == null && a.text() == "[Expand]") || expand ) {
-    expandos.each(function(i) {
-      toggleInherited(this, true);
-    });
-    a.text("[Collapse]");
-  } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
-    expandos.each(function(i) {
-      toggleInherited(this, false);
-    });
-    a.text("[Expand]");
-  }
-  return false;
-}
-
-function toggleAllSummaryInherited(linkObj) {
-  var a = $(linkObj);
-  var content = $(a.parent().parent().parent());
-  var toggles = $(".toggle-all", content);
-  if (a.text() == "[Expand All]") {
-    toggles.each(function(i) {
-      toggleAllInherited(this, true);
-    });
-    a.text("[Collapse All]");
-  } else {
-    toggles.each(function(i) {
-      toggleAllInherited(this, false);
-    });
-    a.text("[Expand All]");
-  }
-  return false;
-}
-
-
 function changeTabLang(lang) {
   var nodes = $("#header-tabs").find("."+lang);
   for (i=0; i < nodes.length; i++) { // for each node in this language 
diff --git a/tools/droiddoc/templates/assets/android-developer-reference.js b/tools/droiddoc/templates/assets/android-developer-reference.js
index 6299596..daddde0 100644
--- a/tools/droiddoc/templates/assets/android-developer-reference.js
+++ b/tools/droiddoc/templates/assets/android-developer-reference.js
@@ -34,25 +34,25 @@
     $("#apiLevelCheckbox").attr("checked","checked");
     $("#api-level-toggle label").removeClass("disabled");
   }
-	
+  
   minLevel = $("body").attr("class");
   var select = $("#apiLevelSelector").html("").change(changeApiLevel);
   for (var i = maxLevel-1; i >= 0; i--) {
     var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
   //  if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
-	  select.append(option);
+    select.append(option);
   }
-	
+  
   // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
-  var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0); 
-  selectedLevelItem.setAttribute('selected',true); 
+  var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
+  selectedLevelItem.setAttribute('selected',true);
 }
 
 function changeApiLevel() {
   var maxLevel = SINCE_DATA.length;
   var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
-  var selectedLevel = maxLevel;	
-	
+  var selectedLevel = maxLevel;
+  
   if (userApiLevelEnabled == 0) {
     toggleVisisbleApis(selectedLevel, "body");
   } else {
@@ -78,17 +78,17 @@
 }
 
 function toggleVisisbleApis(selectedLevel, context) {
-	var apis = $(".api",context);
-	apis.each(function(i) {
-		var obj = $(this);
-		var className = obj.attr("class");
-		var apiLevelIndex = className.lastIndexOf("-")+1;
-		var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
-		apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
-		var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
-		if (apiLevel > selectedLevel) obj.addClass("absent").attr("title","Requires API Level "+apiLevel+" or higher");
-		else obj.removeClass("absent").removeAttr("title");
-	});
+  var apis = $(".api",context);
+  apis.each(function(i) {
+    var obj = $(this);
+    var className = obj.attr("class");
+    var apiLevelIndex = className.lastIndexOf("-")+1;
+    var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
+    apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
+    var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
+    if (apiLevel > selectedLevel) obj.addClass("absent").attr("title","Requires API Level "+apiLevel+" or higher");
+    else obj.removeClass("absent").removeAttr("title");
+  });
 }
 
 /* NAVTREE */
@@ -185,8 +185,8 @@
     node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
     node.expanded = true;
     
-    // perform api level toggling because new nodes are new to the DOM 
-	  var selectedLevel = $("#apiLevelSelector option:selected").val();
+    // perform api level toggling because new nodes are new to the DOM
+    var selectedLevel = $("#apiLevelSelector option:selected").val();
     toggleVisisbleApis(selectedLevel, "#side-nav");
   }
 }
@@ -257,8 +257,8 @@
 function init_default_navtree(toroot) {
   init_navtree("nav-tree", toroot, NAVTREE_DATA);
   
-  // perform api level toggling because because the whole tree is new to the DOM 
-	var selectedLevel = $("#apiLevelSelector option:selected").val();
+  // perform api level toggling because because the whole tree is new to the DOM
+  var selectedLevel = $("#apiLevelSelector option:selected").val();
   toggleVisisbleApis(selectedLevel, "#side-nav");
 }
 
@@ -294,3 +294,97 @@
       });
   }
 }
+
+/* TOGGLE INHERITED MEMBERS */
+
+/* Toggle an inherited class (arrow toggle)
+ * @param linkObj  The link that was clicked.
+ * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
+ *                'null' to simply toggle.
+ */
+function toggleInherited(linkObj, expand) {
+    var base = linkObj.getAttribute("id");
+    var list = document.getElementById(base + "-list");
+    var summary = document.getElementById(base + "-summary");
+    var trigger = document.getElementById(base + "-trigger");
+    var a = $(linkObj);
+    if ( (expand == null && a.hasClass("closed")) || expand ) {
+        list.style.display = "none";
+        summary.style.display = "block";
+        trigger.src = toRoot + "assets/images/triangle-opened.png";
+        a.removeClass("closed");
+        a.addClass("opened");
+    } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
+        list.style.display = "block";
+        summary.style.display = "none";
+        trigger.src = toRoot + "assets/images/triangle-closed.png";
+        a.removeClass("opened");
+        a.addClass("closed");
+    }
+    return false;
+}
+
+/* Toggle all inherited classes in a single table (e.g. all inherited methods)
+ * @param linkObj  The link that was clicked.
+ * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
+ *                'null' to simply toggle.
+ */
+function toggleAllInherited(linkObj, expand) {
+  var a = $(linkObj);
+  var table = $(a.parent().parent().parent()); // ugly way to get table/tbody
+  var expandos = $(".jd-expando-trigger", table);
+  if ( (expand == null && a.text() == "[Expand]") || expand ) {
+    expandos.each(function(i) {
+      toggleInherited(this, true);
+    });
+    a.text("[Collapse]");
+  } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
+    expandos.each(function(i) {
+      toggleInherited(this, false);
+    });
+    a.text("[Expand]");
+  }
+  return false;
+}
+
+/* Toggle all inherited members in the class (link in the class title)
+ */
+function toggleAllClassInherited() {
+  var a = $("#toggleAllClassInherited"); // get toggle link from class title
+  var toggles = $(".toggle-all", $("#doc-content"));
+  if (a.text() == "[Expand All]") {
+    toggles.each(function(i) {
+      toggleAllInherited(this, true);
+    });
+    a.text("[Collapse All]");
+  } else {
+    toggles.each(function(i) {
+      toggleAllInherited(this, false);
+    });
+    a.text("[Expand All]");
+  }
+  return false;
+}
+
+/* Expand all inherited members in the class. Used when initiating page search */
+function ensureAllInheritedExpanded() {
+  var toggles = $(".toggle-all", $("#doc-content"));
+  toggles.each(function(i) {
+    toggleAllInherited(this, true);
+  });
+  $("#toggleAllClassInherited").text("[Collapse All]");
+}
+
+
+/* HANDLE KEY EVENTS
+ * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search)
+ */
+var agent = navigator['userAgent'].toLowerCase();
+var mac = agent.indexOf("macintosh") != -1;
+
+$(document).keydown( function(e) {
+var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
+  if (control && e.which == 70) {  // 70 is "F"
+    ensureAllInheritedExpanded();
+  }
+});
\ No newline at end of file
diff --git a/tools/droiddoc/templates/assets/images/home/froyo-android.png b/tools/droiddoc/templates/assets/images/home/froyo-android.png
new file mode 100644
index 0000000..c63f7f0
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/home/froyo-android.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/home/gdc-logo.png b/tools/droiddoc/templates/assets/images/home/gdc-logo.png
new file mode 100644
index 0000000..5fb53fb
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/home/gdc-logo.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/home/tv_l.png b/tools/droiddoc/templates/assets/images/home/tv_l.png
new file mode 100644
index 0000000..ed89bfc
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/home/tv_l.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/home/tv_s.png b/tools/droiddoc/templates/assets/images/home/tv_s.png
new file mode 100644
index 0000000..6ca68cb
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/home/tv_s.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/search_autocomplete.js b/tools/droiddoc/templates/assets/search_autocomplete.js
index 4fa47a5..dd4552f 100644
--- a/tools/droiddoc/templates/assets/search_autocomplete.js
+++ b/tools/droiddoc/templates/assets/search_autocomplete.js
@@ -2,7 +2,7 @@
 var gSelectedID = -1;
 var gMatches = new Array();
 var gLastText = "";
-var ROW_COUNT = 30;
+var ROW_COUNT = 20;
 var gInitialized = false;
 var DEFAULT_TEXT = "search developer docs";
 
@@ -22,7 +22,7 @@
 function set_row_values(toroot, row, match)
 {
     var link = row.cells[0].childNodes[0];
-    link.innerHTML = match.label;
+    link.innerHTML = match.__hilabel || match.label;
     link.href = toroot + match.link
   //  row.cells[1].innerHTML = match.type;
 }
@@ -104,7 +104,7 @@
 function search_changed(e, kd, toroot)
 {
     var search = document.getElementById("search_autocomplete");
-    var text = search.value;
+    var text = search.value.replace(/(^ +)|( +$)/g, '');
 
     // 13 = enter
     if (e.keyCode == 13) {
@@ -137,21 +137,112 @@
         gMatches = new Array();
         matchedCount = 0;
         gSelectedIndex = -1;
-        for (i=0; i<DATA.length; i++) {
+        for (var i=0; i<DATA.length; i++) {
             var s = DATA[i];
-            if (text.length != 0 && s.label.indexOf(text) != -1) {
+            if (text.length != 0 &&
+                  s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
                 gMatches[matchedCount] = s;
-                if (gSelectedID == s.id) {
-                    gSelectedIndex = matchedCount;
-                }
                 matchedCount++;
             }
         }
+        rank_autocomplete_results(text);
+        for (var i=0; i<gMatches.length; i++) {
+            var s = gMatches[i];
+            if (gSelectedID == s.id) {
+                gSelectedIndex = i;
+            }
+        }
+        highlight_autocomplete_result_labels(text);
         sync_selection_table(toroot);
         return true; // allow the event to bubble up to the search api
     }
 }
 
+function rank_autocomplete_results(query) {
+    query = query || '';
+    if (!gMatches || !gMatches.length)
+      return;
+
+    // helper function that gets the last occurence index of the given regex
+    // in the given string, or -1 if not found
+    var _lastSearch = function(s, re) {
+      if (s == '')
+        return -1;
+      var l = -1;
+      var tmp;
+      while ((tmp = s.search(re)) >= 0) {
+        if (l < 0) l = 0;
+        l += tmp;
+        s = s.substr(tmp + 1);
+      }
+      return l;
+    };
+
+    // helper function that counts the occurrences of a given character in
+    // a given string
+    var _countChar = function(s, c) {
+      var n = 0;
+      for (var i=0; i<s.length; i++)
+        if (s.charAt(i) == c) ++n;
+      return n;
+    };
+
+    var queryLower = query.toLowerCase();
+    var queryAlnum = (queryLower.match(/\w+/) || [''])[0];
+    var partPrefixAlnumRE = new RegExp('\\b' + queryAlnum);
+    var partExactAlnumRE = new RegExp('\\b' + queryAlnum + '\\b');
+
+    var _resultScoreFn = function(result) {
+        // scores are calculated based on exact and prefix matches,
+        // and then number of path separators (dots) from the last
+        // match (i.e. favoring classes and deep package names)
+        var score = 1.0;
+        var labelLower = result.label.toLowerCase();
+        var t;
+        t = _lastSearch(labelLower, partExactAlnumRE);
+        if (t >= 0) {
+            // exact part match
+            var partsAfter = _countChar(labelLower.substr(t + 1), '.');
+            score *= 200 / (partsAfter + 1);
+        } else {
+            t = _lastSearch(labelLower, partPrefixAlnumRE);
+            if (t >= 0) {
+                // part prefix match
+                var partsAfter = _countChar(labelLower.substr(t + 1), '.');
+                score *= 20 / (partsAfter + 1);
+            }
+        }
+
+        return score;
+    };
+
+    for (var i=0; i<gMatches.length; i++) {
+        gMatches[i].__resultScore = _resultScoreFn(gMatches[i]);
+    }
+
+    gMatches.sort(function(a,b){
+        var n = b.__resultScore - a.__resultScore;
+        if (n == 0) // lexicographical sort if scores are the same
+            n = (a.label < b.label) ? -1 : 1;
+        return n;
+    });
+}
+
+function highlight_autocomplete_result_labels(query) {
+    query = query || '';
+    if (!gMatches || !gMatches.length)
+      return;
+
+    var queryLower = query.toLowerCase();
+    var queryAlnumDot = (queryLower.match(/[\w\.]+/) || [''])[0];
+    var queryRE = new RegExp(
+        '(' + queryAlnumDot.replace(/\./g, '\\.') + ')', 'ig');
+    for (var i=0; i<gMatches.length; i++) {
+        gMatches[i].__hilabel = gMatches[i].label.replace(
+            queryRE, '<b>$1</b>');
+    }
+}
+
 function search_focus_changed(obj, focused)
 {
     if (focused) {
diff --git a/tools/droiddoc/templates/class.cs b/tools/droiddoc/templates/class.cs
index 89eb927..d2add18 100644
--- a/tools/droiddoc/templates/class.cs
+++ b/tools/droiddoc/templates/class.cs
@@ -3,29 +3,6 @@
 <html>
 <?cs include:"head_tag.cs" ?>
 <body class="<?cs var:class.since ?>">
-<script type="text/javascript">
-function toggleInherited(linkObj, expand) {
-    var base = linkObj.getAttribute("id");
-    var list = document.getElementById(base + "-list");
-    var summary = document.getElementById(base + "-summary");
-    var trigger = document.getElementById(base + "-trigger");
-    var a = $(linkObj);
-    if ( (expand == null && a.hasClass("closed")) || expand ) {
-        list.style.display = "none";
-        summary.style.display = "block";
-        trigger.src = "<?cs var:toroot ?>assets/images/triangle-opened.png";
-        a.removeClass("closed");
-        a.addClass("opened");
-    } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
-        list.style.display = "block";
-        summary.style.display = "none";
-        trigger.src = "<?cs var:toroot ?>assets/images/triangle-closed.png";
-        a.removeClass("opened");
-        a.addClass("closed");
-    }
-    return false;
-}
-</script>
 <?cs include:"header.cs" ?>
 
 <div class="g-unit" id="doc-content">
@@ -102,7 +79,7 @@
   <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#inhmethods">Inherited Methods</a>
 <?cs /if ?>
 <?cs if:inhattrs || inhconstants || inhfields || inhmethods || subcount(class.subclasses.direct) || subcount(class.subclasses.indirect) ?>
-&#124; <a href="#" onclick="return toggleAllSummaryInherited(this)">[Expand All]</a>
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
 <?cs /if ?>
 </div><!-- end sum-details-links -->
 <div class="api-level">
diff --git a/tools/event_log_tags.py b/tools/event_log_tags.py
new file mode 100644
index 0000000..81e8b39
--- /dev/null
+++ b/tools/event_log_tags.py
@@ -0,0 +1,127 @@
+# 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.
+
+"""A module for reading and parsing event-log-tags files."""
+
+import re
+import sys
+
+class Tag(object):
+  __slots__ = ["tagnum", "tagname", "description", "filename", "linenum"]
+
+  def __init__(self, tagnum, tagname, description, filename, linenum):
+    self.tagnum = tagnum
+    self.tagname = tagname
+    self.description = description
+    self.filename = filename
+    self.linenum = linenum
+
+
+class TagFile(object):
+  """Read an input event-log-tags file."""
+  def AddError(self, msg, linenum=None):
+    if linenum is None:
+      linenum = self.linenum
+    self.errors.append((self.filename, linenum, msg))
+
+  def AddWarning(self, msg, linenum=None):
+    if linenum is None:
+      linenum = self.linenum
+    self.warnings.append((self.filename, linenum, msg))
+
+  def __init__(self, filename, file_object=None):
+    """'filename' is the name of the file (included in any error
+    messages).  If 'file_object' is None, 'filename' will be opened
+    for reading."""
+    self.errors = []
+    self.warnings = []
+    self.tags = []
+    self.options = {}
+
+    self.filename = filename
+    self.linenum = 0
+
+    if file_object is None:
+      try:
+        file_object = open(filename, "rb")
+      except (IOError, OSError), e:
+        self.AddError(str(e))
+        return
+
+    try:
+      for self.linenum, line in enumerate(file_object):
+        self.linenum += 1
+
+        line = line.strip()
+        if not line or line[0] == '#': continue
+        parts = re.split(r"\s+", line, 2)
+
+        if len(parts) < 2:
+          self.AddError("failed to parse \"%s\"" % (line,))
+          continue
+
+        if parts[0] == "option":
+          self.options[parts[1]] = parts[2:]
+          continue
+
+        if parts[0] == "?":
+          tag = None
+        else:
+          try:
+            tag = int(parts[0])
+          except ValueError:
+            self.AddError("\"%s\" isn't an integer tag or '?'" % (parts[0],))
+            continue
+
+        tagname = parts[1]
+        if len(parts) == 3:
+          description = parts[2]
+        else:
+          description = None
+
+        self.tags.append(Tag(tag, tagname, description,
+                             self.filename, self.linenum))
+    except (IOError, OSError), e:
+      self.AddError(str(e))
+
+
+def BooleanFromString(s):
+  """Interpret 's' as a boolean and return its value.  Raise
+  ValueError if it's not something we can interpret as true or
+  false."""
+  s = s.lower()
+  if s in ("true", "t", "1", "on", "yes", "y"):
+    return True
+  if s in ("false", "f", "0", "off", "no", "n"):
+    return False
+  raise ValueError("'%s' not a valid boolean" % (s,))
+
+
+def WriteOutput(output_file, data):
+  """Write 'data' to the given output filename (which may be None to
+  indicate stdout).  Emit an error message and die on any failure.
+  'data' may be a string or a StringIO object."""
+  if not isinstance(data, str):
+    data = data.getvalue()
+  try:
+    if output_file is None:
+      out = sys.stdout
+      output_file = "<stdout>"
+    else:
+      out = open(output_file, "wb")
+    out.write(data)
+    out.close()
+  except (IOError, OSError), e:
+    print >> sys.stderr, "failed to write %s: %s" % (output_file, e)
+    sys.exit(1)
diff --git a/tools/java-event-log-tags.py b/tools/java-event-log-tags.py
new file mode 100755
index 0000000..c63fa20
--- /dev/null
+++ b/tools/java-event-log-tags.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""
+Usage: java-event-log-tags.py [-o output_file] <input_file> <merged_tags_file>
+
+Generate a java class containing constants for each of the event log
+tags in the given input file.
+
+-h to display this usage message and exit.
+"""
+
+import cStringIO
+import getopt
+import os
+import re
+import sys
+
+import event_log_tags
+
+output_file = None
+
+try:
+  opts, args = getopt.getopt(sys.argv[1:], "ho:")
+except getopt.GetoptError, err:
+  print str(err)
+  print __doc__
+  sys.exit(2)
+
+for o, a in opts:
+  if o == "-h":
+    print __doc__
+    sys.exit(2)
+  elif o == "-o":
+    output_file = a
+  else:
+    print >> sys.stderr, "unhandled option %s" % (o,)
+    sys.exit(1)
+
+if len(args) != 2:
+  print "need exactly two input files, not %d" % (len(args),)
+  print __doc__
+  sys.exit(1)
+
+fn = args[0]
+tagfile = event_log_tags.TagFile(fn)
+
+# Load the merged tag file (which should have numbers assigned for all
+# tags.  Use the numbers from the merged file to fill in any missing
+# numbers from the input file.
+merged_fn = args[1]
+merged_tagfile = event_log_tags.TagFile(merged_fn)
+merged_by_name = dict([(t.tagname, t) for t in merged_tagfile.tags])
+for t in tagfile.tags:
+  if t.tagnum is None:
+    if t.tagname in merged_by_name:
+      t.tagnum = merged_by_name[t.tagname].tagnum
+    else:
+      # We're building something that's not being included in the
+      # product, so its tags don't appear in the merged file.  Assign
+      # them all an arbitrary number so we can emit the java and
+      # compile the (unused) package.
+      t.tagnum = 999999
+
+if "java_package" not in tagfile.options:
+  tagfile.AddError("java_package option not specified", linenum=0)
+
+hide = True
+if "javadoc_hide" in tagfile.options:
+  hide = event_log_tags.BooleanFromString(tagfile.options["javadoc_hide"][0])
+
+if tagfile.errors:
+  for fn, ln, msg in tagfile.errors:
+    print >> sys.stderr, "%s:%d: error: %s" % (fn, ln, msg)
+  sys.exit(1)
+
+buffer = cStringIO.StringIO()
+buffer.write("/* This file is auto-generated.  DO NOT MODIFY.\n"
+             " * Source file: %s\n"
+             " */\n\n" % (fn,))
+
+buffer.write("package %s;\n\n" % (tagfile.options["java_package"][0],))
+
+basename, _ = os.path.splitext(os.path.basename(fn))
+
+if hide:
+  buffer.write("/**\n"
+               " * @hide\n"
+               " */\n")
+buffer.write("public class %s {\n" % (basename,))
+buffer.write("  private %s() { }  // don't instantiate\n" % (basename,))
+
+for t in tagfile.tags:
+  if t.description:
+    buffer.write("\n  /** %d %s %s */\n" % (t.tagnum, t.tagname, t.description))
+  else:
+    buffer.write("\n  /** %d %s */\n" % (t.tagnum, t.tagname))
+
+  buffer.write("  public static final int %s = %d;\n" %
+               (t.tagname.upper(), t.tagnum))
+
+keywords = frozenset(["abstract", "continue", "for", "new", "switch", "assert",
+                      "default", "goto", "package", "synchronized", "boolean",
+                      "do", "if", "private", "this", "break", "double",
+                      "implements", "protected", "throw", "byte", "else",
+                      "import", "public", "throws", "case", "enum",
+                      "instanceof", "return", "transient", "catch", "extends",
+                      "int", "short", "try", "char", "final", "interface",
+                      "static", "void", "class", "finally", "long", "strictfp",
+                      "volatile", "const", "float", "native", "super", "while"])
+
+def javaName(name):
+  out = name[0].lower() + re.sub(r"[^A-Za-z0-9]", "", name.title())[1:]
+  if out in keywords:
+    out += "_"
+  return out
+
+javaTypes = ["ERROR", "int", "long", "String", "Object[]"]
+for t in tagfile.tags:
+  methodName = javaName("write_" + t.tagname)
+  if t.description:
+    args = [arg.strip("() ").split("|") for arg in t.description.split(",")]
+  else:
+    args = []
+  argTypesNames = ", ".join([javaTypes[int(arg[1])] + " " + javaName(arg[0]) for arg in args])
+  argNames = "".join([", " + javaName(arg[0]) for arg in args])
+  buffer.write("\n  public static void %s(%s) {" % (methodName, argTypesNames))
+  buffer.write("\n    android.util.EventLog.writeEvent(%s%s);" % (t.tagname.upper(), argNames))
+  buffer.write("\n  }\n")
+
+
+buffer.write("}\n");
+
+event_log_tags.WriteOutput(output_file, buffer)
diff --git a/tools/merge-event-log-tags.py b/tools/merge-event-log-tags.py
new file mode 100755
index 0000000..df9ebce
--- /dev/null
+++ b/tools/merge-event-log-tags.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""
+Usage: merge-event-log-tags.py [-o output_file] [input_files...]
+
+Merge together zero or more event-logs-tags files to produce a single
+output file, stripped of comments.  Checks that no tag numbers conflict
+and fails if they do.
+
+-h to display this usage message and exit.
+"""
+
+import cStringIO
+import getopt
+import md5
+import struct
+import sys
+
+import event_log_tags
+
+errors = []
+warnings = []
+
+output_file = None
+
+# Tags with a tag number of ? are assigned a tag in the range
+# [ASSIGN_START, ASSIGN_LIMIT).
+ASSIGN_START = 900000
+ASSIGN_LIMIT = 1000000
+
+try:
+  opts, args = getopt.getopt(sys.argv[1:], "ho:")
+except getopt.GetoptError, err:
+  print str(err)
+  print __doc__
+  sys.exit(2)
+
+for o, a in opts:
+  if o == "-h":
+    print __doc__
+    sys.exit(2)
+  elif o == "-o":
+    output_file = a
+  else:
+    print >> sys.stderr, "unhandled option %s" % (o,)
+    sys.exit(1)
+
+# Restrictions on tags:
+#
+#   Tag names must be unique.  (If the tag number and description are
+#   also the same, a warning is issued instead of an error.)
+#
+#   Explicit tag numbers must be unique.  (If the tag name is also the
+#   same, no error is issued because the above rule will issue a
+#   warning or error.)
+
+by_tagname = {}
+by_tagnum = {}
+
+for fn in args:
+  tagfile = event_log_tags.TagFile(fn)
+
+  for t in tagfile.tags:
+    tagnum = t.tagnum
+    tagname = t.tagname
+    description = t.description
+
+    if t.tagname in by_tagname:
+      orig = by_tagname[t.tagname]
+
+      # Allow an explicit tag number to define an implicit tag number
+      if orig.tagnum is None:
+        orig.tagnum = t.tagnum
+      elif t.tagnum is None:
+        t.tagnum = orig.tagnum
+
+      if (t.tagnum == orig.tagnum and
+          t.description == orig.description):
+        # if the name and description are identical, issue a warning
+        # instead of failing (to make it easier to move tags between
+        # projects without breaking the build).
+        tagfile.AddWarning("tag \"%s\" (%s) duplicated in %s:%d" %
+                           (t.tagname, t.tagnum, orig.filename, orig.linenum),
+                           linenum=t.linenum)
+      else:
+        tagfile.AddError(
+            "tag name \"%s\" used by conflicting tag %s from %s:%d" %
+            (t.tagname, orig.tagnum, orig.filename, orig.linenum),
+            linenum=t.linenum)
+      continue
+
+    if t.tagnum is not None and t.tagnum in by_tagnum:
+      orig = by_tagnum[t.tagnum]
+
+      if t.tagname != orig.tagname:
+        tagfile.AddError(
+            "tag number %d used by conflicting tag \"%s\" from %s:%d" %
+            (t.tagnum, orig.tagname, orig.filename, orig.linenum),
+            linenum=t.linenum)
+        continue
+
+    by_tagname[t.tagname] = t
+    if t.tagnum is not None:
+      by_tagnum[t.tagnum] = t
+
+  errors.extend(tagfile.errors)
+  warnings.extend(tagfile.warnings)
+
+if errors:
+  for fn, ln, msg in errors:
+    print >> sys.stderr, "%s:%d: error: %s" % (fn, ln, msg)
+  sys.exit(1)
+
+if warnings:
+  for fn, ln, msg in warnings:
+    print >> sys.stderr, "%s:%d: warning: %s" % (fn, ln, msg)
+
+# Python's hash function (a) isn't great and (b) varies between
+# versions of python.  Using md5 is overkill here but is the same from
+# platform to platform and speed shouldn't matter in practice.
+def hashname(str):
+  d = md5.md5(str).digest()[:4]
+  return struct.unpack("!I", d)[0]
+
+# Assign a tag number to all the entries that say they want one
+# assigned.  We do this based on a hash of the tag name so that the
+# numbers should stay relatively stable as tags are added.
+
+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
+
+# by_tagnum should be complete now; we've assigned numbers to all tags.
+
+buffer = cStringIO.StringIO()
+for n, t in sorted(by_tagnum.iteritems()):
+  if t.description:
+    buffer.write("%d %s %s\n" % (t.tagnum, t.tagname, t.description))
+  else:
+    buffer.write("%d %s\n" % (t.tagnum, t.tagname))
+
+event_log_tags.WriteOutput(output_file, buffer)
diff --git a/tools/releasetools/amend_generator.py b/tools/releasetools/amend_generator.py
index f8f4344..b543bf7 100644
--- a/tools/releasetools/amend_generator.py
+++ b/tools/releasetools/amend_generator.py
@@ -100,6 +100,10 @@
     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."""
@@ -192,6 +196,9 @@
     """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
diff --git a/tools/releasetools/both_generator.py b/tools/releasetools/both_generator.py
index df2a659..4ae8d50 100644
--- a/tools/releasetools/both_generator.py
+++ b/tools/releasetools/both_generator.py
@@ -41,6 +41,7 @@
   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)
@@ -55,6 +56,7 @@
   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/check_target_files_signatures b/tools/releasetools/check_target_files_signatures
index b91f3d4..17aebdc 100755
--- a/tools/releasetools/check_target_files_signatures
+++ b/tools/releasetools/check_target_files_signatures
@@ -248,6 +248,7 @@
     d = common.UnzipTemp(filename, '*.apk')
     try:
       self.apks = {}
+      self.apks_by_basename = {}
       for dirpath, dirnames, filenames in os.walk(d):
         for fn in filenames:
           if fn.endswith(".apk"):
@@ -255,12 +256,17 @@
             displayname = fullname[len(d)+1:]
             apk = APK(fullname, displayname)
             self.apks[apk.package] = apk
+            self.apks_by_basename[os.path.basename(apk.filename)] = apk
 
             self.max_pkg_len = max(self.max_pkg_len, len(apk.package))
             self.max_fn_len = max(self.max_fn_len, len(apk.filename))
     finally:
       shutil.rmtree(d)
 
+    z = zipfile.ZipFile(open(filename, "rb"))
+    self.certmap = common.ReadApkCerts(z)
+    z.close()
+
   def CheckSharedUids(self):
     """Look for any instances where packages signed with different
     certs request the same sharedUserId."""
@@ -292,6 +298,20 @@
                                       apk.package, apk.filename)
       print
 
+  def CheckExternalSignatures(self):
+    for apk_filename, certname in self.certmap.iteritems():
+      if certname == "EXTERNAL":
+        # Apps marked EXTERNAL should be signed with the test key
+        # during development, then manually re-signed after
+        # predexopting.  Consider it an error if this app is now
+        # signed with any key that is present in our tree.
+        apk = self.apks_by_basename[apk_filename]
+        name = ALL_CERTS.Get(apk.cert)
+        if not name.startswith("unknown "):
+          Push(apk.filename)
+          AddProblem("hasn't been signed with EXTERNAL cert")
+          Pop()
+
   def PrintCerts(self):
     """Display a table of packages grouped by cert."""
     by_cert = {}
@@ -402,6 +422,7 @@
     Banner("target files")
     target_files.PrintCerts()
   target_files.CheckSharedUids()
+  target_files.CheckExternalSignatures()
   if compare_files:
     if OPTIONS.text:
       Banner("comparison files")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 0e17a5f..ab6678a 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -37,6 +37,11 @@
 OPTIONS.device_specific = None
 OPTIONS.extras = {}
 
+
+# Values for "certificate" in apkcerts that mean special things.
+SPECIAL_CERT_STRINGS = ("PRESIGNED", "EXTERNAL")
+
+
 class ExternalError(RuntimeError): pass
 
 
@@ -166,9 +171,8 @@
   need_passwords = []
   devnull = open("/dev/null", "w+b")
   for k in sorted(keylist):
-    # An empty-string key is used to mean don't re-sign this package.
-    # Obviously we don't need a password for this non-key.
-    if not k:
+    # We don't need a password for things that aren't really keys.
+    if k in SPECIAL_CERT_STRINGS:
       no_passwords.append(k)
       continue
 
@@ -254,6 +258,28 @@
     print "  ", msg
 
 
+def ReadApkCerts(tf_zip):
+  """Given a target_files ZipFile, parse the META/apkcerts.txt file
+  and return a {package: cert} dict."""
+  certmap = {}
+  for line in tf_zip.read("META/apkcerts.txt").split("\n"):
+    line = line.strip()
+    if not line: continue
+    m = re.match(r'^name="(.*)"\s+certificate="(.*)"\s+'
+                 r'private_key="(.*)"$', line)
+    if m:
+      name, cert, privkey = m.groups()
+      if cert in SPECIAL_CERT_STRINGS and not privkey:
+        certmap[name] = cert
+      elif (cert.endswith(".x509.pem") and
+            privkey.endswith(".pk8") and
+            cert[:-9] == privkey[:-4]):
+        certmap[name] = cert[:-9]
+      else:
+        raise ValueError("failed to parse line from apkcerts.txt:\n" + line)
+  return certmap
+
+
 COMMON_DOCSTRING = """
   -p  (--path)  <dir>
       Prepend <dir>/bin to the list of places to search for binaries
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index d1902e1..68b0850 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -112,11 +112,19 @@
 
   def PatchCheck(self, filename, *sha1):
     """Check that the given file (or MTD reference) has one of the
-    given *sha1 hashes."""
+    given *sha1 hashes, checking the version saved in cache if the
+    file does not match."""
     self.script.append('assert(apply_patch_check("%s"' % (filename,) +
                        "".join([', "%s"' % (i,) for i in sha1]) +
                        '));')
 
+  def FileCheck(self, filename, *sha1):
+    """Check that the given file (or MTD reference) has one of the
+    given *sha1 hashes."""
+    self.script.append('assert(sha1_check(read_file("%s")' % (filename,) +
+                       "".join([', "%s"' % (i,) for i in sha1]) +
+                       '));')
+
   def CacheFreeSpaceCheck(self, amount):
     """Check that there's at least 'amount' space that can be made
     available on /cache."""
@@ -164,7 +172,7 @@
     cmd = ['apply_patch("%s",\0"%s",\0%s,\0%d'
            % (srcfile, tgtfile, tgtsha1, tgtsize)]
     for i in range(0, len(patchpairs), 2):
-      cmd.append(',\0"%s:%s"' % patchpairs[i:i+2])
+      cmd.append(',\0%s, package_extract_file("%s")' % patchpairs[i:i+2])
     cmd.append(');')
     cmd = "".join(cmd)
     self.script.append(self._WordWrap(cmd))
@@ -213,14 +221,18 @@
     """Append text verbatim to the output script."""
     self.script.append(extra)
 
+  def UnmountAll(self):
+    for p in sorted(self.mounts):
+      self.script.append('unmount("%s");' % (p,))
+    self.mounts = set()
+
   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 the 'updater' binary needed to run
     script.  If input_path is not None, it will be used as a local
     path for the binary instead of input_zip."""
 
-    for p in sorted(self.mounts):
-      self.script.append('unmount("%s");' % (p,))
+    self.UnmountAll()
 
     common.ZipWriteStr(output_zip, "META-INF/com/google/android/updater-script",
                        "\n".join(self.script) + "\n")
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index f129da1..cf5fb34 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -137,26 +137,41 @@
     return cls.ITEMS[name]
 
   @classmethod
-  def GetMetadata(cls):
-    """Run the external 'fs_config' program to determine the desired
-    uid, gid, and mode for every Item object."""
-    p = common.Run(["fs_config"], stdin=subprocess.PIPE,
-                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    suffix = { False: "", True: "/" }
-    input = "".join(["%s%s\n" % (i.name, suffix[i.dir])
-                     for i in cls.ITEMS.itervalues() if i.name])
-    output, error = p.communicate(input)
-    assert not error
+  def GetMetadata(cls, input_zip):
+
+    try:
+      # See if the target_files contains a record of what the uid,
+      # gid, and mode is supposed to be.
+      output = input_zip.read("META/filesystem_config.txt")
+    except KeyError:
+      # Run the external 'fs_config' program to determine the desired
+      # uid, gid, and mode for every Item object.  Note this uses the
+      # one in the client now, which might not be the same as the one
+      # used when this target_files was built.
+      p = common.Run(["fs_config"], stdin=subprocess.PIPE,
+                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+      suffix = { False: "", True: "/" }
+      input = "".join(["%s%s\n" % (i.name, suffix[i.dir])
+                       for i in cls.ITEMS.itervalues() if i.name])
+      output, error = p.communicate(input)
+      assert not error
 
     for line in output.split("\n"):
       if not line: continue
       name, uid, gid, mode = line.split()
-      i = cls.ITEMS[name]
-      i.uid = int(uid)
-      i.gid = int(gid)
-      i.mode = int(mode, 8)
-      if i.dir:
-        i.children.sort(key=lambda i: i.name)
+      i = cls.ITEMS.get(name, None)
+      if i is not None:
+        i.uid = int(uid)
+        i.gid = int(gid)
+        i.mode = int(mode, 8)
+        if i.dir:
+          i.children.sort(key=lambda i: i.name)
+
+    # set metadata for the files generated by this script.
+    i = cls.ITEMS.get("system/recovery-from-boot.p", None)
+    if i: i.uid, i.gid, i.mode = 0, 0, 0644
+    i = cls.ITEMS.get("system/etc/install-recovery.sh", None)
+    if i: i.uid, i.gid, i.mode = 0, 0, 0544
 
   def CountChildMetadata(self):
     """Count up the (uid, gid, mode) tuples for all children and
@@ -338,11 +353,17 @@
     # change very often.
     script = edify_generator.EdifyGenerator(2)
 
+  metadata = {"post-build": GetBuildProp("ro.build.fingerprint", input_zip),
+              "pre-device": GetBuildProp("ro.product.device", input_zip),
+              }
+
   device_specific = common.DeviceSpecificParams(
       input_zip=input_zip,
+      input_version=GetRecoveryAPIVersion(input_zip),
       output_zip=output_zip,
       script=script,
-      input_tmp=OPTIONS.input_tmp)
+      input_tmp=OPTIONS.input_tmp,
+      metadata=metadata)
 
   if not OPTIONS.omit_prereq:
     ts = GetBuildProp("ro.build.date.utc", input_zip)
@@ -368,16 +389,9 @@
       os.path.join(OPTIONS.input_tmp, "BOOT")))
   recovery_img = File("recovery.img", common.BuildBootableImage(
       os.path.join(OPTIONS.input_tmp, "RECOVERY")))
-  i = MakeRecoveryPatch(output_zip, recovery_img, boot_img)
+  MakeRecoveryPatch(output_zip, recovery_img, boot_img)
 
-  Item.GetMetadata()
-
-  # GetMetadata uses the data in android_filesystem_config.h to assign
-  # the uid/gid/mode of all files.  We want to override that for the
-  # recovery patching shell script to make it executable.
-  i.uid = 0
-  i.gid = 0
-  i.mode = 0544
+  Item.GetMetadata(input_zip)
   Item.Get("system").SetPermissions(script)
 
   common.CheckSize(boot_img.data, "boot.img")
@@ -393,7 +407,15 @@
   if OPTIONS.extra_script is not None:
     script.AppendExtra(OPTIONS.extra_script)
 
+  script.UnmountAll()
   script.AddToZip(input_zip, output_zip)
+  WriteMetadata(metadata, output_zip)
+
+
+def WriteMetadata(metadata, output_zip):
+  common.ZipWriteStr(output_zip, "META-INF/com/android/metadata",
+                     "".join(["%s=%s\n" % kv
+                              for kv in sorted(metadata.iteritems())]))
 
 
 class File(object):
@@ -562,6 +584,7 @@
 
 def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
   source_version = GetRecoveryAPIVersion(source_zip)
+  target_version = GetRecoveryAPIVersion(target_zip)
 
   if OPTIONS.script_mode == 'amend':
     script = amend_generator.AmendGenerator()
@@ -578,11 +601,17 @@
   else:
     raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
 
+  metadata = {"pre-device": GetBuildProp("ro.product.device", source_zip),
+              }
+
   device_specific = common.DeviceSpecificParams(
       source_zip=source_zip,
+      source_version=source_version,
       target_zip=target_zip,
+      target_version=target_version,
       output_zip=output_zip,
-      script=script)
+      script=script,
+      metadata=metadata)
 
   print "Loading target..."
   target_data = LoadSystemFiles(target_zip)
@@ -622,11 +651,13 @@
       verbatim_targets.append((tf.name, tf.size))
     else:
       common.ZipWriteStr(output_zip, "patch/" + tf.name + ".p", d)
-      patch_list.append((tf.name, tf, sf, tf.size))
+      patch_list.append((tf.name, tf, sf, tf.size, sha.sha(d).hexdigest()))
       largest_source_size = max(largest_source_size, sf.size)
 
   source_fp = GetBuildProp("ro.build.fingerprint", source_zip)
   target_fp = GetBuildProp("ro.build.fingerprint", target_zip)
+  metadata["pre-build"] = source_fp
+  metadata["post-build"] = target_fp
 
   script.Mount("MTD", "system", "/system")
   script.AssertSomeFingerprint(source_fp, target_fp)
@@ -664,7 +695,7 @@
     total_verify_size += source_boot.size
   so_far = 0
 
-  for fn, tf, sf, size in patch_list:
+  for fn, tf, sf, size, patch_sha in patch_list:
     script.PatchCheck("/"+fn, tf.sha1, sf.sha1)
     so_far += sf.size
     script.SetProgress(so_far / total_verify_size)
@@ -685,8 +716,6 @@
 
   if patch_list or updating_recovery or updating_boot:
     script.CacheFreeSpaceCheck(largest_source_size)
-    script.Print("Unpacking patches...")
-    script.UnpackPackageDir("patch", "/tmp/patchtmp")
 
   device_specific.IncrementalOTA_VerifyEnd()
 
@@ -709,9 +738,8 @@
   so_far = 0
 
   script.Print("Patching system files...")
-  for fn, tf, sf, size in patch_list:
-    script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1,
-                      sf.sha1, "/tmp/patchtmp/"+fn+".p")
+  for fn, tf, sf, size, _ in patch_list:
+    script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1, sf.sha1, "patch/"+fn+".p")
     so_far += tf.size
     script.SetProgress(so_far / total_patch_size)
 
@@ -725,7 +753,7 @@
                          target_boot.size, target_boot.sha1),
                       "-",
                       target_boot.size, target_boot.sha1,
-                      source_boot.sha1, "/tmp/patchtmp/boot.img.p")
+                      source_boot.sha1, "patch/boot.img.p")
     so_far += target_boot.size
     script.SetProgress(so_far / total_patch_size)
     print "boot image changed; including."
@@ -744,9 +772,9 @@
     # partition, include the binaries and image files from recovery in
     # the boot image (though not in the ramdisk) so they can be used
     # as fodder for constructing the recovery image.
-    recovery_sh_item = MakeRecoveryPatch(output_zip,
-                                         target_recovery, target_boot)
-    script.UnpackPackageDir("recovery", "/system")
+    MakeRecoveryPatch(output_zip, target_recovery, target_boot)
+    script.DeleteFiles(["/system/recovery-from-boot.p",
+                        "/system/etc/install-recovery.sh"])
     print "recovery image changed; including as patch from boot."
   else:
     print "recovery image unchanged; skipping."
@@ -757,11 +785,7 @@
 
   target_symlinks_d = dict([(i[1], i[0]) for i in target_symlinks])
   temp_script = script.MakeTemporary()
-  Item.GetMetadata()
-  if updating_recovery:
-    recovery_sh_item.uid = 0
-    recovery_sh_item.gid = 0
-    recovery_sh_item.mode = 0544
+  Item.GetMetadata(target_zip)
   Item.Get("system").SetPermissions(temp_script)
 
   # Note that this call will mess up the tree of Items, so make sure
@@ -782,6 +806,10 @@
     script.Print("Unpacking new files...")
     script.UnpackPackageDir("system", "/system")
 
+  if updating_recovery:
+    script.Print("Unpacking new recovery...")
+    script.UnpackPackageDir("recovery", "/system")
+
   script.Print("Symlinks and permissions...")
 
   # Create all the symlinks that don't already exist, or point to
@@ -808,6 +836,7 @@
     scirpt.AppendExtra(OPTIONS.extra_script)
 
   script.AddToZip(target_zip, output_zip)
+  WriteMetadata(metadata, output_zip)
 
 
 def main(argv):
diff --git a/tools/releasetools/sign_target_files_apks b/tools/releasetools/sign_target_files_apks
index 9d296d8..5fca691 100755
--- a/tools/releasetools/sign_target_files_apks
+++ b/tools/releasetools/sign_target_files_apks
@@ -83,17 +83,18 @@
 OPTIONS.tag_changes = ("-test-keys", "+release-keys")
 
 def GetApkCerts(tf_zip):
-  certmap = {}
-  for line in tf_zip.read("META/apkcerts.txt").split("\n"):
-    line = line.strip()
-    if not line: continue
-    m = re.match(r'^name="(.*)"\s+certificate="(.*)\.x509\.pem"\s+'
-                 r'private_key="\2\.pk8"$', line)
-    if not m:
-      raise SigningError("failed to parse line from apkcerts.txt:\n" + line)
-    certmap[m.group(1)] = OPTIONS.key_map.get(m.group(2), m.group(2))
-  for apk, cert in OPTIONS.extra_apks.iteritems():
+  certmap = common.ReadApkCerts(tf_zip)
+
+  # apply the key remapping to the contents of the file
+  for apk, cert in certmap.iteritems():
     certmap[apk] = OPTIONS.key_map.get(cert, cert)
+
+  # apply all the -e options, overriding anything in the file
+  for apk, cert in OPTIONS.extra_apks.iteritems():
+    if not cert:
+      cert = "PRESIGNED"
+    certmap[apk] = OPTIONS.key_map.get(cert, cert)
+
   return certmap
 
 
@@ -114,68 +115,6 @@
     sys.exit(1)
 
 
-def SharedUserForApk(data):
-  tmp = tempfile.NamedTemporaryFile()
-  tmp.write(data)
-  tmp.flush()
-
-  p = common.Run(["aapt", "dump", "xmltree", tmp.name, "AndroidManifest.xml"],
-                 stdout=subprocess.PIPE)
-  data, _ = p.communicate()
-  if p.returncode != 0:
-    raise ExternalError("failed to run aapt dump")
-  lines = data.split("\n")
-  for i in lines:
-    m = re.match(r'^\s*A: android:sharedUserId\([0-9a-fx]*\)="([^"]*)" .*$', i)
-    if m:
-      return m.group(1)
-  return None
-
-
-def CheckSharedUserIdsConsistent(input_tf_zip, apk_key_map):
-  """Check that all packages that request the same shared user id are
-  going to be signed with the same key."""
-
-  shared_user_apks = {}
-  maxlen = len("(unknown key)")
-
-  for info in input_tf_zip.infolist():
-    if info.filename.endswith(".apk"):
-      data = input_tf_zip.read(info.filename)
-
-      name = os.path.basename(info.filename)
-      shared_user = SharedUserForApk(data)
-      key = apk_key_map[name]
-      maxlen = max(maxlen, len(key))
-
-      if shared_user is not None:
-        shared_user_apks.setdefault(
-            shared_user, {}).setdefault(key, []).append(name)
-
-  errors = []
-  for k, v in shared_user_apks.iteritems():
-    # each shared user should have exactly one key used for all the
-    # apks that want that user.
-    if len(v) > 1:
-      errors.append((k, v))
-
-  if not errors: return
-
-  print "ERROR:  shared user inconsistency.  All apks wanting to use"
-  print "        a given shared user must be signed with the same key."
-  print
-  errors.sort()
-  for user, keys in errors:
-    print 'shared user id "%s":' % (user,)
-    for key, apps in keys.iteritems():
-      print '  %-*s   %s' % (maxlen, key or "(unknown key)", apps[0])
-      for a in apps[1:]:
-        print (' ' * (maxlen+5)) + a
-    print
-
-  sys.exit(1)
-
-
 def SignApk(data, keyname, pw):
   unsigned = tempfile.NamedTemporaryFile()
   unsigned.write(data)
@@ -203,7 +142,7 @@
     if info.filename.endswith(".apk"):
       name = os.path.basename(info.filename)
       key = apk_key_map[name]
-      if key:
+      if key not in common.SPECIAL_CERT_STRINGS:
         print "    signing: %-*s (%s)" % (maxsize, name, key)
         signed_data = SignApk(data, key, key_passwords[key])
         output_tf_zip.writestr(out_info, signed_data)
@@ -221,6 +160,18 @@
       output_tf_zip.writestr(out_info, data)
 
 
+def EditTags(tags):
+  """Given a string containing comma-separated tags, apply the edits
+  specified in OPTIONS.tag_changes and return the updated string."""
+  tags = set(tags.split(","))
+  for ch in OPTIONS.tag_changes:
+    if ch[0] == "-":
+      tags.discard(ch[1:])
+    elif ch[0] == "+":
+      tags.add(ch[1:])
+  return ",".join(sorted(tags))
+
+
 def RewriteProps(data):
   output = []
   for line in data.split("\n"):
@@ -229,24 +180,17 @@
     if line and line[0] != '#':
       key, value = line.split("=", 1)
       if key == "ro.build.fingerprint":
-        pieces = line.split("/")
-        tags = set(pieces[-1].split(","))
-        for ch in OPTIONS.tag_changes:
-          if ch[0] == "-":
-            tags.discard(ch[1:])
-          elif ch[0] == "+":
-            tags.add(ch[1:])
-        line = "/".join(pieces[:-1] + [",".join(sorted(tags))])
+        pieces = value.split("/")
+        pieces[-1] = EditTags(pieces[-1])
+        value = "/".join(pieces)
       elif key == "ro.build.description":
-        pieces = line.split(" ")
+        pieces = value.split(" ")
         assert len(pieces) == 5
-        tags = set(pieces[-1].split(","))
-        for ch in OPTIONS.tag_changes:
-          if ch[0] == "-":
-            tags.discard(ch[1:])
-          elif ch[0] == "+":
-            tags.add(ch[1:])
-        line = " ".join(pieces[:-1] + [",".join(sorted(tags))])
+        pieces[-1] = EditTags(pieces[-1])
+        value = " ".join(pieces)
+      elif key == "ro.build.tags":
+        value = EditTags(value)
+      line = key + "=" + value
     if line != original_line:
       print "  replace: ", original_line
       print "     with: ", line
@@ -350,7 +294,6 @@
 
   apk_key_map = GetApkCerts(input_zip)
   CheckAllApksSigned(input_zip, apk_key_map)
-  CheckSharedUserIdsConsistent(input_zip, apk_key_map)
 
   key_passwords = common.GetKeyPasswords(set(apk_key_map.values()))
   SignApks(input_zip, output_zip, apk_key_map, key_passwords)
diff --git a/tools/warn.py b/tools/warn.py
index 6fea20a..8097123 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+# This file uses the following encoding: utf-8
 
 import sys
 import re
@@ -51,6 +52,7 @@
     { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'',
         'description':'Incompatible pointer types',
         'patterns':[r".*: warning: assignment from incompatible pointer type",
+                    r".*: warning: return from incompatible pointer type",
                     r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type",
                     r".*: warning: initialization from incompatible pointer type"] },
     { 'category':'C/C++',   'severity':severity.HIGH,     'members':[], 'option':'-fno-builtin',
@@ -61,7 +63,8 @@
         'patterns':[r".*: warning: unused parameter '.*'"] },
     { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'-Wunused',
         'description':'Unused function, variable or label',
-        'patterns':[r".*: warning: '.+' defined but not used"] },
+        'patterns':[r".*: warning: '.+' defined but not used",
+                    r".*: warning: unused variable '.+'"] },
     { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'-Wunused-value',
         'description':'Statement with no effect',
         'patterns':[r".*: warning: statement with no effect"] },
@@ -82,6 +85,9 @@
         'patterns':[r".*: warning: comparison between signed and unsigned",
                     r".*: warning: comparison of promoted \~unsigned with unsigned",
                     r".*: warning: signed and unsigned type in conditional expression"] },
+    { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'Comparison between enum and non-enum',
+        'patterns':[r".*: warning: enumeral and non-enumeral type in conditional expression"] },
     { 'category':'libpng',  'severity':severity.MEDIUM,   'members':[], 'option':'',
         'description':'libpng: zero area',
         'patterns':[r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"] },
@@ -215,6 +221,12 @@
         'description':'Java: Non-varargs call of varargs method with inexact argument type for last parameter',
         'patterns':[r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"] },
     { 'category':'aapt',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'aapt: No default translation',
+        'patterns':[r".*: warning: string '.+' has no default translation in .*"] },
+    { 'category':'aapt',    'severity':severity.MEDIUM,   'members':[], 'option':'',
+        'description':'aapt: Missing default or required localization',
+        'patterns':[r".*: warning: \*\*\*\* string '.+' has no default or required localization for '.+' in .+"] },
+    { 'category':'aapt',    'severity':severity.MEDIUM,   'members':[], 'option':'',
         'description':'aapt: String marked untranslatable, but translation exists',
         'patterns':[r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"] },
     { 'category':'aapt',    'severity':severity.MEDIUM,   'members':[], 'option':'',
@@ -228,7 +240,8 @@
         'patterns':[r".*: warning: backslash and newline separated by space"] },
     { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'-Warray-bounds',
         'description':'Array subscript out of bounds',
-        'patterns':[r".*: warning: array subscript is above array bounds"] },
+        'patterns':[r".*: warning: array subscript is above array bounds",
+                    r".*: warning: array subscript is below array bounds"] },
     { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'',
         'description':'Decimal constant is unsigned only in ISO C90',
         'patterns':[r".*: warning: this decimal constant is unsigned only in ISO C90"] },
@@ -267,6 +280,9 @@
         'patterns':[r".*: warning:   '.+'"] },
     { 'category':'cont.',   'severity':severity.SKIP,     'members':[], 'option':'',
         'description':'',
+        'patterns':[r".*: warning:   base '.+'"] },
+    { 'category':'cont.',   'severity':severity.SKIP,     'members':[], 'option':'',
+        'description':'',
         'patterns':[r".*: warning:   when initialized here"] },
     { 'category':'C/C++',   'severity':severity.MEDIUM,   'members':[], 'option':'-Wmissing-parameter-type',
         'description':'Parameter type not specified',
@@ -301,6 +317,9 @@
     { 'category':'C/C++',   'severity':severity.LOW,      'members':[], 'option':'-Wcomment',
         'description':'Line continuation inside comment',
         'patterns':[r".*: warning: multi-line comment"] },
+    { 'category':'C/C++',   'severity':severity.LOW,      'members':[], 'option':'-Wcomment',
+        'description':'Comment inside comment',
+        'patterns':[r".*: warning: "".+"" within comment"] },
     { 'category':'C/C++',   'severity':severity.HARMLESS, 'members':[], 'option':'',
         'description':'Extra tokens after #endif',
         'patterns':[r".*: warning: extra tokens at end of #endif directive"] },
@@ -339,6 +358,24 @@
     { 'category':'C/C++',   'severity':severity.MEDIUM,     'members':[], 'option':'',
         'description':'Converting from <type> to <other type>',
         'patterns':[r".*: warning: converting to '.+' from '.+'"] },
+    { 'category':'C/C++',   'severity':severity.MEDIUM,     'members':[], 'option':'',
+        'description':'Return value from void function',
+        'patterns':[r".*: warning: 'return' with a value, in function returning void"] },
+    { 'category':'C/C++',   'severity':severity.LOW,     'members':[], 'option':'',
+        'description':'Useless specifier',
+        'patterns':[r".*: warning: useless storage class specifier in empty declaration"] },
+    { 'category':'logtags',   'severity':severity.LOW,     'members':[], 'option':'',
+        'description':'Duplicate logtag',
+        'patterns':[r".*: warning: tag "".+"" \(None\) duplicated in .+"] },
+    { 'category':'C/C++',   'severity':severity.MEDIUM,     'members':[], 'option':'',
+        'description':'Operator new returns NULL',
+        'patterns':[r".*: warning: 'operator new' must not return NULL unless it is declared 'throw\(\)' .+"] },
+    { 'category':'C/C++',   'severity':severity.MEDIUM,     'members':[], 'option':'',
+        'description':'NULL used in arithmetic',
+        'patterns':[r".*: warning: NULL used in arithmetic"] },
+    { 'category':'C/C++',   'severity':severity.MEDIUM,     'members':[], 'option':'',
+        'description':'Use of deprecated method',
+        'patterns':[r".*: warning: '.+' is deprecated .+"] },
 
     # these next ones are to deal with formatting problems resulting from the log being mixed up by 'make -j'
     { 'category':'C/C++',   'severity':severity.SKIP,     'members':[], 'option':'',
@@ -491,6 +528,9 @@
 # read the log file and classify all the warnings
 lastmatchedline = ''
 for line in infile:
+    # replace fancy quotes with plain ol' quotes
+    line = line.replace("‘", "'");
+    line = line.replace("’", "'");
     if warningpattern.match(line):
         if line != lastmatchedline:
             classifywarning(line)
diff --git a/tools/zipalign/Android.mk b/tools/zipalign/Android.mk
index f90a31c..9763bd2 100644
--- a/tools/zipalign/Android.mk
+++ b/tools/zipalign/Android.mk
@@ -18,17 +18,14 @@
 	libutils \
 	libcutils
 
-LOCAL_LDLIBS := -lz
-
 ifeq ($(HOST_OS),linux)
 LOCAL_LDLIBS += -lrt
 endif
 
-# dunno if we need this, but some of the other tools include it
-ifeq ($(HOST_OS),windows)
-ifeq ($(strip $(USE_CYGWIN),),)
-LOCAL_LDLIBS += -lws2_32
-endif
+ifneq ($(strip $(USE_MINGW)),)
+LOCAL_STATIC_LIBRARIES += libz
+else
+LOCAL_LDLIBS += -lz
 endif
 
 LOCAL_MODULE := zipalign