am e0e7bce4: am 2b8ba2fa: Merge "Clean up warnings in soslim" into gingerbread

Merge commit 'e0e7bce46bbb9b6a057ed9e57700dbeb3e45d8c1'

* commit 'e0e7bce46bbb9b6a057ed9e57700dbeb3e45d8c1':
  Clean up warnings in soslim
diff --git a/buildspec.mk.default b/buildspec.mk.default
index c568a82..46aee69 100644
--- a/buildspec.mk.default
+++ b/buildspec.mk.default
@@ -106,9 +106,9 @@
 #WEBCORE_INSTRUMENTATION:=true
 endif
 
-# To enable SVG in webcore define ENABLE_SVG:=true
+# To disable SVG in webcore define ENABLE_SVG:=false
 ifndef ENABLE_SVG
-#ENABLE_SVG:=true
+#ENABLE_SVG:=false
 endif
 
 # when the build system changes such that this file must be updated, this
diff --git a/core/Makefile b/core/Makefile
index d36a2d7..fc73d46 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -521,11 +521,37 @@
 # Targets for user images
 # #################################################################
 
+INTERNAL_USERIMAGES_EXT_VARIANT :=
 ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
-include external/genext2fs/Config.mk
-INTERNAL_MKUSERFS := $(MKEXT2IMG)
+INTERNAL_USERIMAGES_USE_EXT := true
+INTERNAL_USERIMAGES_EXT_VARIANT := ext2
 else
-INTERNAL_MKUSERFS := $(MKYAFFS2)
+ifeq ($(TARGET_USERIMAGES_USE_EXT3),true)
+INTERNAL_USERIMAGES_USE_EXT := true
+INTERNAL_USERIMAGES_EXT_VARIANT := ext3
+else
+ifeq ($(TARGET_USERIMAGES_USE_EXT4),true)
+INTERNAL_USERIMAGES_USE_EXT := true
+INTERNAL_USERIMAGES_EXT_VARIANT := ext4
+endif
+endif
+endif
+
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
+INTERNAL_USERIMAGES_DEPS := $(MKEXT2USERIMG) $(MKEXT2IMG) $(TUNE2FS) $(E2FSCK)
+INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
+
+# $(1): src directory
+# $(2): output file
+# $(3): label (if any)
+# $(4): ext variant (ext2, ext3, ext4)
+define build-userimage-ext-target
+  @mkdir -p $(dir $(2))
+  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$(PATH) \
+	  $(MKEXT2USERIMG) $(1) $(2) $(4) $(3)
+endef
+else
+INTERNAL_USERIMAGES_DEPS := $(MKYAFFS2)
 endif
 
 # -----------------------------------------------------------------
@@ -596,6 +622,7 @@
 	mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp
 	echo Copying baseline ramdisk...
 	cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
+	rm $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
 	echo Modifying ramdisk contents...
 	cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
 	cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/
@@ -640,15 +667,15 @@
 	$(ALL_GENERATED_SOURCES) \
 	$(ALL_DEFAULT_INSTALLED_MODULES))
 
-ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
-## generate an ext2 image
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
+## generate an ext image
 # $(1): output file
 define build-systemimage-target
     @echo "Target system fs image: $(1)"
-    $(call build-userimage-ext2-target,$(TARGET_OUT),$(1),system,)
+    $(call build-userimage-ext-target,$(TARGET_OUT),$(1),system,$(INTERNAL_USERIMAGES_EXT_VARIANT))
 endef
 
-else # TARGET_USERIMAGES_USE_EXT2 != true
+else # INTERNAL_USERIMAGES_USE_EXT != true
 
 ## generate a yaffs2 image
 # $(1): output file
@@ -657,9 +684,10 @@
     @mkdir -p $(dir $(1))
     $(hide) $(MKYAFFS2) -f $(mkyaffs2_extra_flags) $(TARGET_OUT) $(1)
 endef
-endif # TARGET_USERIMAGES_USE_EXT2
+endif # INTERNAL_USERIMAGES_USE_EXT
 
-$(BUILT_SYSTEMIMAGE_UNOPT): $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_MKUSERFS)
+$(BUILT_SYSTEMIMAGE_UNOPT): $(INTERNAL_SYSTEMIMAGE_FILES) \
+                            $(INTERNAL_USERIMAGES_DEPS)
 	$(call build-systemimage-target,$@)
 
 # The installed image, which may be optimized or unoptimized.
@@ -706,7 +734,7 @@
 
 .PHONY: systemimage-nodeps snod
 systemimage-nodeps snod: $(filter-out systemimage-nodeps snod,$(MAKECMDGOALS)) \
-	            | $(INTERNAL_MKUSERFS)
+	            | $(INTERNAL_USERIMAGES_DEPS)
 	@echo "make $@: ignoring dependencies"
 	$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE))
 	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE),yaffs)
@@ -740,16 +768,16 @@
 INTERNAL_USERDATAIMAGE_FILES := \
 	$(filter $(TARGET_OUT_DATA)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
 
-ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
 ## Generate an ext2 image
 define build-userdataimage-target
     $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
     @mkdir -p $(TARGET_OUT_DATA)
-    $(call build-userimage-ext2-target,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET),userdata,)
+    $(call build-userimage-ext-target,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET),userdata,$(INTERNAL_USERIMAGES_EXT_VARIANT))
     $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
 endef
 
-else # TARGET_USERIMAGES_USE_EXT2 != true
+else # INTERNAL_USERIMAGES_USE_EXT != true
 
 ## Generate a yaffs2 image
 define build-userdataimage-target
@@ -758,18 +786,18 @@
     $(hide) $(MKYAFFS2) -f $(mkyaffs2_extra_flags) $(TARGET_OUT_DATA) $(INSTALLED_USERDATAIMAGE_TARGET)
     $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE),yaffs)
 endef
-endif # TARGET_USERIMAGES_USE_EXT2
+endif # INTERNAL_USERIMAGES_USE_EXT
 
 BUILT_USERDATAIMAGE_TARGET := $(PRODUCT_OUT)/userdata.img
 
 # We just build this directly to the install location.
 INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)
-$(INSTALLED_USERDATAIMAGE_TARGET): $(INTERNAL_MKUSERFS) \
+$(INSTALLED_USERDATAIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) \
                                    $(INTERNAL_USERDATAIMAGE_FILES)
 	$(build-userdataimage-target)
 
 .PHONY: userdataimage-nodeps
-userdataimage-nodeps: $(INTERNAL_MKUSERFS)
+userdataimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS)
 	$(build-userdataimage-target)
 
 #######
@@ -812,7 +840,12 @@
 	  $(HOST_OUT_EXECUTABLES)/bsdiff \
 	  $(HOST_OUT_EXECUTABLES)/imgdiff \
 	  $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar \
-	  $(HOST_OUT_JAVA_LIBRARIES)/signapk.jar
+	  $(HOST_OUT_JAVA_LIBRARIES)/signapk.jar \
+	  $(HOST_OUT_EXECUTABLES)/mkuserimg.sh \
+	  $(HOST_OUT_EXECUTABLES)/genext2fs \
+	  $(HOST_OUT_EXECUTABLES)/tune2fs \
+	  $(HOST_OUT_EXECUTABLES)/e2fsck
+
 
 .PHONY: otatools
 otatools: $(OTATOOLS)
@@ -929,11 +962,30 @@
 	$(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
 	$(hide)	echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
 	$(hide) echo "$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/recovery-api-version.txt
-	$(hide) echo "blocksize $(BOARD_FLASH_BLOCK_SIZE)" > $(zip_root)/META/imagesizes.txt
-	$(hide) echo "boot $(call image-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "recovery $(call image-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "system $(call image-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
-	$(hide) echo "userdata $(call image-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt
+ifdef BOARD_FLASH_BLOCK_SIZE
+	$(hide) echo "blocksize=$(BOARD_FLASH_BLOCK_SIZE)" > $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
+	$(hide) echo "boot_size=$(call image-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
+	$(hide) echo "recovery_size=$(call image-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_SYSTEMIMAGE_PARTITION_SIZE
+	$(hide) echo "system_size=$(call image-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_USERDATAIMAGE_PARTITION_SIZE
+	$(hide) echo "userdata_size=$(call image-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/misc_info.txt
+endif
+ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
+	$(hide) echo "fs_type=ext4" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "partition_type=EMMC" >> $(zip_root)/META/misc_info.txt
+	@# TODO: where is the right place to get this path from?  BoardConfig.mk?
+	$(hide) echo "partition_path=/dev/block/platform/sdhci-tegra.3/by-name/" >> $(zip_root)/META/misc_info.txt
+else
+	$(hide) echo "fs_type=yaffs2" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "partition_type=MTD" >> $(zip_root)/META/misc_info.txt
+endif
 	$(hide) echo "$(tool_extensions)" > $(zip_root)/META/tool-extensions.txt
 	@# Zip everything up, preserving symlinks
 	$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
@@ -961,17 +1013,9 @@
 
 $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
 
-ifeq ($(TARGET_OTA_SCRIPT_MODE),)
-# default to "auto"
-$(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := auto
-else
-$(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := $(TARGET_OTA_SCRIPT_MODE)
-endif
-
 $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
 	@echo "Package OTA: $@"
 	$(hide) ./build/tools/releasetools/ota_from_target_files \
-	   -m $(scriptmode) \
 	   -p $(HOST_OUT) \
            -k $(KEY_CERT_PAIR) \
            $(BUILT_TARGET_FILES_PACKAGE) $@
@@ -996,8 +1040,12 @@
 
 .PHONY: installed-file-list
 installed-file-list: $(INSTALLED_FILES_FILE)
+ifneq ($(filter sdk,$(MAKECMDGOALS)),)
 $(call dist-for-goals, sdk, $(INSTALLED_FILES_FILE))
+endif
+ifneq ($(filter sdk_addon,$(MAKECMDGOALS)),)
 $(call dist-for-goals, sdk_addon, $(INSTALLED_FILES_FILE))
+endif
 
 # -----------------------------------------------------------------
 # A zip of the tests that are built when running "make tests".
@@ -1118,6 +1166,7 @@
 	$(hide) ./build/tools/releasetools/img_from_target_files \
 	   -s $(extensions) \
 	   -p $(HOST_OUT) \
+	   $(addprefix --fs_type ,$(INTERNAL_USERIMAGES_EXT_VARIANT)) \
 	   $(BUILT_TARGET_FILES_PACKAGE) $@
 
 .PHONY: updatepackage
diff --git a/core/build_id.mk b/core/build_id.mk
index e954794..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 := OPENMASTER
+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/clear_vars.mk b/core/clear_vars.mk
index c37b43e..8edb4c3 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -79,6 +79,7 @@
 LOCAL_STRIP_MODULE:=
 LOCAL_POST_PROCESS_COMMAND:=true
 LOCAL_JNI_SHARED_LIBRARIES:=
+LOCAL_JNI_SHARED_LIBRARIES_ABI:=
 LOCAL_JAR_MANIFEST:=
 LOCAL_INSTRUMENTATION_FOR:=
 LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME:=
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index aa53767..19c68f1 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -95,6 +95,7 @@
 TARGET_GLOBAL_CFLAGS += \
 			-msoft-float -fpic \
 			-ffunction-sections \
+			-fdata-sections \
 			-funwind-tables \
 			-fstack-protector \
 			-Wa,--noexecstack \
@@ -116,6 +117,7 @@
 
 TARGET_GLOBAL_LDFLAGS += \
 			-Wl,-z,noexecstack \
+			-Wl,--icf=safe \
 			$(arch_variant_ldflags)
 
 # We only need thumb interworking in cases where thumb support
diff --git a/core/combo/javac.mk b/core/combo/javac.mk
index d4c04e7..f8c99fb 100644
--- a/core/combo/javac.mk
+++ b/core/combo/javac.mk
@@ -8,7 +8,7 @@
 #   COMMON_JAVAC -- Java compiler command with common arguments
 
 # Whatever compiler is on this system.
-ifeq ($(HOST_OS), windows)
+ifeq ($(BUILD_OS), windows)
     COMMON_JAVAC := development/host/windows/prebuilt/javawrap.exe -J-Xmx256m \
         -target 1.5 -Xmaxerrs 9999999
 else
diff --git a/core/config.mk b/core/config.mk
index 8d2f96c..cf387e3 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -206,10 +206,11 @@
 APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
 FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
 MKEXT2IMG := $(HOST_OUT_EXECUTABLES)/genext2fs$(HOST_EXECUTABLE_SUFFIX)
+MKEXT2USERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg.sh
 MKEXT2BOOTIMG := external/genext2fs/mkbootimg_ext2.sh
 MKTARBALL := build/tools/mktarball.sh
-TUNE2FS := tune2fs
-E2FSCK := e2fsck
+TUNE2FS := $(HOST_OUT_EXECUTABLES)/tune2fs$(HOST_EXECUTABLE_SUFFIX)
+E2FSCK := $(HOST_OUT_EXECUTABLES)/e2fsck$(HOST_EXECUTABLE_SUFFIX)
 JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
 PROGUARD := external/proguard/bin/proguard.sh
 JAVATAGS := build/tools/java-event-log-tags.py
diff --git a/core/definitions.mk b/core/definitions.mk
index c8ee0ae..2747b4f 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -947,6 +947,24 @@
 ## Commands for running ar
 ###########################################################
 
+define _concat-if-arg2-not-empty
+$(if $(2),$(hide) $(1) $(2))
+endef
+
+# Split long argument list into smaller groups and call the command repeatedly
+#
+# $(1): the command without arguments
+# $(2): the arguments
+define split-long-arguments
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 1,500,$(2)))
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 501,1000,$(2)))
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 1001,1500,$(2)))
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 1501,2000,$(2)))
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 2001,2500,$(2)))
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 2501,3000,$(2)))
+$(call _concat-if-arg2-not-empty,$(1),$(wordlist 3001,99999,$(2)))
+endef
+
 define extract-and-include-target-whole-static-libs
 $(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
 	$(hide) echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
@@ -969,8 +987,7 @@
 @rm -f $@
 $(extract-and-include-target-whole-static-libs)
 @echo "target StaticLib: $(PRIVATE_MODULE) ($@)"
-$(hide) echo $(filter %.o, $^) | \
-    xargs $(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@
+$(call split-long-arguments,$(TARGET_AR) $(TARGET_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@,$(filter %.o, $^))
 endef
 
 ###########################################################
@@ -979,7 +996,7 @@
 
 define extract-and-include-host-whole-static-libs
 $(foreach lib,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES), \
-	@echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
+	$(hide) echo "preparing StaticLib: $(PRIVATE_MODULE) [including $(lib)]"; \
 	ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(lib)))_objs;\
 	rm -rf $$ldir; \
 	mkdir -p $$ldir; \
@@ -999,8 +1016,7 @@
 @rm -f $@
 $(extract-and-include-host-whole-static-libs)
 @echo "host StaticLib: $(PRIVATE_MODULE) ($@)"
-echo $(filter %.o, $^) | \
-	xargs $(HOST_AR) $(HOST_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@
+$(call split-long-arguments,$(HOST_AR) $(HOST_GLOBAL_ARFLAGS) $(PRIVATE_ARFLAGS) $@,$(filter %.o, $^))
 endef
 
 
@@ -1234,7 +1250,7 @@
     $(addprefix --min-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
-    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION))) \
+    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION)-$(BUILD_NUMBER))) \
     $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
     $(addprefix --rename-instrumentation-target-package , $(PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME))
 endef
@@ -1273,7 +1289,12 @@
         @$(call emit-line,$(wordlist 3401,3600,$(1)),$(2))
         @$(call emit-line,$(wordlist 3601,3800,$(1)),$(2))
         @$(call emit-line,$(wordlist 3801,4000,$(1)),$(2))
-        @$(if $(wordlist 4001,4002,$(1)),$(error Too many words ($(words $(1)))))
+        @$(call emit-line,$(wordlist 4001,4200,$(1)),$(2))
+        @$(call emit-line,$(wordlist 4201,4400,$(1)),$(2))
+        @$(call emit-line,$(wordlist 4401,4600,$(1)),$(2))
+        @$(call emit-line,$(wordlist 4601,4800,$(1)),$(2))
+        @$(call emit-line,$(wordlist 4801,5000,$(1)),$(2))
+        @$(if $(wordlist 5001,5002,$(1)),$(error Too many words ($(words $(1)))))
 endef
 
 # For a list of jar files, unzip them to a specified directory,
@@ -1379,7 +1400,7 @@
     $(addprefix --min-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(addprefix --target-sdk-version , $(DEFAULT_APP_TARGET_SDK)) \
     $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
-    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION))) \
+    $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION)-$(BUILD_NUMBER))) \
     $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
     $(addprefix --rename-instrumentation-target-package , $(PRIVATE_INSTRUMENTATION_FOR_PACKAGE_NAME)) \
     -F $@
@@ -1387,8 +1408,8 @@
 
 define add-jni-shared-libs-to-package
 $(hide) rm -rf $(dir $@)lib
-$(hide) mkdir -p $(dir $@)lib/$(TARGET_CPU_ABI)
-$(hide) cp $(PRIVATE_JNI_SHARED_LIBRARIES) $(dir $@)lib/$(TARGET_CPU_ABI)
+$(hide) mkdir -p $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)
+$(hide) cp $(PRIVATE_JNI_SHARED_LIBRARIES) $(dir $@)lib/$(PRIVATE_JNI_SHARED_LIBRARIES_ABI)
 $(hide) (cd $(dir $@) && zip -r $(notdir $@) lib)
 $(hide) rm -rf $(dir $@)lib
 endef
@@ -1593,7 +1614,7 @@
 endef
 else
 define transform-host-ranlib-copy-hack
-true
+@true
 endef
 endif
 
@@ -1603,7 +1624,7 @@
 endef
 else
 define transform-ranlib-copy-hack
-true
+@true
 endef
 endif
 
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index ba4857b..8495e6e 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -163,7 +163,7 @@
 		LD_LIBRARY_PATH=$(HOST_OUT_SHARED_LIBRARIES) \
 		javadoc \
                 \@$(PRIVATE_SRC_LIST_FILE) \
-                -J-Xmx768m \
+                -J-Xmx1024m \
                 -J-Djava.library.path=$(HOST_OUT_SHARED_LIBRARIES) \
                 $(PRIVATE_PROFILING_OPTIONS) \
                 -quiet \
@@ -204,7 +204,7 @@
 		javadoc \
                 $(PRIVATE_DROIDDOC_OPTIONS) \
                 \@$(PRIVATE_SRC_LIST_FILE) \
-                -J-Xmx768m \
+                -J-Xmx1024m \
                 $(PRIVATE_PROFILING_OPTIONS) \
                 $(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
                 -sourcepath $(PRIVATE_SOURCE_PATH)$(addprefix :,$(PRIVATE_CLASSPATH)) \
diff --git a/core/java.mk b/core/java.mk
index 9254dd8..e4dc629 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -29,7 +29,7 @@
   endif
 else
   ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-    LOCAL_JAVA_LIBRARIES := core ext framework $(LOCAL_JAVA_LIBRARIES)
+    LOCAL_JAVA_LIBRARIES := core core-junit ext framework $(LOCAL_JAVA_LIBRARIES)
   endif
 endif
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
diff --git a/core/main.mk b/core/main.mk
index af43a6b..8dcfdb8 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -686,6 +686,8 @@
   $(call dist-for-goals, droid, $(EMMA_META_ZIP))
 endif
 
+# Dist for droid if droid is among the cmd goals, or no cmd goal is given.
+ifneq ($(filter droid,$(MAKECMDGOALS))$(filter ||,|$(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS))|),)
 ifneq ($(TARGET_BUILD_APPS),)
   # If this build is just for apps, only build apps and not the full system by default.
 
@@ -736,7 +738,8 @@
 # Building a full system-- the default is to build droidcore
 droid: droidcore
 
-endif
+endif # TARGET_BUILD_APPS
+endif # droid in $(MAKECMDGOALS)
 
 
 .PHONY: droid tests
@@ -748,10 +751,26 @@
 .PHONY: sdk
 ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
 sdk: $(ALL_SDK_TARGETS)
+ifneq ($(filter sdk,$(MAKECMDGOALS)),)
 $(call dist-for-goals,sdk, \
 	$(ALL_SDK_TARGETS) \
 	$(SYMBOLS_ZIP) \
  )
+endif
+
+.PHONY: samplecode
+sample_MODULES := $(sort $(call get-tagged-modules,samples))
+sample_APKS_DEST_PATH := $(TARGET_COMMON_OUT_ROOT)/samples
+sample_APKS_COLLECTION := \
+        $(foreach module,$(sample_MODULES),$(sample_APKS_DEST_PATH)/$(notdir $(module)))
+$(foreach module,$(sample_MODULES),$(eval $(call \
+        copy-one-file,$(module),$(sample_APKS_DEST_PATH)/$(notdir $(module)))))
+sample_ADDITIONAL_INSTALLED := \
+        $(filter-out $(modules_to_install) $(modules_to_check) $(ALL_PREBUILT),$(sample_MODULES))
+samplecode: $(sample_APKS_COLLECTION)
+	@echo "Collect sample code apks: $^"
+	# remove apks that are not intended to be installed.
+	rm -f $(sample_ADDITIONAL_INSTALLED)
 
 .PHONY: findbugs
 findbugs: $(INTERNAL_FINDBUGS_HTML_TARGET) $(INTERNAL_FINDBUGS_XML_TARGET)
diff --git a/core/package.mk b/core/package.mk
index cdeefb4..bffda93 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -278,6 +278,16 @@
       $(addsuffix $(so_suffix), \
         $(LOCAL_JNI_SHARED_LIBRARIES)))
 
+# Set the abi directory used by the local JNI shared libraries.
+# (Doesn't change how the local shared libraries are compiled, just
+# sets where they are stored in the apk.)
+
+ifeq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI),)
+    jni_shared_libraries_abi := $(TARGET_CPU_ABI)
+else
+    jni_shared_libraries_abi := $(LOCAL_JNI_SHARED_LIBRARIES_ABI)
+endif
+
 # Pick a key to sign the package with.  If this package hasn't specified
 # an explicit certificate, use the default.
 # Secure release builds will have their packages signed after the fact,
@@ -311,6 +321,7 @@
 # Define the rule to build the actual package.
 $(LOCAL_BUILT_MODULE): $(AAPT) | $(ZIPALIGN)
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abi)
 ifneq ($(TARGET_BUILD_APPS),)
     # Include all resources for unbundled apps.
     $(LOCAL_BUILT_MODULE): PRODUCT_AAPT_CONFIG :=
diff --git a/core/pathmap.mk b/core/pathmap.mk
index 70441b7..b97e622 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -88,6 +88,7 @@
 	    wifi \
 	    vpn \
 	    keystore \
+	    icu4j \
 	 )
 
 #
diff --git a/core/prelink-linux-arm.map b/core/prelink-linux-arm.map
index 69a605c..673e5fc 100644
--- a/core/prelink-linux-arm.map
+++ b/core/prelink-linux-arm.map
@@ -207,3 +207,5 @@
 libzxing.so             0x9D000000 # [<64K] for goggles
 libinterstitial.so      0x9CF00000 # [<64K] for goggles
 liblept.so              0x9CA00000 # [~5M] for external/leptonica
+libbcc.so               0x9C600000 # [~4M] for external/llvm
+libchromium_net.so      0x9C400000 # [~2M] for exteral/webkit
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index 917c5dc..46c168b 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -28,26 +28,13 @@
 junit_host_jar := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
 HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
 
-CTS_CORE_CASE_LIST := android.core.tests.annotation \
-	android.core.tests.archive \
-	android.core.tests.concurrent \
-	android.core.tests.crypto \
+CTS_CORE_CASE_LIST := \
 	android.core.tests.dom \
-	android.core.tests.logging \
 	android.core.tests.luni.io \
 	android.core.tests.luni.lang \
 	android.core.tests.luni.net \
 	android.core.tests.luni.util \
-	android.core.tests.math \
-	android.core.tests.nio \
-	android.core.tests.nio_char \
-	android.core.tests.prefs \
-	android.core.tests.regex \
-	android.core.tests.security \
-	android.core.tests.sql \
-	android.core.tests.text \
 	android.core.tests.xml \
-	android.core.tests.xnet \
 	android.core.tests.runner
 
 CTS_SECURITY_APPS_LIST := \
@@ -65,11 +52,13 @@
 CTS_CASE_LIST := \
 	TestDeviceSetup \
 	CtsTestStubs \
+	CtsAccessibilityServiceTestCases \
 	CtsAccountManagerTestCases \
 	CtsAppTestCases \
 	CtsBluetoothTestCases \
 	CtsContentTestCases \
 	CtsDatabaseTestCases \
+	CtsDelegatingAccessibilityService \
 	CtsDpiTestCases \
 	CtsDpiTestCases2 \
 	CtsExampleTestCases \
@@ -102,7 +91,7 @@
 	$(CTS_CORE_CASE_LIST) \
 	$(CTS_SECURITY_APPS_LIST)
 
-DEFAULT_TEST_PLAN := $(PRIVATE_DIR)/resource/plans
+DEFAULT_TEST_PLAN := $(cts_dir)/$(cts_name)/resource/plans
 
 $(cts_dir)/all_cts_files_stamp: PRIVATE_JUNIT_HOST_JAR := $(junit_host_jar)
 
@@ -144,8 +133,13 @@
 endef
 
 CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core,,COMMON)
+JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
+RUNNER_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junitrunner,,COMMON)
+SUPPORT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests-support,,COMMON)
+DOM_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests-dom,,COMMON)
+XML_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests-xml,,COMMON)
 TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
-GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(CORE_INTERMEDIATES)/javalib.jar:$(TESTS_INTERMEDIATES)/javalib.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(RUNNER_INTERMEDIATES)/classes.jar:$(SUPPORT_INTERMEDIATES)/classes.jar:$(DOM_INTERMEDIATES)/classes.jar:$(XML_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(CORE_INTERMEDIATES)/javalib.jar:$(JUNIT_INTERMEDIATES)/javalib.jar:$(RUNNER_INTERMEDIATES)/javalib.jar:$(SUPPORT_INTERMEDIATES)/javalib.jar:$(DOM_INTERMEDIATES)/javalib.jar:$(XML_INTERMEDIATES)/javalib.jar:$(TESTS_INTERMEDIATES)/javalib.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
 
 $(cts_dir)/all_cts_core_files_stamp: PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 $(cts_dir)/all_cts_core_files_stamp: PRIVATE_JAVAOPTS:=-Xmx256M
@@ -156,25 +150,10 @@
 # build system requires that dependencies use javalib.jar.  If
 # javalib.jar is up-to-date, then classes.jar is as well.  Depending
 # on classes.jar will build the files incorrectly.
-$(cts_dir)/all_cts_core_files_stamp: $(CTS_CORE_CASE_LIST) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.annotation,\
-		cts/tests/core/annotation/AndroidManifest.xml,\
-		tests.annotation.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.archive,\
-		cts/tests/core/archive/AndroidManifest.xml,\
-		tests.archive.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.concurrent,\
-		cts/tests/core/concurrent/AndroidManifest.xml,\
-		tests.concurrent.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.crypto,\
-		cts/tests/core/crypto/AndroidManifest.xml,\
-		tests.crypto.AllTests)
+$(cts_dir)/all_cts_core_files_stamp: $(CTS_CORE_CASE_LIST) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(RUNNER_INTERMEDIATES)/javalib.jar $(SUPPORT_INTERMEDIATES)/javalib.jar $(DOM_INTERMEDIATES)/javalib.jar $(XML_INTERMEDIATES)/javalib.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.dom,\
 		cts/tests/core/dom/AndroidManifest.xml,\
 		tests.dom.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.logging,\
-		cts/tests/core/logging/AndroidManifest.xml,\
-		tests.logging.AllTests)
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.luni.io,\
 		cts/tests/core/luni-io/AndroidManifest.xml,\
 		tests.luni.AllTestsIo)
@@ -187,36 +166,9 @@
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.luni.util,\
 		cts/tests/core/luni-util/AndroidManifest.xml,\
 		tests.luni.AllTestsUtil)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.math,\
-		cts/tests/core/math/AndroidManifest.xml,\
-		tests.math.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.nio,\
-		cts/tests/core/nio/AndroidManifest.xml,\
-		tests.nio.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.nio_char,\
-		cts/tests/core/nio_char/AndroidManifest.xml,\
-		tests.nio_char.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.prefs,\
-		cts/tests/core/prefs/AndroidManifest.xml,\
-		tests.prefs.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.regex,\
-		cts/tests/core/regex/AndroidManifest.xml,\
-		tests.regex.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.security,\
-		cts/tests/core/security/AndroidManifest.xml,\
-		tests.security.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.sql,\
-		cts/tests/core/sql/AndroidManifest.xml,\
-		tests.sql.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.text,\
-		cts/tests/core/text/AndroidManifest.xml,\
-		tests.text.AllTests)
 	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.xml,\
 		cts/tests/core/xml/AndroidManifest.xml,\
 		tests.xml.AllTests)
-	$(call generate-core-test-description,$(cts_dir)/$(cts_name)/repository/testcases/android.core.tests.xnet,\
-		cts/tests/core/xnet/AndroidManifest.xml,\
-		tests.xnet.AllTests)
 	$(hide) touch $@
 
 
@@ -226,17 +178,19 @@
 
 VMTESTS_INTERMEDIATES :=$(call intermediates-dir-for,EXECUTABLES,vm-tests,1,)
 # core tests only needed to get hold of junit-framework-classes
-TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
 CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core,,COMMON)
+JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
+RUNNER_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junitrunner,,COMMON)
+TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
 
-GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
+GEN_CLASSPATH := $(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(RUNNER_INTERMEDIATES)/classes.jar:$(TESTS_INTERMEDIATES)/classes.jar:$(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar:$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR)
 
 $(CORE_VM_TEST_DESC): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 $(CORE_VM_TEST_DESC): PRIVATE_PARAMS:=-Dcts.useSuppliedTestResult=true
 $(CORE_VM_TEST_DESC): PRIVATE_PARAMS+=-Dcts.useEnhancedJunit=true
 $(CORE_VM_TEST_DESC): PRIVATE_JAVAOPTS:=-Xmx256M
 # Please see big comment above on why this line depends on javalib.jar instead of classes.jar
-$(CORE_VM_TEST_DESC): vm-tests $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
+$(CORE_VM_TEST_DESC): vm-tests $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(RUNNER_INTERMEDIATES)/javalib.jar $(VMTESTS_INTERMEDIATES)/android.core.vm-tests.jar $(TESTS_INTERMEDIATES)/javalib.jar $(cts_dir)/all_cts_files_stamp | $(ACP)
 	$(call generate-core-test-description,$(CORE_VM_TEST_DESC),\
 		cts/tests/vm-tests/AndroidManifest.xml,\
 		dot.junit.AllJunitHostTests, cts/tools/vm-tests/Android.mk)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index a30b7d9..8a2c21b 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 := AOSP
+  PLATFORM_VERSION := Honeycomb
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -59,7 +59,7 @@
 ifeq "" "$(PLATFORM_VERSION_CODENAME)"
   # This is the current development code-name, if the build is not a final
   # release build.  If this is a final release build, it is simply "REL".
-  PLATFORM_VERSION_CODENAME := AOSP
+  PLATFORM_VERSION_CODENAME := Honeycomb
 endif
 
 ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
diff --git a/envsetup.sh b/envsetup.sh
index 197c4da..9d2c1b8 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -29,8 +29,8 @@
         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
         return
     fi
-    CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
-      make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-abs-$1
+    (cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
+      make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-abs-$1)
 }
 
 # Get the exact value of a build variable.
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 9a91da9..d562cf5 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -37,5 +37,6 @@
     $(LOCAL_DIR)/generic_x86.mk \
     $(LOCAL_DIR)/full.mk \
     $(LOCAL_DIR)/sdk.mk \
-    $(LOCAL_DIR)/sim.mk
+    $(LOCAL_DIR)/sim.mk \
+    $(LOCAL_DIR)/large_emu_hw.mk
 endif
diff --git a/target/product/core.mk b/target/product/core.mk
index f87ee46..becbe50 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -29,7 +29,6 @@
     Contacts \
     Home \
     HTMLViewer \
-    Phone \
     ApplicationsProvider \
     ContactsProvider \
     DownloadProvider \
diff --git a/target/product/generic.mk b/target/product/generic.mk
index 1f26a75..51e17f3 100644
--- a/target/product/generic.mk
+++ b/target/product/generic.mk
@@ -14,9 +14,11 @@
 # limitations under the License.
 #
 
-# This is a generic product that isn't specialized for a specific device.
+# This is a generic phone product that isn't specialized for a specific device.
 # It includes the base Android platform.
 
+PRODUCT_POLICY := android.policy_phone
+
 PRODUCT_PACKAGES := \
     AccountAndSyncSettings \
     CarHome \
@@ -35,6 +37,7 @@
     Mms \
     Music \
     Provision \
+    Phone \
     Protips \
     QuickSearchBox \
     Settings \
diff --git a/target/product/large_emu_hw.mk b/target/product/large_emu_hw.mk
new file mode 100644
index 0000000..6aadc23
--- /dev/null
+++ b/target/product/large_emu_hw.mk
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is a generic product for devices with large display but not specialized
+# for a specific device. It includes the base Android platform.
+
+PRODUCT_POLICY := android.policy_mid
+
+PRODUCT_PACKAGES := \
+    AccountAndSyncSettings \
+    CarHome \
+    DeskClock \
+    AlarmProvider \
+    Bluetooth \
+    Calculator \
+    Calendar \
+    Camera \
+    CertInstaller \
+    DrmProvider \
+    Email \
+    Gallery3D \
+    LatinIME \
+    Launcher2 \
+    Mms \
+    Music \
+    Provision \
+    QuickSearchBox \
+    Settings \
+    Sync \
+    Updater \
+    CalendarProvider \
+    SyncProvider
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
+
+# Overrides
+PRODUCT_BRAND := generic
+PRODUCT_DEVICE := generic
+PRODUCT_NAME := large_emu_hw
diff --git a/target/product/locales_full.mk b/target/product/locales_full.mk
new file mode 100644
index 0000000..f46caeb
--- /dev/null
+++ b/target/product/locales_full.mk
@@ -0,0 +1,5 @@
+# The locales from the ICU "-large.dat" data set.
+# See external/icu4c/stubdata.
+# This is distinct from "languages_full.mk", which contains those locales for
+# which we have translations. If you like, this file is i18n rather than l18n.
+PRODUCT_LOCALES := cs_CZ da_DA de_AT de_CH de_DE de_LI el_GR en_AU en_CA en_GB en_NZ en_SG en_US es_ES fr_CA fr_CH fr_BE fr_FR it_CH it_IT ja_JP ko_KR nb_NO nl_BE nl_NL pl_PL pt_PT ru_RU sv_SV tr_TR zh_CN zh_HK zh_TW
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index b6700b6..50e2539 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -14,6 +14,7 @@
 # limitations under the License.
 #
 
+PRODUCT_POLICY := android.policy_phone
 PRODUCT_PROPERTY_OVERRIDES :=
 
 PRODUCT_PACKAGES := \
@@ -39,6 +40,7 @@
 	sqlite3 \
 	LatinIME \
 	PinyinIME \
+	Phone \
 	OpenWnn \
 	libWnnEngDic \
 	libWnnJpnDic \
@@ -61,40 +63,13 @@
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
 
+$(call inherit-product, $(SRC_TARGET_DIR)/product/locales_full.mk)
+
 # Overrides
 PRODUCT_BRAND := generic
 PRODUCT_NAME := sdk
 PRODUCT_DEVICE := generic
-PRODUCT_LOCALES := \
-	ldpi \
-	hdpi \
-	mdpi \
-	en_US \
-	en_GB \
-	en_CA \
-	en_AU \
-	en_NZ \
-	en_SG \
-	ja_JP \
-	fr_FR \
-	fr_BE \
-	fr_CA \
-	fr_CH \
-	it_IT \
-	it_CH \
-	es_ES \
-	de_DE \
-	de_AT \
-	de_CH \
-	de_LI \
-	nl_NL \
-	nl_BE \
-	cs_CZ \
-	pl_PL \
-	zh_CN \
-	zh_TW \
-	ru_RU \
-	ko_KR
+PRODUCT_LOCALES += ldpi hdpi mdpi
 
 # include available languages for TTS in the system image
 include external/svox/pico/lang/PicoLangDeDeInSystem.mk
diff --git a/target/product/sim.mk b/target/product/sim.mk
index 51b3676..09722d6 100644
--- a/target/product/sim.mk
+++ b/target/product/sim.mk
@@ -1,6 +1,6 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/locales_full.mk)
 
 # Overrides
 PRODUCT_NAME := sim
 PRODUCT_DEVICE := sim
-PRODUCT_LOCALES := en_US
diff --git a/tools/apicheck/src/com/android/apicheck/ApiCheck.java b/tools/apicheck/src/com/android/apicheck/ApiCheck.java
index c8272dd..b2f2265 100644
--- a/tools/apicheck/src/com/android/apicheck/ApiCheck.java
+++ b/tools/apicheck/src/com/android/apicheck/ApiCheck.java
@@ -107,6 +107,7 @@
             xmlreader.parse(new InputSource(fileReader));
             ApiInfo apiInfo = handler.getApi();
             apiInfo.resolveSuperclasses();
+            apiInfo.resolveInterfaces();
             return apiInfo;
         } catch (SAXParseException e) {
             Errors.error(Errors.PARSE_ERROR,
diff --git a/tools/apicheck/src/com/android/apicheck/ApiInfo.java b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
index c237814..47b9a15 100644
--- a/tools/apicheck/src/com/android/apicheck/ApiInfo.java
+++ b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
@@ -31,14 +31,13 @@
         return mAllClasses.get(name);
     }
 
-    private void resolveInterfaces() {
+    public 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 e62a3d0..962a316 100644
--- a/tools/apicheck/src/com/android/apicheck/ClassInfo.java
+++ b/tools/apicheck/src/com/android/apicheck/ClassInfo.java
@@ -86,41 +86,35 @@
         return mIsFinal;
     }
     
-    // Find a superclass implementation of the given method.  Looking at our superclass
-    // instead of at 'this' is unusual, but it fits the point-of-call demands well.
-    public MethodInfo overriddenMethod(MethodInfo candidate) {
-        if (mSuperClass == null) {
+    // Find a superclass implementation of the given method.
+    public static MethodInfo overriddenMethod(MethodInfo candidate, ClassInfo newClassObj) {
+        if (newClassObj == null) {
             return null;
         }
-        
-        // does our immediate superclass have it?
-        ClassInfo sup = mSuperClass;
-        for (MethodInfo mi : sup.mMethods.values()) {
+        for (MethodInfo mi : newClassObj.mMethods.values()) {
             if (mi.matches(candidate)) {
                 // found it
                 return mi;
             }
         }
 
-        // no, so recurse
-        if (sup.mSuperClass != null) {
-            return mSuperClass.overriddenMethod(candidate);
-        }
-        
-        // no parent, so we just don't have it
-        return null;
+        // not found here. recursively search ancestors
+        return ClassInfo.overriddenMethod(candidate, newClassObj.mSuperClass);
     }
     
     // Find a superinterface declaration of the given method.
-    public MethodInfo interfaceMethod(MethodInfo candidate) {
-        for (ClassInfo interfaceInfo : mInterfaces) {
+    public static MethodInfo interfaceMethod(MethodInfo candidate, ClassInfo newClassObj) {
+        if (newClassObj == null) {
+            return null;
+        }
+        for (ClassInfo interfaceInfo : newClassObj.mInterfaces) {
             for (MethodInfo mi : interfaceInfo.mMethods.values()) {
                 if (mi.matches(candidate)) {
                     return mi;
                 }
             }
         }
-        return (mSuperClass != null) ? mSuperClass.interfaceMethod(candidate) : null;
+        return ClassInfo.interfaceMethod(candidate, newClassObj.mSuperClass);
     }
 
     public boolean isConsistent(ClassInfo cl) {
@@ -135,11 +129,7 @@
             consistent = false;
         }
         for (String iface : mInterfaceNames) {
-            boolean found = false;
-            for (ClassInfo c = cl; c != null && !found; c = c.mSuperClass) {
-                found = c.mInterfaceNames.contains(iface);
-            }
-            if (!found) {
+            if (!implementsInterface(cl, iface)) {
                 Errors.error(Errors.REMOVED_INTERFACE, cl.position(),
                         "Class " + qualifiedName() + " no longer implements " + iface);
             }
@@ -163,9 +153,9 @@
                  * Check our ancestry to see if there's an inherited version that still
                  * fulfills the API requirement.
                  */
-                MethodInfo mi = mInfo.containingClass().overriddenMethod(mInfo);
+                MethodInfo mi = ClassInfo.overriddenMethod(mInfo, cl);
                 if (mi == null) {
-                    mi = mInfo.containingClass().interfaceMethod(mInfo);
+                    mi = ClassInfo.interfaceMethod(mInfo, cl);
                 }
                 if (mi == null) {
                     Errors.error(Errors.REMOVED_METHOD, mInfo.position(),
@@ -179,7 +169,7 @@
                 /* Similarly to the above, do not fail if this "new" method is
                  * really an override of an existing superclass method.
                  */
-                MethodInfo mi = mInfo.containingClass().overriddenMethod(mInfo);
+                MethodInfo mi = ClassInfo.overriddenMethod(mInfo, cl);
                 if (mi == null) {
                     Errors.error(Errors.ADDED_METHOD, mInfo.position(),
                             "Added public method " + mInfo.qualifiedName());
@@ -274,6 +264,26 @@
         return consistent;
     }
 
+    /**
+     * Returns true if {@code cl} implements the interface {@code iface} either
+     * by either being that interface, implementing that interface or extending
+     * a type that implements the interface.
+     */
+    private boolean implementsInterface(ClassInfo cl, String iface) {
+        if (cl.qualifiedName().equals(iface)) {
+            return true;
+        }
+        for (ClassInfo clImplements : cl.mInterfaces) {
+            if (implementsInterface(clImplements, iface)) {
+                return true;
+            }
+        }
+        if (cl.mSuperClass != null && implementsInterface(cl.mSuperClass, iface)) {
+            return true;
+        }
+        return false;
+    }
+
     public void resolveInterfaces(ApiInfo apiInfo) {
         for (String interfaceName : mInterfaceNames) {
             mInterfaces.add(apiInfo.findClass(interfaceName));
diff --git a/tools/droiddoc/src/Stubs.java b/tools/droiddoc/src/Stubs.java
index e1ec76a..b988ef5 100644
--- a/tools/droiddoc/src/Stubs.java
+++ b/tools/droiddoc/src/Stubs.java
@@ -315,6 +315,12 @@
             return;
         }
 
+        // Work around the bogus "Array" class we invent for
+        // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505)
+        if (cl.containingPackage() != null && cl.containingPackage().name().equals("")) {
+            return;
+        }
+
         String filename = stubsDir + '/' + javaFileName(cl);
         File file = new File(filename);
         ClearPage.ensureDirectory(file);
@@ -788,6 +794,11 @@
                                 HashSet notStrippable) {
         ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]);
         Arrays.sort(classes, ClassInfo.comparator);
+        // Work around the bogus "Array" class we invent for
+        // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505)
+        if (pack.name().equals("")) {
+            return;
+        }
         xmlWriter.println("<package name=\"" + pack.name() + "\"\n"
                 //+ " source=\"" + pack.position() + "\"\n"
                 + ">");
diff --git a/tools/droiddoc/templates-pdk/customization.cs b/tools/droiddoc/templates-pdk/customization.cs
index 3e9be06..d075bda 100644
--- a/tools/droiddoc/templates-pdk/customization.cs
+++ b/tools/droiddoc/templates-pdk/customization.cs
@@ -11,7 +11,6 @@
                       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>
@@ -23,8 +22,6 @@
                                   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>
-              <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> 
@@ -102,21 +99,6 @@
   </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">
@@ -140,8 +122,6 @@
       <?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" ?>
@@ -150,33 +130,20 @@
   <?cs /if ?>
 <?cs /def ?>
 
-<?cs # appears at the bottom of every page ?><?cs 
-def:custom_cc_copyright() ?>
-  Except as noted, this content is 
-  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
-  Creative Commons Attribution 2.5</a>. For details and 
-  restrictions, see the <a href="http://developer.android.com/license.html">Content 
-  License</a>.<?cs 
-/def ?>
+<?cs def:custom_cc_copyright() ?>
+<?cs /def ?>
 
-<?cs 
-def:custom_copyright() ?>
-  Except as noted, this content is licensed under <a
-  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
-  For details and restrictions, see the <a href="http://developer.android.com/license.html">
-  Content License</a>.<?cs 
-/def ?>
+<?cs def:custom_copyright() ?>
+<?cs /def ?>
 
 <?cs 
 def:custom_footerlinks() ?>
   <p>
     <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
-    <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
-    <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+    <a href="http://www.android.com/privacy.html">Privacy Policy</a>
   </p><?cs 
 /def ?>
 
-<?cs # appears on the right side of the blue bar at the bottom off every page ?><?cs 
-def:custom_buildinfo() ?>
-  Android <?cs var:sdk.platform.version ?>&nbsp;r<?cs var:sdk.rel.id ?> - <?cs var:page.now ?>
+<?cs # appears on the right side of the blue bar at the bottom off every page ?>
+<?cs def:custom_buildinfo() ?>
 <?cs /def ?>
diff --git a/tools/droiddoc/templates-pdk/head_tag.cs b/tools/droiddoc/templates-pdk/head_tag.cs
index 915dc0e..cccbb14 100644
--- a/tools/droiddoc/templates-pdk/head_tag.cs
+++ b/tools/droiddoc/templates-pdk/head_tag.cs
@@ -1,6 +1,6 @@
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>assets-pdk/favicon.ico" />
+<link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>assets/favicon.ico" />
 <title><?cs 
   if:page.title ?><?cs 
     var:page.title ?><?cs
@@ -9,7 +9,7 @@
     /if ?> | <?cs
   /if ?>Android Open Source</title>
 <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" />
+<!-- <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 ?>assets/jquery-resizable.min.js" type="text/javascript"></script>
 <script src="<?cs var:toroot ?>assets/android-developer-docs.js" type="text/javascript"></script>
@@ -28,7 +28,7 @@
 	}
 }
 </script>
-<script type="text/javascript>
+<script type="text/javascript">
   jQuery(document).ready(function() {
         jQuery("pre").addClass("prettyprint");
   });
diff --git a/tools/droiddoc/templates/assets/android-developer-docs.js b/tools/droiddoc/templates/assets/android-developer-docs.js
index 4c59dd6..d61ce72 100644
--- a/tools/droiddoc/templates/assets/android-developer-docs.js
+++ b/tools/droiddoc/templates/assets/android-developer-docs.js
@@ -27,10 +27,10 @@
 
 var agent = navigator['userAgent'].toLowerCase();
 // If a mobile phone, set flag and do mobile setup
-if ((agent.indexOf("mobile") != -1) ||      // android, iphone, ipod 
+if ((agent.indexOf("mobile") != -1) ||      // android, iphone, ipod
     (agent.indexOf("blackberry") != -1) ||
     (agent.indexOf("webos") != -1) ||
-    (agent.indexOf("mini") != -1)) {        // opera mini browsers 
+    (agent.indexOf("mini") != -1)) {        // opera mini browsers
   isMobile = true;
   addLoadEvent(mobileSetup);
 // If not a mobile browser, set the onresize event for IE6, and others
@@ -126,7 +126,7 @@
     expiration = date.toGMTString();
   }
   document.cookie = cookie_namespace + section + cookie + "=" + val + "; expires=" + expiration+"; path=/";
-} 
+}
 
 function init() {
   $("#side-nav").css({position:"absolute",left:0});
@@ -162,11 +162,84 @@
     }
   }
 
-  if (devdocNav.length) { // only dev guide and sdk 
-    highlightNav(location.href); 
+  if (devdocNav.length) { // only dev guide, resources, and sdk
+    tryPopulateResourcesNav();
+    highlightNav(location.href);
   }
 }
 
+function tryPopulateResourcesNav() {
+  var sampleList = $('#devdoc-nav-sample-list');
+  var articleList = $('#devdoc-nav-article-list');
+  var tutorialList = $('#devdoc-nav-tutorial-list');
+  var topicList = $('#devdoc-nav-topic-list');
+
+  if (!topicList.length || !ANDROID_TAGS || !ANDROID_RESOURCES)
+    return;
+
+  var topics = [];
+  for (var topic in ANDROID_TAGS['topic']) {
+    topics.push({name:topic,title:ANDROID_TAGS['topic'][topic]});
+  }
+  topics.sort(function(x,y){ return (x.title < y.title) ? -1 : 1; });
+  for (var i = 0; i < topics.length; i++) {
+    topicList.append(
+        $('<li>').append(
+          $('<a>')
+            .attr('href', toRoot + "resources/browser.html?tag=" + topics[i].name)
+            .append($('<span>')
+              .addClass('en')
+              .html(topics[i].title)
+            )
+          )
+        );
+  }
+
+  var _renderResourceList = function(tag, listNode) {
+    var resources = [];
+    var tags;
+    var resource;
+    var i, j;
+    for (i = 0; i < ANDROID_RESOURCES.length; i++) {
+      resource = ANDROID_RESOURCES[i];
+      tags = resource.tags || [];
+      var hasTag = false;
+      for (j = 0; j < tags.length; j++)
+        if (tags[j] == tag) {
+          hasTag = true;
+          break;
+        }
+      if (!hasTag)
+        continue;
+      resources.push(resource);
+    }
+    //resources.sort(function(x,y){ return (x.title.en < y.title.en) ? -1 : 1; });
+    for (i = 0; i < resources.length; i++) {
+      resource = resources[i];
+      var listItemNode = $('<li>').append(
+          $('<a>')
+            .attr('href', toRoot + "resources/" + resource.path)
+            .append($('<span>')
+              .addClass('en')
+              .html(resource.title.en)
+            )
+          );
+      tags = resource.tags || [];
+      for (j = 0; j < tags.length; j++) {
+        if (tags[j] == 'new') {
+          listItemNode.get(0).innerHTML += '&nbsp;<span class="new">new!</span>';
+          break;
+        }
+      }
+      listNode.append(listItemNode);
+    }
+  };
+
+  _renderResourceList('sample', sampleList);
+  _renderResourceList('article', articleList);
+  _renderResourceList('tutorial', tutorialList);
+}
+
 function highlightNav(fullPageName) {
   var lastSlashPos = fullPageName.lastIndexOf("/");
   var firstSlashPos;
@@ -180,17 +253,23 @@
   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);
+  // First check if the exact URL, with query string and all, is in the navigation menu
+  var pathPageName = fullPageName.substr(firstSlashPos);
   var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
-  if ((link.length == 0) && ((fullPageName.indexOf("/guide/") != -1) || (fullPageName.indexOf("/resources/") != -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;
+  if (link.length == 0) {
+    var htmlPos = fullPageName.lastIndexOf(".html", fullPageName.length);
+    pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5); // +5 advances past ".html"
+    link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
+    if ((link.length == 0) && ((fullPageName.indexOf("/guide/") != -1) || (fullPageName.indexOf("/resources/") != -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 and resources)
+      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;
+      }
     }
   }
 
@@ -436,12 +515,12 @@
 
 function changeTabLang(lang) {
   var nodes = $("#header-tabs").find("."+lang);
-  for (i=0; i < nodes.length; i++) { // for each node in this language 
+  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.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 
+    } else { //otherwise, show English instead
       node.css("display","none");
       node.siblings().filter(".en").css("display","inline");
     }
@@ -450,12 +529,12 @@
 
 function changeNavLang(lang) {
   var nodes = $("#side-nav").find("."+lang);
-  for (i=0; i < nodes.length; i++) { // for each node in this language 
+  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.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 
+    } else { // otherwise, show English instead
       node.css("display","none");
       node.siblings().filter(".en").css("display","inline");
     }
diff --git a/tools/droiddoc/templates/assets/android-developer-resource-browser.css b/tools/droiddoc/templates/assets/android-developer-resource-browser.css
new file mode 100644
index 0000000..a454caa
--- /dev/null
+++ b/tools/droiddoc/templates/assets/android-developer-resource-browser.css
@@ -0,0 +1,31 @@
+/* Resource Browser */
+
+#resource-browser-results .no-results {
+  font-style: italic;
+  display: none;
+}
+
+#resource-browser-results .result {
+  position: relative;
+  padding-left: 84px;
+  background: transparent none no-repeat scroll 4px 12px;
+  border-bottom: 1px solid #ddd;
+}
+
+#resource-browser-results .tagged-article {
+  background-image: url(images/resource-article.png);
+}
+
+#resource-browser-results .tagged-sample {
+  background-image: url(images/resource-sample.png);
+}
+
+#resource-browser-results .tagged-tutorial {
+  background-image: url(images/resource-tutorial.png);
+}
+
+#resource-browser-results .resource-meta {
+  margin-top: -1em;
+  font-size: 0.85em;
+  font-weight: normal;
+}
diff --git a/tools/droiddoc/templates/assets/android-developer-resource-browser.js b/tools/droiddoc/templates/assets/android-developer-resource-browser.js
new file mode 100644
index 0000000..dc65aa2
--- /dev/null
+++ b/tools/droiddoc/templates/assets/android-developer-resource-browser.js
@@ -0,0 +1,235 @@
+(function() { // anonymize
+
+var allTags = {};
+var loadedResults = [];
+
+/**
+ * Initialization code run upon the DOM being ready.
+ */
+$(document).ready(function() {
+  // Parse page query parameters.
+  var params = parseParams(document.location.search);
+  params.tag = params.tag ? makeArray(params.tag) : null;
+
+  // Load tag and resource dataset.
+  loadTags();
+  loadResources();
+
+  showResults(params);
+
+  // Watch for keypresses in the keyword filter textbox, and update
+  // search results to reflect the keyword filter.
+  $('#resource-browser-keyword-filter').keyup(function() {
+    // Filter results on screen by keyword.
+    var keywords = $(this).val().split(/\s+/g);
+    for (var i = 0; i < loadedResults.length; i++) {
+      var hide = false;
+      for (var j = 0; j < keywords.length; j++) {
+        if (!resultMatchesKeyword(loadedResults[i].result, keywords[j])) {
+          hide = true;
+          break;
+        }
+      }
+
+      loadedResults[i].node[hide ? 'hide' : 'show']();
+    }
+  });
+});
+
+/**
+ * Returns whether or not the given search result contains the given keyword.
+ */
+function resultMatchesKeyword(result, keyword) {
+  keyword = keyword.toLowerCase();
+  if (result.title &&
+      result.title.en.toLowerCase().indexOf(keyword) >= 0)
+    return true;
+  else if (result.description &&
+           result.description.en.toLowerCase().indexOf(keyword) >= 0)
+    return true;
+  else if (result.topicsHtml &&
+           result.topicsHtml.replace(/\<.*?\>/g,'').toLowerCase().indexOf(keyword) >= 0)
+    return true;
+  return false;
+}
+
+/**
+ * Populates the allTags array with tag data from the ANDROID_TAGS
+ * variable in the resource data JS file.
+ */
+function loadTags() {
+  for (var tagClass in ANDROID_TAGS) {
+    for (var tag in ANDROID_TAGS[tagClass]) {
+      allTags[tag] = {
+        displayTag: ANDROID_TAGS[tagClass][tag],
+        tagClass: tagClass
+      };
+    }
+  }
+}
+
+/**
+ * Massage the ANDROID_RESOURCES resource list in the resource data JS file.
+ */
+function loadResources() {
+  for (var i = 0; i < ANDROID_RESOURCES.length; i++) {
+    var resource = ANDROID_RESOURCES[i];
+
+    // Convert the tags array to a tags hash for easier querying.
+    resource.tagsHash = {};
+    for (var j = 0; j < resource.tags.length; j++)
+      resource.tagsHash[resource.tags[j]] = true;
+
+    // Determine the type and topics of the resource by inspecting its tags.
+    resource.topics = [];
+    for (tag in resource.tagsHash)
+      if (tag in allTags) {
+        if (allTags[tag].tagClass == 'type') {
+          resource.type = tag;
+        } else if (allTags[tag].tagClass == 'topic') {
+          resource.topics.push(tag);
+        }
+      }
+
+    // Add a humanized topics list string.
+    resource.topicsHtml = humanizeList(resource.topics, function(item) {
+      return '<strong>' + allTags[item].displayTag + '</strong>';
+    });
+  }
+}
+
+/**
+ * Loads resources for the given query parameters.
+ */
+function showResults(params) {
+  loadedResults = [];
+  $('#resource-browser-search-params').empty();
+  $('#resource-browser-results').empty();
+
+  var i, j;
+  var searchTags = [];
+  if (params.tag) {
+    for (i = 0; i < params.tag.length; i++) {
+      var tag = params.tag[i];
+      if (tag.toLowerCase() in allTags) {
+        searchTags.push(tag.toLowerCase());
+      }
+    }
+  }
+
+  if (searchTags.length) {
+    // Show query params.
+    var taggedWithHtml = ['Showing technical resources tagged with '];
+    taggedWithHtml.push(humanizeList(searchTags, function(item) {
+      return '<strong>' + allTags[item].displayTag + '</strong>';
+    }));
+    $('#resource-browser-search-params').html(taggedWithHtml.join('') + ':');
+  } else {
+    $('#resource-browser-search-params').html('Showing all technical resources:');
+  }
+
+  var results = [];
+
+  // Create the list of resources to show.
+  for (i = 0; i < ANDROID_RESOURCES.length; i++) {
+    var resource = ANDROID_RESOURCES[i];
+    var skip = false;
+
+    if (searchTags.length) {
+      for (j = 0; j < searchTags.length; j++)
+        if (!(searchTags[j] in resource.tagsHash)) {
+          skip = true;
+          break;
+        }
+
+      if (skip)
+        continue;
+
+      results.push(resource);
+      continue;
+    }
+
+    results.push(resource);
+  }
+
+  // Format and show the list of resource results.
+  if (results.length) {
+    $('#resource-browser-results .no-results').hide();
+    for (i = 0; i < results.length; i++) {
+      var result = results[i];
+      var resultJqNode = $(tmpl('tmpl_resource_browser_result', result));
+      for (tag in result.tagsHash)
+        resultJqNode.addClass('tagged-' + tag);
+      $('#resource-browser-results').append(resultJqNode);
+
+      loadedResults.push({ node: resultJqNode, result: result });
+    }
+  } else {
+    $('#resource-browser-results .no-results').show();
+  }
+}
+
+/**
+ * Formats the given array into a human readable, English string, ala
+ * 'a, b and c', with an optional item formatter/wrapper function.
+ */
+function humanizeList(arr, itemFormatter) {
+  itemFormatter = itemFormatter || function(o){ return o; };
+  arr = arr || [];
+
+  var out = [];
+  for (var i = 0; i < arr.length; i++) {
+    out.push(itemFormatter(arr[i]) +
+        ((i < arr.length - 2) ? ', ' : '') +
+        ((i == arr.length - 2) ? ' and ' : ''));
+  }
+
+  return out.join('');
+}
+
+/**
+ * Parses a parameter string, i.e. foo=1&bar=2 into
+ * a dictionary object.
+ */
+function parseParams(paramStr) {
+  var params = {};
+  paramStr = paramStr.replace(/^[?#]/, '');
+
+  var pairs = paramStr.split('&');
+  for (var i = 0; i < pairs.length; i++) {
+    var p = pairs[i].split('=');
+    var key = p[0] ? decodeURIComponent(p[0]) : p[0];
+    var val = p[1] ? decodeURIComponent(p[1]) : p[1];
+    if (val === '0')
+      val = 0;
+    if (val === '1')
+      val = 1;
+
+    if (key in params) {
+      // Handle array values.
+      params[key] = makeArray(params[key]);
+      params[key].push(val);
+    } else {
+      params[key] = val;
+    }
+  }
+
+  return params;
+}
+
+/**
+ * Returns the argument as a single-element array, or the argument itself
+ * if it's already an array.
+ */
+function makeArray(o) {
+  if (!o)
+    return [];
+
+  if (typeof o === 'object' && 'splice' in o) {
+    return o;
+  } else {
+    return [o];
+  }
+}
+
+})();
diff --git a/tools/droiddoc/templates/assets/images/resource-article.png b/tools/droiddoc/templates/assets/images/resource-article.png
new file mode 100644
index 0000000..416493f
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-article.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-big-article.png b/tools/droiddoc/templates/assets/images/resource-big-article.png
new file mode 100644
index 0000000..7273275
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-big-article.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-big-sample.png b/tools/droiddoc/templates/assets/images/resource-big-sample.png
new file mode 100644
index 0000000..59b6b68
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-big-sample.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-big-tutorial.png b/tools/droiddoc/templates/assets/images/resource-big-tutorial.png
new file mode 100644
index 0000000..c32e89a
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-big-tutorial.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-big-video.png b/tools/droiddoc/templates/assets/images/resource-big-video.png
new file mode 100644
index 0000000..59d46a0
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-big-video.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-sample.png b/tools/droiddoc/templates/assets/images/resource-sample.png
new file mode 100644
index 0000000..f7a411c
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-sample.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-tutorial.png b/tools/droiddoc/templates/assets/images/resource-tutorial.png
new file mode 100644
index 0000000..10a14fe
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-tutorial.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/images/resource-video.png b/tools/droiddoc/templates/assets/images/resource-video.png
new file mode 100644
index 0000000..8fd5cae
--- /dev/null
+++ b/tools/droiddoc/templates/assets/images/resource-video.png
Binary files differ
diff --git a/tools/droiddoc/templates/assets/microtemplate.js b/tools/droiddoc/templates/assets/microtemplate.js
new file mode 100644
index 0000000..ada1235
--- /dev/null
+++ b/tools/droiddoc/templates/assets/microtemplate.js
@@ -0,0 +1,35 @@
+// Simple JavaScript Templating
+// John Resig - http://ejohn.org/ - MIT Licensed
+(function(){
+  var cache = {};
+
+  this.tmpl = function tmpl(str, data){
+    // Figure out if we're getting a template, or if we need to
+    // load the template - and be sure to cache the result.
+    var fn = !/\W/.test(str) ?
+      cache[str] = cache[str] ||
+        tmpl(document.getElementById(str).innerHTML) :
+
+      // Generate a reusable function that will serve as a template
+      // generator (and which will be cached).
+      new Function("obj",
+        "var p=[],print=function(){p.push.apply(p,arguments);};" +
+
+        // Introduce the data as local variables using with(){}
+        "with(obj){p.push('" +
+
+        // Convert the template into pure JavaScript
+        str
+          .replace(/[\r\t\n]/g, " ")
+          .split("<%").join("\t")
+          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
+          .replace(/\t=(.*?)%>/g, "',$1,'")
+          .split("\t").join("');")
+          .split("%>").join("p.push('")
+          .split("\r").join("\\'")
+      + "');}return p.join('');");
+
+    // Provide some basic currying to the user
+    return data ? fn( data ) : fn;
+  };
+})();
\ No newline at end of file
diff --git a/tools/droiddoc/templates/head_tag.cs b/tools/droiddoc/templates/head_tag.cs
index 5a7fd40..b418e1e 100644
--- a/tools/droiddoc/templates/head_tag.cs
+++ b/tools/droiddoc/templates/head_tag.cs
@@ -20,6 +20,9 @@
 if:reference ?>
 <script src="<?cs var:toroot ?>assets/android-developer-reference.js" type="text/javascript"></script>
 <script src="<?cs var:toroot ?>navtree_data.js" type="text/javascript"></script><?cs 
+/if ?><?cs 
+if:resources ?>
+<script src="<?cs var:toroot ?>resources/resources-data.js" type="text/javascript"></script><?cs 
 /if ?>
 <noscript>
   <style type="text/css">
diff --git a/tools/releasetools/amend_generator.py b/tools/releasetools/amend_generator.py
deleted file mode 100644
index b543bf7..0000000
--- a/tools/releasetools/amend_generator.py
+++ /dev/null
@@ -1,222 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-
-import common
-
-class AmendGenerator(object):
-  """Class to generate scripts in the 'amend' recovery script language
-  used up through cupcake."""
-
-  def __init__(self):
-    self.script = ['assert compatible_with("0.2") == "true"']
-    self.included_files = set()
-
-  def MakeTemporary(self):
-    """Make a temporary script object whose commands can latter be
-    appended to the parent script with AppendScript().  Used when the
-    caller wants to generate script commands out-of-order."""
-    x = AmendGenerator()
-    x.script = []
-    x.included_files = self.included_files
-    return x
-
-  @staticmethod
-  def _FileRoot(fn):
-    """Convert a file path to the 'root' notation used by amend."""
-    if fn.startswith("/system/"):
-      return "SYSTEM:" + fn[8:]
-    elif fn == "/system":
-      return "SYSTEM:"
-    elif fn.startswith("/tmp/"):
-      return "CACHE:.." + fn
-    else:
-      raise ValueError("don't know root for \"%s\"" % (fn,))
-
-  @staticmethod
-  def _PartitionRoot(partition):
-    """Convert a partition name to the 'root' notation used by amend."""
-    if partition == "userdata":
-      return "DATA:"
-    else:
-      return partition.upper() + ":"
-
-  def AppendScript(self, other):
-    """Append the contents of another script (which should be created
-    with temporary=True) to this one."""
-    self.script.extend(other.script)
-    self.included_files.update(other.included_files)
-
-  def AssertSomeFingerprint(self, *fp):
-    """Assert that the current fingerprint is one of *fp."""
-    x = [('file_contains("SYSTEM:build.prop", '
-          '"ro.build.fingerprint=%s") == "true"') % i for i in fp]
-    self.script.append("assert %s" % (" || ".join(x),))
-
-  def AssertOlderBuild(self, timestamp):
-    """Assert that the build on the device is older (or the same as)
-    the given timestamp."""
-    self.script.append("run_program PACKAGE:check_prereq %s" % (timestamp,))
-    self.included_files.add("check_prereq")
-
-  def AssertDevice(self, device):
-    """Assert that the device identifier is the given string."""
-    self.script.append('assert getprop("ro.product.device") == "%s" || '
-                       'getprop("ro.build.product") == "%s"' % (device, device))
-
-  def AssertSomeBootloader(self, *bootloaders):
-    """Asert that the bootloader version is one of *bootloaders."""
-    self.script.append("assert " +
-                  " || ".join(['getprop("ro.bootloader") == "%s"' % (b,)
-                               for b in bootloaders]))
-
-  def ShowProgress(self, frac, dur):
-    """Update the progress bar, advancing it over 'frac' over the next
-    'dur' seconds."""
-    self.script.append("show_progress %f %d" % (frac, int(dur)))
-
-  def SetProgress(self, frac):
-    """Not implemented in amend."""
-    pass
-
-  def PatchCheck(self, filename, *sha1):
-    """Check that the given file (or MTD reference) has one of the
-    given *sha1 hashes."""
-    out = ["run_program PACKAGE:applypatch -c %s" % (filename,)]
-    for i in sha1:
-      out.append(" " + i)
-    self.script.append("".join(out))
-    self.included_files.add(("applypatch_static", "applypatch"))
-
-  # Not quite right since we don't need to check /cache/saved.file on
-  # failure, but shouldn't hurt.
-  FileCheck = PatchCheck
-
-  def CacheFreeSpaceCheck(self, amount):
-    """Check that there's at least 'amount' space that can be made
-    available on /cache."""
-    self.script.append("run_program PACKAGE:applypatch -s %d" % (amount,))
-    self.included_files.add(("applypatch_static", "applypatch"))
-
-  def Mount(self, kind, what, path):
-    # no-op; amend uses it's 'roots' system to automatically mount
-    # things when they're referred to
-    pass
-
-  def UnpackPackageDir(self, src, dst):
-    """Unpack a given directory from the OTA package into the given
-    destination directory."""
-    dst = self._FileRoot(dst)
-    self.script.append("copy_dir PACKAGE:%s %s" % (src, dst))
-
-  def Comment(self, comment):
-    """Write a comment into the update script."""
-    self.script.append("")
-    for i in comment.split("\n"):
-      self.script.append("# " + i)
-    self.script.append("")
-
-  def Print(self, message):
-    """Log a message to the screen (if the logs are visible)."""
-    # no way to do this from amend; substitute a script comment instead
-    self.Comment(message)
-
-  def FormatPartition(self, partition):
-    """Format the given MTD partition."""
-    self.script.append("format %s" % (self._PartitionRoot(partition),))
-
-  def DeleteFiles(self, file_list):
-    """Delete all files in file_list."""
-    line = []
-    t = 0
-    for i in file_list:
-      i = self._FileRoot(i)
-      line.append(i)
-      t += len(i) + 1
-      if t > 80:
-        self.script.append("delete " + " ".join(line))
-        line = []
-        t = 0
-    if line:
-      self.script.append("delete " + " ".join(line))
-
-  def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
-    """Apply binary patches (in *patchpairs) to the given srcfile to
-    produce tgtfile (which may be "-" to indicate overwriting the
-    source file."""
-    if len(patchpairs) % 2 != 0:
-      raise ValueError("bad patches given to ApplyPatch")
-    self.script.append(
-        ("run_program PACKAGE:applypatch %s %s %s %d " %
-         (srcfile, tgtfile, tgtsha1, tgtsize)) +
-        " ".join(["%s:%s" % patchpairs[i:i+2]
-                  for i in range(0, len(patchpairs), 2)]))
-    self.included_files.add(("applypatch_static", "applypatch"))
-
-  def WriteFirmwareImage(self, kind, fn):
-    """Arrange to update the given firmware image (kind must be
-    "hboot" or "radio") when recovery finishes."""
-    self.script.append("write_%s_image PACKAGE:%s" % (kind, fn))
-
-  def WriteRawImage(self, partition, fn):
-    """Write the given file into the given MTD partition."""
-    self.script.append("write_raw_image PACKAGE:%s %s" %
-                       (fn, self._PartitionRoot(partition)))
-
-  def SetPermissions(self, fn, uid, gid, mode):
-    """Set file ownership and permissions."""
-    fn = self._FileRoot(fn)
-    self.script.append("set_perm %d %d 0%o %s" % (uid, gid, mode, fn))
-
-  def SetPermissionsRecursive(self, fn, uid, gid, dmode, fmode):
-    """Recursively set path ownership and permissions."""
-    fn = self._FileRoot(fn)
-    self.script.append("set_perm_recursive %d %d 0%o 0%o %s" %
-                       (uid, gid, dmode, fmode, fn))
-
-  def MakeSymlinks(self, symlink_list):
-    """Create symlinks, given a list of (dest, link) pairs."""
-    self.DeleteFiles([i[1] for i in symlink_list])
-    self.script.extend(["symlink %s %s" % (i[0], self._FileRoot(i[1]))
-                        for i in sorted(symlink_list)])
-
-  def AppendExtra(self, extra):
-    """Append text verbatim to the output script."""
-    self.script.append(extra)
-
-  def UnmountAll(self):
-    pass
-
-  def AddToZip(self, input_zip, output_zip, input_path=None):
-    """Write the accumulated script to the output_zip file.  input_zip
-    is used as the source for any ancillary binaries needed by the
-    script.  If input_path is not None, it will be used as a local
-    path for binaries instead of input_zip."""
-    common.ZipWriteStr(output_zip, "META-INF/com/google/android/update-script",
-                       "\n".join(self.script) + "\n")
-    for i in self.included_files:
-      if isinstance(i, tuple):
-        sourcefn, targetfn = i
-      else:
-        sourcefn = i
-        targetfn = i
-      try:
-        if input_path is None:
-          data = input_zip.read(os.path.join("OTA/bin", sourcefn))
-        else:
-          data = open(os.path.join(input_path, sourcefn)).read()
-        common.ZipWriteStr(output_zip, targetfn, data, perms=0755)
-      except (IOError, KeyError), e:
-        raise ExternalError("unable to include binary %s: %s" % (i, e))
diff --git a/tools/releasetools/both_generator.py b/tools/releasetools/both_generator.py
deleted file mode 100644
index 4ae8d50..0000000
--- a/tools/releasetools/both_generator.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import edify_generator
-import amend_generator
-
-class BothGenerator(object):
-  def __init__(self, version):
-    self.version = version
-    self.edify = edify_generator.EdifyGenerator(version)
-    self.amend = amend_generator.AmendGenerator()
-
-  def MakeTemporary(self):
-    x = BothGenerator(self.version)
-    x.edify = self.edify.MakeTemporary()
-    x.amend = self.amend.MakeTemporary()
-    return x
-
-  def AppendScript(self, other):
-    self.edify.AppendScript(other.edify)
-    self.amend.AppendScript(other.amend)
-
-  def _DoBoth(self, name, *args):
-    getattr(self.edify, name)(*args)
-    getattr(self.amend, name)(*args)
-
-  def AssertSomeFingerprint(self, *a): self._DoBoth("AssertSomeFingerprint", *a)
-  def AssertOlderBuild(self, *a): self._DoBoth("AssertOlderBuild", *a)
-  def AssertDevice(self, *a): self._DoBoth("AssertDevice", *a)
-  def AssertSomeBootloader(self, *a): self._DoBoth("AssertSomeBootloader", *a)
-  def ShowProgress(self, *a): self._DoBoth("ShowProgress", *a)
-  def PatchCheck(self, *a): self._DoBoth("PatchCheck", *a)
-  def FileCheck(self, filename, *sha1): self._DoBoth("FileCheck", *a)
-  def CacheFreeSpaceCheck(self, *a): self._DoBoth("CacheFreeSpaceCheck", *a)
-  def Mount(self, *a): self._DoBoth("Mount", *a)
-  def UnpackPackageDir(self, *a): self._DoBoth("UnpackPackageDir", *a)
-  def Comment(self, *a): self._DoBoth("Comment", *a)
-  def Print(self, *a): self._DoBoth("Print", *a)
-  def FormatPartition(self, *a): self._DoBoth("FormatPartition", *a)
-  def DeleteFiles(self, *a): self._DoBoth("DeleteFiles", *a)
-  def ApplyPatch(self, *a): self._DoBoth("ApplyPatch", *a)
-  def WriteFirmwareImage(self, *a): self._DoBoth("WriteFirmwareImage", *a)
-  def WriteRawImage(self, *a): self._DoBoth("WriteRawImage", *a)
-  def SetPermissions(self, *a): self._DoBoth("SetPermissions", *a)
-  def SetPermissionsRecursive(self, *a): self._DoBoth("SetPermissionsRecursive", *a)
-  def MakeSymlinks(self, *a): self._DoBoth("MakeSymlinks", *a)
-  def AppendExtra(self, *a): self._DoBoth("AppendExtra", *a)
-  def UnmountAll(self, *a): self._DoBoth("UnmountAll", *a)
-
-  def AddToZip(self, input_zip, output_zip, input_path=None):
-    self._DoBoth("AddToZip", input_zip, output_zip, input_path)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index ab6678a..fc8a2be 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -53,9 +53,35 @@
   return subprocess.Popen(args, **kwargs)
 
 
-def LoadMaxSizes():
+def LoadInfoDict():
+  """Read and parse the META/misc_info.txt key/value pairs from the
+  input target files and return a dict."""
+
+  d = {}
+  try:
+    for line in open(os.path.join(OPTIONS.input_tmp, "META", "misc_info.txt")):
+      line = line.strip()
+      if not line or line.startswith("#"): continue
+      k, v = line.split("=", 1)
+      d[k] = v
+  except IOError, e:
+    if e.errno == errno.ENOENT:
+      # ok if misc_info.txt file doesn't exist
+      pass
+    else:
+      raise
+
+  if "fs_type" not in d: info["fs_type"] = "yaffs2"
+  if "partition_type" not in d: info["partition_type"] = "MTD"
+
+  return d
+
+
+def LoadMaxSizes(info):
   """Load the maximum allowable images sizes from the input
-  target_files size."""
+  target_files.  Uses the imagesizes.txt file if it's available
+  (pre-honeycomb target_files), or the more general info dict (which
+  must be passed in) if not."""
   OPTIONS.max_image_size = {}
   try:
     for line in open(os.path.join(OPTIONS.input_tmp, "META", "imagesizes.txt")):
@@ -66,7 +92,15 @@
       OPTIONS.max_image_size[image + ".img"] = size
   except IOError, e:
     if e.errno == errno.ENOENT:
-      pass
+      def copy(x, y):
+        if x in info: OPTIONS.max_image_size[x+".img"] = int(info[x+y])
+      copy("blocksize", "")
+      copy("boot", "_size")
+      copy("recovery", "_size")
+      copy("system", "_size")
+      copy("userdata", "_size")
+    else:
+      raise
 
 
 def BuildAndAddBootableImage(sourcedir, targetname, output_zip):
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 68b0850..3334b43 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -21,10 +21,11 @@
   """Class to generate scripts in the 'edify' recovery script language
   used from donut onwards."""
 
-  def __init__(self, version):
+  def __init__(self, version, info):
     self.script = []
     self.mounts = set()
     self.version = version
+    self.info = info
 
   def MakeTemporary(self):
     """Make a temporary script object whose commands can latter be
@@ -130,12 +131,15 @@
     available on /cache."""
     self.script.append("assert(apply_patch_space(%d));" % (amount,))
 
-  def Mount(self, kind, what, path):
+  def Mount(self, what, mount_point):
     """Mount the given 'what' at the given path.  'what' should be a
-    partition name if kind is "MTD", or a block device if kind is
-    "vfat".  No other values of 'kind' are supported."""
-    self.script.append('mount("%s", "%s", "%s");' % (kind, what, path))
-    self.mounts.add(path)
+    partition name for an MTD partition, or a block device for
+    anything else."""
+    what = self.info.get("partition_path", "") + what
+    self.script.append('mount("%s", "%s", "%s", "%s");' %
+                       (self.info["fs_type"], self.info["partition_type"],
+                        what, mount_point))
+    self.mounts.add(mount_point)
 
   def UnpackPackageDir(self, src, dst):
     """Unpack a given directory from the OTA package into the given
@@ -154,8 +158,11 @@
     self.script.append('ui_print("%s");' % (message,))
 
   def FormatPartition(self, partition):
-    """Format the given MTD partition."""
-    self.script.append('format("MTD", "%s");' % (partition,))
+    """Format the given partition."""
+    partition = self.info.get("partition_path", "") + partition
+    self.script.append('format("%s", "%s", "%s");' %
+                       (self.info["fs_type"], self.info["partition_type"],
+                        partition))
 
   def DeleteFiles(self, file_list):
     """Delete all files in file_list."""
@@ -190,12 +197,23 @@
           'write_firmware_image("PACKAGE:%s", "%s");' % (fn, kind))
 
   def WriteRawImage(self, partition, fn):
-    """Write the given package file into the given MTD partition."""
-    self.script.append(
-        ('assert(package_extract_file("%(fn)s", "/tmp/%(partition)s.img"),\n'
-         '       write_raw_image("/tmp/%(partition)s.img", "%(partition)s"),\n'
-         '       delete("/tmp/%(partition)s.img"));')
-        % {'partition': partition, 'fn': fn})
+    """Write the given package file into the given partition."""
+
+    if self.info["partition_type"] == "MTD":
+      self.script.append(
+          ('assert(package_extract_file("%(fn)s", "/tmp/%(partition)s.img"),\n'
+           '       write_raw_image("/tmp/%(partition)s.img", "%(partition)s"),\n'
+           '       delete("/tmp/%(partition)s.img"));')
+          % {'partition': partition, 'fn': fn})
+    elif self.info["partition_type"] == "EMMC":
+      self.script.append(
+          ('package_extract_file("%(fn)s", "%(dir)s%(partition)s");')
+          % {'partition': partition, 'fn': fn,
+             'dir': self.info.get("partition_path", ""),
+             })
+    else:
+      raise ValueError("don't know how to write \"%s\" partitions" %
+                       (self.info["partition_type"],))
 
   def SetPermissions(self, fn, uid, gid, mode):
     """Set file ownership and permissions."""
diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files
index d157dca..15a43cd 100755
--- a/tools/releasetools/img_from_target_files
+++ b/tools/releasetools/img_from_target_files
@@ -23,6 +23,11 @@
   -b  (--board_config)  <file>
       Deprecated.
 
+  -f  (--fs_type) <value>
+      The file system type of the user image files to be created.
+      It can be ext fs variants, such as ext2, ext3, ext4, etc.
+      Default is yaffs.
+
 """
 
 import sys
@@ -47,6 +52,10 @@
 
 OPTIONS = common.OPTIONS
 
+class UserImageOptions(object): pass
+USERIMAGE_OPTIONS = UserImageOptions()
+USERIMAGE_OPTIONS.fs_type = None
+
 
 def AddUserdata(output_zip):
   """Create an empty userdata image and store it in output_zip."""
@@ -61,9 +70,17 @@
   os.mkdir(user_dir)
   img = tempfile.NamedTemporaryFile()
 
-  p = common.Run(["mkyaffs2image", "-f", user_dir, img.name])
+  build_command = []
+  if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
+    build_command = ["mkuserimg.sh",
+                     user_dir, img.name, USERIMAGE_OPTIONS.fs_type, "userdata"]
+  else:
+    build_command = ["mkyaffs2image", "-f",
+                     user_dir, img.name]
+
+  p = common.Run(build_command);
   p.communicate()
-  assert p.returncode == 0, "mkyaffs2image of userdata.img image failed"
+  assert p.returncode == 0, "build userdata.img image failed"
 
   common.CheckSize(img.name, "userdata.img")
   output_zip.write(img.name, "userdata.img")
@@ -94,10 +111,18 @@
     if (e.errno == errno.EEXIST):
       pass
 
-  p = common.Run(["mkyaffs2image", "-f",
-                  os.path.join(OPTIONS.input_tmp, "system"), img.name])
+  build_command = []
+  if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
+    build_command = ["mkuserimg.sh",
+                     os.path.join(OPTIONS.input_tmp, "system"), img.name,
+                     USERIMAGE_OPTIONS.fs_type, "system"]
+  else:
+    build_command = ["mkyaffs2image", "-f",
+                     os.path.join(OPTIONS.input_tmp, "system"), img.name]
+
+  p = common.Run(build_command)
   p.communicate()
-  assert p.returncode == 0, "mkyaffs2image of system.img image failed"
+  assert p.returncode == 0, "build system.img image failed"
 
   img.seek(os.SEEK_SET, 0)
   data = img.read()
@@ -118,13 +143,15 @@
   def option_handler(o, a):
     if o in ("-b", "--board_config"):
       pass       # deprecated
+    elif o in ("-f", "--fs_type"):
+      USERIMAGE_OPTIONS.fs_type = a
     else:
       return False
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:",
-                             extra_long_opts=["board_config="],
+                             extra_opts="b:f:",
+                             extra_long_opts=["board_config=", "fs_type="],
                              extra_option_handler=option_handler)
 
   if len(args) != 2:
@@ -133,7 +160,8 @@
 
   OPTIONS.input_tmp = common.UnzipTemp(args[0])
 
-  common.LoadMaxSizes()
+  info = common.LoadInfoDict()
+  common.LoadMaxSizes(info)
   if not OPTIONS.max_image_size:
     print
     print "  WARNING:  Failed to load max image sizes; will not enforce"
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index 932d5b0..bb6619c 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -44,10 +44,6 @@
   -e  (--extra_script)  <file>
       Insert the contents of file at the end of the update script.
 
-  -m  (--script_mode)  <mode>
-      Specify 'amend' or 'edify' scripts, or 'auto' to pick
-      automatically (this is the default).
-
 """
 
 import sys
@@ -68,9 +64,7 @@
 import zipfile
 
 import common
-import amend_generator
 import edify_generator
-import both_generator
 
 OPTIONS = common.OPTIONS
 OPTIONS.package_key = "build/target/product/security/testkey"
@@ -81,7 +75,6 @@
 OPTIONS.wipe_user_data = False
 OPTIONS.omit_prereq = False
 OPTIONS.extra_script = None
-OPTIONS.script_mode = 'auto'
 OPTIONS.worker_threads = 3
 
 def MostPopularKey(d, default):
@@ -342,16 +335,11 @@
   return Item.Get("system/etc/install-recovery.sh", dir=False)
 
 
-def WriteFullOTAPackage(input_zip, output_zip):
-  if OPTIONS.script_mode == "auto":
-    script = both_generator.BothGenerator(2)
-  elif OPTIONS.script_mode == "amend":
-    script = amend_generator.AmendGenerator()
-  else:
-    # TODO: how to determine this?  We don't know what version it will
-    # be installed on top of.  For now, we expect the API just won't
-    # change very often.
-    script = edify_generator.EdifyGenerator(2)
+def WriteFullOTAPackage(input_zip, output_zip, info):
+  # TODO: how to determine this?  We don't know what version it will
+  # be installed on top of.  For now, we expect the API just won't
+  # change very often.
+  script = edify_generator.EdifyGenerator(3, info)
 
   metadata = {"post-build": GetBuildProp("ro.build.fingerprint", input_zip),
               "pre-device": GetBuildProp("ro.product.device", input_zip),
@@ -379,7 +367,7 @@
     script.FormatPartition("userdata")
 
   script.FormatPartition("system")
-  script.Mount("MTD", "system", "/system")
+  script.Mount("system", "/system")
   script.UnpackPackageDir("recovery", "/system")
   script.UnpackPackageDir("system", "/system")
 
@@ -583,24 +571,14 @@
       return 0
 
 
-def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
+def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip, info):
   source_version = GetRecoveryAPIVersion(source_zip)
   target_version = GetRecoveryAPIVersion(target_zip)
 
-  if OPTIONS.script_mode == 'amend':
-    script = amend_generator.AmendGenerator()
-  elif OPTIONS.script_mode == 'edify':
-    if source_version == 0:
-      print ("WARNING: generating edify script for a source that "
-             "can't install it.")
-    script = edify_generator.EdifyGenerator(source_version)
-  elif OPTIONS.script_mode == 'auto':
-    if source_version > 0:
-      script = edify_generator.EdifyGenerator(source_version)
-    else:
-      script = amend_generator.AmendGenerator()
-  else:
-    raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
+  if source_version == 0:
+    print ("WARNING: generating edify script for a source that "
+           "can't install it.")
+  script = edify_generator.EdifyGenerator(source_version, info)
 
   metadata = {"pre-device": GetBuildProp("ro.product.device", source_zip),
               "post-timestamp": GetBuildProp("ro.build.date.utc", target_zip),
@@ -661,7 +639,7 @@
   metadata["pre-build"] = source_fp
   metadata["post-build"] = target_fp
 
-  script.Mount("MTD", "system", "/system")
+  script.Mount("system", "/system")
   script.AssertSomeFingerprint(source_fp, target_fp)
 
   source_boot = File("/tmp/boot.img",
@@ -856,8 +834,6 @@
       OPTIONS.omit_prereq = True
     elif o in ("-e", "--extra_script"):
       OPTIONS.extra_script = a
-    elif o in ("-m", "--script_mode"):
-      OPTIONS.script_mode = a
     elif o in ("--worker_threads"):
       OPTIONS.worker_threads = int(a)
     else:
@@ -865,14 +841,13 @@
     return True
 
   args = common.ParseOptions(argv, __doc__,
-                             extra_opts="b:k:i:d:wne:m:",
+                             extra_opts="b:k:i:d:wne:",
                              extra_long_opts=["board_config=",
                                               "package_key=",
                                               "incremental_from=",
                                               "wipe_user_data",
                                               "no_prereq",
                                               "extra_script=",
-                                              "script_mode=",
                                               "worker_threads="],
                              extra_option_handler=option_handler)
 
@@ -880,9 +855,6 @@
     common.Usage(__doc__)
     sys.exit(1)
 
-  if OPTIONS.script_mode not in ("amend", "edify", "auto"):
-    raise ValueError('unknown script mode "%s"' % (OPTIONS.script_mode,))
-
   if OPTIONS.extra_script is not None:
     OPTIONS.extra_script = open(OPTIONS.extra_script).read()
 
@@ -906,7 +878,8 @@
       else:
         raise
 
-  common.LoadMaxSizes()
+  info = common.LoadInfoDict()
+  common.LoadMaxSizes(info)
   if not OPTIONS.max_image_size:
     print
     print "  WARNING:  Failed to load max image sizes; will not enforce"
@@ -924,12 +897,12 @@
                                  compression=zipfile.ZIP_DEFLATED)
 
   if OPTIONS.incremental_source is None:
-    WriteFullOTAPackage(input_zip, output_zip)
+    WriteFullOTAPackage(input_zip, output_zip, info)
   else:
     print "unzipping source target-files..."
     OPTIONS.source_tmp = common.UnzipTemp(OPTIONS.incremental_source)
     source_zip = zipfile.ZipFile(OPTIONS.incremental_source, "r")
-    WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
+    WriteIncrementalOTAPackage(input_zip, source_zip, output_zip, info)
 
   output_zip.close()
   if OPTIONS.package_key: