Reconcile with jb-mr1.1-release - do not merge

Change-Id: Ic2017881546bd6488432b9a87196f1c8eb6e5819
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 59b7d68..998be2a 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -152,6 +152,12 @@
 
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
+# GCC 4.7
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/lib/*.o)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index a25d80f..31a4021 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -156,7 +156,14 @@
 endef
 
 BUILDINFO_SH := build/tools/buildinfo.sh
-$(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
+
+ifdef TARGET_SYSTEM_PROP
+system_prop_file := $(TARGET_SYSTEM_PROP)
+else
+system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
+endif
+
+$(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file)
 	@echo Target buildinfo: $@
 	@mkdir -p $(dir $@)
 	$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
@@ -183,8 +190,8 @@
 			TARGET_CPU_ABI2="$(TARGET_CPU_ABI2)" \
 			TARGET_AAPT_CHARACTERISTICS="$(TARGET_AAPT_CHARACTERISTICS)" \
 	        bash $(BUILDINFO_SH) > $@
-	$(hide) if [ -f $(TARGET_DEVICE_DIR)/system.prop ]; then \
-	          cat $(TARGET_DEVICE_DIR)/system.prop >> $@; \
+	$(hide) if [ -f "$(system_prop_file)" ]; then \
+	          cat $(system_prop_file) >> $@; \
 	        fi
 	$(if $(ADDITIONAL_BUILD_PROPERTIES), \
 		$(hide) echo >> $@; \
@@ -240,6 +247,12 @@
 
 # -----------------------------------------------------------------
 # Cert-to-package mapping.  Used by the post-build signing tools.
+# Use a macro to add newline to each echo command
+define _apkcerts_echo_with_newline
+$(hide) echo $(1)
+
+endef
+
 name := $(TARGET_PRODUCT)
 ifeq ($(TARGET_BUILD_TYPE),debug)
   name := $(name)_debug
@@ -254,13 +267,15 @@
 	@echo APK certs list: $@
 	@mkdir -p $(dir $@)
 	@rm -f $@
-	$(hide) $(foreach p,$(PACKAGES),\
-          $(if $(PACKAGES.$(p).EXTERNAL_KEY),\
-	    echo 'name="$(p).apk" certificate="EXTERNAL" \
-	         private_key=""' >> $@;,\
-	    echo 'name="$(p).apk" certificate="$(PACKAGES.$(p).CERTIFICATE)" \
-	         private_key="$(PACKAGES.$(p).PRIVATE_KEY)"' >> $@;))
-	# In case $(PACKAGES) is empty.
+	$(foreach p,$(PACKAGES),\
+	  $(if $(PACKAGES.$(p).EXTERNAL_KEY),\
+	    $(call _apkcerts_echo_with_newline,\
+	      'name="$(p).apk" certificate="EXTERNAL" \
+	      private_key=""' >> $@),\
+	    $(call _apkcerts_echo_with_newline,\
+	      'name="$(p).apk" certificate="$(PACKAGES.$(p).CERTIFICATE)" \
+	      private_key="$(PACKAGES.$(p).PRIVATE_KEY)"' >> $@)))
+	# In case value of PACKAGES is empty.
 	$(hide) touch $@
 
 .PHONY: apkcerts-list
@@ -562,6 +577,9 @@
 endif
 INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
 
+SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts
+INTERNAL_USERIMAGES_DEPS += $(SELINUX_FC)
+
 # $(1): the path of the output dictionary file
 define generate-userimage-prop-dictionary
 $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1))
@@ -571,14 +589,14 @@
 $(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1))
 $(if $(mkyaffs2_extra_flags),$(hide) echo "mkyaffs2_extra_flags=$(mkyaffs2_extra_flags)" >> $(1))
-$(if $(filter true, $(strip $(HAVE_SELINUX))), echo "selinux_fc=$(TARGET_ROOT_OUT)/file_contexts" >> $(1))
+$(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)
 endef
 
 # -----------------------------------------------------------------
 # Recovery image
 
 # If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true
-ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY) $(BUILD_TINY_ANDROID)))
+ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
 
 INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
 
@@ -591,7 +609,11 @@
 recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res))
 recovery_resource_deps := $(shell find $(recovery_resources_common) \
   $(recovery_resources_private) -type f)
+ifdef TARGET_RECOVERY_FSTAB
+recovery_fstab := $(TARGET_RECOVERY_FSTAB)
+else
 recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab))
+endif
 # Named '.dat' so we don't attempt to use imgdiff for patching it.
 RECOVERY_RESOURCE_ZIP := $(TARGET_OUT)/etc/recovery-resource.dat
 
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 07ef024..5c508cd 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -434,8 +434,7 @@
 ###########################################################
 cleantarget := clean-$(LOCAL_MODULE)
 $(cleantarget) : PRIVATE_MODULE := $(LOCAL_MODULE)
-$(cleantarget) : PRIVATE_CLEAN_FILES := \
-    $(PRIVATE_CLEAN_FILES) \
+$(cleantarget) : PRIVATE_CLEAN_FILES += \
     $(LOCAL_BUILT_MODULE) \
     $(LOCAL_INSTALLED_MODULE) \
     $(intermediates)
diff --git a/core/binary.mk b/core/binary.mk
index 791623b..57c85c2 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -119,7 +119,7 @@
 endif
 
 # Add in libcompiler-rt for all regular device builds
-ifeq (,$(LOCAL_SDK_VERSION)$(LOCAL_IS_HOST_MODULE)$(BUILD_TINY_ANDROID))
+ifeq (,$(LOCAL_SDK_VERSION)$(LOCAL_IS_HOST_MODULE)$(WITHOUT_LIBCOMPILER_RT))
   LOCAL_STATIC_LIBRARIES += $(COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES)
 endif
 
diff --git a/core/build_id.mk b/core/build_id.mk
index e7287eb..e954794 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -1,4 +1,3 @@
-
 #
 # Copyright (C) 2008 The Android Open Source Project
 #
@@ -14,9 +13,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+
+#
+# Defines branch-specific values.
+#
+
 # BUILD_ID is usually used to specify the branch name
 # (like "MAIN") or a branch name and a release candidate
-# (like "CRB01").  It must be a single word, and is
+# (like "TC1-RC5").  It must be a single word, and is
 # capitalized by convention.
+#
+BUILD_ID := OPENMASTER
 
-export BUILD_ID=JDQ39B
+# DISPLAY_BUILD_NUMBER should only be set for development branches,
+# If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
+# a more descriptive BUILD_ID_DISPLAY, otherwise BUILD_ID_DISPLAY
+# is the same as BUILD_ID
+DISPLAY_BUILD_NUMBER := true
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 5d55534..dc17ecc 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -59,6 +59,7 @@
 LOCAL_INTERMEDIATE_SOURCE_DIR:=
 LOCAL_JAVACFLAGS:=
 LOCAL_JAVA_LIBRARIES:=
+LOCAL_JAVA_LAYERS_FILE:=
 LOCAL_NO_STANDARD_LIBRARIES:=
 LOCAL_CLASSPATH:=
 LOCAL_DROIDDOC_USE_STANDARD_DOCLET:=
@@ -69,6 +70,7 @@
 LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=
 LOCAL_DROIDDOC_OPTIONS:=
 LOCAL_DROIDDOC_HTML_DIR:=
+LOCAL_ADDITIONAL_HTML_DIR:=
 LOCAL_ASSET_FILES:=
 LOCAL_ASSET_DIR:=
 LOCAL_RESOURCE_DIR:=
diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
index 5b9f8f3..7361ce9 100644
--- a/core/combo/HOST_darwin-x86.mk
+++ b/core/combo/HOST_darwin-x86.mk
@@ -36,52 +36,69 @@
 
 build_mac_version := $(shell sw_vers -productVersion)
 
-ifneq ($(strip $(BUILD_MAC_SDK_EXPERIMENTAL)),)
-# SDK 10.7 and higher is not fully compatible with Android.
-mac_sdk_versions_supported :=  10.7 10.8
+mac_sdk_versions_supported :=  10.6 10.7 10.8
+ifneq ($(strip $(MAC_SDK_VERSION)),)
+mac_sdk_version := $(MAC_SDK_VERSION)
+ifeq ($(filter $(mac_sdk_version),$(mac_sdk_versions_supported)),)
+$(warning ****************************************************************)
+$(warning * MAC_SDK_VERSION $(MAC_SDK_VERSION) isn't one of the supported $(mac_sdk_versions_supported))
+$(warning ****************************************************************)
+$(error Stop.)
+endif
 else
-mac_sdk_versions_supported :=  10.6
-endif # BUILD_MAC_SDK_EXPERIMENTAL
-mac_sdk_versions_installed := $(shell xcodebuild -showsdks |grep macosx | sort | sed -e "s/.*macosx//g")
+mac_sdk_versions_installed := $(shell xcodebuild -showsdks | grep macosx | sort | sed -e "s/.*macosx//g")
 mac_sdk_version := $(firstword $(filter $(mac_sdk_versions_installed), $(mac_sdk_versions_supported)))
 ifeq ($(mac_sdk_version),)
 mac_sdk_version := $(firstword $(mac_sdk_versions_supported))
 endif
+endif
 
 mac_sdk_path := $(shell xcode-select -print-path)
-ifeq ($(findstring /Applications,$(mac_sdk_path)),)
-# Legacy Xcode
-mac_sdk_root := /Developer/SDKs/MacOSX$(mac_sdk_version).sdk
-else
-#  Xcode 4.4(App Store) or higher
-# /Applications/Xcode*.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.?.sdk
+# try /Applications/Xcode*.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.?.sdk
+#  or /Volume/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.?.sdk
 mac_sdk_root := $(mac_sdk_path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(mac_sdk_version).sdk
+ifeq ($(wildcard $(mac_sdk_root)),)
+# try legacy /Developer/SDKs/MacOSX10.?.sdk
+mac_sdk_root := /Developer/SDKs/MacOSX$(mac_sdk_version).sdk
 endif
-
 ifeq ($(wildcard $(mac_sdk_root)),)
 $(warning *****************************************************)
-$(warning * Cannot find SDK $(mac_sdk_version) at $(mac_sdk_root))
-ifeq ($(strip $(BUILD_MAC_SDK_EXPERIMENTAL)),)
-$(warning * If you wish to build using higher version of SDK, )
-$(warning * try setting BUILD_MAC_SDK_EXPERIMENTAL=1 before )
-$(warning * rerunning this command )
-endif
+$(warning * Can not find SDK $(mac_sdk_version) at $(mac_sdk_root))
 $(warning *****************************************************)
 $(error Stop.)
 endif
 
+ifeq ($(mac_sdk_version),10.6)
+  gcc_darwin_version := 10
+else
+  gcc_darwin_version := 11
+endif
+
+HOST_TOOLCHAIN_ROOT := prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1
+HOST_TOOLCHAIN_PREFIX := $(HOST_TOOLCHAIN_ROOT)/bin/i686-apple-darwin$(gcc_darwin_version)
+# Don't do anything if the toolchain is not there
+ifneq (,$(strip $(wildcard $(HOST_TOOLCHAIN_PREFIX)-gcc)))
+HOST_CC  := $(HOST_TOOLCHAIN_PREFIX)-gcc
+HOST_CXX := $(HOST_TOOLCHAIN_PREFIX)-g++
+ifeq ($(mac_sdk_version),10.8)
+# Mac SDK 10.8 no longer has stdarg.h, etc
+host_toolchain_header := $(HOST_TOOLCHAIN_ROOT)/lib/gcc/i686-apple-darwin$(gcc_darwin_version)/4.2.1/include
+HOST_GLOBAL_CFLAGS += -isystem $(host_toolchain_header)
+endif
+else
+HOST_CC := gcc
+HOST_CXX := g++
+endif # $(HOST_TOOLCHAIN_PREFIX)-gcc exists
+HOST_AR := $(AR)
+HOST_STRIP := $(STRIP)
+HOST_STRIP_COMMAND = $(HOST_STRIP) --strip-debug $< -o $@
+
 HOST_GLOBAL_CFLAGS += -isysroot $(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version) -DMACOSX_DEPLOYMENT_TARGET=$(mac_sdk_version)
 HOST_GLOBAL_LDFLAGS += -isysroot $(mac_sdk_root) -Wl,-syslibroot,$(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version)
 
 HOST_GLOBAL_CFLAGS += -fPIC -funwind-tables
 HOST_NO_UNDEFINED_LDFLAGS := -Wl,-undefined,error
 
-HOST_CC := gcc
-HOST_CXX := g++
-HOST_AR := $(AR)
-HOST_STRIP := $(STRIP)
-HOST_STRIP_COMMAND = $(HOST_STRIP) --strip-debug $< -o $@
-
 HOST_SHLIB_SUFFIX := .dylib
 HOST_JNILIB_SUFFIX := .jnilib
 
diff --git a/core/combo/HOST_linux-x86.mk b/core/combo/HOST_linux-x86.mk
index 28c8f8c..2d586a3 100644
--- a/core/combo/HOST_linux-x86.mk
+++ b/core/combo/HOST_linux-x86.mk
@@ -22,23 +22,15 @@
 stat --format "%s" "$(1)" | tr -d '\n'
 endef
 
-# Special case for the Linux SDK: We need to use a special cross-toolchain
-# that generates machine code that will run properly on Ubuntu 8.04 (Hardy)
-# By default, the code generated by the Lucid host toolchain will not run
-# on previous versions of the platform, due to GLibc ABI mistmatches
-# (Lucid is 2.11, Hardy is 2.7)
-#
-# Note that components that need to be built as 64-bit (e.g. clearsilver
-# which is loaded by the 64-bit JVM through JNI), will have to use
-# LOCAL_CC and LOCAL_CXX to override this.
-#
-HOST_SDK_TOOLCHAIN_PREFIX := prebuilts/tools/gcc-sdk
+# Previously the prebiult host toolchain is used only for the sdk build,
+# that's why we have "sdk" in the path name.
+HOST_TOOLCHAIN_PREFIX := prebuilts/tools/gcc-sdk
 # Don't do anything if the toolchain is not there
-ifneq (,$(strip $(wildcard $(HOST_SDK_TOOLCHAIN_PREFIX)/gcc)))
-HOST_CC  := $(HOST_SDK_TOOLCHAIN_PREFIX)/gcc
-HOST_CXX := $(HOST_SDK_TOOLCHAIN_PREFIX)/g++
-HOST_AR  := $(HOST_SDK_TOOLCHAIN_PREFIX)/ar
-endif # $(HOST_SDK_TOOLCHAIN_PREFIX)/gcc exists
+ifneq (,$(strip $(wildcard $(HOST_TOOLCHAIN_PREFIX)/gcc)))
+HOST_CC  := $(HOST_TOOLCHAIN_PREFIX)/gcc
+HOST_CXX := $(HOST_TOOLCHAIN_PREFIX)/g++
+HOST_AR  := $(HOST_TOOLCHAIN_PREFIX)/ar
+endif # $(HOST_TOOLCHAIN_PREFIX)/gcc exists
 
 ifneq ($(strip $(BUILD_HOST_64bit)),)
 # By default we build everything in 32-bit, because it gives us
@@ -48,7 +40,8 @@
 HOST_GLOBAL_CFLAGS += -m64
 HOST_GLOBAL_LDFLAGS += -m64
 else
-HOST_GLOBAL_CFLAGS += -m32
+# We expect SSE3 floating point math.
+HOST_GLOBAL_CFLAGS += -mstackrealign -msse3 -mfpmath=sse -m32
 HOST_GLOBAL_LDFLAGS += -m32
 endif # BUILD_HOST_64bit
 
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 854037d..cb10542 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -34,6 +34,12 @@
 TARGET_ARCH_VARIANT := armv5te
 endif
 
+ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
+TARGET_GCC_VERSION := 4.7
+else
+TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
+endif
+
 TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
 ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
 $(error Unknown ARM architecture version: $(TARGET_ARCH_VARIANT))
@@ -43,7 +49,7 @@
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-$(TARGET_GCC_VERSION)
 TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/arm-linux-androideabi-
 endif
 
@@ -71,18 +77,11 @@
                         -fstrict-aliasing    \
                         -funswitch-loops
 
-# Modules can choose to compile some source as thumb. As
-# non-thumb enabled targets are supported, this is treated
-# as a 'hint'. If thumb is not enabled, these files are just
-# compiled as ARM.
-ifeq ($(ARCH_ARM_HAVE_THUMB_SUPPORT),true)
+# Modules can choose to compile some source as thumb.
 TARGET_thumb_CFLAGS :=  -mthumb \
                         -Os \
                         -fomit-frame-pointer \
                         -fno-strict-aliasing
-else
-TARGET_thumb_CFLAGS := $(TARGET_arm_CFLAGS)
-endif
 
 # Set FORCE_ARM_DEBUGGING to "true" in your buildspec.mk
 # or in your environment to force a full arm build, even for
@@ -114,11 +113,11 @@
 TARGET_ANDROID_CONFIG_CFLAGS := -include $(android_config_h) -I $(dir $(android_config_h))
 TARGET_GLOBAL_CFLAGS += $(TARGET_ANDROID_CONFIG_CFLAGS)
 
-# This warning causes dalvik not to build with gcc 4.6.x and -Werror.
+# This warning causes dalvik not to build with gcc 4.6+ and -Werror.
 # We cannot turn it off blindly since the option is not available
 # in gcc-4.4.x.  We also want to disable sincos optimization globally
 # by turning off the builtin sin function.
-ifneq ($(filter 4.6 4.6.%, $(shell $(TARGET_CC) --version)),)
+ifneq ($(filter 4.6 4.6.% 4.7 4.7.%, $(shell $(TARGET_CC) --version)),)
 TARGET_GLOBAL_CFLAGS += -Wno-unused-but-set-variable -fno-builtin-sin \
 			-fno-strict-volatile-bitfields
 endif
@@ -141,15 +140,7 @@
 			-Wl,--icf=safe \
 			$(arch_variant_ldflags)
 
-# We only need thumb interworking in cases where thumb support
-# is available in the architecture, and just to be sure, (and
-# since sometimes thumb-interwork appears to be default), we
-# specifically disable when thumb support is unavailable.
-ifeq ($(ARCH_ARM_HAVE_THUMB_SUPPORT),true)
 TARGET_GLOBAL_CFLAGS += -mthumb-interwork
-else
-TARGET_GLOBAL_CFLAGS += -mno-thumb-interwork
-endif
 
 TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
 
@@ -242,11 +233,6 @@
 
 TARGET_CUSTOM_LD_COMMAND := true
 
-# Enable the Dalvik JIT compiler if not already specified.
-ifeq ($(strip $(WITH_JIT)),)
-    WITH_JIT := true
-endif
-
 define transform-o-to-shared-lib-inner
 $(hide) $(PRIVATE_CXX) \
 	-nostdlib -Wl,-soname,$(notdir $@) \
diff --git a/core/combo/TARGET_linux-mips.mk b/core/combo/TARGET_linux-mips.mk
index 7c7a9ef..5e67f3d 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -34,6 +34,12 @@
 TARGET_ARCH_VARIANT := mips32r2-fp
 endif
 
+ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
+TARGET_GCC_VERSION := 4.7
+else
+TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
+endif
+
 TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
 ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
 $(error Unknown MIPS architecture variant: $(TARGET_ARCH_VARIANT))
@@ -43,7 +49,7 @@
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-4.6
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-$(TARGET_GCC_VERSION)
 TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/mipsel-linux-android-
 endif
 
@@ -81,21 +87,23 @@
 TARGET_GLOBAL_CFLAGS += \
 			$(TARGET_mips_CFLAGS) \
 			-Ulinux -U__unix -U__unix__ -Umips \
-			-fpic \
+			-fpic -fPIE\
 			-ffunction-sections \
 			-fdata-sections \
 			-funwind-tables \
+			-Wa,--noexecstack \
 			-Werror=format-security \
+			-D_FORTIFY_SOURCE=1 \
 			$(arch_variant_cflags)
 
 android_config_h := $(call select-android-config-h,linux-mips)
 TARGET_ANDROID_CONFIG_CFLAGS := -include $(android_config_h) -I $(dir $(android_config_h))
 TARGET_GLOBAL_CFLAGS += $(TARGET_ANDROID_CONFIG_CFLAGS)
 
-# This warning causes dalvik not to build with gcc 4.6.x and -Werror.
+# This warning causes dalvik not to build with gcc 4.6+ and -Werror.
 # We cannot turn it off blindly since the option is not available
 # in gcc-4.4.x.
-ifneq ($(filter 4.6 4.6.%, $(shell $(TARGET_CC) --version)),)
+ifneq ($(filter 4.6 4.6.% 4.7 4.7.%, $(shell $(TARGET_CC) --version)),)
 TARGET_GLOBAL_CFLAGS += -Wno-unused-but-set-variable \
                         -fno-strict-volatile-bitfields
 endif
@@ -115,10 +123,13 @@
 endif
 
 TARGET_GLOBAL_LDFLAGS += \
+			-Wl,-z,noexecstack \
+			-Wl,-z,relro \
+			-Wl,-z,now \
+			-Wl,--warn-shared-textrel \
 			$(arch_variant_ldflags)
 
-TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden \
-				-fno-use-cxa-atexit
+TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
 
 # More flags/options can be added here
 TARGET_RELEASE_CFLAGS := \
@@ -154,7 +165,7 @@
 TARGET_FDO_LIB:=
 
 target_libgcov := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
-        --print-file-name=libgcov.a)
+        -print-file-name=libgcov.a)
 ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
   # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
   # The profile will be generated on /data/local/tmp/profile on the device.
@@ -214,16 +225,11 @@
 
 TARGET_CUSTOM_LD_COMMAND := true
 
-# Enable the Dalvik JIT compiler if not already specified.
-ifeq ($(strip $(WITH_JIT)),)
-    WITH_JIT := true
-endif
-
 define transform-o-to-shared-lib-inner
 $(hide) $(PRIVATE_CXX) \
 	-nostdlib -Wl,-soname,$(notdir $@) \
 	-Wl,--gc-sections \
-	-shared -Bsymbolic \
+	-Wl,-shared,-Bsymbolic \
 	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
 	$(PRIVATE_ALL_OBJECTS) \
@@ -243,7 +249,7 @@
 endef
 
 define transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic \
+$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -fPIE -pie \
 	-Wl,-dynamic-linker,/system/bin/linker \
 	-Wl,--gc-sections \
 	-Wl,-z,nocopyreloc \
@@ -253,6 +259,9 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
 	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
@@ -272,6 +281,9 @@
 	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_LDFLAGS) \
 	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
 	$(call normalize-target-libraries,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
 	-Wl,--start-group \
 	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
index 0e7c17d..9424f81 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -22,6 +22,12 @@
 TARGET_ARCH_VARIANT := x86
 endif
 
+ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
+TARGET_GCC_VERSION := 4.7
+else
+TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
+endif
+
 # Include the arch-variant-specific configuration file.
 # Its role is to define various ARCH_X86_HAVE_XXX feature macros,
 # plus initial values for TARGET_GLOBAL_CFLAGS
@@ -36,7 +42,7 @@
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-4.6
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-$(TARGET_GCC_VERSION)
 TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/i686-linux-android-
 endif
 
@@ -84,6 +90,7 @@
 			-Ulinux \
 			-Wa,--noexecstack \
 			-Werror=format-security \
+			-D_FORTIFY_SOURCE=1 \
 			-Wstrict-aliasing=2 \
 			-fPIC -fPIE \
 			-ffunction-sections \
@@ -144,6 +151,7 @@
 
 TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
 TARGET_GLOBAL_LDFLAGS += -Wl,-z,relro -Wl,-z,now
+TARGET_GLOBAL_LDFLAGS += -Wl,--warn-shared-textrel
 TARGET_GLOBAL_LDFLAGS += -Wl,--gc-sections
 
 TARGET_C_INCLUDES := \
diff --git a/core/combo/arch/arm/armv4t.mk b/core/combo/arch/arm/armv4t.mk
deleted file mode 100644
index abc8fa2..0000000
--- a/core/combo/arch/arm/armv4t.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# Configuration for Linux on ARM.
-# Generating binaries for the ARMv4T architecture and higher
-#
-# Supporting armv4 (without thumb) does not make much sense since
-# it's mostly an obsoleted instruction set architecture (only available
-# in StrongArm and arm8). Supporting armv4 will require a lot of conditional
-# code in assembler source since the bx (branch and exchange) instruction is
-# not supported.
-#
-$(warning ARMv4t support is currently a work in progress. It does not work right now!)
-ARCH_ARM_HAVE_THUMB_SUPPORT := false
-ARCH_ARM_HAVE_THUMB_INTERWORKING := false
-ARCH_ARM_HAVE_64BIT_DATA := false
-ARCH_ARM_HAVE_HALFWORD_MULTIPLY := false
-ARCH_ARM_HAVE_CLZ := false
-ARCH_ARM_HAVE_FFS := false
-
-DEFAULT_TARGET_CPU := arm920t
-
-# Note: Hard coding the 'tune' value here is probably not ideal,
-# and a better solution should be found in the future.
-#
-arch_variant_cflags := -march=armv4t -mtune=arm920t -D__ARM_ARCH_4T__
diff --git a/core/combo/arch/arm/armv5te.mk b/core/combo/arch/arm/armv5te.mk
index 29aada6..88e57b7 100644
--- a/core/combo/arch/arm/armv5te.mk
+++ b/core/combo/arch/arm/armv5te.mk
@@ -1,12 +1,6 @@
 # Configuration for Linux on ARM.
 # Generating binaries for the ARMv5TE architecture and higher
 #
-ARCH_ARM_HAVE_THUMB_SUPPORT     := true
-ARCH_ARM_HAVE_FAST_INTERWORKING := true
-ARCH_ARM_HAVE_64BIT_DATA        := true
-ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
-ARCH_ARM_HAVE_CLZ               := true
-ARCH_ARM_HAVE_FFS               := true
 
 # Note: Hard coding the 'tune' value here is probably not ideal,
 # and a better solution should be found in the future.
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index 32273ff..7884366 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -1,14 +1,7 @@
 # Configuration for Linux on ARM.
 # Generating binaries for the ARMv7-a architecture and higher with NEON
 #
-ARCH_ARM_HAVE_THUMB_SUPPORT     := true
-ARCH_ARM_HAVE_FAST_INTERWORKING := true
-ARCH_ARM_HAVE_64BIT_DATA        := true
-ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
-ARCH_ARM_HAVE_CLZ               := true
-ARCH_ARM_HAVE_FFS               := true
 ARCH_ARM_HAVE_ARMV7A            := true
-ARCH_ARM_HAVE_TLS_REGISTER      := true
 ARCH_ARM_HAVE_VFP               := true
 ARCH_ARM_HAVE_VFP_D32           := true
 ARCH_ARM_HAVE_NEON              := true
diff --git a/core/combo/arch/arm/armv7-a.mk b/core/combo/arch/arm/armv7-a.mk
index 220f7ec..4a51977 100644
--- a/core/combo/arch/arm/armv7-a.mk
+++ b/core/combo/arch/arm/armv7-a.mk
@@ -1,14 +1,7 @@
 # Configuration for Linux on ARM.
 # Generating binaries for the ARMv7-a architecture and higher
 #
-ARCH_ARM_HAVE_THUMB_SUPPORT     := true
-ARCH_ARM_HAVE_FAST_INTERWORKING := true
-ARCH_ARM_HAVE_64BIT_DATA        := true
-ARCH_ARM_HAVE_HALFWORD_MULTIPLY := true
-ARCH_ARM_HAVE_CLZ               := true
-ARCH_ARM_HAVE_FFS               := true
 ARCH_ARM_HAVE_ARMV7A            := true
-ARCH_ARM_HAVE_TLS_REGISTER      := true
 ARCH_ARM_HAVE_VFP               := true
 
 # Note: Hard coding the 'tune' value here is probably not ideal,
diff --git a/core/combo/arch/mips/mips32r2-fp.mk b/core/combo/arch/mips/mips32r2-fp.mk
index a407f00..08d91df 100644
--- a/core/combo/arch/mips/mips32r2-fp.mk
+++ b/core/combo/arch/mips/mips32r2-fp.mk
@@ -8,7 +8,8 @@
     -march=mips32r2 \
     -mtune=mips32r2 \
     -mips32r2 \
-    -mhard-float
+    -mhard-float \
+    -msynci
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/arch/mips/mips32r2.mk b/core/combo/arch/mips/mips32r2.mk
index 369d499..16ce76f 100644
--- a/core/combo/arch/mips/mips32r2.mk
+++ b/core/combo/arch/mips/mips32r2.mk
@@ -6,7 +6,8 @@
     -march=mips32r2 \
     -mtune=mips32r2 \
     -mips32r2 \
-    -msoft-float
+    -msoft-float \
+    -msynci
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/arch/mips/mips32r2dsp-fp.mk b/core/combo/arch/mips/mips32r2dsp-fp.mk
index 886872d..fe2b1fe 100644
--- a/core/combo/arch/mips/mips32r2dsp-fp.mk
+++ b/core/combo/arch/mips/mips32r2dsp-fp.mk
@@ -11,7 +11,8 @@
     -mtune=mips32r2 \
     -mips32r2 \
     -mhard-float \
-    -mdsp
+    -mdsp \
+    -msynci
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/arch/mips/mips32r2dsp.mk b/core/combo/arch/mips/mips32r2dsp.mk
index e67adc7..8a8976c 100644
--- a/core/combo/arch/mips/mips32r2dsp.mk
+++ b/core/combo/arch/mips/mips32r2dsp.mk
@@ -10,7 +10,8 @@
     -mtune=mips32r2 \
     -mips32r2 \
     -msoft-float \
-    -mdsp
+    -mdsp \
+    -msynci
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/arch/mips/mips32r2dspr2-fp.mk b/core/combo/arch/mips/mips32r2dspr2-fp.mk
index 27e090d..7e882b3 100644
--- a/core/combo/arch/mips/mips32r2dspr2-fp.mk
+++ b/core/combo/arch/mips/mips32r2dspr2-fp.mk
@@ -11,7 +11,8 @@
     -mtune=mips32r2 \
     -mips32r2 \
     -mhard-float \
-    -mdspr2
+    -mdspr2 \
+    -msynci
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/arch/mips/mips32r2dspr2.mk b/core/combo/arch/mips/mips32r2dspr2.mk
index c493d9a..c311523 100644
--- a/core/combo/arch/mips/mips32r2dspr2.mk
+++ b/core/combo/arch/mips/mips32r2dspr2.mk
@@ -10,7 +10,8 @@
     -mtune=mips32r2 \
     -mips32r2 \
     -msoft-float \
-    -mdspr2
+    -mdspr2 \
+    -msynci
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/include/arch/darwin-x86/AndroidConfig.h b/core/combo/include/arch/darwin-x86/AndroidConfig.h
index 9da01c5..012f014 100644
--- a/core/combo/include/arch/darwin-x86/AndroidConfig.h
+++ b/core/combo/include/arch/darwin-x86/AndroidConfig.h
@@ -171,13 +171,6 @@
 #define HAVE_BACKTRACE 0
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 1
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/freebsd-x86/AndroidConfig.h b/core/combo/include/arch/freebsd-x86/AndroidConfig.h
index 4bc5559..6f50918 100644
--- a/core/combo/include/arch/freebsd-x86/AndroidConfig.h
+++ b/core/combo/include/arch/freebsd-x86/AndroidConfig.h
@@ -187,13 +187,6 @@
 #define HAVE_BACKTRACE 0
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 1
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/linux-arm/AndroidConfig.h b/core/combo/include/arch/linux-arm/AndroidConfig.h
index 233752b..9257d3e 100644
--- a/core/combo/include/arch/linux-arm/AndroidConfig.h
+++ b/core/combo/include/arch/linux-arm/AndroidConfig.h
@@ -186,13 +186,6 @@
 #define HAVE_BACKTRACE 0
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 1
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/linux-mips/AndroidConfig.h b/core/combo/include/arch/linux-mips/AndroidConfig.h
index 2d51dc7..e24f3ea 100644
--- a/core/combo/include/arch/linux-mips/AndroidConfig.h
+++ b/core/combo/include/arch/linux-mips/AndroidConfig.h
@@ -191,13 +191,6 @@
 #define HAVE_BACKTRACE 0
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 1
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/linux-ppc/AndroidConfig.h b/core/combo/include/arch/linux-ppc/AndroidConfig.h
index ae2569b..a12ef47 100644
--- a/core/combo/include/arch/linux-ppc/AndroidConfig.h
+++ b/core/combo/include/arch/linux-ppc/AndroidConfig.h
@@ -176,13 +176,6 @@
 #define HAVE_BACKTRACE 1
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 1
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/linux-x86/AndroidConfig.h b/core/combo/include/arch/linux-x86/AndroidConfig.h
index 431a54b..2db66a2 100644
--- a/core/combo/include/arch/linux-x86/AndroidConfig.h
+++ b/core/combo/include/arch/linux-x86/AndroidConfig.h
@@ -176,13 +176,6 @@
 #define HAVE_BACKTRACE 1
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 1
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/target_linux-x86/AndroidConfig.h b/core/combo/include/arch/target_linux-x86/AndroidConfig.h
index ab53892..aaaf0c9 100644
--- a/core/combo/include/arch/target_linux-x86/AndroidConfig.h
+++ b/core/combo/include/arch/target_linux-x86/AndroidConfig.h
@@ -175,13 +175,6 @@
 #define HAVE_BACKTRACE 0
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 0
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/combo/include/arch/windows/AndroidConfig.h b/core/combo/include/arch/windows/AndroidConfig.h
index 0274da5..83d0a0f 100644
--- a/core/combo/include/arch/windows/AndroidConfig.h
+++ b/core/combo/include/arch/windows/AndroidConfig.h
@@ -189,13 +189,6 @@
 #define HAVE_BACKTRACE 0
 
 /*
- * Defined if we have the dladdr() call for retrieving the symbol associated
- * with a memory address.  If not defined, stack crawls will not have symbolic
- * information.
- */
-#define HAVE_DLADDR 0
-
-/*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
  * not defined, stack crawls will be displayed with raw mangled symbols
  */
diff --git a/core/definitions.mk b/core/definitions.mk
index 4f4e583..26fe7b4 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -178,7 +178,7 @@
 define all-java-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) -name "*.java" -and -not -name ".*") \
+          find -L $(1) -name "*.java" -and -not -name ".*") \
  )
 endef
 
@@ -200,7 +200,7 @@
 define all-c-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) -name "*.c" -and -not -name ".*") \
+          find -L $(1) -name "*.c" -and -not -name ".*") \
  )
 endef
 
@@ -222,7 +222,7 @@
 define all-Iaidl-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) -name "I*.aidl" -and -not -name ".*") \
+          find -L $(1) -name "I*.aidl" -and -not -name ".*") \
  )
 endef
 
@@ -243,7 +243,7 @@
 define all-logtags-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) -name "*.logtags" -and -not -name ".*") \
+          find -L $(1) -name "*.logtags" -and -not -name ".*") \
   )
 endef
 
@@ -256,7 +256,7 @@
 define all-proto-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) -name "*.proto" -and -not -name ".*") \
+          find -L $(1) -name "*.proto" -and -not -name ".*") \
   )
 endef
 
@@ -269,7 +269,7 @@
 define all-renderscript-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) \( -name "*.rs" -or -name "*.fs" \) -and -not -name ".*") \
+          find -L $(1) \( -name "*.rs" -or -name "*.fs" \) -and -not -name ".*") \
   )
 endef
 
@@ -282,7 +282,7 @@
 define all-html-files-under
 $(patsubst ./%,%, \
   $(shell cd $(LOCAL_PATH) ; \
-          find $(1) -name "*.html" -and -not -name ".*") \
+          find -L $(1) -name "*.html" -and -not -name ".*") \
  )
 endef
 
@@ -301,7 +301,7 @@
 ###########################################################
 
 define find-subdir-files
-$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find $(1)))
+$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find -L $(1)))
 endef
 
 ###########################################################
@@ -314,7 +314,7 @@
 
 define find-subdir-subdir-files
 $(filter-out $(patsubst %,$(1)/%,$(3)),$(patsubst ./%,%,$(shell cd \
-            $(LOCAL_PATH) ; find $(1) -maxdepth 1 -name $(2))))
+            $(LOCAL_PATH) ; find -L $(1) -maxdepth 1 -name $(2))))
 endef
 
 ###########################################################
@@ -1475,6 +1475,8 @@
     \@$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq \
     || ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 ) \
 fi
+$(if $(PRIVATE_JAVA_LAYERS_FILE), $(hide) build/tools/java-layers.py \
+    $(PRIVATE_JAVA_LAYERS_FILE) \@$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq,)
 $(hide) rm -f $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list
 $(hide) rm -f $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq
 $(if $(PRIVATE_JAR_EXCLUDE_FILES), $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) \
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 03a5011..ce0c46e 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -160,7 +160,7 @@
 
 $(full_target): $(full_src_files) $(droiddoc_templates) $(droiddoc) $(html_dir_files) $(full_java_lib_deps) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	@echo Docs droiddoc: $(PRIVATE_OUT_DIR)
-	$(hide) mkdir -p $(dir $(full_target))
+	$(hide) mkdir -p $(dir $@)
 	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
 			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
 	$(hide) ( \
@@ -193,7 +193,7 @@
 ##
 $(full_target): $(full_src_files) $(full_java_lib_deps)
 	@echo Docs javadoc: $(PRIVATE_OUT_DIR)
-	@mkdir -p $(dir $(full_target))
+	@mkdir -p $(dir $@)
 	$(call prepare-doc-source-list,$(PRIVATE_SRC_LIST_FILE),$(PRIVATE_JAVA_FILES), \
 			$(PRIVATE_SOURCE_INTERMEDIATES_DIR) $(PRIVATE_ADDITIONAL_JAVA_DIR))
 	$(hide) ( \
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index 5298f35..47ac9e2 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -11,23 +11,27 @@
 
 # Add the ARM toolchain bin dir if it actually exists
 ifeq ($(TARGET_ARCH),arm)
-    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6/bin),)
+    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-$(TARGET_GCC_VERSION)/bin),)
         # this should be copied to HOST_OUT_EXECUTABLES instead
-        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6/bin
+        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-$(TARGET_GCC_VERSION)/bin
+    endif
+    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-eabi-$(TARGET_GCC_VERSION)/bin),)
+        # this should be copied to HOST_OUT_EXECUTABLES instead
+        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-eabi-$(TARGET_GCC_VERSION)/bin
     endif
 else ifeq ($(TARGET_ARCH),x86)
 
 # Add the x86 toolchain bin dir if it actually exists
-    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-4.6/bin),)
+    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-$(TARGET_GCC_VERSION)/bin),)
         # this should be copied to HOST_OUT_EXECUTABLES instead
-        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-4.6/bin
+        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-$(TARGET_GCC_VERSION)/bin
     endif
 endif
 
 # Add the mips toolchain bin dir if it actually exists
-ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-4.6/bin),)
+ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-$(TARGET_GCC_VERSION)/bin),)
     # this should be copied to HOST_OUT_EXECUTABLES instead
-    ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-4.6/bin
+    ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mipsel-linux-android-$(TARGET_GCC_VERSION)/bin
 endif
 
 ANDROID_BUILD_PATHS := $(ABP)
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index 0ca1858..6ede57f 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -128,8 +128,7 @@
 endif # LOCAL_STRIP_MODULE
 
 
-$(cleantarget): PRIVATE_CLEAN_FILES := \
-			$(PRIVATE_CLEAN_FILES) \
-			$(linked_module) \
-			$(symbolic_output) \
-			$(compress_output)
+$(cleantarget): PRIVATE_CLEAN_FILES += \
+    $(linked_module) \
+    $(symbolic_output) \
+    $(compress_output)
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index 5930da6..91942dc 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -24,6 +24,10 @@
 LOCAL_BUILT_MODULE_STEM := javalib.jar
 
 ifeq ($(LOCAL_BUILD_HOST_DEX),true)
+ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+  LOCAL_JAVA_LIBRARIES := $(sort core-hostdex $(LOCAL_JAVA_LIBRARIES))
+endif
+
 intermediates := $(call local-intermediates-dir)
 intermediates.COMMON := $(call local-intermediates-dir,COMMON)
 
@@ -43,6 +47,10 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
+# The layers file allows you to enforce a layering between java packages.
+# Run build/tools/java-layers.py for more details.
+layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
+
 ifeq ($(LOCAL_BUILD_HOST_DEX),true)
 $(LOCAL_INTERMEDIATE_TARGETS): \
 	PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates.COMMON)/classes
@@ -51,9 +59,11 @@
 
 $(cleantarget): PRIVATE_CLEAN_FILES += $(intermediates.COMMON)
 
+$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
 $(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
 $(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
-$(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) $(jar_manifest_file)
+$(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) \
+        $(jar_manifest_file) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-java-to-package)
 
 # Run jarjar if necessary, otherwise just copy the file.
@@ -90,6 +100,8 @@
 else
 $(LOCAL_BUILT_MODULE): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
 $(LOCAL_BUILT_MODULE): PRIVATE_JAR_EXCLUDE_FILES :=
-$(LOCAL_BUILT_MODULE): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) $(jar_manifest_file)
+$(LOCAL_BUILT_MODULE): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
+$(LOCAL_BUILT_MODULE): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) \
+		$(jar_manifest_file) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-host-java-to-package)
 endif  # LOCAL_BUILD_HOST_DEX
diff --git a/core/java.mk b/core/java.mk
index 99e67f4..65c9be9 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -254,6 +254,11 @@
 	$(hide) $(ACP) -fp $(PRIVATE_SOURCE_FILE) $@
 ALL_MODULES.$(LOCAL_MODULE).STUBS := $(full_classes_stubs_jar)
 
+# The layers file allows you to enforce a layering between java packages.
+# Run build/tools/java-layers.py for more details.
+layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
+$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
+
 # Compile the java files to a .jar file.
 # This intentionally depends on java_sources, not all_java_sources.
 # Deps for generated source files must be handled separately,
@@ -261,8 +266,9 @@
 $(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS)
 $(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES := $(LOCAL_JAR_EXCLUDE_FILES)
 $(full_classes_compiled_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
-$(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) $(jar_manifest_file) \
-	$(RenderScript_file_stamp) $(proto_java_sources_file_stamp)
+$(full_classes_compiled_jar): $(java_sources) $(java_resource_sources) $(full_java_lib_deps) \
+        $(jar_manifest_file) $(layers_file) $(RenderScript_file_stamp) \
+        $(proto_java_sources_file_stamp) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 	$(transform-java-to-classes.jar)
 
 # All of the rules after full_classes_compiled_jar are very unlikely
diff --git a/core/llvm_config.mk b/core/llvm_config.mk
index 0308b28..7a26842 100644
--- a/core/llvm_config.mk
+++ b/core/llvm_config.mk
@@ -59,7 +59,8 @@
     -march=mips32r2 \
     -mtune=mips32r2 \
     -march=mips32 \
-    -mtune=mips32
+    -mtune=mips32 \
+    -msynci
 endif
 ifeq ($(TARGET_ARCH),x86)
   CLANG_CONFIG_EXTRA_CFLAGS += \
diff --git a/core/main.mk b/core/main.mk
index 87488f4..e03d873 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -121,12 +121,20 @@
 $(error Directory names containing spaces not supported)
 endif
 
+# Check for the corrent jdk
+ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
+$(info ************************************************************)
+$(info You are attempting to build with an unsupported JDK.)
+$(info $(space))
+$(info You use OpenJDK but only Sun/Oracle JDK is supported.)
+$(info Please follow the machine setup instructions at)
+$(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
+$(info ************************************************************)
+$(error stop)
+endif
 
 # Check for the correct version of java
 java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')
-ifneq ($(shell java -version 2>&1 | grep -i openjdk),)
-java_version :=
-endif
 ifeq ($(strip $(java_version)),)
 $(info ************************************************************)
 $(info You are attempting to build with the incorrect version)
@@ -158,7 +166,7 @@
 endif
 
 ifeq (darwin,$(HOST_OS))
-GCC_REALPATH = $(realpath $(shell which gcc))
+GCC_REALPATH = $(realpath $(shell which $(HOST_CC)))
 ifneq ($(findstring llvm-gcc,$(GCC_REALPATH)),)
   # Using LLVM GCC results in a non functional emulator due to it
   # not honouring global register variables
@@ -170,23 +178,6 @@
 else
   BUILD_EMULATOR := true
 endif
-# When building on Leopard or above, we need to use the 10.4 SDK
-# or the generated binary will not run on Tiger.
-darwin_version := $(strip $(shell sw_vers -productVersion))
-ifneq ($(filter 10.1 10.2 10.3 10.1.% 10.2.% 10.3.% 10.4 10.4.%,$(darwin_version)),)
-    $(error Building the Android emulator requires OS X 10.5 or above)
-endif
-ifneq ($(filter 10.5 10.5.% 10.6 10.6.%,$(darwin_version)),)
-    # We are on Leopard or Snow Leopard
-    MSDK=10.5
-else
-    # We are on Lion or beyond, and 10.6 SDK is the minimum in Xcode 4.x
-   MSDK=10.6
-endif
-MACOSX_SDK := /Developer/SDKs/MacOSX$(MSDK).sdk
-ifeq ($(strip $(wildcard $(MACOSX_SDK))),)
-  BUILD_EMULATOR := false
-endif
 else   # HOST_OS is not darwin
   BUILD_EMULATOR := true
 endif  # HOST_OS is darwin
@@ -275,11 +266,6 @@
 is_sdk_build := true
 endif
 
-## have selinux ##
-ifeq ($(HAVE_SELINUX),true)
-ADDITIONAL_BUILD_PROPERTIES += ro.build.selinux=1
-endif # HAVE_SELINUX
-
 ## user/userdebug ##
 
 user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
@@ -453,25 +439,6 @@
 endif
 
 else	# !SDK_ONLY
-ifeq ($(BUILD_TINY_ANDROID), true)
-
-# TINY_ANDROID is a super-minimal build configuration, handy for board
-# bringup and very low level debugging
-
-subdirs := \
-	bionic \
-	system/core \
-	system/extras/ext4_utils \
-	system/extras/su \
-	build/libs \
-	build/target \
-	build/tools/acp \
-	external/gcc-demangle \
-	external/mksh \
-	external/openssl \
-	external/yaffs2 \
-	external/zlib
-else	# !BUILD_TINY_ANDROID
 #
 # Typical build; include any Android.mk files we can find.
 #
@@ -479,8 +446,6 @@
 
 FULL_BUILD := true
 
-endif	# !BUILD_TINY_ANDROID
-
 endif	# !SDK_ONLY
 
 # Before we go and include all of the module makefiles, stash away
@@ -738,7 +703,6 @@
 .PHONY: files
 files: prebuilt \
         $(modules_to_install) \
-        $(modules_to_check) \
         $(INSTALLED_ANDROID_INFO_TXT_TARGET)
 
 # -------------------------------------------------------------------
@@ -777,10 +741,6 @@
 .PHONY: bootimage
 bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
 
-ifeq ($(BUILD_TINY_ANDROID), true)
-INSTALLED_RECOVERYIMAGE_TARGET :=
-endif
-
 # Build files and then package it into the rom formats
 .PHONY: droidcore
 droidcore: files \
diff --git a/core/package.mk b/core/package.mk
index 358caee..11e557f 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -410,15 +410,17 @@
 	$(add-java-resources-to-package)
 endif
 	$(sign-package)
-	@# Alignment must happen after all other zip operations.
-	$(align-package)
 ifdef LOCAL_DEX_PREOPT
 	$(hide) rm -f $(patsubst %.apk,%.odex,$@)
 	$(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@))
 ifneq (nostripping,$(LOCAL_DEX_PREOPT))
 	$(call dexpreopt-remove-classes.dex,$@)
 endif
+endif
+	@# Alignment must happen after all other zip operations.
+	$(align-package)
 
+ifdef LOCAL_DEX_PREOPT
 built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
 $(built_odex): $(LOCAL_BUILT_MODULE)
 endif
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index f59a17b..31ea0e0 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -59,10 +59,18 @@
   built_module := $(LOCAL_BUILT_MODULE)
 
 ifdef prebuilt_module_is_a_library
-# Create a dummy export_includes.
-$(intermediates)/export_includes:
+export_includes := $(intermediates)/export_includes
+$(export_includes): PRIVATE_EXPORT_C_INCLUDE_DIRS := $(LOCAL_EXPORT_C_INCLUDE_DIRS)
+$(export_includes) : $(LOCAL_MODULE_MAKEFILE)
+	@echo Export includes file: $< -- $@
 	$(hide) mkdir -p $(dir $@) && rm -f $@
+ifdef LOCAL_EXPORT_C_INCLUDE_DIRS
+	$(hide) for d in $(PRIVATE_EXPORT_C_INCLUDE_DIRS); do \
+	        echo "-I $$d" >> $@; \
+	        done
+else
 	$(hide) touch $@
+endif
 
 $(LOCAL_BUILT_MODULE) : | $(intermediates)/export_includes
 endif
diff --git a/core/product_config.mk b/core/product_config.mk
index 75df954..e05907d 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -220,7 +220,7 @@
 else
 # Import just the current product.
 ifndef current_product_makefile
-$(error Cannot locate config makefile for product "$(TARGET_PRODUCT)")
+$(error Can not locate config makefile for product "$(TARGET_PRODUCT)")
 endif
 ifneq (1,$(words $(current_product_makefile)))
 $(error Product "$(TARGET_PRODUCT)" ambiguous: matches $(current_product_makefile))
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
index 2c1300b..24b3428 100644
--- a/core/tasks/apicheck.mk
+++ b/core/tasks/apicheck.mk
@@ -17,8 +17,8 @@
 # api compatibility or added apis illegally.
 #
 
-# skip api check for TINY_ANDROID and PDK buid
-ifeq (,$(filter true, $(BUILD_TINY_ANDROID) $(TARGET_BUILD_PDK)))
+# skip api check for PDK buid
+ifeq (,$(filter true, $(WITHOUT_CHECK_API) $(TARGET_BUILD_PDK)))
 
 .PHONY: checkapi
 
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index 108e30b..5b041d6 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -75,6 +75,7 @@
 define generate-core-test-description
 @echo "Generate core-test description ("$(notdir $(1))")"
 $(hide) java -Xmx256M \
+	-Xbootclasspath/a:$(PRIVATE_CLASSPATH) \
 	-classpath $(PRIVATE_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR) \
 	$(PRIVATE_PARAMS) CollectAllTests $(1) $(2) $(3) "$(4)" $(5) $(6)
 endef
diff --git a/core/tasks/factory_bundle.mk b/core/tasks/factory_bundle.mk
index 06d7a78..5c5adc3 100644
--- a/core/tasks/factory_bundle.mk
+++ b/core/tasks/factory_bundle.mk
@@ -15,6 +15,7 @@
 #
 
 ifeq (,$(ONE_SHOT_MAKEFILE))
+ifneq ($(TARGET_BUILD_PDK),true)
 
 # PRODUCT_FACTORY_RAMDISK_MODULES consists of "<module_name>:<install_path>[:<install_path>...]" tuples.
 # <install_path> is relative to the staging directory for the bundle.
@@ -76,5 +77,6 @@
 
 endif
 
+endif # TARGET_BUILD_PDK
 endif # ONE_SHOT_MAKEFILE
 
diff --git a/core/tasks/factory_ramdisk.mk b/core/tasks/factory_ramdisk.mk
index 38a5887..579fd6a 100644
--- a/core/tasks/factory_ramdisk.mk
+++ b/core/tasks/factory_ramdisk.mk
@@ -15,6 +15,7 @@
 #
 
 ifeq (,$(ONE_SHOT_MAKEFILE))
+ifneq ($(TARGET_BUILD_PDK),true)
 
 # PRODUCT_FACTORY_RAMDISK_MODULES consists of "<module_name>:<install_path>[:<install_path>...]" tuples.
 # <install_path> is relative to TARGET_FACTORY_RAMDISK_OUT.
@@ -87,4 +88,5 @@
 
 endif
 
+endif # TARGET_BUILD_PDK
 endif # ONE_SHOT_MAKEFILE
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index e3ba14f..9330465 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -41,7 +41,7 @@
   # which is the version that we reveal to the end user.
   # Update this value when the platform version changes (rather
   # than overriding it somewhere else).  Can be an arbitrary string.
-  PLATFORM_VERSION := 4.2.2
+  PLATFORM_VERSION := 4.2.2.2.2.2.2.2.2.2
 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 := REL
+  PLATFORM_VERSION_CODENAME := AOSP
 endif
 
 ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
diff --git a/envsetup.sh b/envsetup.sh
index b57a272..b4199b0 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -31,7 +31,7 @@
         echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
         return
     fi
-    (cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
+    (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
       make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-abs-$1)
 }
 
@@ -116,15 +116,19 @@
     prebuiltdir=$(getprebuilt)
     gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
 
+    # defined in core/config.mk
+    targetgccversion=$(get_build_var TARGET_GCC_VERSION)
+    export TARGET_GCC_VERSION=$targetgccversion
+
     # The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it.
     export ANDROID_EABI_TOOLCHAIN=
     local ARCH=$(get_build_var TARGET_ARCH)
     case $ARCH in
-        x86) toolchaindir=x86/i686-linux-android-4.6/bin
+        x86) toolchaindir=x86/i686-linux-android-$targetgccversion/bin
             ;;
-        arm) toolchaindir=arm/arm-linux-androideabi-4.6/bin
+        arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
             ;;
-        mips) toolchaindir=mips/mipsel-linux-android-4.6/bin
+        mips) toolchaindir=mips/mipsel-linux-android-$targetgccversion/bin
             ;;
         *)
             echo "Can't find toolchain for unknown architecture: $ARCH"
@@ -138,7 +142,7 @@
     unset ARM_EABI_TOOLCHAIN ARM_EABI_TOOLCHAIN_PATH
     case $ARCH in
         arm)
-            toolchaindir=arm/arm-eabi-4.6/bin
+            toolchaindir=arm/arm-eabi-$targetgccversion/bin
             if [ -d "$gccprebuiltdir/$toolchaindir" ]; then
                  export ARM_EABI_TOOLCHAIN="$gccprebuiltdir/$toolchaindir"
                  ARM_EABI_TOOLCHAIN_PATH=":$gccprebuiltdir/$toolchaindir"
@@ -580,16 +584,13 @@
             # faked up with symlink names.
             PWD= /bin/pwd
         else
-            # We redirect cd to /dev/null in case it's aliased to
-            # a command that prints something as a side-effect
-            # (like pushd)
             local HERE=$PWD
             T=
             while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
-                cd .. > /dev/null
+                \cd ..
                 T=`PWD= /bin/pwd`
             done
-            cd $HERE > /dev/null
+            \cd $HERE
             if [ -f "$T/$TOPFILE" ]; then
                 echo $T
             fi
@@ -610,21 +611,18 @@
 function findmakefile()
 {
     TOPFILE=build/core/envsetup.mk
-    # We redirect cd to /dev/null in case it's aliased to
-    # a command that prints something as a side-effect
-    # (like pushd)
     local HERE=$PWD
     T=
     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
         T=`PWD= /bin/pwd`
         if [ -f "$T/Android.mk" ]; then
             echo $T/Android.mk
-            cd $HERE > /dev/null
+            \cd $HERE
             return
         fi
-        cd .. > /dev/null
+        \cd ..
     done
-    cd $HERE > /dev/null
+    \cd $HERE
 }
 
 function mm()
@@ -666,7 +664,7 @@
             fi
             DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
             if [ -f $DIR/Android.mk ]; then
-                TO_CHOP=`(cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
+                TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
                 TO_CHOP=`expr $TO_CHOP + 1`
                 START=`PWD= /bin/pwd`
                 MFILE=`echo $START | cut -c${TO_CHOP}-`
@@ -701,7 +699,7 @@
 {
     T=$(gettop)
     if [ "$T" ]; then
-        cd $(gettop)
+        \cd $(gettop)
     else
         echo "Couldn't locate the top of the tree.  Try setting TOP."
     fi
@@ -710,20 +708,17 @@
 function cproj()
 {
     TOPFILE=build/core/envsetup.mk
-    # We redirect cd to /dev/null in case it's aliased to
-    # a command that prints something as a side-effect
-    # (like pushd)
     local HERE=$PWD
     T=
     while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
         T=$PWD
         if [ -f "$T/Android.mk" ]; then
-            cd $T
+            \cd $T
             return
         fi
-        cd .. > /dev/null
+        \cd ..
     done
-    cd $HERE > /dev/null
+    \cd $HERE
     echo "can't find Android.mk"
 }
 
@@ -1063,7 +1058,7 @@
         return
     fi
 
-    (cd "$T" && mmm tests/SmokeTest) &&
+    (\cd "$T" && mmm tests/SmokeTest) &&
       adb uninstall com.android.smoketest > /dev/null &&
       adb uninstall com.android.smoketest.tests > /dev/null &&
       adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk &&
@@ -1090,7 +1085,7 @@
     T=$(gettop)
     if [[ ! -f $T/filelist ]]; then
         echo -n "Creating index..."
-        (cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist)
+        (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist)
         echo " Done"
         echo ""
     fi
@@ -1123,7 +1118,7 @@
     else
         pathname=${lines[0]}
     fi
-    cd $T/$pathname
+    \cd $T/$pathname
 }
 
 # Force JAVA_HOME to point to java 1.6 if it isn't already set
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 7a25f30..3b03250 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -22,7 +22,6 @@
 TARGET_ARCH_VARIANT := armv7-a
 TARGET_CPU_ABI := armeabi-v7a
 TARGET_CPU_ABI2 := armeabi
-ARCH_ARM_HAVE_TLS_REGISTER := true
 
 HAVE_HTC_AUDIO_DRIVER := true
 BOARD_USES_GENERIC_AUDIO := true
diff --git a/target/board/generic_mips/BoardConfig.mk b/target/board/generic_mips/BoardConfig.mk
index 8c2371f..c3881b4 100644
--- a/target/board/generic_mips/BoardConfig.mk
+++ b/target/board/generic_mips/BoardConfig.mk
@@ -34,9 +34,6 @@
 # no hardware camera
 USE_CAMERA_STUB := true
 
-# Set /system/bin/sh to ash, not mksh, to make sure we can switch back.
-TARGET_SHELL := ash
-
 # Enable dex-preoptimization to speed up the first boot sequence
 # of an SDK AVD. Note that this operation only works on Linux for now
 ifeq ($(HOST_OS),linux)
diff --git a/target/product/base.mk b/target/product/base.mk
index 9d8ef3f..68fed42 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -18,74 +18,46 @@
 PRODUCT_PACKAGES += \
     20-dns.conf \
     95-configured \
-    adb \
-    adbd \
     am \
     android.policy \
     android.test.runner \
     app_process \
     applypatch \
     bmgr \
-    bootanimation \
     bugreport \
     content \
     dbus-daemon \
-    debuggerd \
     dhcpcd \
     dhcpcd-run-hooks \
     dnsmasq \
-    dumpstate \
-    dumpsys \
     framework \
     fsck_msdos \
-    gralloc.default \
-    gzip \
     ime \
-    init \
-    input \
     javax.obex \
-    libEGL \
-    libETC1 \
-    libFFTEm \
-    libGLES_android \
-    libGLESv1_CM \
-    libGLESv2 \
     libSR_AudioIn \
     libandroid \
     libandroid_runtime \
     libandroid_servers \
     libaudioeffect_jni \
     libaudioflinger \
-    libbinder \
     libbundlewrapper \
-    libc \
     libcamera_client \
     libcameraservice \
     libchromium_net \
-    libctest \
-    libcutils \
     libdbus \
     libdl \
     libdrm1 \
     libdrm1_jni \
     libeffects \
-    libgui \
-    libhardware \
-    libhardware_legacy \
     libiprouteutil \
     libjni_latinime \
     libjnigraphics \
-    libjpeg \
-    liblog \
-    libm \
     libmedia \
     libmedia_jni \
     libmediaplayerservice \
     libmtp \
     libnetlink \
     libnetutils \
-    libpixelflinger \
-    libpower \
     libreference-ril \
     libreverbwrapper \
     libril \
@@ -102,24 +74,13 @@
     libstagefright_foundation \
     libstagefright_omx \
     libstagefright_yuv \
-    libstdc++ \
-    libstlport \
-    libsurfaceflinger \
-    libsurfaceflinger_client \
-    libsurfaceflinger_ddmconnection \
     libsystem_server \
-    libsysutils \
-    libthread_db \
-    libui \
     libusbhost \
     libutils \
     libvisualizer \
     libvorbisidec \
     libwebcore \
     libwpa_client \
-    linker \
-    logcat \
-    logwrapper \
     mediaserver \
     monkey \
     mtpd \
@@ -135,15 +96,13 @@
     schedtest \
     screenshot \
     sdcard \
-    service \
-    servicemanager \
     services \
     settings \
-    surfaceflinger \
     svc \
     system_server \
     tc \
-    toolbox \
     vdc \
     vold
 
+$(call inherit-product, $(SRC_TARGET_DIR)/product/embedded.mk)
+
diff --git a/target/product/core.mk b/target/product/core.mk
index 1d62eb8..e10dc31 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -128,14 +128,15 @@
     lint \
     uiautomator \
     telephony-common \
-    mms-common \
-    zoneinfo.dat \
-    zoneinfo.idx \
-    zoneinfo.version
+    mms-common
 
-PRODUCT_COPY_FILES += \
-    system/core/rootdir/init.usb.rc:root/init.usb.rc \
-    system/core/rootdir/init.trace.rc:root/init.trace.rc \
+# SELinux packages
+PRODUCT_PACKAGES += \
+    sepolicy \
+    file_contexts \
+    seapp_contexts \
+    property_contexts \
+    mac_permissions.xml
 
 # host-only dependencies
 ifeq ($(WITH_HOST_DALVIK),true)
@@ -150,20 +151,7 @@
         libjavacore \
         libssl \
         libz-host \
-        dalvik \
-        zoneinfo-host.dat \
-        zoneinfo-host.idx \
-        zoneinfo-host.version
-endif
-
-ifeq ($(HAVE_SELINUX),true)
-    PRODUCT_PACKAGES += \
-        sepolicy \
-        file_contexts \
-        seapp_contexts \
-        property_contexts \
-        mac_permissions.xml
+        dalvik
 endif
 
 $(call inherit-product, $(SRC_TARGET_DIR)/product/base.mk)
-
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
new file mode 100644
index 0000000..7f681b1
--- /dev/null
+++ b/target/product/embedded.mk
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is a build configuration for a very minimal build of the
+# Open-Source part of the tree.
+
+PRODUCT_PACKAGES += \
+    adb \
+    adbd \
+    bootanimation \
+    debuggerd \
+    dumpstate \
+    dumpsys \
+    gralloc.default \
+    gzip \
+    init \
+    input \
+    libEGL \
+    libETC1 \
+    libFFTEm \
+    libGLES_android \
+    libGLESv1_CM \
+    libGLESv2 \
+    libbinder \
+    libc \
+    libctest \
+    libcutils \
+    libdl \
+    libgui \
+    libhardware \
+    libhardware_legacy \
+    libjpeg \
+    liblog \
+    libm \
+    libpixelflinger \
+    libpower \
+    libstdc++ \
+    libstlport \
+    libsurfaceflinger \
+    libsurfaceflinger_client \
+    libsurfaceflinger_ddmconnection \
+    libsysutils \
+    libthread_db \
+    libui \
+    libutils \
+    linker \
+    logcat \
+    logwrapper \
+    service \
+    servicemanager \
+    surfaceflinger \
+    toolbox
+
+# SELinux packages
+PRODUCT_PACKAGES += \
+    sepolicy \
+    file_contexts \
+    seapp_contexts \
+    property_contexts \
+    mac_permissions.xml
+
+PRODUCT_COPY_FILES += \
+    system/core/rootdir/init.usb.rc:root/init.usb.rc \
+    system/core/rootdir/init.trace.rc:root/init.trace.rc \
diff --git a/target/product/emulator.mk b/target/product/emulator.mk
new file mode 100644
index 0000000..582ca64
--- /dev/null
+++ b/target/product/emulator.mk
@@ -0,0 +1,36 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# This file is included by other product makefiles to add all the
+# emulator-related host modules to PRODUCT_PACKAGES.
+#
+
+PRODUCT_PACKAGES += \
+	emulator \
+	emulator-x86 \
+	emulator-arm \
+	emulator-mips \
+	emulator64-x86 \
+	emulator64-arm \
+	emulator64-mips \
+	libOpenglRender \
+	libGLES_CM_translator \
+	libGLES_V2_translator \
+	libEGL_translator \
+	lib64OpenglRender \
+	lib64GLES_CM_translator \
+	lib64GLES_V2_translator \
+	lib64EGL_translator
diff --git a/target/product/full_base.mk b/target/product/full_base.mk
index b2e3189..c28fd1b 100644
--- a/target/product/full_base.mk
+++ b/target/product/full_base.mk
@@ -40,6 +40,8 @@
     VisualizationWallpapers \
     PhotoTable
 
+include $(SRC_TARGET_DIR)/product/emulator.mk
+
 # Additional settings used in all AOSP builds
 PRODUCT_PROPERTY_OVERRIDES := \
     ro.com.android.dateformat=MM-dd-yyyy \
diff --git a/target/product/generic_no_telephony.mk b/target/product/generic_no_telephony.mk
index f139cbd..5bdc596 100644
--- a/target/product/generic_no_telephony.mk
+++ b/target/product/generic_no_telephony.mk
@@ -26,7 +26,7 @@
     Calendar \
     CertInstaller \
     DrmProvider \
-    Email2 \
+    Email \
     Exchange2 \
     FusedLocation \
     Gallery2 \
diff --git a/target/product/large_emu_hw.mk b/target/product/large_emu_hw.mk
index 27ebc96..8a070b1 100644
--- a/target/product/large_emu_hw.mk
+++ b/target/product/large_emu_hw.mk
@@ -27,7 +27,7 @@
     Calendar \
     CertInstaller \
     DrmProvider \
-    Email2 \
+    Email \
     Exchange2 \
     Gallery2 \
     LatinIME \
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 88fc2f3..f7a65db 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -20,7 +20,7 @@
 PRODUCT_PACKAGES := \
 	Calculator \
 	DeskClock \
-	Email2 \
+	Email \
 	Exchange2 \
 	FusedLocation \
 	Gallery \
@@ -68,6 +68,7 @@
 	rild \
 	LegacyCamera
 
+include $(SRC_TARGET_DIR)/product/emulator.mk
 
 # Define the host tools and libs that are parts of the SDK.
 -include sdk/build/product_sdk.mk
diff --git a/tools/adbs b/tools/adbs
index 598af85..37c520c 100755
--- a/tools/adbs
+++ b/tools/adbs
@@ -140,13 +140,15 @@
     uname = "darwin-x86"
   elif uname == "Linux":
     uname = "linux-x86"
-  prefix = "./prebuilts/gcc/" + uname + "/arm/arm-linux-androideabi-4.6/bin/"
+  gcc_version = os.environ["TARGET_GCC_VERSION"]
+  prefix = "./prebuilts/gcc/" + uname + "/arm/arm-linux-androideabi-" + \
+           gcc_version + "/bin/"
   addr2line_cmd = prefix + "arm-linux-androideabi-addr2line"
 
   if (not os.path.exists(addr2line_cmd)):
     try:
       prefix = os.environ['ANDROID_BUILD_TOP'] + "/prebuilts/gcc/" + \
-               uname + "/arm/arm-linux-androideabi-4.6/bin/"
+               uname + "/arm/arm-linux-androideabi-" + gcc_version + "/bin/"
     except:
       prefix = "";
 
diff --git a/tools/droiddoc/templates-sdk/assets/android-developer-docs.css b/tools/droiddoc/templates-sdk/assets/android-developer-docs.css
new file mode 100644
index 0000000..cd610f7
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/assets/android-developer-docs.css
@@ -0,0 +1,2768 @@
+/* file: android-developer-core.css
+   author: smain
+   date: september 2008
+   info: core developer styles (developer.android.com)
+   Required by jdiff
+*/
+
+
+/* RESET STYLES */
+
+html,body,div,h1,h2,h3,h4,h5,h6,p,img,
+dl,dt,dd,ol,ul,li,table,caption,tbody,
+tfoot,thead,tr,th,td,form,fieldset,
+embed,object,applet {
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+
+/* BASICS */
+
+html, body {
+  overflow:hidden; /* keeps scrollbar off IE */
+  background-color:#fff;
+}
+
+body {
+  font-family:arial,sans-serif;
+  color:#000;
+  font-size:13px;
+  color:#333;
+  background-image:url(images/bg_fade.jpg);
+  background-repeat:repeat-x;
+}
+
+a, a code {
+  color:#006699;
+}
+
+a:active,
+a:active code {
+  color:#f00;
+} 
+
+a:visited,
+a:visited code {
+  color:#006699;
+}
+
+input, select,
+textarea, option, label {
+  font-family:inherit;
+  font-size:inherit;
+  padding:0;
+  margin:0;
+  vertical-align:middle;
+}
+
+option {
+  padding:0 4px;
+}
+
+p, form {
+  padding:0;
+  margin:0 0 1em;
+}
+
+code, pre {
+  color:#007000;
+  font-family:monospace;
+  line-height:1em;
+}
+
+var {
+  color:#007000;
+  font-style:italic;
+}
+
+pre {
+  border:1px solid #ccc;
+  background-color:#fafafa;
+  padding:10px;
+  margin:0 0 1em 1em;
+  overflow:auto;
+  line-height:inherit; /* fixes vertical scrolling in webkit */
+}
+
+h1,h2,h3,h4,h5 {
+  margin:1em 0;
+  padding:0;
+}
+
+p,ul,ol,dl,dd,dt,li {
+  line-height:1.3em;
+}
+
+ul,ol {
+  margin:0 0 .8em;
+  padding:0 0 0 2em;
+}
+
+li {
+  padding:0 0 .5em;
+}
+
+dl {
+  margin:0 0 1em 0;
+  padding:0;
+}
+
+dt {
+  margin:0;
+  padding:0;
+}
+
+dd {
+  margin:0 0 1em;
+  padding:0 0 0 2em;
+}
+
+li p {
+  margin:.5em 0 0;
+}
+
+dd p {
+  margin:1em 0 0;
+}
+
+li pre, li table, li img {
+  margin:.5em 0 0 1em;
+}
+
+dd pre,
+#jd-content dd table,
+#jd-content dd img {
+  margin:1em 0 0 1em;
+}
+
+li ul,
+li ol,
+dd ul,
+dd ol {
+  margin:0;
+  padding: 0 0 0 2em;
+}
+
+li li,
+dd li {
+  margin:0;
+  padding:.5em 0 0;
+}
+
+dl dl,
+ol dl,
+ul dl {
+  margin:0 0 1em;
+  padding:0;
+}
+
+table {
+  font-size:1em;
+  margin:0 0 1em;
+  padding:0;
+  border-collapse:collapse;
+  border-width:0;
+  empty-cells:show;
+}
+
+td,th {
+  border:1px solid #ccc;
+  padding:6px 12px;
+  text-align:left;
+  vertical-align:top;
+  background-color:inherit;
+}
+
+th {
+  background-color:#dee8f1;
+}
+
+td > p:last-child {
+  margin:0;
+}
+
+hr.blue {
+  background-color:#DDF0F2;
+  border:none;
+  height:5px;
+  margin:20px 0 10px;
+}
+
+blockquote {
+  margin: 0 0 1em 1em;
+  padding: 0 4em 0 1em;
+  border-left:2px solid #eee;
+}
+/* LAYOUT */
+
+#body-content {
+  /* "Preliminary" watermark for preview releases and interim builds.
+  background:transparent url(images/preliminary.png) repeat scroll 0 0; */
+  margin:0;
+  position:relative;
+  width:100%;
+}
+
+#header {
+  height: 114px;
+  position:relative;
+  z-index:100;
+  min-width:675px; /* min width for the tabs, before they wrap */
+  padding:0 10px;
+  border-bottom:3px solid #94b922;
+}
+
+#headerLeft{
+  padding: 25px 0 0;
+}
+
+#headerLeft img{
+  height:50px;
+  width:180px;
+}
+
+#headerRight {
+  position:absolute;
+  right:0;
+  top:0;
+  text-align:right;
+}
+
+/* Tabs in the header */
+
+#header ul {
+  list-style: none;
+  margin: 7px 0 0;
+  padding: 0;
+  height: 29px;
+}
+
+#header li {
+  float: left;
+  margin: 0px 2px 0px 0px;
+  padding:0;
+}
+
+#header li a {
+  text-decoration: none;
+  display: block;
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 -58px;
+  background-repeat: no-repeat;
+  color: #666;
+  font-size: 13px;
+  font-weight: bold;
+  width: 94px;
+  height: 29px;
+  text-align: center;
+  margin: 0px;
+}
+
+#header li a:hover {
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 -29px;
+  background-repeat: no-repeat;
+}
+
+#header li a span {
+  position:relative;
+  top:7px;
+}
+
+#header li a span+span {
+  display:none;
+}
+
+/* tab highlighting */
+
+.home #home-link a,
+.guide #guide-link a,
+.reference #reference-link a,
+.sdk #sdk-link a,
+.resources #resources-link a,
+.videos #videos-link a {
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 0;
+  background-repeat: no-repeat;
+  color: #fff;
+  font-weight: bold;
+  cursor:default;
+}
+
+.home #home-link a:hover,
+.guide #guide-link a:hover,
+.reference #reference-link a:hover,
+.sdk #sdk-link a:hover,
+.resources #resources-link a:hover,
+.videos #videos-link  a:hover {
+  background-image: url(images/bg_images_sprite.png);
+  background-position: 0 0;
+}
+
+#headerLinks {
+  margin:10px 10px 0 0;
+  height:13px;
+  font-size: 11px;
+  vertical-align: top;
+}
+
+#headerLinks a {
+  color: #7FA9B5;
+}
+
+#headerLinks img {
+  vertical-align:middle;
+}
+
+#language {
+  margin:0 10px 0 4px;
+}
+
+#search {
+  height:45px;
+  margin:15px 10px 0 0;
+}
+
+/* MAIN BODY */
+
+#mainBodyFluid {
+  margin: 20px 10px;
+  color:#333;
+}
+
+#mainBodyFixed {
+  margin: 20px 10px;
+  color: #333;
+  width:930px;
+  position:relative;
+}
+
+#mainBodyFixed h3,
+#mainBodyFluid h3 {
+  color:#336666;
+  font-size:1.25em;
+  margin: 0em 0em 0em 0em;
+  padding-bottom:.5em;
+}
+
+#mainBodyFixed h2,
+#mainBodyFluid h2 {
+  color:#336666;
+  font-size:1.25em;
+  margin: 0;
+  padding-bottom:.5em;
+}
+
+#mainBodyFixed h1,
+#mainBodyFluid h1 {
+  color:#435A6E;
+  font-size:1.7em;
+  margin: 1em 0;
+}
+
+#mainBodyFixed .green,
+#mainBodyFluid .green,
+#jd-content .green {
+  color:#7BB026;
+  background-color:none;
+}
+
+#mainBodyLeft {
+  float: left;
+  width: 600px;
+  margin-right: 20px;
+  color: #333;
+  position:relative;
+}
+
+div.indent {
+  margin-left: 40px;
+  margin-right: 70px;
+}
+
+#mainBodyLeft p {
+  color: #333;
+  font-size: 13px;
+}
+
+#mainBodyLeft p.blue {
+  color: #669999;
+}
+
+#mainBodyLeft #communityDiv {
+  float: left;
+  background-image:url(images/bg_community_leftDiv.jpg);
+  background-repeat: no-repeat;
+  width: 581px;
+  height: 347px;
+  padding: 20px 0px 0px 20px;
+}
+
+#mainBodyRight {
+  float: left;
+  width: 300px;
+  color: #333;
+}
+
+#mainBodyRight p {
+  padding-right: 50px;
+  color: #333;
+}
+
+#mainBodyRight table {
+  width: 100%;
+}
+
+#mainBodyRight td {
+  border:0px solid #666;
+  padding:0px 5px;
+  text-align:left;
+}
+
+#mainBodyRight td p {
+  margin:0 0 1em 0;
+}
+
+#mainBodyRight .blueBorderBox {
+  border:5px solid #ddf0f2;
+  padding:18px 18px 18px 18px;
+  text-align:left;
+}
+
+#mainBodyFixed .seperator {
+  background-image:url(images/hr_gray_side.jpg);
+  background-repeat:no-repeat;
+  width: 100%;
+  float: left;
+  clear: both;
+}
+
+#mainBodyBottom {
+  float: left;
+  width: 100%;
+  clear:both;
+  color: #333;
+}
+
+#mainBodyBottom .seperator {
+  background-image:url(images/hr_gray_main.jpg);
+  background-repeat:no-repeat;
+  width: 100%;
+  float: left;
+  clear: both;
+}
+
+/* FOOTER */
+
+#footer {
+  float: left;
+  width:90%;
+  margin: 20px;
+  color: #aaa;
+  font-size: 11px;
+}
+
+#footer a {
+  color: #aaa;
+  font-size: 11px;
+}
+
+#footer a:hover {
+  text-decoration: underline;
+  color:#aaa;
+}
+
+#footerlinks {
+  margin-top:2px;
+}
+
+#footerlinks a,
+#footerlinks a:visited {
+  color:#006699;
+}
+
+/* SEARCH FILTER */
+
+#search_autocomplete {
+  color:#aaa;
+}
+
+#search-button {
+  display:inline;
+}
+
+#search_filtered_div {
+  position:absolute;
+  margin-top:-1px;
+  z-index:101;
+  border:1px solid #BCCDF0;
+  background-color:#fff;
+}
+
+#search_filtered {
+  min-width:100%;
+}
+#search_filtered td{
+  background-color:#fff;
+  border-bottom: 1px solid #669999;
+  line-height:1.5em;
+}
+
+#search_filtered .jd-selected {
+  background-color: #94b922;
+  cursor:pointer;
+}
+#search_filtered .jd-selected,
+#search_filtered .jd-selected a {
+  color:#fff;
+}
+
+.no-display {
+  display: none;
+}
+
+.jd-autocomplete {
+  font-family: Arial, sans-serif;
+  padding-left: 6px;
+  padding-right: 6px;
+  padding-top: 1px;
+  padding-bottom: 1px;
+  font-size: 0.81em;
+  border: none;
+  margin: 0;
+  line-height: 1.05em;
+}
+
+.show-row {
+  display: table-row;
+}
+.hide-row {
+  display: hidden;
+}
+
+/* SEARCH */
+
+/* restrict global search form width */
+#searchForm {
+  width:350px;
+}
+
+#searchTxt {
+  width:200px;
+}
+
+/* disable twiddle and size selectors for left column */
+#leftSearchControl div {
+  width: 100%;
+}
+
+#leftSearchControl .gsc-twiddle {
+  background-image : none;
+}
+
+#leftSearchControl td, #searchForm td {
+  border: 0px solid #000;
+}
+
+#leftSearchControl .gsc-resultsHeader .gsc-title {
+  padding-left : 0px;
+  font-weight : bold;
+  font-size : 13px;
+  color:#006699;
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsHeader div.gsc-results-selector {
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsRoot {
+  padding-top : 6px;
+}
+
+#leftSearchControl div.gs-visibleUrl-long {
+  display : block;
+  color:#006699;
+}
+
+.gsc-webResult div.gs-visibleUrl-short,
+table.gsc-branding,
+.gsc-clear-button {
+  display : none;
+}
+
+.gsc-cursor-box .gsc-cursor div.gsc-cursor-page,
+.gsc-cursor-box .gsc-trailing-more-results a.gsc-trailing-more-results,
+#leftSearchControl a,
+#leftSearchControl a b {
+  color:#006699;
+}
+
+.gsc-resultsHeader {
+  display: none;
+}
+
+/* Disable built in search forms */
+.gsc-control form.gsc-search-box {
+  display : none;
+}
+table.gsc-search-box {
+  margin:6px 0 0 0;
+  border-collapse:collapse;
+}
+
+td.gsc-input {
+  padding:0 2px;
+  width:100%;
+  vertical-align:middle;
+}
+
+input.gsc-input {
+  border:1px solid #BCCDF0;
+  width:99%;
+  padding-left:2px;
+  font-size:.95em;
+}
+
+td.gsc-search-button {
+  text-align: right;
+  padding:0;
+  vertical-align:top;
+}
+
+#search-button {
+  margin:0 0 0 2px;
+  font-size:11px;
+}
+
+/* search result tabs */
+
+#doc-content .gsc-control {
+  position:relative;
+}
+
+#doc-content .gsc-tabsArea {
+  position:relative;
+  white-space:nowrap;
+}
+
+#doc-content .gsc-tabHeader {
+  padding: 3px 6px;
+  position:relative;
+  width:auto;
+}
+
+#doc-content .gsc-tabHeader.gsc-tabhActive {
+  border-top: 2px solid #94B922;
+}
+
+#doc-content h2#searchTitle {
+  padding:0;
+}
+
+#doc-content .gsc-resultsbox-visible {
+  padding:1em 0 0 6px;
+}
+
+/* CAROUSEL */
+
+#homeMiddle {
+  padding: 0px 0px 0px 0px;
+  float: left;
+  width: 584px;
+  height: 627px;
+  position:relative;
+}
+
+#topAnnouncement {
+  background:url(images/home/bg_home_announcement.png) no-repeat 0 0;
+}
+  
+#homeTitle {
+  padding:15px 15px 0;
+  height:30px;
+}
+
+#homeTitle h2 {
+  padding:0;
+}
+
+#announcement-block {
+  padding:0 15px 0;
+  overflow:hidden;
+  background: url(images/hr_gray_side.jpg) no-repeat 15px 0;
+  zoom:1;
+}
+
+#announcement-block>* {
+  padding:15px 0 0;
+}
+
+#announcement-block img {
+  float:left;
+  margin:0 30px 0 0;
+}
+
+#announcement {
+  float:left;
+  margin:0;
+}
+
+#carousel {
+  background:url(images/home/bg_home_carousel.png) no-repeat 0 0;
+  position:relative;
+  height:400px;
+}
+
+#carouselMain {
+  background: url(images/home/bg_home_carousel_board.png) 0 0 no-repeat;
+  height:auto;
+  padding: 25px 21px 0;
+  overflow:hidden;
+  position:relative;
+  zoom:1; /*IE6*/
+}
+
+#carouselMain img {
+  margin:0;
+}
+
+#carouselMain .bulletinDesc h3 {
+  margin:0;
+  padding:0;
+}
+
+#carouselMain .bulletinDesc p {
+  margin:0;
+  padding:0.7em 0 0;
+}
+
+#carouselWheel {
+  background: url(images/home/bg_home_carousel_wheel.png) 0 0 no-repeat;
+  padding-top:40px;
+  height:150px;
+}
+
+.clearer { clear:both; }
+
+a#arrow-left, a#arrow-right {
+  float:left;
+  width:42px;
+  height:42px;
+  background-image:url(images/home/carousel_buttons_sprite.png);
+  background-repeat:no-repeat;
+}
+a#arrow-left {
+  margin:35px 3px 0 10px;
+}
+a#arrow-right {
+  margin:35px 10px 0 0;
+}
+a.arrow-left-off,
+a#arrow-left.arrow-left-off:hover {
+  background-position:0 0;
+}
+a.arrow-right-off,
+a#arrow-right.arrow-right-off:hover {
+  background-position:-42px 0;
+}
+a#arrow-left:hover {
+  background-position:0 -42px;
+}
+a#arrow-right:hover {
+  background-position:-42px -42px;
+}
+a.arrow-left-on {
+  background-position:0 0;
+}
+a.arrow-right-on {
+  background-position:-42px 0;
+}
+a.arrow-right-off,
+a.arrow-left-off {
+  cursor:default;
+}
+
+.app-list-container {
+  margin:0 20px;
+  position:relative;
+  width:100%;
+}
+
+div#list-clip {
+  height:110px;
+  width:438px;
+  overflow:hidden;
+  position:relative;
+  float:left;
+}
+
+div#app-list {
+  left:0;
+  z-index:1;
+  position:absolute;
+  margin:11px 0 0;
+  _margin-top:13px;
+  width:1000%;
+}
+
+#app-list a {
+  display:block;
+  float:left;
+  height:90px;
+  width:90px;
+  margin:0 24px 0;
+  padding:3px;
+  background:#99cccc;
+  -webkit-border-radius:7px;
+  -moz-border-radius:7px;
+  border-radius:7px;
+  text-decoration:none;
+  text-align:center;
+  font-size:11px;
+  line-height:11px;
+}
+
+#app-list a span {
+  position:relative;
+  top:-4px;
+}
+
+#app-list img {
+  width:90px;
+  height:70px;
+  margin:0;
+}
+
+#app-list a.selected,
+#app-list a:active.selected,
+#app-list a:hover.selected {
+  background:#A4C639;
+  color:#fff;
+  cursor:default;
+  text-decoration:none;
+}
+
+#app-list a:hover,
+#app-list a:active {
+  background:#ff9900;
+}
+
+#app-list a:hover span,
+#app-list a:active span {
+  text-decoration:underline;
+}
+
+#droid-name {
+  padding-top:.5em;
+  color:#666;
+  padding-bottom:.25em;
+}
+
+/*IE6*/
+* html #app-list a { zoom: 1; margin:0 24px 0 15px;}
+
+* html #list-clip {
+  width:430px !important;
+}
+
+/*carousel bulletin layouts*/
+/*460px width*/
+/*185px height*/
+.img-left {
+  float:left;
+  width:230px;
+  overflow:hidden;
+  padding:8px 0 8px 8px;
+}
+.desc-right {
+  float:left;
+  width:270px;
+  padding:10px;
+}
+.img-right {
+  float:right;
+  width:220px;
+  overflow:hidden;
+  padding:8px 8px 8px 0;
+}
+.desc-left {
+  float:right;
+  width:280px;
+  padding:10px;
+  text-align:right;
+}
+.img-top {
+  padding:20px 20px 0;
+}
+.desc-bottom {
+  padding:10px;
+}
+
+
+/* VIDEO PAGE */
+
+#mainBodyLeft.videoPlayer {
+  width:570px;
+}
+
+#mainBodyRight.videoPlayer {
+  width:330px;
+}
+
+/* player */
+
+#videoPlayerBox {
+  background-color: #DAF3FC;
+  border-radius:7px;
+  -moz-border-radius:7px;
+  -webkit-border-radius:7px;
+  width:530px;
+  padding:20px;
+  border:1px solid #d3ecf5;
+  box-shadow:2px 3px 1px #eee;
+  -moz-box-shadow:2px 3px 1px #eee;
+  -webkit-box-shadow:2px 3px 1px #eee;
+}
+
+#videoBorder {
+  background-color: #FFF;
+  min-height:399px;
+  height:auto !important;
+  border:1px solid #ccdada;
+  border-radius:7px 7px 0 0;
+  -moz-border-radius:7px 7px 0 0;
+  -webkit-border-top-left-radius:7px;
+  -webkit-border-top-right-radius:7px;
+}
+
+#videoPlayerTitle {
+  width:500px;
+  padding:15px 15px 0;
+}
+
+#videoPlayerTitle h2 {
+  font-weight:bold;
+  font-size:1.2em;
+  color:#336666;
+  margin:0;
+  padding:0;
+}
+
+#objectWrapper {
+  padding:15px 15px;
+  height:334px;
+  width:500px;
+}
+
+/* playlist tabs */
+
+ul#videoTabs {
+  list-style-type:none;
+  padding:0;
+  clear:both;
+  margin:0;
+  padding: 20px 0 0 15px;
+  zoom:1; /* IE7/8, otherwise top-padding is double */
+}
+
+ul#videoTabs li {
+  display:inline;
+  padding:0;
+  margin:0 3px 0 0;
+  line-height:2em;
+}
+
+ul#videoTabs li a {
+  border-radius:7px 7px 0 0;
+  -moz-border-radius:7px 7px 0 0;
+  -webkit-border-top-left-radius:7px;
+  -webkit-border-top-right-radius:7px;
+  background:#95c0d0;
+  color:#fff;
+  text-decoration:none;
+  padding:.45em 1.5em;
+  font-weight:bold;
+}
+
+ul#videoTabs li.selected a {
+  font-weight:bold;
+  text-decoration:none;
+  color:#555;
+  background:#daf3fc;
+  border-bottom:1px solid #daf3fc;
+}
+
+ul#videoTabs li:hover a {
+  background:#85acba;
+}
+
+ul#videoTabs li.selected:hover a {
+  background:#daf3fc;
+}
+
+/* playlists */
+
+#videos {
+  background:#daf3fc;
+  margin-bottom:1.5em;
+  padding:15px;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+  box-shadow:2px 3px 1px #eee;
+  -moz-box-shadow:2px 3px 1px #eee;
+  -webkit-box-shadow:2px 3px 1px #eee;
+}
+
+#videos div {
+  display:none;
+}
+
+#videos div.selected {
+  display:block;
+}
+
+ul.videoPreviews {
+  list-style:none;
+  padding:0;
+  margin:0;
+  zoom:1; /* IE, otherwise, layout doesn't update when showing 'more' */
+}
+
+ul.videoPreviews li {
+  margin:0 0 5px;
+  padding:0;
+  overflow:hidden;
+  position:relative;
+}
+
+#mainBodyFixed ul.videoPreviews h3 {
+  font-size: 12px;
+  margin:0 0 1em 130px;
+  padding:0;
+  font-weight:bold;
+  color:inherit;
+}
+
+ul.videoPreviews a {
+  margin:1px;
+  padding:10px;
+  text-decoration:none;
+  height:90px;
+  display:block;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+  background-color:transparent;
+}
+
+ul.videoPreviews a:hover {
+  background-color:#FFF;
+  border:none; /* IE8, otherwise, bg doesn't work */
+}
+
+ul.videoPreviews a.selected {
+  background-color: #FF9900;
+}
+
+ul.videoPreviews img {
+  float:left;
+  clear:left;
+  margin:0;
+}
+
+ul.videoPreviews h3 {
+  font-size:12px;
+  font-weight:bold;
+  text-decoration:none;
+  margin:0 0 1em 130px;
+  padding:0;
+}
+
+ul.videoPreviews p {
+  font-size: 12px;
+  text-decoration:none;
+  margin:0 0 1.2em 130px;
+}
+
+ul.videoPreviews p.full {
+  display:none;
+}
+
+ul.videoPreviews span.more {
+  padding:0 0 0 12px;
+  background:url(images/arrow_bluelink_down.png) 0 2px no-repeat;
+}
+
+ul.videoPreviews span.less {
+  padding:0 0 0 12px;
+  background:url(images/arrow_bluelink_up.png) 0 2px no-repeat;
+  display:none;
+}
+
+ul.videoPreviews p.toggle {
+  position:absolute;
+  margin:0;
+  margin-top:-23px; /* instead of bottom:23px, because IE won't do it correctly */
+  left:140px;
+}
+
+ul.videoPreviews p.toggle a {
+  height:auto;
+  margin:0;
+  padding:0;
+  zoom:1; /* IE6, otherwise the margin considers the img on redraws */
+}
+
+ul.videoPreviews p.toggle a:hover {
+  text-decoration:underline;
+  background:transparent; /* IE6, otherwise it inherits white */
+}
+
+/* featured videos */
+
+#mainBodyRight h2 {
+  padding:0 0 5px;
+}
+
+#mainBodyRight ul.videoPreviews {
+  margin:10px 0 0;
+}
+
+#mainBodyRight ul.videoPreviews li {
+  font-size:11px;
+  line-height:13px;
+  margin:0 0 5px;
+  padding:0;
+}
+
+#mainBodyRight ul.videoPreviews h3 {
+  padding:0;
+  margin:0;
+  font-size:100%;
+}
+
+#mainBodyRight ul.videoPreviews a {
+  text-decoration:none;
+  height:108px;
+  border:1px solid #FFF;
+}
+
+#mainBodyRight ul.videoPreviews a:hover {
+  border:1px solid #CCDADA;
+}
+
+#mainBodyRight ul.videoPreviews a.selected {
+  border:1px solid #FFF;
+}
+
+#mainBodyRight ul.videoPreviews p {
+  line-height:1.2em;
+  padding:0;
+  margin:4px 0 0 130px;
+}
+
+#mainBodyRight ul.videoPreviews img {
+  margin-top:5px;
+}
+
+/* Pretty printing styles. Used with prettify.js. */
+
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+dl.tag-list dt code,
+.tag { color: #008; }
+dl.atn-list dt code,
+.atn { color: #828; }
+.atv { color: #080; }
+.dec { color: #606; }
+
+@media print {
+  .str { color: #060; }
+  .kwd { color: #006; font-weight: bold; }
+  .com { color: #600; font-style: italic; }
+  .typ { color: #404; font-weight: bold; }
+  .lit { color: #044; }
+  .pun { color: #440; }
+  .pln { color: #000; }
+  .tag { color: #006; font-weight: bold; }
+  .atn { color: #404; }
+  .atv { color: #060; }
+}
+
+
+#title {
+  border-bottom: 4px solid #ccc;
+  display:none;
+}
+
+#title h1 {
+  color:#336666;
+  margin:0;
+  padding: 5px 10px;
+  font-size: 1em;
+  line-height: 15px;
+}
+
+#title h1 .small{
+  color:#000;
+  margin:0;
+  font-size: 13px;
+  padding:0 0 0 15px;
+}
+
+/* SIDE NAVIGATION */
+
+#side-nav {
+  padding:0 6px 0 0;
+  background-color: #fff;
+  font-size:12px;
+}
+
+#resize-packages-nav {
+/* keeps the resize handle below the h-scroll handle */
+  height:270px;
+  overflow:hidden;
+  max-height:100%;
+}
+
+#packages-nav {
+  height:270px;
+  max-height:inherit;
+  position:relative;
+  overflow:auto;
+}
+
+#classes-nav,
+#devdoc-nav {
+  overflow:auto;
+  position:relative;
+}
+
+#side-nav ul {
+  list-style: none;
+  margin: 0;
+  padding:5px 0;
+}
+
+#side-nav ul ul {
+  margin: .5em 0 0 0;
+  padding: 0;
+}
+
+#side-nav li {
+  padding:0;
+  padding:1px 0 1px 0;
+  zoom:1;
+}
+
+#side-nav li span.heading,
+#side-nav li h2 {
+  display:block;
+  font-size:12px;
+  font-weight: bold;
+  margin:.5em 0 0 0;
+  padding: 3px 0 1px 9px;
+}
+
+#side-nav li a {
+  display: inline-block; /* needed to apply padding to line-wraps */
+  text-decoration:none;
+  padding: 0 0 0 18px;
+  zoom:1;
+}
+
+#side-nav li a span+span {
+  display:none;
+}
+
+#side-nav li a:hover {
+  text-decoration:underline;
+}
+
+#side-nav li a+a {
+  padding: 0;
+}
+/*second level (nested) list*/
+#side-nav li li li a {
+  padding: 0 0 0 28px;
+}
+/*third level (nested) list*/
+#side-nav li li li li a {
+  padding: 0 0 0 38px;
+}
+
+#side-nav .selected {
+  background-color: #435a6e;
+  color: #fff;
+  font-weight:bold;
+}
+
+#side-nav .selected a {
+  color: #fff;
+  text-decoration:none;
+}
+
+#side-nav strong {
+  display:block;
+}
+
+#side-nav .toggle-list .toggle-img {
+  margin:0;
+  padding:0;
+  position:absolute;
+  top:0;
+  left:0;
+  height:16px;
+  width:15px;
+  outline-style:none;
+}
+/* second-level toggle */
+#side-nav .toggle-list .toggle-list .toggle-img {
+  left:10px;
+}
+
+#side-nav .closed .toggle-img,
+#side-nav .open .closed .toggle-img {
+  background:url('images/triangle-closed-small.png') 7px 4px no-repeat;
+}
+#side-nav .open .toggle-img {
+  background:url('images/triangle-opened-small.png') 7px 4px no-repeat;
+}
+
+#side-nav .toggle-list {
+  position:relative;
+}
+
+#side-nav .toggle-list ul {
+  margin:0;
+  display:none;
+}
+
+#side-nav .toggle-list div {
+  display:block;
+}
+
+#index-links .selected {
+  background-color: #fff;
+  color: #000;
+  font-weight:normal;
+  text-decoration:none;
+}
+
+#index-links {
+  padding:7px 0 4px 10px;
+}
+
+/* nav tree */
+
+#nav-tree ul {
+  padding:5px 0 1.5em;
+}
+
+#side-nav #nav-tree ul li a,
+#side-nav #nav-tree ul li span.no-children {
+  padding: 0 0 0 0;
+  margin: 0;
+}
+
+#nav-tree .plus {
+  margin: 0 3px 0 0;
+}
+
+#nav-tree ul ul {
+  list-style: none;
+  margin: 0;
+  padding: 0 0 0 0;
+}
+
+#nav-tree ul li {
+  margin: 0;
+  padding: 0 0 0 0;
+  white-space: nowrap;
+}
+
+#nav-tree .children_ul {
+  margin:0;
+}
+
+#nav-tree a.nolink {
+  color: black;
+  text-decoration: none;
+}
+
+#nav-tree span.label {
+  width: 100%;
+}
+
+#nav-tree {
+  overflow-x: auto;
+  overflow-y: scroll;
+}
+
+#nav-swap {
+  font-size:10px;
+  line-height:10px;
+  margin-left:1em;
+  text-decoration:none;
+  display:block;
+}
+
+#tree-link {
+
+}
+
+/* DOCUMENT BODY */
+
+#doc-content {
+  overflow:auto;
+}
+
+#jd-header {
+  background-color: #E2E2E2;
+  padding: 7px 15px;
+}
+
+#jd-header h1 {
+  margin: 0 0 10px;
+  font-size:1.7em;
+}
+
+#jd-header .crumb {
+  font-size:.9em;
+  line-height:1em;
+  color:#777;
+}
+
+#jd-header .crumb a,
+#jd-header .crumb a:visited {
+  text-decoration:none;
+  color:#777;
+}
+
+#jd-header .crumb a:hover {
+  text-decoration:underline;
+}
+
+#jd-header table {
+  margin:0;
+  padding:0;
+}
+
+#jd-header td {
+  border:none;
+  padding:0;
+  vertical-align:top;
+}
+
+#jd-header.guide-header {
+  background-color:#fff;
+  color:#435a6e;
+  height:50px;
+}
+
+#jd-descr {
+  position:relative;
+}
+
+/* summary tables for reference pages */
+.jd-sumtable {
+  margin: .5em 1em 1em 1em;
+  width:95%; /* consistent table widths; within IE's quirks */
+  font-size:.9em;
+}
+
+.jd-sumtable a {
+  text-decoration:none;
+}
+
+.jd-sumtable a:hover {
+  text-decoration:underline;
+}
+
+/* the link inside a sumtable for "Show All/Hide All" */
+.toggle-all {
+  display:block;
+  float:right;
+  font-weight:normal;
+  font-size:0.9em;
+}
+
+/* adjustments for in/direct subclasses tables */
+.jd-sumtable-subclasses {
+  margin: 1em 0 0 0;
+  max-width:968px;
+}
+
+/* extra space between end of method name and open-paren */
+.sympad {
+  margin-right: 2px;
+}
+
+/* right alignment for the return type in sumtable */
+.jd-sumtable .jd-typecol {
+  text-align:right;
+}
+
+/* adjustments for the expando table-in-table */
+.jd-sumtable-expando {
+  margin:.5em 0;
+  padding:0;
+}
+
+/* a div that holds a short description */
+.jd-descrdiv {
+  padding:3px 1em 0 1em;
+  margin:0;
+  border:0;
+}
+
+/* page-top-right container for reference pages (holds
+links to summary tables) */
+#api-info-block {
+  font-size:.8em;
+  padding:6px 10px;
+  font-weight:normal;
+  float:right;
+  text-align:right;
+  color:#999;
+  max-width:70%;
+}
+
+#api-level-toggle {
+  padding:0 10px;
+  font-size:11px;
+  float:right;
+}
+
+#api-level-toggle label.disabled {
+  color:#999;
+}
+
+div.api-level {
+  font-size:.8em;
+  font-weight:normal;
+  color:#999;
+  float:right;
+  padding:0 7px 0;
+  margin-top:-25px;
+}
+
+#api-info-block div.api-level {
+  font-size:1.3em;
+  font-weight:bold;
+  float:none;
+  color:#444;
+  padding:0;
+  margin:0;
+}
+
+/* Force link colors for IE6 */
+div.api-level a {
+  color:#999;
+}
+#api-info-block div.api-level a:link {
+  color:#444;
+}
+#api-level-toggle a {
+  color:#999;
+}
+
+div#deprecatedSticker {
+  display:none;
+  z-index:99;
+  position:fixed;
+  right:15px;
+  top:114px;
+  margin:0;
+  padding:1em;
+  background:#FFF;
+  border:1px solid #dddd00;
+  box-shadow:-5px 5px 10px #ccc;
+  -moz-box-shadow:-5px 5px 10px #ccc;
+  -webkit-box-shadow:-5px 5px 10px #ccc;
+}
+
+div#naMessage {
+  display:none;
+  width:555px;
+  height:0;
+  margin:0 auto;
+}
+
+div#naMessage div {
+  z-index:99;
+  width:450px;
+  position:fixed;
+  margin:50px 0;
+  padding:4em 4em 3em;
+  background:#FFF;
+  border:1px solid #dddd00;
+  box-shadow:-10px 10px 40px #888;
+  -moz-box-shadow:-10px 10px 40px #888;
+  -webkit-box-shadow:-10px 10px 40px #888;
+}
+/* IE6 can't position fixed */
+* html div#naMessage div { position:absolute; }
+
+div#naMessage strong {
+  font-size:1.1em;
+}
+
+.absent,
+.absent a:link,
+.absent a:visited,
+.absent a:hover,
+.absent * {
+  color:#bbb !important;
+  cursor:default !important;
+  text-decoration:none !important;
+}
+
+#api-level-toggle a,
+.api-level a {
+  color:inherit;
+  text-decoration:none;
+}
+
+#api-level-toggle a:hover,
+.api-level a:hover {
+  color:inherit;
+  text-decoration:underline !important;
+  cursor:pointer !important;
+}
+
+#side-nav li.absent.selected,
+#side-nav li.absent.selected *,
+#side-nav div.label.absent.selected,
+#side-nav div.label.absent.selected * {
+  background-color:#eaeaea !important;
+}
+/* IE6 quirk (won't chain classes, so just keep background blue) */
+* html #side-nav li.selected,
+* html #side-nav li.selected *,
+* html #side-nav div.label.selected,
+* html #side-nav div.label.selected * {
+  background-color: #435a6e !important;
+}
+
+
+.absent h4.jd-details-title,
+.absent h4.jd-details-title * {
+  background-color:#f6f6f6 !important;
+}
+
+.absent img {
+  opacity: .3;
+  filter: alpha(opacity=30);
+  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
+}
+
+
+/* applies to a div containing links to summary tables */
+.sum-details-links {
+  padding:0;
+  font-weight:normal;
+}
+
+.sum-details-links a {
+  text-decoration:none;
+}
+
+.sum-details-links a:hover {
+  text-decoration:underline;
+}
+
+
+/* inheritance table */
+.jd-inheritance-table {
+  border-spacing:0;
+  margin:0;
+  padding:0;
+  font-size:.9em;
+}
+.jd-inheritance-table td {
+  border: none;
+  margin: 0;
+  padding: 0;
+}
+.jd-inheritance-table .jd-inheritance-space {
+  font-weight:bold;
+  width:1em;
+}
+.jd-inheritance-table .jd-inheritance-interface-cell {
+  padding-left: 17px;
+}
+
+#jd-content {
+  padding: 18px 15px;
+}
+
+hr {
+  background-color:#ccc;
+  border-color:#fff;
+  margin:2em 0 1em;
+}
+
+/* DOC CLASSES */
+
+#jd-content h1 {
+/*sdk page*/
+  font-size:1.6em;
+  color:#336666;
+  margin:0 0 .5em;
+}
+
+#jd-content h2 {
+  font-size:1.45em;
+  color:#111;
+  border-top:2px solid #ccc;
+  padding: .5em 0 0;
+  margin: 2em 0 1em 0;
+}
+
+#jd-content h3 {
+  font-size:1.3em;
+  color:#3a3a3a;
+  padding: 0;
+  margin: 1.5em 0 .65em 0;
+}
+
+#jd-content h4 {
+  font-size:1.1em;
+  color:#3a3a3a;
+  padding: 0;
+  margin: 1.25em 0 .65em 0;
+}
+
+#jd-content h5 {
+  font-size:1.0em;
+  color:#3a3a3a;
+  padding: 0;
+  margin: 1em 0 .65em 0;
+}
+
+#jd-content .small-header {
+  font-size:1em;
+  color:#000;
+  font-weight:bold;
+  border:none;
+  padding:0;
+  margin:1em 0 .5em;
+  position:inherit;
+}
+
+#jd-content table {
+  margin: 0 0 1em 1em;
+}
+
+#jd-content img {
+  margin: 0 0 1em 1em;
+}
+
+#jd-content li img,
+#jd-content dd img {
+  margin:.5em 0 .5em 1em;
+}
+
+.nolist {
+  list-style:none;
+  padding:0;
+  margin:0 0 1em 1em;
+}
+
+.nolist li {
+  padding:0 0 2px;
+  margin:0;
+}
+
+h4 .normal {
+  font-size:.9em;
+  font-weight:normal;
+}
+
+.caps {
+  font-variant:small-caps;
+  font-size:1.2em;
+}
+
+dl.tag-list dl.atn-list {
+  padding:0 0 0 2em;
+}
+
+.jd-details {
+/*  border:1px solid #669999;
+  padding:4px; */
+  margin:0 0 1em;
+}
+
+/* API reference: a container for the
+.tagdata blocks that make up the detailed
+description */
+.jd-details-descr {
+  padding:0;
+  margin:.5em .25em;
+}
+
+/* API reference: a block containing
+a detailed description, a params table,
+seealso list, etc */
+.jd-tagdata {
+  margin:.5em 1em;
+}
+
+.jd-tagdata p {
+  margin:0 0 1em 1em;
+}
+
+/* API reference: adjustments to
+the detailed description block */
+.jd-tagdescr {
+  margin:.25em 0 .75em 0;
+  line-height:1em;
+}
+
+.jd-tagdescr p {
+  margin:.5em 0;
+  padding:0;
+
+}
+
+.jd-tagdescr ol,
+.jd-tagdescr ul {
+  margin:0 2.5em;
+  padding:0;
+}
+
+.jd-tagdescr table,
+.jd-tagdescr img {
+  margin:.25em 1em;
+}
+
+.jd-tagdescr li {
+margin:0 0 .25em 0;
+padding:0;
+}
+
+/* API reference: heading marking
+the details section for constants,
+attrs, methods, etc. */
+h4.jd-details-title {
+  font-size:1.15em;
+  background-color: #E2E2E2;
+  margin:1.5em 0 .6em;
+  padding:3px 95px 3px 3px; /* room for api-level */
+}
+
+h4.jd-tagtitle {
+  margin:0;
+}
+
+/* API reference: heading for "Parameters", "See Also", etc.,
+in details sections */
+h5.jd-tagtitle {
+  margin:0 0 .25em 0;
+  font-size:1em;
+}
+
+.jd-tagtable {
+  margin:0;
+}
+
+.jd-tagtable td,
+.jd-tagtable th {
+  border:none;
+  background-color:#fff;
+  vertical-align:top;
+  font-weight:normal;
+  padding:2px 10px;
+}
+
+.jd-tagtable th {
+  font-style:italic;
+}
+
+#jd-content table h2 {
+  background-color: #d6d6d6;
+  font-size: 1.1em;
+  margin:0 0 10px;
+  padding:5px;
+  left:0;
+  width:auto;
+}
+
+div.design-announce {
+  border-top:1px solid #33B5E5;
+  border-bottom:1px solid #33B5E5;
+  padding:5px 10px 10px 55px;
+  margin:2em 0;
+  background:url('images/icon_design.png') 5px 13px no-repeat;
+}
+
+div.design-announce p {
+  margin: .5em 0 0 0;
+}
+
+div.special {
+  padding: .5em 1em 1em 1em;
+  margin: 0 0 1em;
+  background-color: #DAF3FC;
+  border:1px solid #d3ecf5;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+}
+
+div.special p {
+  margin: .5em 0 0 0;
+}
+
+div.special ol {
+  margin: 0;
+}
+
+div.special ol li {
+  margin: 0;
+  padding: 0;
+}
+
+#jd-content div.special h2,
+#jd-content div.special h3 {
+  color:#669999;
+  font-size:1.2em;
+  border:none;
+  margin:0 0 .5em;
+  padding:0;
+}
+
+#jd-content div.special.reference h2,
+#jd-content div.special.reference h3,
+#jd-content div.special.reference h4 {
+  color:#000;
+  font-size:1em;
+  border:none;
+  font-weight:bold;
+  margin:.5em 0;
+  padding:0;
+}
+
+p.note, div.note,
+p.caution, div.caution,
+p.warning, div.warning {
+  margin: 1em;
+  padding: 0 0 0 .5em;
+  border-left: 4px solid;
+}
+
+p.special-note,
+div.special-note {
+  background-color:#EBF3DB;
+  padding:10px 20px;
+  margin:0 0 1em;
+}
+
+p.note,
+div.note {
+ border-color: #99aacc;
+}
+
+p.warning,
+div.warning {
+  border-color: #aa0033;
+}
+
+p.caution,
+div.caution {
+  border-color: #ffcf00;
+}
+
+li .note,
+li .caution,
+li .warning {
+  margin: .5em 0 0 0;
+  padding: .2em .5em .2em .9em;
+}
+
+/* Makes sure the first paragraph does not add top-whitespace within the box*/
+li .note>p:first-child,
+li .caution>p:first-child,
+li .warning>p:first-child {
+  margin-top:0;
+  padding-top:0;
+}
+
+dl.xml dt {
+  font-variant:small-caps;
+  font-size:1.2em;
+}
+
+dl.xml dl {
+  padding:0;
+}
+
+dl.xml dl dt {
+  font-variant:normal;
+  font-size:1em;
+}
+
+.listhead li {
+  font-weight: bold;
+}
+
+.listhead li *, /*ie*/.listhead li li {
+  font-weight: normal;
+}
+
+ol.no-style,
+ul.no-style {
+  list-style:none;
+  padding-left:1em;
+}
+
+.new,
+.new-child {
+  font-size: .78em;
+  font-weight: bold;
+  color: #ff3d3d;
+  text-decoration: none;
+  vertical-align:top;
+  line-height:.9em;
+  white-space:nowrap;
+}
+
+.toggle-list.open .new-child {
+  display:none;
+}
+
+pre.classic {
+  background-color:transparent;
+  border:none;
+  padding:0;
+}
+
+p.img-caption {
+  margin: -0.5em 0 1em 1em; /* matches default img left-margin */
+}
+
+div.figure {
+  float:right;
+  clear:right;
+  margin:1em 0 0 0;
+  padding:0 0 0 3em;
+  background-color:#fff;
+  /* width must be defined w/ an inline style matching the image width */
+}
+
+#jd-content
+div.figure img {
+  margin: 0 0 1em;
+}
+
+div.figure p.img-caption {
+  margin: -0.5em 0 1em 0;
+}
+
+p.table-caption {
+  margin: 0 0 0.5em 1em; /* matches default table left-margin */
+}
+
+
+/* toggle for misc content (such as long sample code) 
+   see toggleContent() script in android-developer-docs.js */
+.toggle-content.closed .toggle-content-toggleme {
+  display:none;
+}
+
+.toggle-content a[href="#"] {
+  text-decoration:none;
+  color:inherit;
+}
+
+.toggle-content-toggleme {
+  padding-bottom:1px; /* fixes animation bounce due to margins */
+}
+
+#jd-content .toggle-content img.toggle-content-img {
+  margin:0;
+}
+
+
+/* BEGIN quickview sidebar element styles */
+
+#qv-wrapper {
+  float: right;
+  width:310px; /* +35px padding */
+  background-color:#fff;
+  margin:-48px 0 2px 0;
+  padding:0 0 20px 35px;
+}
+
+#qv {
+  background-color:#fff;
+  border:4px solid #dee8f1;
+  margin:0;
+  padding:0 5px 5px;
+  width:292px; /* +10px padding; +8px border */
+  font-size:.9em;
+}
+
+#qv ol {
+  list-style:none;
+  padding: 0;
+}
+
+#qv ol ol{
+  list-style:none;
+  padding: 0 0 0 12px;
+  margin:0;
+}
+
+#qv ul {
+  padding: 0 10px 0 2em;
+}
+
+#qv li {
+  padding: 0 10px 3px;
+  line-height: 1.2em;
+}
+
+#qv li li {
+  padding: 3px 10px 0;
+}
+
+#qv ul li {
+  padding: 0 10px 0 0;
+}
+
+#qv li.selected a {
+  color:#555;
+  text-decoration:none;
+}
+
+#qv a,
+#qv a code {
+  color:#cc6600;
+}
+
+#qv p {
+  margin:8px 0 0;
+  padding:0 10px;
+}
+
+#jd-content #qv h2 {
+  font-size:1.05em;
+  font-weight:bold;
+  margin:12px 0 .25em 0;
+  padding:0 10px;
+  background-color:transparent;
+  color:#7BB026;
+  border:none;
+  left:0;
+  z-index:1;
+}
+
+#qv-extra #rule {
+  padding: 0 10px;
+  margin: 0;
+}
+
+#qv-sub-rule {
+  padding: 5px 15px 10px;
+  margin: 0;
+}
+
+#jd-content
+#qv-sub-rule h2 {
+  margin: 0 0 .5em 0;
+}
+
+/* END quickview sidebar element styles */
+
+/* Begin sidebox sidebar element styles */
+
+.sidebox-wrapper {
+  float:right;
+  clear:right;
+  width:310px; /* +35px padding */
+  background-color:#fff;
+  margin:0;
+  padding:0 0 20px 35px;
+}
+
+.sidebox {
+  border-left:1px solid #dee8f1;
+  background-color:#ffffee;
+  margin:0;
+  padding:8px 12px;
+  font-size:0.9em;
+  width:285px; /* +24px padding; +1px border */
+}
+
+.sidebox p {
+  margin-bottom: .75em;
+}
+
+.sidebox ul {
+  padding: 0 0 0 1.5em;
+}
+
+.sidebox li ul {
+  margin-top:0;
+  margin-bottom:.1em;
+}
+
+.sidebox li {
+padding:0 0 0 0em;
+}
+
+#jd-content .sidebox h2,
+#jd-content .sidebox h3,
+#jd-content .sidebox h4,
+#jd-content .sidebox h5 {
+  border:none;
+  font-size:1em;
+  margin:0;
+  padding:0 0 8px;
+  left:0;
+  z-index:0;
+}
+
+.sidebox hr {
+  background-color:#ccc;
+  border:none;
+}
+
+/* End sidebox sidebar element styles */
+
+/* BEGIN developer training bar styles */
+
+div#tb-wrapper {
+  float: right;
+  clear:right;
+  width:380px; /* +25px padding = 405 */
+  background-color:#fff;
+  margin:0 0 2px 0;
+  padding:0 0 20px 25px;
+}
+
+div#tb {
+  margin:0;
+  padding:0 15px;
+  width:350px; /* +15px padding = 380 */
+  font-size:.9em;
+  background:#e9e9e9;
+  border:1px solid #aaa;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+  overflow:auto;
+}
+
+div#tb h2 {
+  font-size:1.3em;
+  font-weight:bold;
+  margin:1em 0;
+  padding:0;
+  background-color:transparent;
+  border:none;
+  clear:both;
+}
+
+div.download-box a.button {
+  color: #069;
+  font-size:1.1em;
+  font-weight:bold;
+  text-decoration:none;
+  height:27px;
+  line-height:27px;
+  text-align:center;
+  padding:5px 8px;
+  background-color: #fff;
+  border: 1px solid #aaa;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+}
+
+div.download-box a.button:hover {
+  border-color: #09C;
+  background-color: #4CADCB;
+  background-image: -webkit-gradient(linear,left top,left bottom,from(#5dbcd9),to(#4cadcb));
+  background-image: -webkit-linear-gradient(top,#5dbcd9,#4cadcb);
+  background-image: -moz-linear-gradient(top,#5dbcd9,#4cadcb);
+  background-image: -ms-linear-gradient(top,#5dbcd9,#4cadcb);
+  background-image: -o-linear-gradient(top,#5dbcd9,#4cadcb);
+  background-image: linear-gradient(top,#5dbcd9,#4cadcb);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#5dbcd9',EndColorStr='#4cadcb');
+  color: #fff;
+}
+
+div.download-box a.button:active {
+  background-color: #1E799A;
+  background-image: none;
+  border-color: #30B7E6;
+}
+
+div.download-box p.filename {
+  font-size:0.85em;
+  color:#888;
+  margin:4px 0 1em 10px;
+}
+
+/* End developer training bar */
+
+/* Training nav bar (previous/next) */
+
+div.training-nav-top {
+  float: right;
+  width:380px; /* +25px padding = 405 */
+  margin:-58px 0 0 0;
+  padding:0 0 20px 25px;
+}
+
+div.training-nav-bottom {
+  padding:1px; /* for weird FF bug (scrollbar appears) */
+  margin:3em 0;
+  overflow:auto;
+}
+
+div.training-nav-button-next a,
+div.training-nav-button-previous a {
+  display:block;
+  width:160px;
+  height:55px;
+  padding:4px 7px;
+  border:1px solid #aaa;
+  border-radius:5px;
+  -moz-border-radius:5px;
+  -webkit-border-radius:5px;
+  text-decoration:none;
+  font-weight:bold;
+}
+
+div.training-nav-button-next a:hover,
+div.training-nav-button-previous a:hover {
+  border:1px solid #069; /* match link color */
+}
+
+div.training-nav-button-next a:active,
+div.training-nav-button-previous a:active {
+  border:1px solid #f00; /* match link color */
+}
+  
+div.training-nav-button-previous {
+  float:left;
+  text-align:left;
+}
+
+div.training-nav-button-next {
+  float:right;
+  text-align:right;
+}
+
+span.training-nav-button-title {
+  display:block;
+  font-size:.85em;
+  font-weight:normal;
+  line-height:1.3em;
+  margin:.5em 0 0;
+}
+
+/* End training nav bar */
+
+/* BEGIN image and caption styles (originally for UI Guidelines docs) */
+
+table.image-caption {
+  padding:0;
+  margin:.5em 0;
+  border:0;
+}
+
+td.image-caption-i {
+  font-size:92%;
+  padding:0 5px;
+  margin:0;
+  border:0;
+}
+
+td.image-caption-i img {
+  padding:0 1em;
+  margin:0;
+}
+
+.image-list {
+  width:24px;
+  text-align:center;
+}
+
+td.image-caption-c {
+  font-size:92%;
+  padding:1em 2px 2px 2px;
+  margin:0;
+  border:0;
+  width:350px;
+}
+
+.grad-rule-top {
+background-image:url(images/grad-rule-qv.png);
+background-repeat:no-repeat;
+padding-top:1em;
+margin-top:0;
+}
+
+.image-caption-nested {
+  margin-top:0;
+  padding:0 0 0 1em;
+}
+
+.image-caption-nested td {
+  padding:0 4px 2px 0;
+  margin:0;
+  border:0;
+}
+
+/* END image and caption styles */
+
+/* table of contents */
+
+ol.toc {
+  margin: 0 0 1em 0;
+  padding: 0;
+  list-style: none;
+  font-size:95%;
+}
+
+ol.toc li {
+  font-weight: bold;
+  margin: 0 0 .5em 1em;
+  padding: 0;
+}
+
+ol.toc li p {
+  font-weight: normal;
+}
+
+ol.toc li ol {
+  margin: 0;
+  padding: 0;
+}
+
+ol.toc li li {
+  padding: 0;
+  margin: 0 0 0 1em;
+  font-weight: normal;
+  list-style: none;
+}
+
+table ol.toc {
+  margin-left: 0;
+}
+
+.columns td {
+  padding:0 5px;
+  border:none;
+}
+
+/* link table */
+.jd-linktable {
+  margin: 0 0 1em;
+  border-bottom: 1px solid #888;
+}
+.jd-linktable th,
+.jd-linktable td {
+  padding: 3px 5px;
+  vertical-align: top;
+  text-align: left;
+  border:none;
+}
+.jd-linktable tr {
+  background-color: #fff;
+}
+.jd-linktable td {
+  border-top: 1px solid #888;
+  background-color: inherit;
+}
+.jd-linktable td  p {
+  padding: 0 0 5px;
+}
+.jd-linktable .jd-linkcol {
+}
+.jd-linktable .jd-descrcol {
+}
+.jd-linktable .jd-typecol {
+  text-align:right;
+}
+.jd-linktable .jd-valcol {
+}
+.jd-linktable .jd-commentrow {
+  border-top:none;
+  padding-left:25px;
+}
+.jd-deprecated-warning {
+  margin-top: 0;
+  margin-bottom: 10px;
+}
+
+tr.alt-color {
+  background-color: #f6f6f6;
+}
+
+/* expando trigger */
+#jd-content .jd-expando-trigger-img {
+  margin:0;
+}
+
+/* jd-expando */
+.jd-inheritedlinks {
+  padding:0 0 0 13px
+}
+
+/* SDK PAGE */
+table.download tr {
+  background-color:#d9d9d9;
+}
+
+table.download tr.alt-color {
+  background-color:#ededed;
+}
+
+table.download td,
+table.download th {
+  border:2px solid #fff;
+  padding:10px 5px;
+}
+
+table.download th {
+  background-color:#6d8293;
+  color:#fff;
+}
+
+/* INLAY 180 COPY and 240PX EXTENSION */
+/* modified to 43px so that all browsers eliminate the package panel h-scroll */
+.g-tpl-240 .g-unit,
+.g-unit .g-tpl-240 .g-unit,
+.g-unit .g-unit .g-tpl-240 .g-unit {
+  display: block;
+  margin: 0 0 0 243px;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-240 .g-first,
+.g-unit .g-tpl-240 .g-first,
+.g-tpl-240 .g-first {
+  display: block;
+  margin: 0;
+  width: 243px;
+  float: left;
+}
+/* 240px alt */
+.g-tpl-240-alt .g-unit,
+.g-unit .g-tpl-240-alt .g-unit,
+.g-unit .g-unit .g-tpl-240-alt .g-unit {
+  display: block;
+  margin: 0 243px 0 0;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-240-alt .g-first,
+.g-unit .g-tpl-240-alt .g-first,
+.g-tpl-240-alt .g-first {
+  display: block;
+  margin: 0;
+  width: 243px;
+  float: right;
+}
+
+/* 200px */
+.g-tpl-200 .g-unit,
+.g-unit .g-tpl-200 .g-unit,
+.g-unit .g-unit .g-tpl-200 .g-unit {
+  display: block;
+  margin: 0 0 0 200px;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-200 .g-first,
+.g-unit .g-tpl-200 .g-first,
+.g-tpl-200 .g-first {
+  display: block;
+  margin: 0;
+  width: 200px;
+  float: left;
+}
+/* 200px alt */
+.g-tpl-200-alt .g-unit,
+.g-unit .g-tpl-200-alt .g-unit,
+.g-unit .g-unit .g-tpl-200-alt .g-unit {
+  display: block;
+  margin: 0 200px 0 0;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-200-alt .g-first,
+.g-unit .g-tpl-200-alt .g-first,
+.g-tpl-200-alt .g-first {
+  display: block;
+  margin: 0;
+  width: 200px;
+  float: right;
+}
+
+/* 190px */
+.g-tpl-190 .g-unit,
+.g-unit .g-tpl-190 .g-unit,
+.g-unit .g-unit .g-tpl-190 .g-unit {
+  display: block;
+  margin: 0 0 0 190px;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-190 .g-first,
+.g-unit .g-tpl-190 .g-first,
+.g-tpl-190 .g-first {
+  display: block;
+  margin: 0;
+  width: 190px;
+  float: left;
+}
+/* 190px alt */
+.g-tpl-190-alt .g-unit,
+.g-unit .g-tpl-190-alt .g-unit,
+.g-unit .g-unit .g-tpl-190-alt .g-unit {
+  display: block;
+  margin: 0 190px 0 0;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-190-alt .g-first,
+.g-unit .g-tpl-190-alt .g-first,
+.g-tpl-190-alt .g-first {
+  display: block;
+  margin: 0;
+  width: 190px;
+  float: right;
+}
+
+/* 180px */
+.g-tpl-180 .g-unit,
+.g-unit .g-tpl-180 .g-unit,
+.g-unit .g-unit .g-tpl-180 .g-unit {
+  display: block;
+  margin: 0 0 0 180px;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-180 .g-first,
+.g-unit .g-tpl-180 .g-first,
+.g-tpl-180 .g-first {
+  display: block;
+  margin: 0;
+  width: 180px;
+  float: left;
+}
+/* 180px alt */
+.g-tpl-180-alt .g-unit,
+.g-unit .g-tpl-180-alt .g-unit,
+.g-unit .g-unit .g-tpl-180-alt .g-unit {
+  display: block;
+  margin: 0 180px 0 0;
+  width: auto;
+  float: none;
+}
+.g-unit .g-unit .g-tpl-180-alt .g-first,
+.g-unit .g-tpl-180-alt .g-first,
+.g-tpl-180-alt .g-first {
+  display: block;
+  margin: 0;
+  width: 180px;
+  float: right;
+}
+
+
+/* JQUERY RESIZABLE STYLES */
+.ui-resizable { position: relative; }
+.ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; z-index:1; }
+.ui-resizable .ui-resizable-handle { display: block; }
+body .ui-resizable-disabled .ui-resizable-handle { display: none; }
+body .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-s { cursor: s-resize; height: 6px; width: 100%; bottom: 0px; left: 0px;
+  background: transparent url("images/resizable-s2.gif") repeat scroll center top; }
+.ui-resizable-e { cursor: e-resize; width: 6px; right: 0px; top: 0px; height: 100%;
+  background: transparent url("images/resizable-e2.gif") repeat scroll right center; }
+
+@media print {
+
+  body {
+    overflow:visible;
+  }
+
+  #header {
+    height:60px;
+  }
+
+  #headerLeft {
+    padding:0;
+  }
+
+  #header-tabs,
+  #headerRight,
+  #side-nav,
+  #api-info-block {
+    display:none;
+  }
+
+  #body-content {
+    position:inherit;
+  }
+
+  #doc-content {
+    margin-left:0 !important;
+    height:auto !important;
+    width:auto !important;
+    overflow:inherit;
+    display:inline;
+  }
+
+  #jd-header {
+    padding:10px 0;
+  }
+
+  #jd-content {
+    padding:15px 0 0;
+  }
+
+  #footer {
+    float:none;
+    margin:2em 0 0;
+  }
+
+  h4.jd-details-title {
+    border-bottom:1px solid #666;
+  }
+
+  pre {
+    /* these allow lines to break (if there's a white space) */
+    overflow: visible;
+    text-wrap: unrestricted;
+    white-space: -moz-pre-wrap; /* Moz */
+    white-space: -pre-wrap; /* Opera 4-6 */
+    white-space: -o-pre-wrap; /* Opera 7 */
+    white-space: pre-wrap; /* CSS3  */
+    word-wrap: break-word; /* IE 5.5+ */
+  }
+
+  h1, h2, h3, h4, h5, h6 {
+    page-break-after: avoid;
+  }
+
+  table, img {
+    page-break-inside: avoid;
+  }
+}
diff --git a/tools/droiddoc/templates-sdk/assets/css/default.css b/tools/droiddoc/templates-sdk/assets/css/default.css
index 20e462c..9f4edc6 100644
--- a/tools/droiddoc/templates-sdk/assets/css/default.css
+++ b/tools/droiddoc/templates-sdk/assets/css/default.css
@@ -2443,7 +2443,8 @@
   color:#666;
 }
 
-div.figure {
+div.figure,
+div.figure-right {
   float:right;
   clear:right;
   margin:10px 0 0 0;
@@ -2451,6 +2452,19 @@
   /* width must be defined w/ an inline style matching the image width */
 }
 
+div.figure-left {
+  float:left;
+  clear:left;
+  margin:10px 0 0 0;
+  padding:0 20px 0 0;
+  /* width must be defined w/ an inline style matching the image width */
+}
+
+img.frame {
+  border:1px solid #DDD;
+  padding:4px;
+}
+
 p.table-caption {
   margin: 0 0 4px 0;
   font-size:13px;
@@ -3170,18 +3184,6 @@
   padding: 0;
 }
 
-
-#search_filtered li{
-  line-height:1.5em;
-  margin: 0 0 2px;
-  padding: 0;
-}
-
-#search_filtered li a {
-  padding:0 5px;
-  color:#222 !important;
-}
-
 #search_filtered .jd-selected {
   background-color: #33B5E5;
   cursor:pointer;
@@ -3195,15 +3197,31 @@
   display: none;
 }
 
-.jd-autocomplete {
-  padding-left: 6px;
-  padding-right: 6px;
-  padding-top: 1px;
-  padding-bottom: 1px;
+#search_filtered li.jd-autocomplete {
   font-size: 0.81em;
   border: none;
-  margin: 0;
-  line-height: 1.05em;
+  margin: 0 0 2px;
+  padding: 0;
+  line-height:1.5em;
+}
+
+#search_filtered li a {
+  padding:0 5px;
+  color:#222 !important;
+}
+
+#search_filtered li.header {
+  color:#aaa;
+  font-weight:bold;
+  font-size: 0.81em;
+  border: none;
+  margin: 8px 0 2px;
+  padding:1px 5px;
+  line-height:1.5em;
+}
+
+#search_filtered li.header:first-child {
+  margin: 0 0 2px;
 }
 
 .show-item {
diff --git a/tools/droiddoc/templates-sdk/assets/js/docs.js b/tools/droiddoc/templates-sdk/assets/js/docs.js
index 394dbe4..eec97b2 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -9,12 +9,35 @@
 
 var basePath = getBaseUri(location.pathname);
 var SITE_ROOT = toRoot + basePath.substring(1,basePath.indexOf("/",1));
+var GOOGLE_DATA; // combined data for google service apis, used for search suggest
   
 
 /******  ON LOAD SET UP STUFF *********/
 
 var navBarIsFixed = false;
 $(document).ready(function() {
+
+  // load json file for Android API search suggestions
+  $.getScript(toRoot + 'reference/lists.js');
+  // load json files for Google services API suggestions
+  $.getScript(toRoot + 'reference/gcm_lists.js', function(data, textStatus, jqxhr) {
+      // once the GCM json (GCM_DATA) is loaded, load the GMS json (GMS_DATA) and merge the data
+      if(jqxhr.status === 200) {
+          $.getScript(toRoot + 'reference/gms_lists.js', function(data, textStatus, jqxhr) {
+              if(jqxhr.status === 200) {
+                  // combine GCM and GMS data
+                  GOOGLE_DATA = GMS_DATA;
+                  var start = GOOGLE_DATA.length;
+                  for (var i=0; i<GCM_DATA.length; i++) {
+                      GOOGLE_DATA.push({id:start+i, label:GCM_DATA[i].label,
+                              link:GCM_DATA[i].link, type:GCM_DATA[i].type});
+                  }
+              }
+          });
+      }
+  });
+
+  // layout hosted on devsite is special
   if (devsite) {
     // move the lang selector into the overflow menu
     $("#moremenu .mid div.header:last").after($("#language").detach());
@@ -50,7 +73,7 @@
     hideResults();  // see search_autocomplete.js
   });
   $('.search').click(function() {
-    if (!$('#search_autocomplete').is(":focused")) {
+    if (!$('#search_autocomplete').is(":focus")) {
         $('#search_autocomplete').focus();
     }
   });
@@ -112,7 +135,7 @@
   if (pagePath.indexOf("/intl/") == 0) {
     pagePath = pagePath.substr(pagePath.indexOf("/",6)); // start after intl/ to get last /
   }
-  
+
   if (pagePath.indexOf(SITE_ROOT) == 0) {
     if (pagePath == '' || pagePath.charAt(pagePath.length - 1) == '/') {
       pagePath += 'index.html';
@@ -138,12 +161,47 @@
     // Otherwise the page path is already an absolute URL
   }
 
-  // select current page in sidenav and set up prev/next links if they exist
+  // Highlight the header tabs...
+  // highlight Design tab
+  if ($("body").hasClass("design")) {
+    $("#header li.design a").addClass("selected");
+
+  // highlight Develop tab
+  } else if ($("body").hasClass("develop") || $("body").hasClass("google")) {
+    $("#header li.develop a").addClass("selected");
+
+    // In Develop docs, also highlight appropriate sub-tab
+    var rootDir = pagePath.substring(1,pagePath.indexOf('/', 1));
+    if (rootDir == "training") {
+      $("#nav-x li.training a").addClass("selected");
+    } else if (rootDir == "guide") {
+      $("#nav-x li.guide a").addClass("selected");
+    } else if (rootDir == "reference") {
+      // If the root is reference, but page is also part of Google Services, select Google
+      if ($("body").hasClass("google")) {
+        $("#nav-x li.google a").addClass("selected");
+      } else {
+        $("#nav-x li.reference a").addClass("selected");
+      }
+    } else if ((rootDir == "tools") || (rootDir == "sdk")) {
+      $("#nav-x li.tools a").addClass("selected");
+    } else if ($("body").hasClass("google")) {
+      $("#nav-x li.google a").addClass("selected");
+    }
+
+  // highlight Distribute tab
+  } else if ($("body").hasClass("distribute")) {
+    $("#header li.distribute a").addClass("selected");
+  }
+
+
+  // select current page in sidenav and header, and set up prev/next links if they exist
   var $selNavLink = $('#nav').find('a[href="' + pagePath + '"]');
   var $selListItem;
   if ($selNavLink.length) {
-    $selListItem = $selNavLink.closest('li');
 
+    // Find this page's <li> in sidenav and set selected
+    $selListItem = $selNavLink.closest('li');
     $selListItem.addClass('selected');
     
     // Traverse up the tree and expand all parent nav-sections
@@ -151,7 +209,6 @@
       $(this).addClass('expanded');
       $(this).children('ul').show();
     });
-    
 
     // set up prev links
     var $prevLink = [];
@@ -526,6 +583,7 @@
   }
 
 });
+// END of the onload event
 
 
 
@@ -596,16 +654,6 @@
 }
 
 
-/* loads the lists.js file to the page.
-Loading this in the head was slowing page load time */
-addLoadEvent( function() {
-  var lists = document.createElement("script");
-  lists.setAttribute("type","text/javascript");
-  lists.setAttribute("src", toRoot+"reference/lists.js");
-  document.getElementsByTagName("head")[0].appendChild(lists);
-} );
-
-
 addLoadEvent( function() {
   $("pre:not(.no-pretty-print)").addClass("prettyprint");
   prettyPrint();
@@ -1448,12 +1496,18 @@
 /* ######################################################## */
 
 
+
 var gSelectedIndex = -1;
-var gSelectedID = -1;
 var gMatches = new Array();
 var gLastText = "";
-var ROW_COUNT = 20;
 var gInitialized = false;
+var ROW_COUNT_FRAMEWORK = 20;       // max number of results in list
+var gListLength = 0;
+
+
+var gGoogleMatches = new Array();
+var ROW_COUNT_GOOGLE = 15;          // max number of results in list
+var gGoogleListLength = 0;
 
 function set_item_selected($li, selected)
 {
@@ -1471,59 +1525,66 @@
     $link.attr('href',toroot + match.link);
 }
 
+function new_suggestion() {
+    var $list = $("#search_filtered");
+    var $li = $("<li class='jd-autocomplete'></li>");
+    $list.append($li);
+
+    $li.mousedown(function() {
+        window.location = this.firstChild.getAttribute("href");
+    });
+    $li.mouseover(function() {
+        $('#search_filtered li').removeClass('jd-selected');
+        $(this).addClass('jd-selected');
+        gSelectedIndex = $('#search_filtered li').index(this);
+    });
+    $li.append('<a></a>');
+    $li.attr('class','show-item');
+    return $li;
+}
+
 function sync_selection_table(toroot)
 {
     var $list = $("#search_filtered");
     var $li; //list item jquery object
     var i; //list item iterator
-    gSelectedID = -1;
-    
-    //initialize the table; draw it for the first time (but not visible).
-    if (!gInitialized) {
-        for (i=0; i<ROW_COUNT; i++) {
-            var $li = $("<li class='jd-autocomplete'></li>");
-            $list.append($li);
-            
-            $li.mousedown(function() {
-                window.location = this.firstChild.getAttribute("href");
-            });
-            $li.mouseover(function() {
-                $('#search_filtered li').removeClass('jd-selected');
-                $(this).addClass('jd-selected');
-                gSelectedIndex = $('#search_filtered li').index(this);
-            });
-            $li.append('<a></a>');
-        }
-        gInitialized = true;
-    }
   
+    // reset the list
+    $("li",$list).remove();
+
     //if we have results, make the table visible and initialize result info
-    if (gMatches.length > 0) {
+    if ((gMatches.length > 0) || (gGoogleMatches.length > 0)) {
+        // reveal suggestion list
         $('#search_filtered_div').removeClass('no-display');
-        var N = gMatches.length < ROW_COUNT ? gMatches.length : ROW_COUNT;
-        for (i=0; i<N; i++) {
-            $li = $('#search_filtered li:nth-child('+(i+1)+')');
-            $li.attr('class','show-item');
-            set_item_values(toroot, $li, gMatches[i]);
-            set_item_selected($li, i == gSelectedIndex);
-            if (i == gSelectedIndex) {
-                gSelectedID = gMatches[i].id;
+        var listIndex = 0; // list index position
+
+        // ########### ANDROID RESULTS #############
+        if (gMatches.length > 0) {
+
+            // determine android results to show
+            gListLength = gMatches.length < ROW_COUNT_FRAMEWORK ?
+                          gMatches.length : ROW_COUNT_FRAMEWORK;
+            for (i=0; i<gListLength; i++) {
+                var $li = new_suggestion();
+                set_item_values(toroot, $li, gMatches[i]);
+                set_item_selected($li, i == gSelectedIndex);
             }
         }
-        //start hiding rows that are no longer matches
-        for (; i<ROW_COUNT; i++) {
-            $li = $('#search_filtered li:nth-child('+(i+1)+')');
-            $li.attr('class','no-display');
+
+        // ########### GOOGLE RESULTS #############
+        if (gGoogleMatches.length > 0) {
+            // show header for list
+            $list.append("<li class='header'>in Google Services:</li>");
+
+            // determine google results to show
+            gGoogleListLength = gGoogleMatches.length < ROW_COUNT_GOOGLE ? gGoogleMatches.length : ROW_COUNT_GOOGLE;
+            for (i=0; i<gGoogleListLength; i++) {
+                var $li = new_suggestion();
+                set_item_values(toroot, $li, gGoogleMatches[i]);
+                set_item_selected($li, i == gSelectedIndex);
+            }
         }
-        //if there are more results we're not showing, so say so.
-/*      if (gMatches.length > ROW_COUNT) {
-            li = list.rows[ROW_COUNT];
-            li.className = "show-item";
-            c1 = li.cells[0];
-            c1.innerHTML = "plus " + (gMatches.length-ROW_COUNT) + " more"; 
-        } else {
-            list.rows[ROW_COUNT].className = "hide-item";
-        }*/
+
     //if we have no results, hide the table
     } else {
         $('#search_filtered_div').addClass('no-display');
@@ -1546,8 +1607,8 @@
     if (e.keyCode == 13) {
         $('#search_filtered_div').addClass('no-display');
         if (!$('#search_filtered_div').hasClass('no-display') || (gSelectedIndex < 0)) {
-            if ($("#searchResults").is(":hidden")) {
-              // if results aren't showing, return true to allow search to execute
+            if ($("#searchResults").is(":hidden") && (search.value != "")) {
+              // if results aren't showing (and text not empty), return true to allow search to execute
               return true;
             } else {
               // otherwise, results are already showing, so allow ajax to auto refresh the results
@@ -1555,33 +1616,49 @@
               return false;
             }
         } else if (kd && gSelectedIndex >= 0) {
-            window.location = toroot + gMatches[gSelectedIndex].link;
+            window.location = $("a",$('#search_filtered li')[gSelectedIndex]).attr("href");
             return false;
         }
     }
     // 38 -- arrow up
     else if (kd && (e.keyCode == 38)) {
-        if (gSelectedIndex >= 0) {
-            $('#search_filtered li').removeClass('jd-selected');
+        if ($($("#search_filtered li")[gSelectedIndex-1]).hasClass("header")) {
+            $('#search_filtered_div li').removeClass('jd-selected');
             gSelectedIndex--;
-            $('#search_filtered li:nth-child('+(gSelectedIndex+1)+')').addClass('jd-selected');
+            $('#search_filtered_div li:nth-child('+(gSelectedIndex+1)+')').addClass('jd-selected');
+        }
+        if (gSelectedIndex >= 0) {
+            $('#search_filtered_div li').removeClass('jd-selected');
+            gSelectedIndex--;
+            $('#search_filtered_div li:nth-child('+(gSelectedIndex+1)+')').addClass('jd-selected');
         }
         return false;
     }
     // 40 -- arrow down
     else if (kd && (e.keyCode == 40)) {
-        if (gSelectedIndex < gMatches.length-1
-                        && gSelectedIndex < ROW_COUNT-1) {
-            $('#search_filtered li').removeClass('jd-selected');
+        if ($($("#search_filtered li")[gSelectedIndex+1]).hasClass("header")) {
+            $('#search_filtered_div li').removeClass('jd-selected');
             gSelectedIndex++;
-            $('#search_filtered li:nth-child('+(gSelectedIndex+1)+')').addClass('jd-selected');
+            $('#search_filtered_div li:nth-child('+(gSelectedIndex+1)+')').addClass('jd-selected');
+        }
+        if ((gSelectedIndex < $("ul#search_filtered li").length-1) ||
+                        ($($("#search_filtered li")[gSelectedIndex+1]).hasClass("header"))) {
+            $('#search_filtered_div li').removeClass('jd-selected');
+            gSelectedIndex++;
+            $('#search_filtered_div li:nth-child('+(gSelectedIndex+1)+')').addClass('jd-selected');
         }
         return false;
     }
+    // if key-up event and not arrow down/up,
+    // read the search query and add suggestsions to gMatches
     else if (!kd && (e.keyCode != 40) && (e.keyCode != 38)) {
         gMatches = new Array();
         matchedCount = 0;
+        gGoogleMatches = new Array();
+        matchedCountGoogle = 0;
         gSelectedIndex = -1;
+
+        // Search for Android matches
         for (var i=0; i<DATA.length; i++) {
             var s = DATA[i];
             if (text.length != 0 &&
@@ -1590,22 +1667,38 @@
                 matchedCount++;
             }
         }
-        rank_autocomplete_results(text);
+        rank_autocomplete_results(text, gMatches);
         for (var i=0; i<gMatches.length; i++) {
             var s = gMatches[i];
-            if (gSelectedID == s.id) {
-                gSelectedIndex = i;
+        }
+
+
+        // Search for Google matches
+        for (var i=0; i<GOOGLE_DATA.length; i++) {
+            var s = GOOGLE_DATA[i];
+            if (text.length != 0 &&
+                  s.label.toLowerCase().indexOf(text.toLowerCase()) != -1) {
+                gGoogleMatches[matchedCountGoogle] = s;
+                matchedCountGoogle++;
             }
         }
+        rank_autocomplete_results(text, gGoogleMatches);
+        for (var i=0; i<gGoogleMatches.length; i++) {
+            var s = gGoogleMatches[i];
+        }
+
         highlight_autocomplete_result_labels(text);
         sync_selection_table(toroot);
+
+
         return true; // allow the event to bubble up to the search api
     }
 }
 
-function rank_autocomplete_results(query) {
+/* Order the result list based on match quality */
+function rank_autocomplete_results(query, matches) {
     query = query || '';
-    if (!gMatches || !gMatches.length)
+    if (!matches || !matches.length)
       return;
 
     // helper function that gets the last occurence index of the given regex
@@ -1661,11 +1754,11 @@
         return score;
     };
 
-    for (var i=0; i<gMatches.length; i++) {
-        gMatches[i].__resultScore = _resultScoreFn(gMatches[i]);
+    for (var i=0; i<matches.length; i++) {
+        matches[i].__resultScore = _resultScoreFn(matches[i]);
     }
 
-    gMatches.sort(function(a,b){
+    matches.sort(function(a,b){
         var n = b.__resultScore - a.__resultScore;
         if (n == 0) // lexicographical sort if scores are the same
             n = (a.label < b.label) ? -1 : 1;
@@ -1673,9 +1766,10 @@
     });
 }
 
+/* Add emphasis to part of string that matches query */
 function highlight_autocomplete_result_labels(query) {
     query = query || '';
-    if (!gMatches || !gMatches.length)
+    if ((!gMatches || !gMatches.length) && (!gGoogleMatches || !gGoogleMatches.length))
       return;
 
     var queryLower = query.toLowerCase();
@@ -1686,6 +1780,10 @@
         gMatches[i].__hilabel = gMatches[i].label.replace(
             queryRE, '<b>$1</b>');
     }
+    for (var i=0; i<gGoogleMatches.length; i++) {
+        gGoogleMatches[i].__hilabel = gGoogleMatches[i].label.replace(
+            queryRE, '<b>$1</b>');
+    }
 }
 
 function search_focus_changed(obj, focused)
diff --git a/tools/droiddoc/templates-sdk/components/masthead.cs b/tools/droiddoc/templates-sdk/components/masthead.cs
index fc16161..9f19906 100644
--- a/tools/droiddoc/templates-sdk/components/masthead.cs
+++ b/tools/droiddoc/templates-sdk/components/masthead.cs
@@ -13,8 +13,7 @@
           </div>
             <ul class="nav-x col-9">
                 <li class="design">
-                  <a href="<?cs var:toroot ?>design/index.html" <?cs
-                  if:design ?>class="selected"<?cs /if ?>
+                  <a href="<?cs var:toroot ?>design/index.html"
                   zh-TW-lang="設計"
                   zh-CN-lang="设计"
                   ru-lang="Проектирование"
@@ -22,8 +21,7 @@
                   ja-lang="設計"
                   es-lang="Diseñar"               
                   >Design</a></li>
-                <li class="develop"><a href="<?cs var:toroot ?>develop/index.html" <?cs
-                  if:training || guide || reference || tools || develop || google ?>class="selected"<?cs /if ?>
+                <li class="develop"><a href="<?cs var:toroot ?>develop/index.html"
                   zh-TW-lang="開發"
                   zh-CN-lang="开发"
                   ru-lang="Разработка"
@@ -31,8 +29,7 @@
                   ja-lang="開発"
                   es-lang="Desarrollar"               
                   >Develop</a></li>
-                <li class="distribute last"><a href="<?cs var:toroot ?>distribute/index.html" <?cs
-                  if:distribute ?>class="selected"<?cs /if ?>
+                <li class="distribute last"><a href="<?cs var:toroot ?>distribute/index.html"
                   zh-TW-lang="發佈"
                   zh-CN-lang="分发"
                   ru-lang="Распространение"
@@ -203,8 +200,7 @@
     <div id="nav-x">
         <div class="wrap">
             <ul class="nav-x col-9 develop" style="width:100%">
-                <li><a href="<?cs var:toroot ?>training/index.html" <?cs
-                  if:training ?>class="selected"<?cs /if ?>
+                <li class="training"><a href="<?cs var:toroot ?>training/index.html"
                   zh-TW-lang="訓練課程"
                   zh-CN-lang="培训"
                   ru-lang="Курсы"
@@ -212,8 +208,7 @@
                   ja-lang="トレーニング"
                   es-lang="Capacitación"               
                   >Training</a></li>
-                <li><a href="<?cs var:toroot ?>guide/components/index.html" <?cs
-                  if:guide ?>class="selected"<?cs /if ?>
+                <li class="guide"><a href="<?cs var:toroot ?>guide/components/index.html"
                   zh-TW-lang="API 指南"
                   zh-CN-lang="API 指南"
                   ru-lang="Руководства по API"
@@ -221,8 +216,7 @@
                   ja-lang="API ガイド"
                   es-lang="Guías de la API"               
                   >API Guides</a></li>
-                <li><a href="<?cs var:toroot ?>reference/packages.html" <?cs
-                  if:reference && !(reference.gcm || reference.gms) ?>class="selected"<?cs /if ?>
+                <li class="reference"><a href="<?cs var:toroot ?>reference/packages.html"
                   zh-TW-lang="參考資源"
                   zh-CN-lang="参考"
                   ru-lang="Справочник"
@@ -230,8 +224,7 @@
                   ja-lang="リファレンス"
                   es-lang="Referencia"               
                   >Reference</a></li>
-                <li><a href="<?cs var:toroot ?>tools/index.html" <?cs
-                  if:tools ?>class="selected"<?cs /if ?>
+                <li class="tools"><a href="<?cs var:toroot ?>tools/index.html"
                   zh-TW-lang="相關工具"
                   zh-CN-lang="工具"
                   ru-lang="Инструменты"
@@ -239,8 +232,7 @@
                   ja-lang="ツール"
                   es-lang="Herramientas"
                   >Tools</a></li>
-                <li><a href="<?cs var:toroot ?>google/index.html" <?cs
-                  if:google || reference.gcm || reference.gms?>class="selected"<?cs /if ?>
+                <li class="google"><a href="<?cs var:toroot ?>google/index.html"
                   >Google Services</a>
                 </li>
             </ul>
diff --git a/tools/droiddoc/templates-sdk/head_tag.cs b/tools/droiddoc/templates-sdk/head_tag.cs
index 54493b8..d84a3be 100644
--- a/tools/droiddoc/templates-sdk/head_tag.cs
+++ b/tools/droiddoc/templates-sdk/head_tag.cs
@@ -24,7 +24,7 @@
 <script src="<?cs if:android.whichdoc != 'online' ?>http:<?cs /if ?>//www.google.com/jsapi" type="text/javascript"></script>
 <?cs
 if:devsite
-  ?><script src="//android-dot-devsite.googleplex.com/_static/js/android_3p-bundle.js" type="text/javascript"></script><?cs
+  ?><script src="<?cs var:toroot ?>_static/js/android_3p-bundle.js" type="text/javascript"></script><?cs
 else
   ?><script src="<?cs var:toroot ?>assets/js/android_3p-bundle.js" type="text/javascript"></script><?cs
 /if ?>
@@ -38,10 +38,10 @@
 </script>
 <script src="<?cs var:toroot ?>assets/js/docs.js" type="text/javascript"></script>
 <?cs if:reference.gms || reference.gcm || google?>
-<script src="<?cs var:toroot ?>gms_navtree_data.js" type="text/javascript"></script>
-<script src="<?cs var:toroot ?>gcm_navtree_data.js" type="text/javascript"></script>
-<?cs else ?>
-<script src="<?cs var:toroot ?>navtree_data.js" type="text/javascript"></script>
+<script src="<?cs var:toroot ?>gms_navtree_data.js" async type="text/javascript"></script>
+<script src="<?cs var:toroot ?>gcm_navtree_data.js" async type="text/javascript"></script>
+<?cs elif:reference ?>
+<script src="<?cs var:toroot ?>navtree_data.js" async type="text/javascript"></script>
 <?cs /if ?>
 
 <script type="text/javascript">
diff --git a/tools/fs_config/fs_config.c b/tools/fs_config/fs_config.c
index 5b99b30..f6760cc 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -62,7 +62,8 @@
     }
 
     unsigned uid = 0, gid = 0, mode = 0;
-    fs_config(buffer, is_dir, &uid, &gid, &mode);
+    uint64_t capabilities;
+    fs_config(buffer, is_dir, &uid, &gid, &mode, &capabilities);
     printf("%s %d %d %o\n", buffer, uid, gid, mode);
   }
   return 0;
diff --git a/tools/fs_get_stats/fs_get_stats.c b/tools/fs_get_stats/fs_get_stats.c
index 356f6f9..a9814b9 100644
--- a/tools/fs_get_stats/fs_get_stats.c
+++ b/tools/fs_get_stats/fs_get_stats.c
@@ -57,7 +57,8 @@
 	if (!strcmp(argv[2], "1"))
 		is_dir = 1;
 
-	fs_config(argv[3], is_dir, &uid, &gid, &perms);
+	uint64_t capabilities;
+	fs_config(argv[3], is_dir, &uid, &gid, &perms, &capabilities);
 	fprintf(stdout, "%d %d 0%o\n", uid, gid, perms);
 
 	return 0;
diff --git a/tools/java-layers.py b/tools/java-layers.py
new file mode 100755
index 0000000..b3aec2b
--- /dev/null
+++ b/tools/java-layers.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python
+
+import os
+import re
+import sys
+
+def fail_with_usage():
+  sys.stderr.write("usage: java-layers.py DEPENDENCY_FILE SOURCE_DIRECTORIES...\n")
+  sys.stderr.write("\n")
+  sys.stderr.write("Enforces layering between java packages.  Scans\n")
+  sys.stderr.write("DIRECTORY and prints errors when the packages violate\n")
+  sys.stderr.write("the rules defined in the DEPENDENCY_FILE.\n")
+  sys.stderr.write("\n")
+  sys.stderr.write("Prints a warning when an unknown package is encountered\n")
+  sys.stderr.write("on the assumption that it should fit somewhere into the\n")
+  sys.stderr.write("layering.\n")
+  sys.stderr.write("\n")
+  sys.stderr.write("DEPENDENCY_FILE format\n")
+  sys.stderr.write("  - # starts comment\n")
+  sys.stderr.write("  - Lines consisting of two java package names:  The\n")
+  sys.stderr.write("    first package listed must not contain any references\n")
+  sys.stderr.write("    to any classes present in the second package, or any\n")
+  sys.stderr.write("    of its dependencies.\n")
+  sys.stderr.write("  - Lines consisting of one java package name:  The\n")
+  sys.stderr.write("    packge is assumed to be a high level package and\n")
+  sys.stderr.write("    nothing may depend on it.\n")
+  sys.stderr.write("  - Lines consisting of a dash (+) followed by one java\n")
+  sys.stderr.write("    package name: The package is considered a low level\n")
+  sys.stderr.write("    package and may not import any of the other packages\n")
+  sys.stderr.write("    listed in the dependency file.\n")
+  sys.stderr.write("  - Lines consisting of a plus (-) followed by one java\n")
+  sys.stderr.write("    package name: The package is considered \'legacy\'\n")
+  sys.stderr.write("    and excluded from errors.\n")
+  sys.stderr.write("\n")
+  sys.exit(1)
+
+class Dependency:
+  def __init__(self, filename, lineno, lower, top, lowlevel, legacy):
+    self.filename = filename
+    self.lineno = lineno
+    self.lower = lower
+    self.top = top
+    self.lowlevel = lowlevel
+    self.legacy = legacy
+    self.uppers = []
+    self.transitive = set()
+
+  def matches(self, imp):
+    for d in self.transitive:
+      if imp.startswith(d):
+        return True
+    return False
+
+class Dependencies:
+  def __init__(self, deps):
+    def recurse(obj, dep, visited):
+      global err
+      if dep in visited:
+        sys.stderr.write("%s:%d: Circular dependency found:\n"
+            % (dep.filename, dep.lineno))
+        for v in visited:
+          sys.stderr.write("%s:%d:    Dependency: %s\n"
+              % (v.filename, v.lineno, v.lower))
+        err = True
+        return
+      visited.append(dep)
+      for upper in dep.uppers:
+        obj.transitive.add(upper)
+        if upper in deps:
+          recurse(obj, deps[upper], visited)
+    self.deps = deps
+    self.parts = [(dep.lower.split('.'),dep) for dep in deps.itervalues()]
+    # transitive closure of dependencies
+    for dep in deps.itervalues():
+      recurse(dep, dep, [])
+    # disallow everything from the low level components
+    for dep in deps.itervalues():
+      if dep.lowlevel:
+        for d in deps.itervalues():
+          if dep != d and not d.legacy:
+            dep.transitive.add(d.lower)
+    # disallow the 'top' components everywhere but in their own package
+    for dep in deps.itervalues():
+      if dep.top and not dep.legacy:
+        for d in deps.itervalues():
+          if dep != d and not d.legacy:
+            d.transitive.add(dep.lower)
+    for dep in deps.itervalues():
+      dep.transitive = set([x+"." for x in dep.transitive])
+    if False:
+      for dep in deps.itervalues():
+        print "-->", dep.lower, "-->", dep.transitive
+
+  # Lookup the dep object for the given package.  If pkg is a subpackage
+  # of one with a rule, that one will be returned.  If no matches are found,
+  # None is returned.
+  def lookup(self, pkg):
+    # Returns the number of parts that match
+    def compare_parts(parts, pkg):
+      if len(parts) > len(pkg):
+        return 0
+      n = 0
+      for i in range(0, len(parts)):
+        if parts[i] != pkg[i]:
+          return 0
+        n = n + 1
+      return n
+    pkg = pkg.split(".")
+    matched = 0
+    result = None
+    for (parts,dep) in self.parts:
+      x = compare_parts(parts, pkg)
+      if x > matched:
+        matched = x
+        result = dep
+    return result
+
+def parse_dependency_file(filename):
+  global err
+  f = file(filename)
+  lines = f.readlines()
+  f.close()
+  def lineno(s, i):
+    i[0] = i[0] + 1
+    return (i[0],s)
+  n = [0]
+  lines = [lineno(x,n) for x in lines]
+  lines = [(n,s.split("#")[0].strip()) for (n,s) in lines]
+  lines = [(n,s) for (n,s) in lines if len(s) > 0]
+  lines = [(n,s.split()) for (n,s) in lines]
+  deps = {}
+  for n,words in lines:
+    if len(words) == 1:
+      lower = words[0]
+      top = True
+      legacy = False
+      lowlevel = False
+      if lower[0] == '+':
+        lower = lower[1:]
+        top = False
+        lowlevel = True
+      elif lower[0] == '-':
+        lower = lower[1:]
+        legacy = True
+      if lower in deps:
+        sys.stderr.write(("%s:%d: Package '%s' already defined on"
+            + " line %d.\n") % (filename, n, lower, deps[lower].lineno))
+        err = True
+      else:
+        deps[lower] = Dependency(filename, n, lower, top, lowlevel, legacy)
+    elif len(words) == 2:
+      lower = words[0]
+      upper = words[1]
+      if lower in deps:
+        dep = deps[lower]
+        if dep.top:
+          sys.stderr.write(("%s:%d: Can't add dependency to top level package "
+            + "'%s'\n") % (filename, n, lower))
+          err = True
+      else:
+        dep = Dependency(filename, n, lower, False, False, False)
+        deps[lower] = dep
+      dep.uppers.append(upper)
+    else:
+      sys.stderr.write("%s:%d: Too many words on line starting at \'%s\'\n" % (
+          filename, n, words[2]))
+      err = True
+  return Dependencies(deps)
+
+def find_java_files(srcs):
+  result = []
+  for d in srcs:
+    if d[0] == '@':
+      f = file(d[1:])
+      result.extend([fn for fn in [s.strip() for s in f.readlines()]
+          if len(fn) != 0])
+      f.close()
+    else:
+      for root, dirs, files in os.walk(d):
+        result.extend([os.sep.join((root,f)) for f in files
+            if f.lower().endswith(".java")])
+  return result
+
+COMMENTS = re.compile("//.*?\n|/\*.*?\*/", re.S)
+PACKAGE = re.compile("package\s+(.*)")
+IMPORT = re.compile("import\s+(.*)")
+
+def examine_java_file(deps, filename):
+  global err
+  # Yes, this is a crappy java parser.  Write a better one if you want to.
+  f = file(filename)
+  text = f.read()
+  f.close()
+  text = COMMENTS.sub("", text)
+  index = text.find("{")
+  if index < 0:
+    sys.stderr.write(("%s: Error: Unable to parse java. Can't find class "
+        + "declaration.\n") % filename)
+    err = True
+    return
+  text = text[0:index]
+  statements = [s.strip() for s in text.split(";")]
+  # First comes the package declaration.  Then iterate while we see import
+  # statements.  Anything else is either bad syntax that we don't care about
+  # because the compiler will fail, or the beginning of the class declaration.
+  m = PACKAGE.match(statements[0])
+  if not m:
+    sys.stderr.write(("%s: Error: Unable to parse java. Missing package "
+        + "statement.\n") % filename)
+    err = True
+    return
+  pkg = m.group(1)
+  imports = []
+  for statement in statements[1:]:
+    m = IMPORT.match(statement)
+    if not m:
+      break
+    imports.append(m.group(1))
+  # Do the checking
+  if False:
+    print filename
+    print "'%s' --> %s" % (pkg, imports)
+  dep = deps.lookup(pkg)
+  if not dep:
+    sys.stderr.write(("%s: Error: Package does not appear in dependency file: "
+      + "%s\n") % (filename, pkg))
+    err = True
+    return
+  for imp in imports:
+    if dep.matches(imp):
+      sys.stderr.write("%s: Illegal import in package '%s' of '%s'\n"
+          % (filename, pkg, imp))
+      err = True
+
+err = False
+
+def main(argv):
+  if len(argv) < 3:
+    fail_with_usage()
+  deps = parse_dependency_file(argv[1])
+
+  if err:
+    sys.exit(1)
+
+  java = find_java_files(argv[2:])
+  for filename in java:
+    examine_java_file(deps, filename)
+
+  if err:
+    sys.stderr.write("%s: Using this file as dependency file.\n" % argv[1])
+    sys.exit(1)
+
+  sys.exit(0)
+
+if __name__ == "__main__":
+  main(sys.argv)
+
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 127784d..263ae11 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -117,6 +117,9 @@
       # ok if extensions don't exist
       pass
 
+  if "fstab_version" not in d:
+    d["fstab_version"] = "1"
+
   try:
     data = zip.read("META/imagesizes.txt")
     for line in data.split("\n"):
@@ -141,8 +144,9 @@
   makeint("cache_size")
   makeint("recovery_size")
   makeint("boot_size")
+  makeint("fstab_version")
 
-  d["fstab"] = LoadRecoveryFSTab(zip)
+  d["fstab"] = LoadRecoveryFSTab(zip, d["fstab_version"])
   d["build.prop"] = LoadBuildProp(zip)
   return d
 
@@ -161,7 +165,7 @@
     d[name] = value
   return d
 
-def LoadRecoveryFSTab(zip):
+def LoadRecoveryFSTab(zip, fstab_version):
   class Partition(object):
     pass
 
@@ -171,40 +175,76 @@
     print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab in %s." % zip
     data = ""
 
-  d = {}
-  for line in data.split("\n"):
-    line = line.strip()
-    if not line or line.startswith("#"): continue
-    pieces = line.split()
-    if not (3 <= len(pieces) <= 4):
-      raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
+  if fstab_version == 1:
+    d = {}
+    for line in data.split("\n"):
+      line = line.strip()
+      if not line or line.startswith("#"): continue
+      pieces = line.split()
+      if not (3 <= len(pieces) <= 4):
+        raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
 
-    p = Partition()
-    p.mount_point = pieces[0]
-    p.fs_type = pieces[1]
-    p.device = pieces[2]
-    p.length = 0
-    options = None
-    if len(pieces) >= 4:
-      if pieces[3].startswith("/"):
-        p.device2 = pieces[3]
-        if len(pieces) >= 5:
-          options = pieces[4]
+      p = Partition()
+      p.mount_point = pieces[0]
+      p.fs_type = pieces[1]
+      p.device = pieces[2]
+      p.length = 0
+      options = None
+      if len(pieces) >= 4:
+        if pieces[3].startswith("/"):
+          p.device2 = pieces[3]
+          if len(pieces) >= 5:
+            options = pieces[4]
+        else:
+          p.device2 = None
+          options = pieces[3]
       else:
         p.device2 = None
-        options = pieces[3]
-    else:
-      p.device2 = None
 
-    if options:
+      if options:
+        options = options.split(",")
+        for i in options:
+          if i.startswith("length="):
+            p.length = int(i[7:])
+          else:
+              print "%s: unknown option \"%s\"" % (p.mount_point, i)
+
+      d[p.mount_point] = p
+
+  elif fstab_version == 2:
+    d = {}
+    for line in data.split("\n"):
+      line = line.strip()
+      if not line or line.startswith("#"): continue
+      pieces = line.split()
+      if len(pieces) != 5:
+        raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
+
+      # Ignore entries that are managed by vold
+      options = pieces[4]
+      if "voldmanaged=" in options: continue
+
+      # It's a good line, parse it
+      p = Partition()
+      p.device = pieces[0]
+      p.mount_point = pieces[1]
+      p.fs_type = pieces[2]
+      p.device2 = None
+      p.length = 0
+
       options = options.split(",")
       for i in options:
         if i.startswith("length="):
           p.length = int(i[7:])
         else:
-          print "%s: unknown option \"%s\"" % (p.mount_point, i)
+          # Ignore all unknown options in the unified fstab
+          continue
 
-    d[p.mount_point] = p
+      d[p.mount_point] = p
+
+  else:
+    raise ValueError("Unknown fstab_version: \"%d\"" % (fstab_version,))
+
   return d
 
 
diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java
index 07aefa7..adfe9a3 100644
--- a/tools/signapk/SignApk.java
+++ b/tools/signapk/SignApk.java
@@ -35,6 +35,7 @@
 import org.bouncycastle.util.encoders.Base64;
 
 import java.io.BufferedReader;
+import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.File;
@@ -83,6 +84,8 @@
 class SignApk {
     private static final String CERT_SF_NAME = "META-INF/CERT.SF";
     private static final String CERT_RSA_NAME = "META-INF/CERT.RSA";
+    private static final String CERT_SF_MULTI_NAME = "META-INF/CERT%d.SF";
+    private static final String CERT_RSA_MULTI_NAME = "META-INF/CERT%d.RSA";
 
     private static final String OTACERT_NAME = "META-INF/com/android/otacert";
 
@@ -90,10 +93,11 @@
 
     // Files matching this pattern are not copied to the output.
     private static Pattern stripPattern =
-            Pattern.compile("^META-INF/(.*)[.](SF|RSA|DSA)$");
+        Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA)|com/android/otacert))|(" +
+                        Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
 
     private static X509Certificate readPublicKey(File file)
-            throws IOException, GeneralSecurityException {
+        throws IOException, GeneralSecurityException {
         FileInputStream input = new FileInputStream(file);
         try {
             CertificateFactory cf = CertificateFactory.getInstance("X.509");
@@ -130,7 +134,7 @@
      * @param keyFile The file containing the private key
      */
     private static KeySpec decryptPrivateKey(byte[] encryptedPrivateKey, File keyFile)
-            throws GeneralSecurityException {
+        throws GeneralSecurityException {
         EncryptedPrivateKeyInfo epkInfo;
         try {
             epkInfo = new EncryptedPrivateKeyInfo(encryptedPrivateKey);
@@ -157,7 +161,7 @@
 
     /** Read a PKCS 8 format private key. */
     private static PrivateKey readPrivateKey(File file)
-            throws IOException, GeneralSecurityException {
+        throws IOException, GeneralSecurityException {
         DataInputStream input = new DataInputStream(new FileInputStream(file));
         try {
             byte[] bytes = new byte[(int) file.length()];
@@ -180,7 +184,7 @@
 
     /** Add the SHA1 of every file to the manifest, creating it if necessary. */
     private static Manifest addDigestsToManifest(JarFile jar)
-            throws IOException, GeneralSecurityException {
+        throws IOException, GeneralSecurityException {
         Manifest input = jar.getManifest();
         Manifest output = new Manifest();
         Attributes main = output.getMainAttributes();
@@ -208,11 +212,8 @@
 
         for (JarEntry entry: byName.values()) {
             String name = entry.getName();
-            if (!entry.isDirectory() && !name.equals(JarFile.MANIFEST_NAME) &&
-                !name.equals(CERT_SF_NAME) && !name.equals(CERT_RSA_NAME) &&
-                !name.equals(OTACERT_NAME) &&
-                (stripPattern == null ||
-                 !stripPattern.matcher(name).matches())) {
+            if (!entry.isDirectory() &&
+                (stripPattern == null || !stripPattern.matcher(name).matches())) {
                 InputStream data = jar.getInputStream(entry);
                 while ((num = data.read(buffer)) > 0) {
                     md.update(buffer, 0, num);
@@ -301,8 +302,8 @@
 
         MessageDigest md = MessageDigest.getInstance("SHA1");
         PrintStream print = new PrintStream(
-                new DigestOutputStream(new ByteArrayOutputStream(), md),
-                true, "UTF-8");
+            new DigestOutputStream(new ByteArrayOutputStream(), md),
+            true, "UTF-8");
 
         // Digest of the entire manifest
         manifest.write(print);
@@ -339,31 +340,6 @@
         }
     }
 
-    private static class CMSByteArraySlice implements CMSTypedData {
-        private final ASN1ObjectIdentifier type;
-        private final byte[] data;
-        private final int offset;
-        private final int length;
-        public CMSByteArraySlice(byte[] data, int offset, int length) {
-            this.data = data;
-            this.offset = offset;
-            this.length = length;
-            this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId());
-        }
-
-        public Object getContent() {
-            throw new UnsupportedOperationException();
-        }
-
-        public ASN1ObjectIdentifier getContentType() {
-            return type;
-        }
-
-        public void write(OutputStream out) throws IOException {
-            out.write(data, offset, length);
-        }
-    }
-
     /** Sign data and write the digital signature to 'out'. */
     private static void writeSignatureBlock(
         CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey,
@@ -395,23 +371,170 @@
         dos.writeObject(asn1.readObject());
     }
 
-    private static void signWholeOutputFile(byte[] zipData,
-                                            OutputStream outputStream,
-                                            X509Certificate publicKey,
-                                            PrivateKey privateKey)
-        throws IOException,
-               CertificateEncodingException,
-               OperatorCreationException,
-               CMSException {
-        // For a zip with no archive comment, the
-        // end-of-central-directory record will be 22 bytes long, so
-        // we expect to find the EOCD marker 22 bytes from the end.
-        if (zipData[zipData.length-22] != 0x50 ||
-            zipData[zipData.length-21] != 0x4b ||
-            zipData[zipData.length-20] != 0x05 ||
-            zipData[zipData.length-19] != 0x06) {
-            throw new IllegalArgumentException("zip data already has an archive comment");
+    /**
+     * Copy all the files in a manifest from input to output.  We set
+     * the modification times in the output to a fixed time, so as to
+     * reduce variation in the output file and make incremental OTAs
+     * more efficient.
+     */
+    private static void copyFiles(Manifest manifest,
+                                  JarFile in, JarOutputStream out, long timestamp) throws IOException {
+        byte[] buffer = new byte[4096];
+        int num;
+
+        Map<String, Attributes> entries = manifest.getEntries();
+        ArrayList<String> names = new ArrayList<String>(entries.keySet());
+        Collections.sort(names);
+        for (String name : names) {
+            JarEntry inEntry = in.getJarEntry(name);
+            JarEntry outEntry = null;
+            if (inEntry.getMethod() == JarEntry.STORED) {
+                // Preserve the STORED method of the input entry.
+                outEntry = new JarEntry(inEntry);
+            } else {
+                // Create a new entry so that the compressed len is recomputed.
+                outEntry = new JarEntry(name);
+            }
+            outEntry.setTime(timestamp);
+            out.putNextEntry(outEntry);
+
+            InputStream data = in.getInputStream(inEntry);
+            while ((num = data.read(buffer)) > 0) {
+                out.write(buffer, 0, num);
+            }
+            out.flush();
         }
+    }
+
+    private static class WholeFileSignerOutputStream extends FilterOutputStream {
+        private boolean closing = false;
+        private ByteArrayOutputStream footer = new ByteArrayOutputStream();
+        private OutputStream tee;
+
+        public WholeFileSignerOutputStream(OutputStream out, OutputStream tee) {
+            super(out);
+            this.tee = tee;
+        }
+
+        public void notifyClosing() {
+            closing = true;
+        }
+
+        public void finish() throws IOException {
+            closing = false;
+
+            byte[] data = footer.toByteArray();
+            if (data.length < 2)
+                throw new IOException("Less than two bytes written to footer");
+            write(data, 0, data.length - 2);
+        }
+
+        public byte[] getTail() {
+            return footer.toByteArray();
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+            write(b, 0, b.length);
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            if (closing) {
+                // if the jar is about to close, save the footer that will be written
+                footer.write(b, off, len);
+            }
+            else {
+                // write to both output streams. out is the CMSTypedData signer and tee is the file.
+                out.write(b, off, len);
+                tee.write(b, off, len);
+            }
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            if (closing) {
+                // if the jar is about to close, save the footer that will be written
+                footer.write(b);
+            }
+            else {
+                // write to both output streams. out is the CMSTypedData signer and tee is the file.
+                out.write(b);
+                tee.write(b);
+            }
+        }
+    }
+
+    private static class CMSSigner implements CMSTypedData {
+        private JarFile inputJar;
+        private File publicKeyFile;
+        private X509Certificate publicKey;
+        private PrivateKey privateKey;
+        private String outputFile;
+        private OutputStream outputStream;
+        private final ASN1ObjectIdentifier type;
+        private WholeFileSignerOutputStream signer;
+
+        public CMSSigner(JarFile inputJar, File publicKeyFile,
+                         X509Certificate publicKey, PrivateKey privateKey,
+                         OutputStream outputStream) {
+            this.inputJar = inputJar;
+            this.publicKeyFile = publicKeyFile;
+            this.publicKey = publicKey;
+            this.privateKey = privateKey;
+            this.outputStream = outputStream;
+            this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId());
+        }
+
+        public Object getContent() {
+            throw new UnsupportedOperationException();
+        }
+
+        public ASN1ObjectIdentifier getContentType() {
+            return type;
+        }
+
+        public void write(OutputStream out) throws IOException {
+            try {
+                signer = new WholeFileSignerOutputStream(out, outputStream);
+                JarOutputStream outputJar = new JarOutputStream(signer);
+
+                Manifest manifest = addDigestsToManifest(inputJar);
+                signFile(manifest, inputJar,
+                         new X509Certificate[]{ publicKey },
+                         new PrivateKey[]{ privateKey },
+                         outputJar);
+                // Assume the certificate is valid for at least an hour.
+                long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
+                addOtacert(outputJar, publicKeyFile, timestamp, manifest);
+
+                signer.notifyClosing();
+                outputJar.close();
+                signer.finish();
+            }
+            catch (Exception e) {
+                throw new IOException(e);
+            }
+        }
+
+        public void writeSignatureBlock(ByteArrayOutputStream temp)
+            throws IOException,
+                   CertificateEncodingException,
+                   OperatorCreationException,
+                   CMSException {
+            SignApk.writeSignatureBlock(this, publicKey, privateKey, temp);
+        }
+
+        public WholeFileSignerOutputStream getSigner() {
+            return signer;
+        }
+    }
+
+    private static void signWholeFile(JarFile inputJar, File publicKeyFile,
+                                      X509Certificate publicKey, PrivateKey privateKey,
+                                      OutputStream outputStream) throws Exception {
+        CMSSigner cmsOut = new CMSSigner(inputJar, publicKeyFile,
+                                         publicKey, privateKey, outputStream);
 
         ByteArrayOutputStream temp = new ByteArrayOutputStream();
 
@@ -423,8 +546,20 @@
         temp.write(message);
         temp.write(0);
 
-        writeSignatureBlock(new CMSByteArraySlice(zipData, 0, zipData.length-2),
-                            publicKey, privateKey, temp);
+        cmsOut.writeSignatureBlock(temp);
+
+        byte[] zipData = cmsOut.getSigner().getTail();
+
+        // For a zip with no archive comment, the
+        // end-of-central-directory record will be 22 bytes long, so
+        // we expect to find the EOCD marker 22 bytes from the end.
+        if (zipData[zipData.length-22] != 0x50 ||
+            zipData[zipData.length-21] != 0x4b ||
+            zipData[zipData.length-20] != 0x05 ||
+            zipData[zipData.length-19] != 0x06) {
+            throw new IllegalArgumentException("zip data already has an archive comment");
+        }
+
         int total_size = temp.size() + 6;
         if (total_size > 0xffff) {
             throw new IllegalArgumentException("signature is too big for ZIP file comment");
@@ -458,54 +593,61 @@
             }
         }
 
-        outputStream.write(zipData, 0, zipData.length-2);
         outputStream.write(total_size & 0xff);
         outputStream.write((total_size >> 8) & 0xff);
         temp.writeTo(outputStream);
     }
 
-    /**
-     * Copy all the files in a manifest from input to output.  We set
-     * the modification times in the output to a fixed time, so as to
-     * reduce variation in the output file and make incremental OTAs
-     * more efficient.
-     */
-    private static void copyFiles(Manifest manifest,
-        JarFile in, JarOutputStream out, long timestamp) throws IOException {
-        byte[] buffer = new byte[4096];
-        int num;
+    private static void signFile(Manifest manifest, JarFile inputJar,
+                                 X509Certificate[] publicKey, PrivateKey[] privateKey,
+                                 JarOutputStream outputJar)
+        throws Exception {
+        // Assume the certificate is valid for at least an hour.
+        long timestamp = publicKey[0].getNotBefore().getTime() + 3600L * 1000;
 
-        Map<String, Attributes> entries = manifest.getEntries();
-        ArrayList<String> names = new ArrayList<String>(entries.keySet());
-        Collections.sort(names);
-        for (String name : names) {
-            JarEntry inEntry = in.getJarEntry(name);
-            JarEntry outEntry = null;
-            if (inEntry.getMethod() == JarEntry.STORED) {
-                // Preserve the STORED method of the input entry.
-                outEntry = new JarEntry(inEntry);
-            } else {
-                // Create a new entry so that the compressed len is recomputed.
-                outEntry = new JarEntry(name);
-            }
-            outEntry.setTime(timestamp);
-            out.putNextEntry(outEntry);
+        JarEntry je;
 
-            InputStream data = in.getInputStream(inEntry);
-            while ((num = data.read(buffer)) > 0) {
-                out.write(buffer, 0, num);
-            }
-            out.flush();
+        // Everything else
+        copyFiles(manifest, inputJar, outputJar, timestamp);
+
+        // MANIFEST.MF
+        je = new JarEntry(JarFile.MANIFEST_NAME);
+        je.setTime(timestamp);
+        outputJar.putNextEntry(je);
+        manifest.write(outputJar);
+
+        int numKeys = publicKey.length;
+        for (int k = 0; k < numKeys; ++k) {
+            // CERT.SF / CERT#.SF
+            je = new JarEntry(numKeys == 1 ? CERT_SF_NAME :
+                              (String.format(CERT_SF_MULTI_NAME, k)));
+            je.setTime(timestamp);
+            outputJar.putNextEntry(je);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            writeSignatureFile(manifest, baos);
+            byte[] signedData = baos.toByteArray();
+            outputJar.write(signedData);
+
+            // CERT.RSA / CERT#.RSA
+            je = new JarEntry(numKeys == 1 ? CERT_RSA_NAME :
+                              (String.format(CERT_RSA_MULTI_NAME, k)));
+            je.setTime(timestamp);
+            outputJar.putNextEntry(je);
+            writeSignatureBlock(new CMSProcessableByteArray(signedData),
+                                publicKey[k], privateKey[k], outputJar);
         }
     }
 
+    private static void usage() {
+        System.err.println("Usage: signapk [-w] " +
+                           "publickey.x509[.pem] privatekey.pk8 " +
+                           "[publickey2.x509[.pem] privatekey2.pk8 ...] " +
+                           "input.jar output.jar");
+        System.exit(2);
+    }
+
     public static void main(String[] args) {
-        if (args.length != 4 && args.length != 5) {
-            System.err.println("Usage: signapk [-w] " +
-                    "publickey.x509[.pem] privatekey.pk8 " +
-                    "input.jar output.jar");
-            System.exit(2);
-        }
+        if (args.length < 4) usage();
 
         sBouncyCastleProvider = new BouncyCastleProvider();
         Security.addProvider(sBouncyCastleProvider);
@@ -517,80 +659,60 @@
             argstart = 1;
         }
 
+        if ((args.length - argstart) % 2 == 1) usage();
+        int numKeys = ((args.length - argstart) / 2) - 1;
+        if (signWholeFile && numKeys > 1) {
+            System.err.println("Only one key may be used with -w.");
+            System.exit(2);
+        }
+
+        String inputFilename = args[args.length-2];
+        String outputFilename = args[args.length-1];
+
         JarFile inputJar = null;
-        JarOutputStream outputJar = null;
         FileOutputStream outputFile = null;
 
         try {
-            File publicKeyFile = new File(args[argstart+0]);
-            X509Certificate publicKey = readPublicKey(publicKeyFile);
+            File firstPublicKeyFile = new File(args[argstart+0]);
 
-            // Assume the certificate is valid for at least an hour.
-            long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
+            X509Certificate[] publicKey = new X509Certificate[numKeys];
+            for (int i = 0; i < numKeys; ++i) {
+                int argNum = argstart + i*2;
+                publicKey[i] = readPublicKey(new File(args[argNum]));
+            }
 
-            PrivateKey privateKey = readPrivateKey(new File(args[argstart+1]));
-            inputJar = new JarFile(new File(args[argstart+2]), false);  // Don't verify.
+            // Set the ZIP file timestamp to the starting valid time
+            // of the 0th certificate plus one hour (to match what
+            // we've historically done).
+            long timestamp = publicKey[0].getNotBefore().getTime() + 3600L * 1000;
 
-            OutputStream outputStream = null;
+            PrivateKey[] privateKey = new PrivateKey[numKeys];
+            for (int i = 0; i < numKeys; ++i) {
+                int argNum = argstart + i*2 + 1;
+                privateKey[i] = readPrivateKey(new File(args[argNum]));
+            }
+            inputJar = new JarFile(new File(inputFilename), false);  // Don't verify.
+
+            outputFile = new FileOutputStream(outputFilename);
+
+
             if (signWholeFile) {
-                outputStream = new ByteArrayOutputStream();
+                SignApk.signWholeFile(inputJar, firstPublicKeyFile,
+                                      publicKey[0], privateKey[0], outputFile);
             } else {
-                outputStream = outputFile = new FileOutputStream(args[argstart+3]);
-            }
-            outputJar = new JarOutputStream(outputStream);
+                JarOutputStream outputJar = new JarOutputStream(outputFile);
 
-            // For signing .apks, use the maximum compression to make
-            // them as small as possible (since they live forever on
-            // the system partition).  For OTA packages, use the
-            // default compression level, which is much much faster
-            // and produces output that is only a tiny bit larger
-            // (~0.1% on full OTA packages I tested).
-            if (!signWholeFile) {
+                // For signing .apks, use the maximum compression to make
+                // them as small as possible (since they live forever on
+                // the system partition).  For OTA packages, use the
+                // default compression level, which is much much faster
+                // and produces output that is only a tiny bit larger
+                // (~0.1% on full OTA packages I tested).
                 outputJar.setLevel(9);
-            }
 
-            JarEntry je;
-
-            Manifest manifest = addDigestsToManifest(inputJar);
-
-            // Everything else
-            copyFiles(manifest, inputJar, outputJar, timestamp);
-
-            // otacert
-            if (signWholeFile) {
-                addOtacert(outputJar, publicKeyFile, timestamp, manifest);
-            }
-
-            // MANIFEST.MF
-            je = new JarEntry(JarFile.MANIFEST_NAME);
-            je.setTime(timestamp);
-            outputJar.putNextEntry(je);
-            manifest.write(outputJar);
-
-            // CERT.SF
-            je = new JarEntry(CERT_SF_NAME);
-            je.setTime(timestamp);
-            outputJar.putNextEntry(je);
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            writeSignatureFile(manifest, baos);
-            byte[] signedData = baos.toByteArray();
-            outputJar.write(signedData);
-
-            // CERT.RSA
-            je = new JarEntry(CERT_RSA_NAME);
-            je.setTime(timestamp);
-            outputJar.putNextEntry(je);
-            writeSignatureBlock(new CMSProcessableByteArray(signedData),
-                                publicKey, privateKey, outputJar);
-
-            outputJar.close();
-            outputJar = null;
-            outputStream.flush();
-
-            if (signWholeFile) {
-                outputFile = new FileOutputStream(args[argstart+3]);
-                signWholeOutputFile(((ByteArrayOutputStream)outputStream).toByteArray(),
-                                    outputFile, publicKey, privateKey);
+                signFile(addDigestsToManifest(inputJar), inputJar,
+                         publicKey, privateKey, outputJar);
+                outputJar.close();
             }
         } catch (Exception e) {
             e.printStackTrace();