Merge jb-mr1-dev into aosp/master - do not merge

Change-Id: Icf16741de4c0d248e5ffe3ef3b31ce6ce51c4c9f
diff --git a/core/Makefile b/core/Makefile
index e0f6da8..7ce82a0 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -240,6 +240,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 +260,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 +570,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 +582,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
 
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 cfff307..e954794 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -23,7 +23,7 @@
 # (like "TC1-RC5").  It must be a single word, and is
 # capitalized by convention.
 #
-BUILD_ID := JB_MR1
+BUILD_ID := OPENMASTER
 
 # DISPLAY_BUILD_NUMBER should only be set for development branches,
 # If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 5d55534..dd852a1 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:=
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..3001f59 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
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 854037d..dd7a8f0 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -43,7 +43,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
 
@@ -114,11 +114,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
@@ -242,11 +242,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..6e9cd01 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -43,7 +43,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,7 +81,7 @@
 TARGET_GLOBAL_CFLAGS += \
 			$(TARGET_mips_CFLAGS) \
 			-Ulinux -U__unix -U__unix__ -Umips \
-			-fpic \
+			-fpic -fPIE\
 			-ffunction-sections \
 			-fdata-sections \
 			-funwind-tables \
@@ -92,10 +92,10 @@
 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
@@ -214,11 +214,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 $@) \
@@ -243,7 +238,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 \
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
index 0e7c17d..569914b 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -36,7 +36,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
 
@@ -144,6 +144,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/config.mk b/core/config.mk
index 747d8ed..1af5a2a 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -225,6 +225,11 @@
 endif
 TARGET_CPU_ABI2 := $(strip $(TARGET_CPU_ABI2))
 
+# default target GCC version
+ifeq ($(strip $(TARGET_GCC_VERSION)),)
+TARGET_GCC_VERSION := 4.6
+endif
+
 # $(1): os/arch
 define select-android-config-h
 build/core/combo/include/arch/$(1)/AndroidConfig.h
diff --git a/core/definitions.mk b/core/definitions.mk
index 06db960..a524b2f 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/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/host_java_library.mk b/core/host_java_library.mk
index 5930da6..c938d57 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -43,6 +43,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 +55,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 +96,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/main.mk b/core/main.mk
index 87488f4..0c70d92 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -158,7 +158,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 +170,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 +258,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 +431,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 +438,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 +695,6 @@
 .PHONY: files
 files: prebuilt \
         $(modules_to_install) \
-        $(modules_to_check) \
         $(INSTALLED_ANDROID_INFO_TXT_TARGET)
 
 # -------------------------------------------------------------------
@@ -777,10 +733,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/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 8d9928e..63fd4d4 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/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 fb1f361..09eeb67 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.1
+  PLATFORM_VERSION := 4.2.1.2.4.8.16.32.64
 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 c758fcc..1b70d10 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -116,13 +116,16 @@
     prebuiltdir=$(getprebuilt)
     gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
 
+    # defined in core/config.mk
+    targetgccversion=$(get_build_var TARGET_GCC_VERSION)
+
     # 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
             ;;
-        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
             ;;
@@ -138,7 +141,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"
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 831298a..a7236f0 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -129,14 +129,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)
@@ -151,20 +152,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..7f681b13
--- /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/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)
+