Merge changes Id9717132,I3e3b7251,I021c7971,I8a117a86,Ia5196f1f, ...

* changes:
  Allow AndroidMkData.Custom handlers to extend normal values
  Remove error from AndroidMkDataProvider.AndroidMk
  Remove error from AndroidMkData.Custom
  Remove error from AndroidMkData.Extra
  Bring java support closer to current version of make
  Rename java_prebuilt_library to java_import
diff --git a/android/androidmk.go b/android/androidmk.go
index 6197f59..46e7fcf 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -33,7 +33,7 @@
 }
 
 type AndroidMkDataProvider interface {
-	AndroidMk() (AndroidMkData, error)
+	AndroidMk() AndroidMkData
 	BaseModuleName() string
 }
 
@@ -43,11 +43,15 @@
 	OutputFile OptionalPath
 	Disabled   bool
 
-	Custom func(w io.Writer, name, prefix, moduleDir string) error
+	Custom func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData)
 
-	Extra []func(w io.Writer, outputFile Path) error
+	Extra []AndroidMkExtraFunc
+
+	preamble bytes.Buffer
 }
 
+type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
+
 func AndroidMkSingleton() blueprint.Singleton {
 	return &androidMkSingleton{}
 }
@@ -157,58 +161,39 @@
 		return nil
 	}
 
-	data, err := provider.AndroidMk()
-	if err != nil {
-		return err
-	}
+	data := provider.AndroidMk()
 
 	// Make does not understand LinuxBionic
 	if amod.Os() == LinuxBionic {
 		return nil
 	}
 
-	if data.SubName != "" {
-		name += data.SubName
-	}
+	prefix := ""
+	if amod.ArchSpecific() {
+		switch amod.Os().Class {
+		case Host:
+			prefix = "HOST_"
+		case HostCross:
+			prefix = "HOST_CROSS_"
+		case Device:
+			prefix = "TARGET_"
 
-	if data.Custom != nil {
-		prefix := ""
-		if amod.ArchSpecific() {
-			switch amod.Os().Class {
-			case Host:
-				prefix = "HOST_"
-			case HostCross:
-				prefix = "HOST_CROSS_"
-			case Device:
-				prefix = "TARGET_"
-
-			}
-
-			config := ctx.Config().(Config)
-			if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType {
-				prefix = "2ND_" + prefix
-			}
 		}
 
-		return data.Custom(w, name, prefix, filepath.Dir(ctx.BlueprintFile(mod)))
+		config := ctx.Config().(Config)
+		if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType {
+			prefix = "2ND_" + prefix
+		}
 	}
 
-	if data.Disabled {
-		return nil
-	}
-
-	if !data.OutputFile.Valid() {
-		return err
-	}
-
-	fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
-	fmt.Fprintln(w, "LOCAL_PATH :=", filepath.Dir(ctx.BlueprintFile(mod)))
-	fmt.Fprintln(w, "LOCAL_MODULE :=", name)
-	fmt.Fprintln(w, "LOCAL_MODULE_CLASS :=", data.Class)
-	fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", data.OutputFile.String())
+	fmt.Fprintln(&data.preamble, "\ninclude $(CLEAR_VARS)")
+	fmt.Fprintln(&data.preamble, "LOCAL_PATH :=", filepath.Dir(ctx.BlueprintFile(mod)))
+	fmt.Fprintln(&data.preamble, "LOCAL_MODULE :=", name+data.SubName)
+	fmt.Fprintln(&data.preamble, "LOCAL_MODULE_CLASS :=", data.Class)
+	fmt.Fprintln(&data.preamble, "LOCAL_PREBUILT_MODULE_FILE :=", data.OutputFile.String())
 
 	if len(amod.commonProperties.Required) > 0 {
-		fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(amod.commonProperties.Required, " "))
+		fmt.Fprintln(&data.preamble, "LOCAL_REQUIRED_MODULES := "+strings.Join(amod.commonProperties.Required, " "))
 	}
 
 	archStr := amod.Arch().ArchType.String()
@@ -217,51 +202,68 @@
 	case Host:
 		// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
 		if archStr != "common" {
-			fmt.Fprintln(w, "LOCAL_MODULE_HOST_ARCH :=", archStr)
+			fmt.Fprintln(&data.preamble, "LOCAL_MODULE_HOST_ARCH :=", archStr)
 		}
 		host = true
 	case HostCross:
 		// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
 		if archStr != "common" {
-			fmt.Fprintln(w, "LOCAL_MODULE_HOST_CROSS_ARCH :=", archStr)
+			fmt.Fprintln(&data.preamble, "LOCAL_MODULE_HOST_CROSS_ARCH :=", archStr)
 		}
 		host = true
 	case Device:
 		// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
 		if archStr != "common" {
-			fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", archStr)
+			fmt.Fprintln(&data.preamble, "LOCAL_MODULE_TARGET_ARCH :=", archStr)
 		}
 
 		if len(amod.commonProperties.Logtags) > 0 {
-			fmt.Fprintln(w, "LOCAL_LOGTAGS_FILES := ", strings.Join(amod.commonProperties.Logtags, " "))
+			fmt.Fprintln(&data.preamble, "LOCAL_LOGTAGS_FILES := ", strings.Join(amod.commonProperties.Logtags, " "))
 		}
 		if len(amod.commonProperties.Init_rc) > 0 {
-			fmt.Fprintln(w, "LOCAL_INIT_RC := ", strings.Join(amod.commonProperties.Init_rc, " "))
+			fmt.Fprintln(&data.preamble, "LOCAL_INIT_RC := ", strings.Join(amod.commonProperties.Init_rc, " "))
 		}
 		if amod.commonProperties.Proprietary {
-			fmt.Fprintln(w, "LOCAL_PROPRIETARY_MODULE := true")
+			fmt.Fprintln(&data.preamble, "LOCAL_PROPRIETARY_MODULE := true")
 		}
 		if amod.commonProperties.Vendor {
-			fmt.Fprintln(w, "LOCAL_VENDOR_MODULE := true")
+			fmt.Fprintln(&data.preamble, "LOCAL_VENDOR_MODULE := true")
 		}
 		if amod.commonProperties.Owner != nil {
-			fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner)
+			fmt.Fprintln(&data.preamble, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner)
 		}
 	}
 
 	if host {
-		fmt.Fprintln(w, "LOCAL_MODULE_HOST_OS :=", amod.Os().String())
-		fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
+		fmt.Fprintln(&data.preamble, "LOCAL_MODULE_HOST_OS :=", amod.Os().String())
+		fmt.Fprintln(&data.preamble, "LOCAL_IS_HOST_MODULE := true")
 	}
 
+	blueprintDir := filepath.Dir(ctx.BlueprintFile(mod))
+
+	if data.Custom != nil {
+		data.Custom(w, name, prefix, blueprintDir, data)
+	} else {
+		WriteAndroidMkData(w, data)
+	}
+
+	return nil
+}
+
+func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
+	if data.Disabled {
+		return
+	}
+
+	if !data.OutputFile.Valid() {
+		return
+	}
+
+	w.Write(data.preamble.Bytes())
+
 	for _, extra := range data.Extra {
-		err = extra(w, data.OutputFile.Path())
-		if err != nil {
-			return err
-		}
+		extra(w, data.OutputFile.Path())
 	}
 
 	fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
-
-	return err
 }
diff --git a/android/package_ctx.go b/android/package_ctx.go
index 5304403..2bc98aa 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -75,6 +75,22 @@
 	})
 }
 
+// SourcePathVariableWithEnvOverride returns a Variable whose value is the source directory
+// appended with the supplied path, or the value of the given environment variable if it is set.
+// The environment variable is not required to point to a path inside the source tree.
+// It may only be called during a Go package's initialization - either from the init() function or
+// as part of a package-scoped variable's initialization.
+func (p AndroidPackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
+	return p.VariableFunc(name, func(config interface{}) (string, error) {
+		ctx := &configErrorWrapper{p, config.(Config), []error{}}
+		p := safePathForSource(ctx, path)
+		if len(ctx.errors) > 0 {
+			return "", ctx.errors[0]
+		}
+		return config.(Config).GetenvWithDefault(env, p.String()), nil
+	})
+}
+
 // HostBinVariable returns a Variable whose value is the path to a host tool
 // in the bin directory for host targets. It may only be called during a Go
 // package's initialization - either from the init() function or as part of a
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 507aa5f..f61a0dd 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -14,7 +14,11 @@
 
 package android
 
-import "github.com/google/blueprint"
+import (
+	"fmt"
+
+	"github.com/google/blueprint"
+)
 
 // This file implements common functionality for handling modules that may exist as prebuilts,
 // source, or both.
@@ -25,35 +29,43 @@
 
 var prebuiltDepTag prebuiltDependencyTag
 
-type Prebuilt struct {
-	Properties struct {
-		Srcs []string `android:"arch_variant"`
-		// When prefer is set to true the prebuilt will be used instead of any source module with
-		// a matching name.
-		Prefer bool `android:"arch_variant"`
+type PrebuiltProperties struct {
+	// When prefer is set to true the prebuilt will be used instead of any source module with
+	// a matching name.
+	Prefer bool `android:"arch_variant"`
 
-		SourceExists bool `blueprint:"mutated"`
-		UsePrebuilt  bool `blueprint:"mutated"`
-	}
-	module Module
+	SourceExists bool `blueprint:"mutated"`
+	UsePrebuilt  bool `blueprint:"mutated"`
+}
+
+type Prebuilt struct {
+	properties PrebuiltProperties
+	module     Module
+	srcs       *[]string
 }
 
 func (p *Prebuilt) Name(name string) string {
 	return "prebuilt_" + name
 }
 
-func (p *Prebuilt) Path(ctx ModuleContext) Path {
-	if len(p.Properties.Srcs) == 0 {
+func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
+	if len(*p.srcs) == 0 {
 		ctx.PropertyErrorf("srcs", "missing prebuilt source file")
 		return nil
 	}
 
-	if len(p.Properties.Srcs) > 1 {
+	if len(*p.srcs) > 1 {
 		ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
 		return nil
 	}
 
-	return PathForModuleSrc(ctx, p.Properties.Srcs[0])
+	return PathForModuleSrc(ctx, (*p.srcs)[0])
+}
+
+func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
+	p := module.Prebuilt()
+	module.AddProperties(&p.properties)
+	p.srcs = srcs
 }
 
 type PrebuiltInterface interface {
@@ -78,7 +90,7 @@
 		name := m.base().BaseModuleName()
 		if ctx.OtherModuleExists(name) {
 			ctx.AddReverseDependency(ctx.Module(), prebuiltDepTag, name)
-			p.Properties.SourceExists = true
+			p.properties.SourceExists = true
 		} else {
 			ctx.Rename(name)
 		}
@@ -90,15 +102,18 @@
 func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
 	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
 		p := m.Prebuilt()
-		if !p.Properties.SourceExists {
-			p.Properties.UsePrebuilt = p.usePrebuilt(ctx, nil)
+		if p.srcs == nil {
+			panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it"))
+		}
+		if !p.properties.SourceExists {
+			p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil)
 		}
 	} else if s, ok := ctx.Module().(Module); ok {
 		ctx.VisitDirectDeps(func(m blueprint.Module) {
 			if ctx.OtherModuleDependencyTag(m) == prebuiltDepTag {
 				p := m.(PrebuiltInterface).Prebuilt()
 				if p.usePrebuilt(ctx, s) {
-					p.Properties.UsePrebuilt = true
+					p.properties.UsePrebuilt = true
 					s.SkipInstall()
 				}
 			}
@@ -113,8 +128,8 @@
 	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
 		p := m.Prebuilt()
 		name := m.base().BaseModuleName()
-		if p.Properties.UsePrebuilt {
-			if p.Properties.SourceExists {
+		if p.properties.UsePrebuilt {
+			if p.properties.SourceExists {
 				ctx.ReplaceDependencies(name)
 			}
 		} else {
@@ -126,12 +141,12 @@
 // usePrebuilt returns true if a prebuilt should be used instead of the source module.  The prebuilt
 // will be used if it is marked "prefer" or if the source module is disabled.
 func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool {
-	if len(p.Properties.Srcs) == 0 {
+	if len(*p.srcs) == 0 {
 		return false
 	}
 
 	// TODO: use p.Properties.Name and ctx.ModuleDir to override preference
-	if p.Properties.Prefer {
+	if p.properties.Prefer {
 		return true
 	}
 
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 774a15c..9a1de9c 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -151,7 +151,7 @@
 				}
 				if p, ok := m.(*prebuiltModule); ok {
 					dependsOnPrebuiltModule = true
-					if !p.Prebuilt().Properties.UsePrebuilt {
+					if !p.Prebuilt().properties.UsePrebuilt {
 						t.Errorf("dependency on prebuilt module not marked used")
 					}
 				}
@@ -180,12 +180,16 @@
 
 type prebuiltModule struct {
 	ModuleBase
-	prebuilt Prebuilt
+	prebuilt   Prebuilt
+	properties struct {
+		Srcs []string
+	}
 }
 
 func newPrebuiltModule() Module {
 	m := &prebuiltModule{}
-	m.AddProperties(&m.prebuilt.Properties)
+	m.AddProperties(&m.properties)
+	InitPrebuiltModule(m, &m.properties.Srcs)
 	InitAndroidModule(m)
 	return m
 }
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 940e7c7..fc45b7a 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -49,30 +49,34 @@
 	}
 }
 
-func (c *Module) AndroidMk() (ret android.AndroidMkData, err error) {
+func (c *Module) AndroidMk() android.AndroidMkData {
 	if c.Properties.HideFromMake {
-		ret.Disabled = true
-		return ret, nil
+		return android.AndroidMkData{
+			Disabled: true,
+		}
 	}
 
-	ret.OutputFile = c.outputFile
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) (err error) {
-		fmt.Fprintln(w, "LOCAL_SANITIZE := never")
-		if len(c.Properties.AndroidMkSharedLibs) > 0 {
-			fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
-		}
-		if c.Target().Os == android.Android && c.Properties.Sdk_version != "" && !c.vndk() {
-			fmt.Fprintln(w, "LOCAL_SDK_VERSION := "+c.Properties.Sdk_version)
-			fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
-		} else {
-			// These are already included in LOCAL_SHARED_LIBRARIES
-			fmt.Fprintln(w, "LOCAL_CXX_STL := none")
-		}
-		if c.vndk() {
-			fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
-		}
-		return nil
-	})
+	ret := android.AndroidMkData{
+		OutputFile: c.outputFile,
+		Extra: []android.AndroidMkExtraFunc{
+			func(w io.Writer, outputFile android.Path) {
+				fmt.Fprintln(w, "LOCAL_SANITIZE := never")
+				if len(c.Properties.AndroidMkSharedLibs) > 0 {
+					fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
+				}
+				if c.Target().Os == android.Android && c.Properties.Sdk_version != "" && !c.vndk() {
+					fmt.Fprintln(w, "LOCAL_SDK_VERSION := "+c.Properties.Sdk_version)
+					fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
+				} else {
+					// These are already included in LOCAL_SHARED_LIBRARIES
+					fmt.Fprintln(w, "LOCAL_CXX_STL := none")
+				}
+				if c.vndk() {
+					fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
+				}
+			},
+		},
+	}
 
 	for _, feature := range c.features {
 		c.subAndroidMk(&ret, feature)
@@ -91,7 +95,7 @@
 		ret.SubName += vendorSuffix
 	}
 
-	return ret, nil
+	return ret
 }
 
 func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, ret *android.AndroidMkData) {
@@ -106,9 +110,8 @@
 		testFiles = append(testFiles, path+":"+rel)
 	}
 	if len(testFiles) > 0 {
-		ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+		ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 			fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " "))
-			return nil
 		})
 	}
 }
@@ -133,10 +136,10 @@
 
 		ret.Class = "SHARED_LIBRARIES"
 	} else if library.header() {
-		ret.Custom = func(w io.Writer, name, prefix, moduleDir string) error {
+		ret.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
 			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
 			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
-			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+			fmt.Fprintln(w, "LOCAL_MODULE :=", name+data.SubName)
 
 			archStr := ctx.Target().Arch.ArchType.String()
 			var host bool
@@ -160,14 +163,12 @@
 
 			library.androidMkWriteExportedFlags(w)
 			fmt.Fprintln(w, "include $(BUILD_HEADER_LIBRARY)")
-
-			return nil
 		}
 
 		return
 	}
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		library.androidMkWriteExportedFlags(w)
 		fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := ")
 		if library.sAbiOutputFile.Valid() {
@@ -185,8 +186,6 @@
 		if library.coverageOutputFile.Valid() {
 			fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", library.coverageOutputFile.String())
 		}
-
-		return nil
 	})
 
 	if library.shared() {
@@ -195,13 +194,11 @@
 }
 
 func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
-	ret.Custom = func(w io.Writer, name, prefix, moduleDir string) error {
+	ret.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
 		out := ret.OutputFile.Path()
 
-		fmt.Fprintln(w, "\n$("+prefix+"OUT_INTERMEDIATE_LIBRARIES)/"+name+objectExtension+":", out.String())
+		fmt.Fprintln(w, "\n$("+prefix+"OUT_INTERMEDIATE_LIBRARIES)/"+name+data.SubName+objectExtension+":", out.String())
 		fmt.Fprintln(w, "\t$(copy-file-to-target)")
-
-		return nil
 	}
 }
 
@@ -210,7 +207,7 @@
 	ctx.subAndroidMk(ret, &binary.stripper)
 
 	ret.Class = "EXECUTABLES"
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
 		if Bool(binary.Properties.Static_executable) {
 			fmt.Fprintln(w, "LOCAL_FORCE_STATIC_EXECUTABLE := true")
@@ -223,19 +220,17 @@
 		if binary.coverageOutputFile.Valid() {
 			fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", binary.coverageOutputFile.String())
 		}
-		return nil
 	})
 }
 
 func (benchmark *benchmarkDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
 	ctx.subAndroidMk(ret, benchmark.binaryDecorator)
 	ret.Class = "NATIVE_TESTS"
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		if len(benchmark.Properties.Test_suites) > 0 {
 			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
 				strings.Join(benchmark.Properties.Test_suites, " "))
 		}
-		return nil
 	})
 
 	androidMkWriteTestData(benchmark.data, ctx, ret)
@@ -248,12 +243,11 @@
 		ret.SubName = "_" + test.binaryDecorator.Properties.Stem
 	}
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		if len(test.Properties.Test_suites) > 0 {
 			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
 				strings.Join(test.Properties.Test_suites, " "))
 		}
-		return nil
 	})
 
 	androidMkWriteTestData(test.data, ctx, ret)
@@ -265,11 +259,9 @@
 
 func (library *toolchainLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
 	ret.Class = "STATIC_LIBRARIES"
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())
 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
-
-		return nil
 	})
 }
 
@@ -279,7 +271,7 @@
 		return
 	}
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		if stripper.StripProperties.Strip.None {
 			fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
 		} else if stripper.StripProperties.Strip.Keep_symbols {
@@ -287,17 +279,14 @@
 		} else {
 			fmt.Fprintln(w, "LOCAL_STRIP_MODULE := mini-debug-info")
 		}
-
-		return nil
 	})
 }
 
 func (packer *relocationPacker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		if packer.Properties.PackingRelocations {
 			fmt.Fprintln(w, "LOCAL_PACK_MODULE_RELOCATIONS := true")
 		}
-		return nil
 	})
 }
 
@@ -308,14 +297,13 @@
 		ret.OutputFile = android.OptionalPathForPath(installer.path)
 	}
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		path := installer.path.RelPathString()
 		dir, file := filepath.Split(path)
 		stem := strings.TrimSuffix(file, filepath.Ext(file))
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file))
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
-		return nil
 	})
 }
 
@@ -323,7 +311,7 @@
 	ret.SubName = ndkLibrarySuffix + "." + c.properties.ApiLevel
 	ret.Class = "SHARED_LIBRARIES"
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		path, file := filepath.Split(c.installPath)
 		stem := strings.TrimSuffix(file, filepath.Ext(file))
 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
@@ -336,7 +324,6 @@
 		// dozens of libraries with the same name, they'll clobber each other
 		// and the real versions of the libraries from the platform).
 		fmt.Fprintln(w, "LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES := false")
-		return nil
 	})
 }
 
@@ -344,7 +331,7 @@
 	ret.Class = "SHARED_LIBRARIES"
 	ret.SubName = ".vendor"
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		c.libraryDecorator.androidMkWriteExportedFlags(w)
 
 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext())
@@ -353,7 +340,5 @@
 		fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
 		fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
 		fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
-
-		return nil
 	})
 }
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 976c711..089ce28 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -31,12 +31,19 @@
 
 type prebuiltLinker struct {
 	android.Prebuilt
+	properties struct {
+		Srcs []string `android:"arch_variant"`
+	}
 }
 
 func (p *prebuiltLinker) prebuilt() *android.Prebuilt {
 	return &p.Prebuilt
 }
 
+func (p *prebuiltLinker) PrebuiltSrcs() []string {
+	return p.properties.Srcs
+}
+
 type prebuiltLibraryLinker struct {
 	*libraryDecorator
 	prebuiltLinker
@@ -44,20 +51,15 @@
 
 var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil)
 
-func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
-	props := p.libraryDecorator.linkerProps()
-	return append(props, &p.Prebuilt.Properties)
-}
-
 func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 	// TODO(ccross): verify shared library dependencies
-	if len(p.Prebuilt.Properties.Srcs) > 0 {
+	if len(p.properties.Srcs) > 0 {
 		p.libraryDecorator.exportIncludes(ctx, "-I")
 		p.libraryDecorator.reexportFlags(deps.ReexportedFlags)
 		p.libraryDecorator.reexportDeps(deps.ReexportedFlagsDeps)
 		// TODO(ccross): .toc optimization, stripping, packing
-		return p.Prebuilt.Path(ctx)
+		return p.Prebuilt.SingleSourcePath(ctx)
 	}
 
 	return nil
@@ -78,6 +80,9 @@
 	}
 	module.linker = prebuilt
 
+	module.AddProperties(&prebuilt.properties)
+
+	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
 	return module, library
 }
 
@@ -96,6 +101,9 @@
 	}
 	module.linker = prebuilt
 
+	module.AddProperties(&prebuilt.properties)
+
+	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
 	return module, library
 }
 
@@ -106,15 +114,10 @@
 
 var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil)
 
-func (p *prebuiltBinaryLinker) linkerProps() []interface{} {
-	props := p.binaryDecorator.linkerProps()
-	return append(props, &p.Prebuilt.Properties)
-}
-
 func (p *prebuiltBinaryLinker) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 	// TODO(ccross): verify shared library dependencies
-	if len(p.Prebuilt.Properties.Srcs) > 0 {
+	if len(p.properties.Srcs) > 0 {
 		// TODO(ccross): .toc optimization, stripping, packing
 
 		// Copy binaries to a name matching the final installed name
@@ -125,7 +128,7 @@
 			Rule:        android.Cp,
 			Description: "prebuilt",
 			Output:      outputFile,
-			Input:       p.Prebuilt.Path(ctx),
+			Input:       p.Prebuilt.SingleSourcePath(ctx),
 		})
 
 		return outputFile
@@ -148,5 +151,8 @@
 	}
 	module.linker = prebuilt
 
+	module.AddProperties(&prebuilt.properties)
+
+	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
 	return module, binary
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 1fcb32c..4ea4d26 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -444,12 +444,10 @@
 }
 
 func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		if sanitize.androidMkRuntimeLibrary != "" {
 			fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES += "+sanitize.androidMkRuntimeLibrary)
 		}
-
-		return nil
 	})
 }
 
diff --git a/java/androidmk.go b/java/androidmk.go
index 9ccf856..1939924 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -15,17 +15,32 @@
 package java
 
 import (
+	"fmt"
+	"io"
+
 	"android/soong/android"
 )
 
-func (library *Library) AndroidMk() (ret android.AndroidMkData, err error) {
-	ret.Class = "JAVA_LIBRARIES"
-	ret.OutputFile = android.OptionalPathForPath(library.outputFile)
-	return
+func (library *Library) AndroidMk() android.AndroidMkData {
+	return android.AndroidMkData{
+		Class:      "JAVA_LIBRARIES",
+		OutputFile: android.OptionalPathForPath(library.outputFile),
+		Extra: []android.AndroidMkExtraFunc{
+			func(w io.Writer, outputFile android.Path) {
+				fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := .jar")
+			},
+		},
+	}
 }
 
-func (prebuilt *Prebuilt) AndroidMk() (ret android.AndroidMkData, err error) {
-	ret.Class = "JAVA_LIBRARIES"
-	ret.OutputFile = android.OptionalPathForPath(prebuilt.classpathFile)
-	return
+func (prebuilt *Import) AndroidMk() android.AndroidMkData {
+	return android.AndroidMkData{
+		Class:      "JAVA_LIBRARIES",
+		OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile),
+		Extra: []android.AndroidMkExtraFunc{
+			func(w io.Writer, outputFile android.Path) {
+				fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := .jar")
+			},
+		},
+	}
 }
diff --git a/java/app.go b/java/app.go
index 8a221ef..ceb7791 100644
--- a/java/app.go
+++ b/java/app.go
@@ -231,18 +231,19 @@
 	aaptFlags = append(aaptFlags, android.JoinWithPrefix(resourceDirs.Strings(), "-S "))
 
 	ctx.VisitDirectDeps(func(module blueprint.Module) {
-		var depFile android.OptionalPath
+		var depFiles android.Paths
 		if sdkDep, ok := module.(sdkDependency); ok {
-			depFile = android.OptionalPathForPath(sdkDep.ClasspathFile())
+			depFiles = sdkDep.ClasspathFiles()
 		} else if javaDep, ok := module.(Dependency); ok {
 			if ctx.OtherModuleName(module) == "framework-res" {
-				depFile = android.OptionalPathForPath(javaDep.(*AndroidApp).exportPackage)
+				depFiles = android.Paths{javaDep.(*AndroidApp).exportPackage}
 			}
 		}
-		if depFile.Valid() {
-			aaptFlags = append(aaptFlags, "-I "+depFile.String())
-			aaptDeps = append(aaptDeps, depFile.Path())
+
+		for _, dep := range depFiles {
+			aaptFlags = append(aaptFlags, "-I "+dep.String())
 		}
+		aaptDeps = append(aaptDeps, depFiles...)
 	})
 
 	sdkVersion := a.deviceProperties.Sdk_version
diff --git a/java/builder.go b/java/builder.go
index ed9d82c..017f64f 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -19,13 +19,11 @@
 // functions.
 
 import (
-	"path/filepath"
 	"strings"
 
 	"android/soong/android"
 
 	"github.com/google/blueprint"
-	_ "github.com/google/blueprint/bootstrap"
 )
 
 var (
@@ -39,36 +37,37 @@
 	// read from directly using @<listfile>)
 	javac = pctx.AndroidGomaStaticRule("javac",
 		blueprint.RuleParams{
-			Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
-				`${JavacWrapper}$javacCmd ` +
-				`-encoding UTF-8 $javacFlags $bootClasspath $classpath ` +
-				`-extdirs "" -d $outDir @$out.rsp || ( rm -rf "$outDir"; exit 41 ) && ` +
+			Command: `rm -rf "$outDir" "$annoDir" && mkdir -p "$outDir" "$annoDir" && ` +
+				`${config.JavacWrapper}${config.JavacCmd} ${config.CommonJdkFlags} ` +
+				`$javacFlags $bootClasspath $classpath ` +
+				`-source $javaVersion -target $javaVersion ` +
+				`-d $outDir -s $annoDir @$out.rsp || ( rm -rf "$outDir"; exit 41 ) && ` +
 				`find $outDir -name "*.class" > $out`,
 			Rspfile:        "$out.rsp",
 			RspfileContent: "$in",
 		},
-		"javacCmd", "javacFlags", "bootClasspath", "classpath", "outDir")
+		"javacFlags", "bootClasspath", "classpath", "outDir", "annoDir", "javaVersion")
 
 	jar = pctx.AndroidStaticRule("jar",
 		blueprint.RuleParams{
-			Command:     `$jarCmd -o $out $jarArgs`,
-			CommandDeps: []string{"$jarCmd"},
+			Command:     `${config.SoongZipCmd} -o $out -d $jarArgs`,
+			CommandDeps: []string{"${config.SoongZipCmd}"},
 		},
 		"jarCmd", "jarArgs")
 
 	dx = pctx.AndroidStaticRule("dx",
 		blueprint.RuleParams{
 			Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
-				`$dxCmd --dex --output=$outDir $dxFlags $in || ( rm -rf "$outDir"; exit 41 ) && ` +
-				`find "$outDir" -name "classes*.dex" > $out`,
-			CommandDeps: []string{"$dxCmd"},
+				`${config.DxCmd} --dex --output=$outDir $dxFlags $in || ( rm -rf "$outDir"; exit 41 ) && ` +
+				`find "$outDir" -name "classes*.dex" | sort > $out`,
+			CommandDeps: []string{"${config.DxCmd}"},
 		},
 		"outDir", "dxFlags")
 
 	jarjar = pctx.AndroidStaticRule("jarjar",
 		blueprint.RuleParams{
-			Command:     "java -jar $jarjarCmd process $rulesFile $in $out",
-			CommandDeps: []string{"$jarjarCmd", "$rulesFile"},
+			Command:     "${config.JavaCmd} -jar ${config.JarjarCmd} process $rulesFile $in $out",
+			CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
 		},
 		"rulesFile")
 
@@ -83,19 +82,7 @@
 )
 
 func init() {
-	pctx.Import("github.com/google/blueprint/bootstrap")
-	pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
-	pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
-	pctx.StaticVariable("jarCmd", filepath.Join("${bootstrap.ToolDir}", "soong_zip"))
-	pctx.HostBinToolVariable("dxCmd", "dx")
-	pctx.HostJavaToolVariable("jarjarCmd", "jarjar.jar")
-
-	pctx.VariableFunc("JavacWrapper", func(config interface{}) (string, error) {
-		if override := config.(android.Config).Getenv("JAVAC_WRAPPER"); override != "" {
-			return override + " ", nil
-		}
-		return "", nil
-	})
+	pctx.Import("android/soong/java/config")
 }
 
 type javaBuilderFlags struct {
@@ -104,6 +91,7 @@
 	bootClasspath string
 	classpath     string
 	aidlFlags     string
+	javaVersion   string
 }
 
 type jarSpec struct {
@@ -118,6 +106,7 @@
 	flags javaBuilderFlags, deps android.Paths) jarSpec {
 
 	classDir := android.PathForModuleOut(ctx, "classes")
+	annoDir := android.PathForModuleOut(ctx, "anno")
 	classFileList := android.PathForModuleOut(ctx, "classes.list")
 
 	javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
@@ -135,6 +124,8 @@
 			"bootClasspath": flags.bootClasspath,
 			"classpath":     flags.classpath,
 			"outDir":        classDir.String(),
+			"annoDir":       annoDir.String(),
+			"javaVersion":   flags.javaVersion,
 		},
 	})
 
@@ -237,11 +228,11 @@
 }
 
 func TransformPrebuiltJarToClasses(ctx android.ModuleContext,
-	prebuilt android.Path) (classJarSpec, resourceJarSpec jarSpec) {
+	subdir string, prebuilt android.Path) (classJarSpec, resourceJarSpec jarSpec) {
 
-	classDir := android.PathForModuleOut(ctx, "extracted/classes")
-	classFileList := android.PathForModuleOut(ctx, "extracted/classes.list")
-	resourceFileList := android.PathForModuleOut(ctx, "extracted/resources.list")
+	classDir := android.PathForModuleOut(ctx, subdir, "classes")
+	classFileList := android.PathForModuleOut(ctx, subdir, "classes.list")
+	resourceFileList := android.PathForModuleOut(ctx, subdir, "resources.list")
 
 	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
 		Rule:        extractPrebuilt,
diff --git a/java/config/config.go b/java/config/config.go
index 848d09d..44651cb 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -14,10 +14,53 @@
 
 package config
 
-import "android/soong/android"
+import (
+	"path/filepath"
+	"strings"
+
+	_ "github.com/google/blueprint/bootstrap"
+
+	"android/soong/android"
+)
 
 var (
+	pctx = android.NewPackageContext("android/soong/java/config")
+
 	DefaultLibraries = []string{"core-oj", "core-libart", "ext", "framework", "okhttp"}
 )
 
-var pctx = android.NewPackageContext("android/soong/java/config")
+func init() {
+	pctx.Import("github.com/google/blueprint/bootstrap")
+
+	pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
+		`-J-Xmx2048M`,
+		`-Xmaxerrs 9999999`,
+		`-encoding UTF-8`,
+		`-sourcepath ""`,
+		`-g`,
+	}, " "))
+
+	pctx.StaticVariable("DefaultJavaVersion", "1.8")
+
+	pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
+
+	pctx.SourcePathVariableWithEnvOverride("JavaHome",
+		"prebuilts/jdk/jdk8/${hostPrebuiltTag}", "OVERRIDE_ANDROID_JAVA_HOME")
+	pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
+	pctx.SourcePathVariableWithEnvOverride("JavacCmd",
+		"${JavaToolchain}/javac", "ALTERNATE_JAVAC")
+	pctx.SourcePathVariable("JavaCmd", "${JavaToolchain}/java")
+	pctx.SourcePathVariable("JarCmd", "${JavaToolchain}/jar")
+	pctx.SourcePathVariable("JavadocCmd", "${JavaToolchain}/javadoc")
+
+	pctx.StaticVariable("SoongZipCmd", filepath.Join("${bootstrap.ToolDir}", "soong_zip"))
+	pctx.HostBinToolVariable("DxCmd", "dx")
+	pctx.HostJavaToolVariable("JarjarCmd", "jarjar.jar")
+
+	pctx.VariableFunc("JavacWrapper", func(config interface{}) (string, error) {
+		if override := config.(android.Config).Getenv("JAVAC_WRAPPER"); override != "" {
+			return override + " ", nil
+		}
+		return "", nil
+	})
+}
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 6702454..ec0d939 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -26,4 +26,14 @@
 
 func makeVarsProvider(ctx android.MakeVarsContext) {
 	ctx.Strict("TARGET_DEFAULT_JAVA_LIBRARIES", strings.Join(DefaultLibraries, " "))
+
+	ctx.Strict("DEFAULT_JAVA_LANGUAGE_VERSION", "${DefaultJavaVersion}")
+
+	ctx.Strict("ANDROID_JAVA_HOME", "${JavaHome}")
+	ctx.Strict("ANDROID_JAVA_TOOLCHAIN", "${JavaToolchain}")
+	ctx.Strict("JAVA", "${JavaCmd}")
+	ctx.Strict("JAVAC", "${JavacCmd}")
+	ctx.Strict("JAR", "${JarCmd}")
+	ctx.Strict("JAVADOC", "${JavadocCmd}")
+	ctx.Strict("COMMON_JDK_FLAGS", "${CommonJdkFlags}")
 }
diff --git a/java/java.go b/java/java.go
index f7191bf..4c614e5 100644
--- a/java/java.go
+++ b/java/java.go
@@ -20,6 +20,7 @@
 
 import (
 	"fmt"
+	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -37,7 +38,8 @@
 	android.RegisterModuleType("java_library_host", LibraryHostFactory)
 	android.RegisterModuleType("java_binary", BinaryFactory)
 	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
-	android.RegisterModuleType("java_prebuilt_library", PrebuiltFactory)
+	android.RegisterModuleType("java_import", ImportFactory)
+	android.RegisterModuleType("java_import_host", ImportFactoryHost)
 	android.RegisterModuleType("android_prebuilt_sdk", SdkPrebuiltFactory)
 	android.RegisterModuleType("android_app", AndroidAppFactory)
 
@@ -90,6 +92,9 @@
 
 	// if not blank, run jarjar using the specified rules file
 	Jarjar_rules *string
+
+	// If not blank, set the java version passed to javac as -source and -target
+	Java_version *string
 }
 
 type CompilerDeviceProperties struct {
@@ -144,7 +149,7 @@
 }
 
 type Dependency interface {
-	ClasspathFile() android.Path
+	ClasspathFiles() android.Paths
 	ClassJarSpecs() []jarSpec
 	ResourceJarSpecs() []jarSpec
 	AidlIncludeDirs() android.Paths
@@ -220,7 +225,7 @@
 }
 
 func (j *Module) collectDeps(ctx android.ModuleContext) (classpath android.Paths,
-	bootClasspath android.OptionalPath, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess android.OptionalPath,
+	bootClasspath android.Paths, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess android.OptionalPath,
 	aidlIncludeDirs android.Paths, srcFileLists android.Paths) {
 
 	ctx.VisitDirectDeps(func(module blueprint.Module) {
@@ -239,11 +244,11 @@
 
 		switch tag {
 		case bootClasspathTag:
-			bootClasspath = android.OptionalPathForPath(dep.ClasspathFile())
+			bootClasspath = append(bootClasspath, dep.ClasspathFiles()...)
 		case libTag:
-			classpath = append(classpath, dep.ClasspathFile())
+			classpath = append(classpath, dep.ClasspathFiles()...)
 		case staticLibTag:
-			classpath = append(classpath, dep.ClasspathFile())
+			classpath = append(classpath, dep.ClasspathFiles()...)
 			classJarSpecs = append(classJarSpecs, dep.ClassJarSpecs()...)
 			resourceJarSpecs = append(resourceJarSpecs, dep.ResourceJarSpecs()...)
 		case frameworkResTag:
@@ -283,6 +288,13 @@
 	var flags javaBuilderFlags
 
 	javacFlags := j.properties.Javacflags
+
+	if j.properties.Java_version != nil {
+		flags.javaVersion = *j.properties.Java_version
+	} else {
+		flags.javaVersion = "${config.DefaultJavaVersion}"
+	}
+
 	if len(javacFlags) > 0 {
 		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
 		flags.javacFlags = "$javacFlags"
@@ -296,9 +308,9 @@
 
 	var deps android.Paths
 
-	if bootClasspath.Valid() {
-		flags.bootClasspath = "-bootclasspath " + bootClasspath.String()
-		deps = append(deps, bootClasspath.Path())
+	if len(bootClasspath) > 0 {
+		flags.bootClasspath = "-bootclasspath " + strings.Join(bootClasspath.Strings(), ":")
+		deps = append(deps, bootClasspath...)
 	}
 
 	if len(classpath) > 0 {
@@ -350,7 +362,7 @@
 			return
 		}
 
-		classes, _ := TransformPrebuiltJarToClasses(ctx, outputFile)
+		classes, _ := TransformPrebuiltJarToClasses(ctx, "jarjar_extracted", outputFile)
 		classJarSpecs = []jarSpec{classes}
 	}
 
@@ -399,8 +411,8 @@
 
 var _ Dependency = (*Library)(nil)
 
-func (j *Module) ClasspathFile() android.Path {
-	return j.classpathFile
+func (j *Module) ClasspathFiles() android.Paths {
+	return android.Paths{j.classpathFile}
 }
 
 func (j *Module) ClassJarSpecs() []jarSpec {
@@ -519,63 +531,92 @@
 // Java prebuilts
 //
 
-type Prebuilt struct {
+type ImportProperties struct {
+	Jars []string
+}
+
+type Import struct {
 	android.ModuleBase
 	prebuilt android.Prebuilt
 
-	classpathFile                   android.Path
+	properties ImportProperties
+
+	classpathFiles                  android.Paths
+	combinedClasspathFile           android.Path
 	classJarSpecs, resourceJarSpecs []jarSpec
 }
 
-func (j *Prebuilt) Prebuilt() *android.Prebuilt {
+func (j *Import) Prebuilt() *android.Prebuilt {
 	return &j.prebuilt
 }
 
-func (j *Prebuilt) Name() string {
+func (j *Import) PrebuiltSrcs() []string {
+	return j.properties.Jars
+}
+
+func (j *Import) Name() string {
 	return j.prebuilt.Name(j.ModuleBase.Name())
 }
 
-func (j *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
 }
 
-func (j *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	prebuilt := j.prebuilt.Path(ctx)
+func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)
 
-	classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, prebuilt)
+	for i, prebuilt := range j.classpathFiles {
+		subdir := "extracted" + strconv.Itoa(i)
+		classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, subdir, prebuilt)
+		j.classJarSpecs = append(j.classJarSpecs, classJarSpec)
+		j.resourceJarSpecs = append(j.resourceJarSpecs, resourceJarSpec)
+	}
 
-	j.classpathFile = prebuilt
-	j.classJarSpecs = []jarSpec{classJarSpec}
-	j.resourceJarSpecs = []jarSpec{resourceJarSpec}
-	ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.classpathFile)
+	j.combinedClasspathFile = TransformClassesToJar(ctx, j.classJarSpecs, android.OptionalPath{})
+
+	ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"),
+		ctx.ModuleName()+".jar", j.combinedClasspathFile)
 }
 
-var _ Dependency = (*Prebuilt)(nil)
+var _ Dependency = (*Import)(nil)
 
-func (j *Prebuilt) ClasspathFile() android.Path {
-	return j.classpathFile
+func (j *Import) ClasspathFiles() android.Paths {
+	return j.classpathFiles
 }
 
-func (j *Prebuilt) ClassJarSpecs() []jarSpec {
+func (j *Import) ClassJarSpecs() []jarSpec {
 	return j.classJarSpecs
 }
 
-func (j *Prebuilt) ResourceJarSpecs() []jarSpec {
+func (j *Import) ResourceJarSpecs() []jarSpec {
 	return j.resourceJarSpecs
 }
 
-func (j *Prebuilt) AidlIncludeDirs() android.Paths {
+func (j *Import) AidlIncludeDirs() android.Paths {
 	return nil
 }
 
-func PrebuiltFactory() android.Module {
-	module := &Prebuilt{}
+var _ android.PrebuiltInterface = (*Import)(nil)
 
-	module.AddProperties(&module.prebuilt.Properties)
+func ImportFactory() android.Module {
+	module := &Import{}
 
+	module.AddProperties(&module.properties)
+
+	android.InitPrebuiltModule(module, &module.properties.Jars)
 	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
 	return module
 }
 
+func ImportFactoryHost() android.Module {
+	module := &Import{}
+
+	module.AddProperties(&module.properties)
+
+	android.InitPrebuiltModule(module, &module.properties.Jars)
+	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+	return module
+}
+
 //
 // SDK java prebuilts (.jar containing resources plus framework.aidl)
 //
@@ -592,7 +633,7 @@
 }
 
 type sdkPrebuilt struct {
-	Prebuilt
+	Import
 
 	sdkProperties sdkPrebuiltProperties
 
@@ -600,7 +641,7 @@
 }
 
 func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	j.Prebuilt.GenerateAndroidBuildActions(ctx)
+	j.Import.GenerateAndroidBuildActions(ctx)
 
 	j.aidlPreprocessed = android.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed)
 }
@@ -612,10 +653,9 @@
 func SdkPrebuiltFactory() android.Module {
 	module := &sdkPrebuilt{}
 
-	module.AddProperties(
-		&module.prebuilt.Properties,
-		&module.sdkProperties)
+	module.AddProperties(&module.sdkProperties)
 
+	android.InitPrebuiltModule(module, &module.properties.Jars)
 	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
 	return module
 }
diff --git a/java/java_test.go b/java/java_test.go
index de3be49..eb116c9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -55,7 +55,7 @@
 	ctx := android.NewTestContext()
 	ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory))
 	ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory))
-	ctx.RegisterModuleType("java_prebuilt_library", android.ModuleFactoryAdaptor(PrebuiltFactory))
+	ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory))
 	ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
 	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
 	ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
@@ -209,14 +209,14 @@
 			static_libs: ["baz"],
 		}
 
-		java_prebuilt_library {
+		java_import {
 			name: "bar",
-			srcs: ["a.jar"],
+			jars: ["a.jar"],
 		}
 
-		java_prebuilt_library {
+		java_import {
 			name: "baz",
-			srcs: ["b.jar"],
+			jars: ["b.jar"],
 		}
 		`)
 
@@ -228,7 +228,7 @@
 		t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
 	}
 
-	baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted", "classes.list")
+	baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted0", "classes.list")
 	if !strings.Contains(jar.Args["jarArgs"], baz) {
 		t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz)
 	}
diff --git a/phony/phony.go b/phony/phony.go
index 79f3a1b..a39b5d5 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -48,15 +48,14 @@
 	}
 }
 
-func (p *phony) AndroidMk() (ret android.AndroidMkData, err error) {
-	ret.Custom = func(w io.Writer, name, prefix, moduleDir string) error {
-		fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
-		fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
-		fmt.Fprintln(w, "LOCAL_MODULE :=", name)
-		fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(p.requiredModuleNames, " "))
-		fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
-
-		return nil
+func (p *phony) AndroidMk() android.AndroidMkData {
+	return android.AndroidMkData{
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+			fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(p.requiredModuleNames, " "))
+			fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
+		},
 	}
-	return
 }
diff --git a/python/androidmk.go b/python/androidmk.go
index 0a79e73..ab24e99 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -38,10 +38,12 @@
 	}
 }
 
-func (p *pythonBaseModule) AndroidMk() (ret android.AndroidMkData, err error) {
+func (p *pythonBaseModule) AndroidMk() android.AndroidMkData {
+	ret := android.AndroidMkData{}
+
 	p.subAndroidMk(&ret, p.installer)
 
-	return ret, nil
+	return ret
 }
 
 func (p *pythonBinaryHostDecorator) AndroidMk(base *pythonBaseModule, ret *android.AndroidMkData) {
@@ -61,7 +63,7 @@
 		ret.OutputFile = android.OptionalPathForPath(installer.path)
 	}
 
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		path := installer.path.RelPathString()
 		dir, file := filepath.Split(path)
 		stem := strings.TrimSuffix(file, filepath.Ext(file))
@@ -69,6 +71,5 @@
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file))
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
-		return nil
 	})
 }