diff --git a/java/java.go b/java/java.go
index 8c714ee..9786947 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,11 +21,9 @@
 import (
 	"fmt"
 	"path/filepath"
-	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
@@ -122,441 +120,6 @@
 
 }
 
-// TODO:
-// Autogenerated files:
-//  Renderscript
-// Post-jar passes:
-//  Proguard
-// Rmtypedefs
-// DroidDoc
-// Findbugs
-
-// Properties that are common to most Java modules, i.e. whether it's a host or device module.
-type CommonProperties struct {
-	// list of source files used to compile the Java module.  May be .java, .kt, .logtags, .proto,
-	// or .aidl files.
-	Srcs []string `android:"path,arch_variant"`
-
-	// list Kotlin of source files containing Kotlin code that should be treated as common code in
-	// a codebase that supports Kotlin multiplatform.  See
-	// https://kotlinlang.org/docs/reference/multiplatform.html.  May be only be .kt files.
-	Common_srcs []string `android:"path,arch_variant"`
-
-	// list of source files that should not be used to build the Java module.
-	// This is most useful in the arch/multilib variants to remove non-common files
-	Exclude_srcs []string `android:"path,arch_variant"`
-
-	// list of directories containing Java resources
-	Java_resource_dirs []string `android:"arch_variant"`
-
-	// list of directories that should be excluded from java_resource_dirs
-	Exclude_java_resource_dirs []string `android:"arch_variant"`
-
-	// list of files to use as Java resources
-	Java_resources []string `android:"path,arch_variant"`
-
-	// list of files that should be excluded from java_resources and java_resource_dirs
-	Exclude_java_resources []string `android:"path,arch_variant"`
-
-	// list of module-specific flags that will be used for javac compiles
-	Javacflags []string `android:"arch_variant"`
-
-	// list of module-specific flags that will be used for kotlinc compiles
-	Kotlincflags []string `android:"arch_variant"`
-
-	// list of of java libraries that will be in the classpath
-	Libs []string `android:"arch_variant"`
-
-	// list of java libraries that will be compiled into the resulting jar
-	Static_libs []string `android:"arch_variant"`
-
-	// manifest file to be included in resulting jar
-	Manifest *string `android:"path"`
-
-	// if not blank, run jarjar using the specified rules file
-	Jarjar_rules *string `android:"path,arch_variant"`
-
-	// If not blank, set the java version passed to javac as -source and -target
-	Java_version *string
-
-	// If set to true, allow this module to be dexed and installed on devices.  Has no
-	// effect on host modules, which are always considered installable.
-	Installable *bool
-
-	// If set to true, include sources used to compile the module in to the final jar
-	Include_srcs *bool
-
-	// If not empty, classes are restricted to the specified packages and their sub-packages.
-	// This restriction is checked after applying jarjar rules and including static libs.
-	Permitted_packages []string
-
-	// List of modules to use as annotation processors
-	Plugins []string
-
-	// List of modules to export to libraries that directly depend on this library as annotation
-	// processors.  Note that if the plugins set generates_api: true this will disable the turbine
-	// optimization on modules that depend on this module, which will reduce parallelism and cause
-	// more recompilation.
-	Exported_plugins []string
-
-	// The number of Java source entries each Javac instance can process
-	Javac_shard_size *int64
-
-	// Add host jdk tools.jar to bootclasspath
-	Use_tools_jar *bool
-
-	Openjdk9 struct {
-		// List of source files that should only be used when passing -source 1.9 or higher
-		Srcs []string `android:"path"`
-
-		// List of javac flags that should only be used when passing -source 1.9 or higher
-		Javacflags []string
-	}
-
-	// When compiling language level 9+ .java code in packages that are part of
-	// a system module, patch_module names the module that your sources and
-	// dependencies should be patched into. The Android runtime currently
-	// doesn't implement the JEP 261 module system so this option is only
-	// supported at compile time. It should only be needed to compile tests in
-	// packages that exist in libcore and which are inconvenient to move
-	// elsewhere.
-	Patch_module *string `android:"arch_variant"`
-
-	Jacoco struct {
-		// List of classes to include for instrumentation with jacoco to collect coverage
-		// information at runtime when building with coverage enabled.  If unset defaults to all
-		// classes.
-		// Supports '*' as the last character of an entry in the list as a wildcard match.
-		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
-		// it matches classes in the package that have the class name as a prefix.
-		Include_filter []string
-
-		// List of classes to exclude from instrumentation with jacoco to collect coverage
-		// information at runtime when building with coverage enabled.  Overrides classes selected
-		// by the include_filter property.
-		// Supports '*' as the last character of an entry in the list as a wildcard match.
-		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
-		// it matches classes in the package that have the class name as a prefix.
-		Exclude_filter []string
-	}
-
-	Errorprone struct {
-		// List of javac flags that should only be used when running errorprone.
-		Javacflags []string
-
-		// List of java_plugin modules that provide extra errorprone checks.
-		Extra_check_modules []string
-	}
-
-	Proto struct {
-		// List of extra options that will be passed to the proto generator.
-		Output_params []string
-	}
-
-	Instrument bool `blueprint:"mutated"`
-
-	// List of files to include in the META-INF/services folder of the resulting jar.
-	Services []string `android:"path,arch_variant"`
-
-	// If true, package the kotlin stdlib into the jar.  Defaults to true.
-	Static_kotlin_stdlib *bool `android:"arch_variant"`
-
-	// A list of java_library instances that provide additional hiddenapi annotations for the library.
-	Hiddenapi_additional_annotations []string
-}
-
-// Properties that are specific to device modules. Host module factories should not add these when
-// constructing a new module.
-type DeviceProperties struct {
-	// if not blank, set to the version of the sdk to compile against.
-	// Defaults to compiling against the current platform.
-	Sdk_version *string
-
-	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
-	// Defaults to sdk_version if not set.
-	Min_sdk_version *string
-
-	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
-	// Defaults to sdk_version if not set.
-	Target_sdk_version *string
-
-	// Whether to compile against the platform APIs instead of an SDK.
-	// If true, then sdk_version must be empty. The value of this field
-	// is ignored when module's type isn't android_app.
-	Platform_apis *bool
-
-	Aidl struct {
-		// Top level directories to pass to aidl tool
-		Include_dirs []string
-
-		// Directories rooted at the Android.bp file to pass to aidl tool
-		Local_include_dirs []string
-
-		// directories that should be added as include directories for any aidl sources of modules
-		// that depend on this module, as well as to aidl for this module.
-		Export_include_dirs []string
-
-		// whether to generate traces (for systrace) for this interface
-		Generate_traces *bool
-
-		// whether to generate Binder#GetTransaction name method.
-		Generate_get_transaction_name *bool
-
-		// list of flags that will be passed to the AIDL compiler
-		Flags []string
-	}
-
-	// If true, export a copy of the module as a -hostdex module for host testing.
-	Hostdex *bool
-
-	Target struct {
-		Hostdex struct {
-			// Additional required dependencies to add to -hostdex modules.
-			Required []string
-		}
-	}
-
-	// When targeting 1.9 and above, override the modules to use with --system,
-	// otherwise provides defaults libraries to add to the bootclasspath.
-	System_modules *string
-
-	// The name of the module as used in build configuration.
-	//
-	// Allows a library to separate its actual name from the name used in
-	// build configuration, e.g.ctx.Config().BootJars().
-	ConfigurationName *string `blueprint:"mutated"`
-
-	// set the name of the output
-	Stem *string
-
-	IsSDKLibrary bool `blueprint:"mutated"`
-
-	// If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
-	// Defaults to false.
-	V4_signature *bool
-
-	// Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the
-	// public stubs library.
-	SyspropPublicStub string `blueprint:"mutated"`
-}
-
-// Functionality common to Module and Import
-//
-// It is embedded in Module so its functionality can be used by methods in Module
-// but it is currently only initialized by Import and Library.
-type embeddableInModuleAndImport struct {
-
-	// Functionality related to this being used as a component of a java_sdk_library.
-	EmbeddableSdkLibraryComponent
-}
-
-func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) {
-	e.initSdkLibraryComponent(moduleBase)
-}
-
-// Module/Import's DepIsInSameApex(...) delegates to this method.
-//
-// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with
-// the one provided by ApexModuleBase.
-func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
-	// dependencies other than the static linkage are all considered crossing APEX boundary
-	if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
-		return true
-	}
-	return false
-}
-
-// Module contains the properties and members used by all java module types
-type Module struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	android.ApexModuleBase
-	android.SdkBase
-
-	// Functionality common to Module and Import.
-	embeddableInModuleAndImport
-
-	properties       CommonProperties
-	protoProperties  android.ProtoProperties
-	deviceProperties DeviceProperties
-
-	// jar file containing header classes including static library dependencies, suitable for
-	// inserting into the bootclasspath/classpath of another compile
-	headerJarFile android.Path
-
-	// jar file containing implementation classes including static library dependencies but no
-	// resources
-	implementationJarFile android.Path
-
-	// jar file containing only resources including from static library dependencies
-	resourceJar android.Path
-
-	// args and dependencies to package source files into a srcjar
-	srcJarArgs []string
-	srcJarDeps android.Paths
-
-	// jar file containing implementation classes and resources including static library
-	// dependencies
-	implementationAndResourcesJar android.Path
-
-	// output file containing classes.dex and resources
-	dexJarFile android.Path
-
-	// output file containing uninstrumented classes that will be instrumented by jacoco
-	jacocoReportClassesFile android.Path
-
-	// output file of the module, which may be a classes jar or a dex jar
-	outputFile       android.Path
-	extraOutputFiles android.Paths
-
-	exportAidlIncludeDirs android.Paths
-
-	logtagsSrcs android.Paths
-
-	// installed file for binary dependency
-	installFile android.Path
-
-	// list of .java files and srcjars that was passed to javac
-	compiledJavaSrcs android.Paths
-	compiledSrcJars  android.Paths
-
-	// manifest file to use instead of properties.Manifest
-	overrideManifest android.OptionalPath
-
-	// map of SDK version to class loader context
-	classLoaderContexts dexpreopt.ClassLoaderContextMap
-
-	// list of plugins that this java module is exporting
-	exportedPluginJars android.Paths
-
-	// list of plugins that this java module is exporting
-	exportedPluginClasses []string
-
-	// if true, the exported plugins generate API and require disabling turbine.
-	exportedDisableTurbine bool
-
-	// list of source files, collected from srcFiles with unique java and all kt files,
-	// will be used by android.IDEInfo struct
-	expandIDEInfoCompiledSrcs []string
-
-	// expanded Jarjar_rules
-	expandJarjarRules android.Path
-
-	// list of additional targets for checkbuild
-	additionalCheckedModules android.Paths
-
-	// Extra files generated by the module type to be added as java resources.
-	extraResources android.Paths
-
-	hiddenAPI
-	dexer
-	dexpreopter
-	usesLibrary
-	linter
-
-	// list of the xref extraction files
-	kytheFiles android.Paths
-
-	// Collect the module directory for IDE info in java/jdeps.go.
-	modulePaths []string
-
-	hideApexVariantFromMake bool
-}
-
-func (j *Module) CheckStableSdkVersion() error {
-	sdkVersion := j.sdkVersion()
-	if sdkVersion.stable() {
-		return nil
-	}
-	if sdkVersion.kind == sdkCorePlatform {
-		if useLegacyCorePlatformApiByName(j.BaseModuleName()) {
-			return fmt.Errorf("non stable SDK %v - uses legacy core platform", sdkVersion)
-		} else {
-			// Treat stable core platform as stable.
-			return nil
-		}
-	} else {
-		return fmt.Errorf("non stable SDK %v", sdkVersion)
-	}
-}
-
-// checkSdkVersions enforces restrictions around SDK dependencies.
-func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
-	if j.RequiresStableAPIs(ctx) {
-		if sc, ok := ctx.Module().(sdkContext); ok {
-			if !sc.sdkVersion().specified() {
-				ctx.PropertyErrorf("sdk_version",
-					"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
-			}
-		}
-	}
-
-	// Make sure this module doesn't statically link to modules with lower-ranked SDK link type.
-	// See rank() for details.
-	ctx.VisitDirectDeps(func(module android.Module) {
-		tag := ctx.OtherModuleDependencyTag(module)
-		switch module.(type) {
-		// TODO(satayev): cover other types as well, e.g. imports
-		case *Library, *AndroidLibrary:
-			switch tag {
-			case bootClasspathTag, libTag, staticLibTag, java9LibTag:
-				j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag))
-			}
-		}
-	})
-}
-
-func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
-	if sc, ok := ctx.Module().(sdkContext); ok {
-		usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
-		sdkVersionSpecified := sc.sdkVersion().specified()
-		if usePlatformAPI && sdkVersionSpecified {
-			ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
-		} else if !usePlatformAPI && !sdkVersionSpecified {
-			ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.")
-		}
-
-	}
-}
-
-func (j *Module) addHostProperties() {
-	j.AddProperties(
-		&j.properties,
-		&j.protoProperties,
-		&j.usesLibraryProperties,
-	)
-}
-
-func (j *Module) addHostAndDeviceProperties() {
-	j.addHostProperties()
-	j.AddProperties(
-		&j.deviceProperties,
-		&j.dexer.dexProperties,
-		&j.dexpreoptProperties,
-		&j.linter.properties,
-	)
-}
-
-func (j *Module) OutputFiles(tag string) (android.Paths, error) {
-	switch tag {
-	case "":
-		return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
-	case android.DefaultDistTag:
-		return android.Paths{j.outputFile}, nil
-	case ".jar":
-		return android.Paths{j.implementationAndResourcesJar}, nil
-	case ".proguard_map":
-		if j.dexer.proguardDictionary.Valid() {
-			return android.Paths{j.dexer.proguardDictionary.Path()}, nil
-		}
-		return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
-	default:
-		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
-	}
-}
-
-var _ android.OutputFileProducer = (*Module)(nil)
-
 // JavaInfo contains information about a java module for use by modules that depend on it.
 type JavaInfo struct {
 	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -627,6 +190,7 @@
 	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
 }
 
+// TODO(jungjw): Move this to kythe.go once it's created.
 type xref interface {
 	XrefJavaFiles() android.Paths
 }
@@ -635,24 +199,6 @@
 	return j.kytheFiles
 }
 
-func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
-	initJavaModule(module, hod, false)
-}
-
-func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
-	initJavaModule(module, hod, true)
-}
-
-func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
-	multilib := android.MultilibCommon
-	if multiTargets {
-		android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
-	} else {
-		android.InitAndroidArchModule(module, hod, multilib)
-	}
-	android.InitDefaultableModule(module)
-}
-
 type dependencyTag struct {
 	blueprint.BaseDependencyTag
 	name string
@@ -758,70 +304,6 @@
 	unstrippedFile android.Path
 }
 
-func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
-	return j.properties.Instrument &&
-		ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
-		ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
-}
-
-func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
-	return j.shouldInstrument(ctx) &&
-		(ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
-			ctx.Config().UnbundledBuild())
-}
-
-func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
-	// Force enable the instrumentation for java code that is built for APEXes ...
-	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
-	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
-	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
-	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
-	if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() {
-		if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
-			return true
-		} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
-			return true
-		}
-	}
-	return false
-}
-
-func (j *Module) sdkVersion() sdkSpec {
-	return sdkSpecFrom(String(j.deviceProperties.Sdk_version))
-}
-
-func (j *Module) systemModules() string {
-	return proptools.String(j.deviceProperties.System_modules)
-}
-
-func (j *Module) minSdkVersion() sdkSpec {
-	if j.deviceProperties.Min_sdk_version != nil {
-		return sdkSpecFrom(*j.deviceProperties.Min_sdk_version)
-	}
-	return j.sdkVersion()
-}
-
-func (j *Module) targetSdkVersion() sdkSpec {
-	if j.deviceProperties.Target_sdk_version != nil {
-		return sdkSpecFrom(*j.deviceProperties.Target_sdk_version)
-	}
-	return j.sdkVersion()
-}
-
-func (j *Module) MinSdkVersion() string {
-	return j.minSdkVersion().version.String()
-}
-
-func (j *Module) AvailableFor(what string) bool {
-	if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
-		// Exception: for hostdex: true libraries, the platform variant is created
-		// even if it's not marked as available to platform. In that case, the platform
-		// variant is used only for the hostdex and not installed to the device.
-		return true
-	}
-	return j.ApexModuleBase.AvailableFor(what)
-}
-
 func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext sdkContext, d dexer) {
 	sdkDep := decodeSdkDep(ctx, sdkContext)
 	if sdkDep.useModule {
@@ -840,155 +322,6 @@
 	}
 }
 
-func (j *Module) deps(ctx android.BottomUpMutatorContext) {
-	if ctx.Device() {
-		j.linter.deps(ctx)
-
-		sdkDeps(ctx, sdkContext(j), j.dexer)
-
-		if j.deviceProperties.SyspropPublicStub != "" {
-			// This is a sysprop implementation library that has a corresponding sysprop public
-			// stubs library, and a dependency on it so that dependencies on the implementation can
-			// be forwarded to the public stubs library when necessary.
-			ctx.AddVariationDependencies(nil, syspropPublicStubDepTag, j.deviceProperties.SyspropPublicStub)
-		}
-	}
-
-	libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
-	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
-
-	// Add dependency on libraries that provide additional hidden api annotations.
-	ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
-
-	if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
-		// Require java_sdk_library at inter-partition java dependency to ensure stable
-		// interface between partitions. If inter-partition java_library dependency is detected,
-		// raise build error because java_library doesn't have a stable interface.
-		//
-		// Inputs:
-		//    PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY
-		//      if true, enable enforcement
-		//    PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST
-		//      exception list of java_library names to allow inter-partition dependency
-		for idx := range j.properties.Libs {
-			if libDeps[idx] == nil {
-				continue
-			}
-
-			if javaDep, ok := libDeps[idx].(javaSdkLibraryEnforceContext); ok {
-				// java_sdk_library is always allowed at inter-partition dependency.
-				// So, skip check.
-				if _, ok := javaDep.(*SdkLibrary); ok {
-					continue
-				}
-
-				j.checkPartitionsForJavaDependency(ctx, "libs", javaDep)
-			}
-		}
-	}
-
-	// For library dependencies that are component libraries (like stubs), add the implementation
-	// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
-	for _, dep := range libDeps {
-		if dep != nil {
-			if component, ok := dep.(SdkLibraryComponentDependency); ok {
-				if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
-					ctx.AddVariationDependencies(nil, usesLibTag, *lib)
-				}
-			}
-		}
-	}
-
-	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
-	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...)
-	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
-
-	android.ProtoDeps(ctx, &j.protoProperties)
-	if j.hasSrcExt(".proto") {
-		protoDeps(ctx, &j.protoProperties)
-	}
-
-	if j.hasSrcExt(".kt") {
-		// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
-		// Kotlin files
-		ctx.AddVariationDependencies(nil, kotlinStdlibTag,
-			"kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8")
-		if len(j.properties.Plugins) > 0 {
-			ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
-		}
-	}
-
-	// Framework libraries need special handling in static coverage builds: they should not have
-	// static dependency on jacoco, otherwise there would be multiple conflicting definitions of
-	// the same jacoco classes coming from different bootclasspath jars.
-	if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
-		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
-			j.properties.Instrument = true
-		}
-	} else if j.shouldInstrumentStatic(ctx) {
-		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
-	}
-}
-
-func hasSrcExt(srcs []string, ext string) bool {
-	for _, src := range srcs {
-		if filepath.Ext(src) == ext {
-			return true
-		}
-	}
-
-	return false
-}
-
-func (j *Module) hasSrcExt(ext string) bool {
-	return hasSrcExt(j.properties.Srcs, ext)
-}
-
-func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
-	aidlIncludeDirs android.Paths) (string, android.Paths) {
-
-	aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
-	aidlIncludes = append(aidlIncludes,
-		android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
-	aidlIncludes = append(aidlIncludes,
-		android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
-
-	var flags []string
-	var deps android.Paths
-
-	flags = append(flags, j.deviceProperties.Aidl.Flags...)
-
-	if aidlPreprocess.Valid() {
-		flags = append(flags, "-p"+aidlPreprocess.String())
-		deps = append(deps, aidlPreprocess.Path())
-	} else if len(aidlIncludeDirs) > 0 {
-		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
-	}
-
-	if len(j.exportAidlIncludeDirs) > 0 {
-		flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
-	}
-
-	if len(aidlIncludes) > 0 {
-		flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
-	}
-
-	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
-	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
-		flags = append(flags, "-I"+src.String())
-	}
-
-	if Bool(j.deviceProperties.Aidl.Generate_traces) {
-		flags = append(flags, "-t")
-	}
-
-	if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
-		flags = append(flags, "--transaction_names")
-	}
-
-	return strings.Join(flags, " "), deps
-}
-
 type deps struct {
 	classpath               classpath
 	java9Classpath          classpath
@@ -1019,272 +352,6 @@
 	}
 }
 
-type sdkLinkType int
-
-const (
-	// TODO(jiyong) rename these for better readability. Make the allowed
-	// and disallowed link types explicit
-	// order is important here. See rank()
-	javaCore sdkLinkType = iota
-	javaSdk
-	javaSystem
-	javaModule
-	javaSystemServer
-	javaPlatform
-)
-
-func (lt sdkLinkType) String() string {
-	switch lt {
-	case javaCore:
-		return "core Java API"
-	case javaSdk:
-		return "Android API"
-	case javaSystem:
-		return "system API"
-	case javaModule:
-		return "module API"
-	case javaSystemServer:
-		return "system server API"
-	case javaPlatform:
-		return "private API"
-	default:
-		panic(fmt.Errorf("unrecognized linktype: %d", lt))
-	}
-}
-
-// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to
-// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK
-// can't statically depend on modules that use Platform API.
-func (lt sdkLinkType) rank() int {
-	return int(lt)
-}
-
-type moduleWithSdkDep interface {
-	android.Module
-	getSdkLinkType(name string) (ret sdkLinkType, stubs bool)
-}
-
-func (m *Module) getSdkLinkType(name string) (ret sdkLinkType, stubs bool) {
-	switch name {
-	case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs",
-		"stub-annotations", "private-stub-annotations-jar",
-		"core-lambda-stubs", "core-generated-annotation-stubs":
-		return javaCore, true
-	case "android_stubs_current":
-		return javaSdk, true
-	case "android_system_stubs_current":
-		return javaSystem, true
-	case "android_module_lib_stubs_current":
-		return javaModule, true
-	case "android_system_server_stubs_current":
-		return javaSystemServer, true
-	case "android_test_stubs_current":
-		return javaSystem, true
-	}
-
-	if stub, linkType := moduleStubLinkType(name); stub {
-		return linkType, true
-	}
-
-	ver := m.sdkVersion()
-	switch ver.kind {
-	case sdkCore:
-		return javaCore, false
-	case sdkSystem:
-		return javaSystem, false
-	case sdkPublic:
-		return javaSdk, false
-	case sdkModule:
-		return javaModule, false
-	case sdkSystemServer:
-		return javaSystemServer, false
-	case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest:
-		return javaPlatform, false
-	}
-
-	if !ver.valid() {
-		panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
-	}
-	return javaSdk, false
-}
-
-// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
-// this module's. See the comment on rank() for details and an example.
-func (j *Module) checkSdkLinkType(
-	ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) {
-	if ctx.Host() {
-		return
-	}
-
-	myLinkType, stubs := j.getSdkLinkType(ctx.ModuleName())
-	if stubs {
-		return
-	}
-	depLinkType, _ := dep.getSdkLinkType(ctx.OtherModuleName(dep))
-
-	if myLinkType.rank() < depLinkType.rank() {
-		ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
-			"In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
-			"property of the source or target module so that target module is built "+
-			"with the same or smaller API set when compared to the source.",
-			myLinkType, ctx.OtherModuleName(dep), depLinkType)
-	}
-}
-
-func (j *Module) collectDeps(ctx android.ModuleContext) deps {
-	var deps deps
-
-	if ctx.Device() {
-		sdkDep := decodeSdkDep(ctx, sdkContext(j))
-		if sdkDep.invalidVersion {
-			ctx.AddMissingDependencies(sdkDep.bootclasspath)
-			ctx.AddMissingDependencies(sdkDep.java9Classpath)
-		} else if sdkDep.useFiles {
-			// sdkDep.jar is actually equivalent to turbine header.jar.
-			deps.classpath = append(deps.classpath, sdkDep.jars...)
-			deps.aidlPreprocess = sdkDep.aidl
-		} else {
-			deps.aidlPreprocess = sdkDep.aidl
-		}
-	}
-
-	sdkLinkType, _ := j.getSdkLinkType(ctx.ModuleName())
-
-	ctx.VisitDirectDeps(func(module android.Module) {
-		otherName := ctx.OtherModuleName(module)
-		tag := ctx.OtherModuleDependencyTag(module)
-
-		if IsJniDepTag(tag) {
-			// Handled by AndroidApp.collectAppDeps
-			return
-		}
-		if tag == certificateTag {
-			// Handled by AndroidApp.collectAppDeps
-			return
-		}
-
-		if dep, ok := module.(SdkLibraryDependency); ok {
-			switch tag {
-			case libTag:
-				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
-			case staticLibTag:
-				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
-			}
-		} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
-			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
-			if sdkLinkType != javaPlatform &&
-				ctx.OtherModuleHasProvider(module, SyspropPublicStubInfoProvider) {
-				// dep is a sysprop implementation library, but this module is not linking against
-				// the platform, so it gets the sysprop public stubs library instead.  Replace
-				// dep with the JavaInfo from the SyspropPublicStubInfoProvider.
-				syspropDep := ctx.OtherModuleProvider(module, SyspropPublicStubInfoProvider).(SyspropPublicStubInfo)
-				dep = syspropDep.JavaInfo
-			}
-			switch tag {
-			case bootClasspathTag:
-				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
-			case libTag, instrumentationForTag:
-				deps.classpath = append(deps.classpath, dep.HeaderJars...)
-				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
-				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
-				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
-			case java9LibTag:
-				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
-			case staticLibTag:
-				deps.classpath = append(deps.classpath, dep.HeaderJars...)
-				deps.staticJars = append(deps.staticJars, dep.ImplementationJars...)
-				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...)
-				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...)
-				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
-				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
-				// Turbine doesn't run annotation processors, so any module that uses an
-				// annotation processor that generates API is incompatible with the turbine
-				// optimization.
-				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
-			case pluginTag:
-				if plugin, ok := module.(*Plugin); ok {
-					if plugin.pluginProperties.Processor_class != nil {
-						addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
-					} else {
-						addPlugins(&deps, dep.ImplementationAndResourcesJars)
-					}
-					// Turbine doesn't run annotation processors, so any module that uses an
-					// annotation processor that generates API is incompatible with the turbine
-					// optimization.
-					deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
-				} else {
-					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
-				}
-			case errorpronePluginTag:
-				if _, ok := module.(*Plugin); ok {
-					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
-				} else {
-					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
-				}
-			case exportedPluginTag:
-				if plugin, ok := module.(*Plugin); ok {
-					j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
-					if plugin.pluginProperties.Processor_class != nil {
-						j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
-					}
-					// Turbine doesn't run annotation processors, so any module that uses an
-					// annotation processor that generates API is incompatible with the turbine
-					// optimization.
-					j.exportedDisableTurbine = Bool(plugin.pluginProperties.Generates_api)
-				} else {
-					ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
-				}
-			case kotlinStdlibTag:
-				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...)
-			case kotlinAnnotationsTag:
-				deps.kotlinAnnotations = dep.HeaderJars
-			case syspropPublicStubDepTag:
-				// This is a sysprop implementation library, forward the JavaInfoProvider from
-				// the corresponding sysprop public stub library as SyspropPublicStubInfoProvider.
-				ctx.SetProvider(SyspropPublicStubInfoProvider, SyspropPublicStubInfo{
-					JavaInfo: dep,
-				})
-			}
-		} else if dep, ok := module.(android.SourceFileProducer); ok {
-			switch tag {
-			case libTag:
-				checkProducesJars(ctx, dep)
-				deps.classpath = append(deps.classpath, dep.Srcs()...)
-			case staticLibTag:
-				checkProducesJars(ctx, dep)
-				deps.classpath = append(deps.classpath, dep.Srcs()...)
-				deps.staticJars = append(deps.staticJars, dep.Srcs()...)
-				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
-			}
-		} else {
-			switch tag {
-			case bootClasspathTag:
-				// If a system modules dependency has been added to the bootclasspath
-				// then add its libs to the bootclasspath.
-				sm := module.(SystemModulesProvider)
-				deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
-
-			case systemModulesTag:
-				if deps.systemModules != nil {
-					panic("Found two system module dependencies")
-				}
-				sm := module.(SystemModulesProvider)
-				outputDir, outputDeps := sm.OutputDirAndDeps()
-				deps.systemModules = &systemModules{outputDir, outputDeps}
-			}
-		}
-
-		addCLCFromDep(ctx, module, j.classLoaderContexts)
-	})
-
-	return deps
-}
-
-func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
-	deps.processorPath = append(deps.processorPath, pluginJars...)
-	deps.processorClasses = append(deps.processorClasses, pluginClasses...)
-}
-
 func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion {
 	if javaVersion != "" {
 		return normalizeJavaVersion(ctx, javaVersion)
@@ -1344,824 +411,6 @@
 	}
 }
 
-func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
-
-	var flags javaBuilderFlags
-
-	// javaVersion flag.
-	flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
-
-	if ctx.Config().RunErrorProne() {
-		if config.ErrorProneClasspath == nil && ctx.Config().TestProductVariables == nil {
-			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
-		}
-
-		errorProneFlags := []string{
-			"-Xplugin:ErrorProne",
-			"${config.ErrorProneChecks}",
-		}
-		errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
-
-		flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
-			"'" + strings.Join(errorProneFlags, " ") + "'"
-		flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
-	}
-
-	// classpath
-	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
-	flags.classpath = append(flags.classpath, deps.classpath...)
-	flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
-	flags.processorPath = append(flags.processorPath, deps.processorPath...)
-	flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...)
-
-	flags.processors = append(flags.processors, deps.processorClasses...)
-	flags.processors = android.FirstUniqueStrings(flags.processors)
-
-	if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() &&
-		decodeSdkDep(ctx, sdkContext(j)).hasStandardLibs() {
-		// Give host-side tools a version of OpenJDK's standard libraries
-		// close to what they're targeting. As of Dec 2017, AOSP is only
-		// bundling OpenJDK 8 and 9, so nothing < 8 is available.
-		//
-		// When building with OpenJDK 8, the following should have no
-		// effect since those jars would be available by default.
-		//
-		// When building with OpenJDK 9 but targeting a version < 1.8,
-		// putting them on the bootclasspath means that:
-		// a) code can't (accidentally) refer to OpenJDK 9 specific APIs
-		// b) references to existing APIs are not reinterpreted in an
-		//    OpenJDK 9-specific way, eg. calls to subclasses of
-		//    java.nio.Buffer as in http://b/70862583
-		java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
-		flags.bootClasspath = append(flags.bootClasspath,
-			android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"),
-			android.PathForSource(ctx, java8Home, "jre/lib/rt.jar"))
-		if Bool(j.properties.Use_tools_jar) {
-			flags.bootClasspath = append(flags.bootClasspath,
-				android.PathForSource(ctx, java8Home, "lib/tools.jar"))
-		}
-	}
-
-	// systemModules
-	flags.systemModules = deps.systemModules
-
-	// aidl flags.
-	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
-
-	return flags
-}
-
-func (j *Module) collectJavacFlags(
-	ctx android.ModuleContext, flags javaBuilderFlags, srcFiles android.Paths) javaBuilderFlags {
-	// javac flags.
-	javacFlags := j.properties.Javacflags
-
-	if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() {
-		// For non-host binaries, override the -g flag passed globally to remove
-		// local variable debug info to reduce disk and memory usage.
-		javacFlags = append(javacFlags, "-g:source,lines")
-	}
-	javacFlags = append(javacFlags, "-Xlint:-dep-ann")
-
-	if flags.javaVersion.usesJavaModules() {
-		javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
-
-		if j.properties.Patch_module != nil {
-			// Manually specify build directory in case it is not under the repo root.
-			// (javac doesn't seem to expand into symbolic links when searching for patch-module targets, so
-			// just adding a symlink under the root doesn't help.)
-			patchPaths := []string{".", ctx.Config().BuildDir()}
-
-			// b/150878007
-			//
-			// Workaround to support *Bazel-executed* JDK9 javac in Bazel's
-			// execution root for --patch-module. If this javac command line is
-			// invoked within Bazel's execution root working directory, the top
-			// level directories (e.g. libcore/, tools/, frameworks/) are all
-			// symlinks. JDK9 javac does not traverse into symlinks, which causes
-			// --patch-module to fail source file lookups when invoked in the
-			// execution root.
-			//
-			// Short of patching javac or enumerating *all* directories as possible
-			// input dirs, manually add the top level dir of the source files to be
-			// compiled.
-			topLevelDirs := map[string]bool{}
-			for _, srcFilePath := range srcFiles {
-				srcFileParts := strings.Split(srcFilePath.String(), "/")
-				// Ignore source files that are already in the top level directory
-				// as well as generated files in the out directory. The out
-				// directory may be an absolute path, which means srcFileParts[0] is the
-				// empty string, so check that as well. Note that "out" in Bazel's execution
-				// root is *not* a symlink, which doesn't cause problems for --patch-modules
-				// anyway, so it's fine to not apply this workaround for generated
-				// source files.
-				if len(srcFileParts) > 1 &&
-					srcFileParts[0] != "" &&
-					srcFileParts[0] != "out" {
-					topLevelDirs[srcFileParts[0]] = true
-				}
-			}
-			patchPaths = append(patchPaths, android.SortedStringKeys(topLevelDirs)...)
-
-			classPath := flags.classpath.FormJavaClassPath("")
-			if classPath != "" {
-				patchPaths = append(patchPaths, classPath)
-			}
-			javacFlags = append(
-				javacFlags,
-				"--patch-module="+String(j.properties.Patch_module)+"="+strings.Join(patchPaths, ":"))
-		}
-	}
-
-	if len(javacFlags) > 0 {
-		// optimization.
-		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
-		flags.javacFlags = "$javacFlags"
-	}
-
-	return flags
-}
-
-func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
-	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
-
-	deps := j.collectDeps(ctx)
-	flags := j.collectBuilderFlags(ctx, deps)
-
-	if flags.javaVersion.usesJavaModules() {
-		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
-	}
-	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
-	if hasSrcExt(srcFiles.Strings(), ".proto") {
-		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
-	}
-
-	kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
-	if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
-		ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
-	}
-
-	srcFiles = j.genSources(ctx, srcFiles, flags)
-
-	// Collect javac flags only after computing the full set of srcFiles to
-	// ensure that the --patch-module lookup paths are complete.
-	flags = j.collectJavacFlags(ctx, flags, srcFiles)
-
-	srcJars := srcFiles.FilterByExt(".srcjar")
-	srcJars = append(srcJars, deps.srcJars...)
-	if aaptSrcJar != nil {
-		srcJars = append(srcJars, aaptSrcJar)
-	}
-
-	if j.properties.Jarjar_rules != nil {
-		j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
-	}
-
-	jarName := ctx.ModuleName() + ".jar"
-
-	javaSrcFiles := srcFiles.FilterByExt(".java")
-	var uniqueSrcFiles android.Paths
-	set := make(map[string]bool)
-	for _, v := range javaSrcFiles {
-		if _, found := set[v.String()]; !found {
-			set[v.String()] = true
-			uniqueSrcFiles = append(uniqueSrcFiles, v)
-		}
-	}
-
-	// Collect .java files for AIDEGen
-	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
-
-	var kotlinJars android.Paths
-
-	if srcFiles.HasExt(".kt") {
-		// user defined kotlin flags.
-		kotlincFlags := j.properties.Kotlincflags
-		CheckKotlincFlags(ctx, kotlincFlags)
-
-		// Dogfood the JVM_IR backend.
-		kotlincFlags = append(kotlincFlags, "-Xuse-ir")
-
-		// If there are kotlin files, compile them first but pass all the kotlin and java files
-		// kotlinc will use the java files to resolve types referenced by the kotlin files, but
-		// won't emit any classes for them.
-		kotlincFlags = append(kotlincFlags, "-no-stdlib")
-		if ctx.Device() {
-			kotlincFlags = append(kotlincFlags, "-no-jdk")
-		}
-		if len(kotlincFlags) > 0 {
-			// optimization.
-			ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
-			flags.kotlincFlags += "$kotlincFlags"
-		}
-
-		var kotlinSrcFiles android.Paths
-		kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
-		kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
-
-		// Collect .kt files for AIDEGen
-		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
-		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
-
-		flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
-		flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
-
-		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
-		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
-
-		if len(flags.processorPath) > 0 {
-			// Use kapt for annotation processing
-			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
-			kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
-			kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
-			srcJars = append(srcJars, kaptSrcJar)
-			kotlinJars = append(kotlinJars, kaptResJar)
-			// Disable annotation processing in javac, it's already been handled by kapt
-			flags.processorPath = nil
-			flags.processors = nil
-		}
-
-		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
-		kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
-		if ctx.Failed() {
-			return
-		}
-
-		// Make javac rule depend on the kotlinc rule
-		flags.classpath = append(flags.classpath, kotlinJar)
-
-		kotlinJars = append(kotlinJars, kotlinJar)
-		// Jar kotlin classes into the final jar after javac
-		if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
-			kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
-		}
-	}
-
-	jars := append(android.Paths(nil), kotlinJars...)
-
-	// Store the list of .java files that was passed to javac
-	j.compiledJavaSrcs = uniqueSrcFiles
-	j.compiledSrcJars = srcJars
-
-	enableSharding := false
-	var headerJarFileWithoutJarjar android.Path
-	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine {
-		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
-			enableSharding = true
-			// Formerly, there was a check here that prevented annotation processors
-			// from being used when sharding was enabled, as some annotation processors
-			// do not function correctly in sharded environments. It was removed to
-			// allow for the use of annotation processors that do function correctly
-			// with sharding enabled. See: b/77284273.
-		}
-		headerJarFileWithoutJarjar, j.headerJarFile =
-			j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
-		if ctx.Failed() {
-			return
-		}
-	}
-	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
-		var extraJarDeps android.Paths
-		if ctx.Config().RunErrorProne() {
-			// If error-prone is enabled, add an additional rule to compile the java files into
-			// a separate set of classes (so that they don't overwrite the normal ones and require
-			// a rebuild when error-prone is turned off).
-			// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
-			//    enable error-prone without affecting the output class files.
-			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
-			RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
-			extraJarDeps = append(extraJarDeps, errorprone)
-		}
-
-		if enableSharding {
-			flags.classpath = append(flags.classpath, headerJarFileWithoutJarjar)
-			shardSize := int(*(j.properties.Javac_shard_size))
-			var shardSrcs []android.Paths
-			if len(uniqueSrcFiles) > 0 {
-				shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize)
-				for idx, shardSrc := range shardSrcs {
-					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
-						nil, flags, extraJarDeps)
-					jars = append(jars, classes)
-				}
-			}
-			if len(srcJars) > 0 {
-				classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs),
-					nil, srcJars, flags, extraJarDeps)
-				jars = append(jars, classes)
-			}
-		} else {
-			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
-			jars = append(jars, classes)
-		}
-		if ctx.Failed() {
-			return
-		}
-	}
-
-	j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
-
-	var includeSrcJar android.WritablePath
-	if Bool(j.properties.Include_srcs) {
-		includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar")
-		TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps)
-	}
-
-	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
-		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
-	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
-	extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
-
-	var resArgs []string
-	var resDeps android.Paths
-
-	resArgs = append(resArgs, dirArgs...)
-	resDeps = append(resDeps, dirDeps...)
-
-	resArgs = append(resArgs, fileArgs...)
-	resDeps = append(resDeps, fileDeps...)
-
-	resArgs = append(resArgs, extraArgs...)
-	resDeps = append(resDeps, extraDeps...)
-
-	if len(resArgs) > 0 {
-		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
-		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
-		j.resourceJar = resourceJar
-		if ctx.Failed() {
-			return
-		}
-	}
-
-	var resourceJars android.Paths
-	if j.resourceJar != nil {
-		resourceJars = append(resourceJars, j.resourceJar)
-	}
-	if Bool(j.properties.Include_srcs) {
-		resourceJars = append(resourceJars, includeSrcJar)
-	}
-	resourceJars = append(resourceJars, deps.staticResourceJars...)
-
-	if len(resourceJars) > 1 {
-		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
-		TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
-			false, nil, nil)
-		j.resourceJar = combinedJar
-	} else if len(resourceJars) == 1 {
-		j.resourceJar = resourceJars[0]
-	}
-
-	if len(deps.staticJars) > 0 {
-		jars = append(jars, deps.staticJars...)
-	}
-
-	manifest := j.overrideManifest
-	if !manifest.Valid() && j.properties.Manifest != nil {
-		manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
-	}
-
-	services := android.PathsForModuleSrc(ctx, j.properties.Services)
-	if len(services) > 0 {
-		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
-		var zipargs []string
-		for _, file := range services {
-			serviceFile := file.String()
-			zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
-		}
-		rule := zip
-		args := map[string]string{
-			"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
-		}
-		if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
-			rule = zipRE
-			args["implicits"] = strings.Join(services.Strings(), ",")
-		}
-		ctx.Build(pctx, android.BuildParams{
-			Rule:      rule,
-			Output:    servicesJar,
-			Implicits: services,
-			Args:      args,
-		})
-		jars = append(jars, servicesJar)
-	}
-
-	// Combine the classes built from sources, any manifests, and any static libraries into
-	// classes.jar. If there is only one input jar this step will be skipped.
-	var outputFile android.OutputPath
-
-	if len(jars) == 1 && !manifest.Valid() {
-		// Optimization: skip the combine step as there is nothing to do
-		// TODO(ccross): this leaves any module-info.class files, but those should only come from
-		// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
-		// any if len(jars) == 1.
-
-		// Transform the single path to the jar into an OutputPath as that is required by the following
-		// code.
-		if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
-			// The path contains an embedded OutputPath so reuse that.
-			outputFile = moduleOutPath.OutputPath
-		} else if outputPath, ok := jars[0].(android.OutputPath); ok {
-			// The path is an OutputPath so reuse it directly.
-			outputFile = outputPath
-		} else {
-			// The file is not in the out directory so create an OutputPath into which it can be copied
-			// and which the following code can use to refer to it.
-			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
-			ctx.Build(pctx, android.BuildParams{
-				Rule:   android.Cp,
-				Input:  jars[0],
-				Output: combinedJar,
-			})
-			outputFile = combinedJar.OutputPath
-		}
-	} else {
-		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
-		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
-			false, nil, nil)
-		outputFile = combinedJar.OutputPath
-	}
-
-	// jarjar implementation jar if necessary
-	if j.expandJarjarRules != nil {
-		// Transform classes.jar into classes-jarjar.jar
-		jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName).OutputPath
-		TransformJarJar(ctx, jarjarFile, outputFile, j.expandJarjarRules)
-		outputFile = jarjarFile
-
-		// jarjar resource jar if necessary
-		if j.resourceJar != nil {
-			resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName)
-			TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, j.expandJarjarRules)
-			j.resourceJar = resourceJarJarFile
-		}
-
-		if ctx.Failed() {
-			return
-		}
-	}
-
-	// Check package restrictions if necessary.
-	if len(j.properties.Permitted_packages) > 0 {
-		// Check packages and copy to package-checked file.
-		pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
-		CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
-		j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile)
-
-		if ctx.Failed() {
-			return
-		}
-	}
-
-	j.implementationJarFile = outputFile
-	if j.headerJarFile == nil {
-		j.headerJarFile = j.implementationJarFile
-	}
-
-	if j.shouldInstrumentInApex(ctx) {
-		j.properties.Instrument = true
-	}
-
-	if j.shouldInstrument(ctx) {
-		outputFile = j.instrument(ctx, flags, outputFile, jarName)
-	}
-
-	// merge implementation jar with resources if necessary
-	implementationAndResourcesJar := outputFile
-	if j.resourceJar != nil {
-		jars := android.Paths{j.resourceJar, implementationAndResourcesJar}
-		combinedJar := android.PathForModuleOut(ctx, "withres", jarName).OutputPath
-		TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest,
-			false, nil, nil)
-		implementationAndResourcesJar = combinedJar
-	}
-
-	j.implementationAndResourcesJar = implementationAndResourcesJar
-
-	// Enable dex compilation for the APEX variants, unless it is disabled explicitly
-	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
-	if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() {
-		if j.dexProperties.Compile_dex == nil {
-			j.dexProperties.Compile_dex = proptools.BoolPtr(true)
-		}
-		if j.deviceProperties.Hostdex == nil {
-			j.deviceProperties.Hostdex = proptools.BoolPtr(true)
-		}
-	}
-
-	if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.dexProperties.Compile_dex)) {
-		if j.hasCode(ctx) {
-			if j.shouldInstrumentStatic(ctx) {
-				j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles,
-					android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
-			}
-			// Dex compilation
-			var dexOutputFile android.OutputPath
-			dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName)
-			if ctx.Failed() {
-				return
-			}
-
-			// Hidden API CSV generation and dex encoding
-			dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,
-				proptools.Bool(j.dexProperties.Uncompress_dex))
-
-			// merge dex jar with resources if necessary
-			if j.resourceJar != nil {
-				jars := android.Paths{dexOutputFile, j.resourceJar}
-				combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName).OutputPath
-				TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
-					false, nil, nil)
-				if *j.dexProperties.Uncompress_dex {
-					combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath
-					TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
-					dexOutputFile = combinedAlignedJar
-				} else {
-					dexOutputFile = combinedJar
-				}
-			}
-
-			j.dexJarFile = dexOutputFile
-
-			// Dexpreopting
-			j.dexpreopt(ctx, dexOutputFile)
-
-			outputFile = dexOutputFile
-		} else {
-			// There is no code to compile into a dex jar, make sure the resources are propagated
-			// to the APK if this is an app.
-			outputFile = implementationAndResourcesJar
-			j.dexJarFile = j.resourceJar
-		}
-
-		if ctx.Failed() {
-			return
-		}
-	} else {
-		outputFile = implementationAndResourcesJar
-	}
-
-	if ctx.Device() {
-		lintSDKVersionString := func(sdkSpec sdkSpec) string {
-			if v := sdkSpec.version; v.isNumbered() {
-				return v.String()
-			} else {
-				return ctx.Config().DefaultAppTargetSdk(ctx).String()
-			}
-		}
-
-		j.linter.name = ctx.ModuleName()
-		j.linter.srcs = srcFiles
-		j.linter.srcJars = srcJars
-		j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
-		j.linter.classes = j.implementationJarFile
-		j.linter.minSdkVersion = lintSDKVersionString(j.minSdkVersion())
-		j.linter.targetSdkVersion = lintSDKVersionString(j.targetSdkVersion())
-		j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
-		j.linter.javaLanguageLevel = flags.javaVersion.String()
-		j.linter.kotlinLanguageLevel = "1.3"
-		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
-			j.linter.buildModuleReportZip = true
-		}
-		j.linter.lint(ctx)
-	}
-
-	ctx.CheckbuildFile(outputFile)
-
-	ctx.SetProvider(JavaInfoProvider, JavaInfo{
-		HeaderJars:                     android.PathsIfNonNil(j.headerJarFile),
-		ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
-		ImplementationJars:             android.PathsIfNonNil(j.implementationJarFile),
-		ResourceJars:                   android.PathsIfNonNil(j.resourceJar),
-		AidlIncludeDirs:                j.exportAidlIncludeDirs,
-		SrcJarArgs:                     j.srcJarArgs,
-		SrcJarDeps:                     j.srcJarDeps,
-		ExportedPlugins:                j.exportedPluginJars,
-		ExportedPluginClasses:          j.exportedPluginClasses,
-		ExportedPluginDisableTurbine:   j.exportedDisableTurbine,
-		JacocoReportClassesFile:        j.jacocoReportClassesFile,
-	})
-
-	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
-	j.outputFile = outputFile.WithoutRel()
-}
-
-func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
-	srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
-
-	kzipName := pathtools.ReplaceExtension(jarName, "kzip")
-	if idx >= 0 {
-		kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
-		jarName += strconv.Itoa(idx)
-	}
-
-	classes := android.PathForModuleOut(ctx, "javac", jarName).OutputPath
-	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps)
-
-	if ctx.Config().EmitXrefRules() {
-		extractionFile := android.PathForModuleOut(ctx, kzipName)
-		emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
-		j.kytheFiles = append(j.kytheFiles, extractionFile)
-	}
-
-	return classes
-}
-
-// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
-// since some of these flags may be used internally.
-func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
-	for _, flag := range flags {
-		flag = strings.TrimSpace(flag)
-
-		if !strings.HasPrefix(flag, "-") {
-			ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
-		} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
-			ctx.PropertyErrorf("kotlincflags",
-				"Bad flag: `%s`, only use internal compiler for consistency.", flag)
-		} else if inList(flag, config.KotlincIllegalFlags) {
-			ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
-		} else if flag == "-include-runtime" {
-			ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
-		} else {
-			args := strings.Split(flag, " ")
-			if args[0] == "-kotlin-home" {
-				ctx.PropertyErrorf("kotlincflags",
-					"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
-			}
-		}
-	}
-}
-
-func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
-	deps deps, flags javaBuilderFlags, jarName string,
-	extraJars android.Paths) (headerJar, jarjarHeaderJar android.Path) {
-
-	var jars android.Paths
-	if len(srcFiles) > 0 || len(srcJars) > 0 {
-		// Compile java sources into turbine.jar.
-		turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
-		TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
-		if ctx.Failed() {
-			return nil, nil
-		}
-		jars = append(jars, turbineJar)
-	}
-
-	jars = append(jars, extraJars...)
-
-	// Combine any static header libraries into classes-header.jar. If there is only
-	// one input jar this step will be skipped.
-	jars = append(jars, deps.staticHeaderJars...)
-
-	// we cannot skip the combine step for now if there is only one jar
-	// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
-	combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName)
-	TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
-		false, nil, []string{"META-INF/TRANSITIVE"})
-	headerJar = combinedJar
-	jarjarHeaderJar = combinedJar
-
-	if j.expandJarjarRules != nil {
-		// Transform classes.jar into classes-jarjar.jar
-		jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
-		TransformJarJar(ctx, jarjarFile, headerJar, j.expandJarjarRules)
-		jarjarHeaderJar = jarjarFile
-		if ctx.Failed() {
-			return nil, nil
-		}
-	}
-
-	return headerJar, jarjarHeaderJar
-}
-
-func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
-	classesJar android.Path, jarName string) android.OutputPath {
-
-	specs := j.jacocoModuleToZipCommand(ctx)
-
-	jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
-	instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName).OutputPath
-
-	jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
-
-	j.jacocoReportClassesFile = jacocoReportClassesFile
-
-	return instrumentedJar
-}
-
-func (j *Module) HeaderJars() android.Paths {
-	if j.headerJarFile == nil {
-		return nil
-	}
-	return android.Paths{j.headerJarFile}
-}
-
-func (j *Module) ImplementationJars() android.Paths {
-	if j.implementationJarFile == nil {
-		return nil
-	}
-	return android.Paths{j.implementationJarFile}
-}
-
-func (j *Module) DexJarBuildPath() android.Path {
-	return j.dexJarFile
-}
-
-func (j *Module) DexJarInstallPath() android.Path {
-	return j.installFile
-}
-
-func (j *Module) ImplementationAndResourcesJars() android.Paths {
-	if j.implementationAndResourcesJar == nil {
-		return nil
-	}
-	return android.Paths{j.implementationAndResourcesJar}
-}
-
-func (j *Module) AidlIncludeDirs() android.Paths {
-	// exportAidlIncludeDirs is type android.Paths already
-	return j.exportAidlIncludeDirs
-}
-
-func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
-	return j.classLoaderContexts
-}
-
-var _ logtagsProducer = (*Module)(nil)
-
-func (j *Module) logtags() android.Paths {
-	return j.logtagsSrcs
-}
-
-// Collect information for opening IDE project files in java/jdeps.go.
-func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
-	dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
-	dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
-	dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
-	dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
-	if j.expandJarjarRules != nil {
-		dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
-	}
-	dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...)
-}
-
-func (j *Module) CompilerDeps() []string {
-	jdeps := []string{}
-	jdeps = append(jdeps, j.properties.Libs...)
-	jdeps = append(jdeps, j.properties.Static_libs...)
-	return jdeps
-}
-
-func (j *Module) hasCode(ctx android.ModuleContext) bool {
-	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
-	return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
-}
-
-// Implements android.ApexModule
-func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
-	return j.depIsInSameApex(ctx, dep)
-}
-
-// Implements android.ApexModule
-func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
-	sdkVersion android.ApiLevel) error {
-	sdkSpec := j.minSdkVersion()
-	if !sdkSpec.specified() {
-		return fmt.Errorf("min_sdk_version is not specified")
-	}
-	if sdkSpec.kind == sdkCore {
-		return nil
-	}
-	ver, err := sdkSpec.effectiveVersion(ctx)
-	if err != nil {
-		return err
-	}
-	if ver.ApiLevel(ctx).GreaterThan(sdkVersion) {
-		return fmt.Errorf("newer SDK(%v)", ver)
-	}
-	return nil
-}
-
-func (j *Module) Stem() string {
-	return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
-}
-
-// ConfigurationName returns the name of the module as used in build configuration.
-//
-// This is usually the same as BaseModuleName() except for the <x>.impl libraries created by
-// java_sdk_library in which case this is the BaseModuleName() without the ".impl" suffix,
-// i.e. just <x>.
-func (j *Module) ConfigurationName() string {
-	return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName())
-}
-
-func (j *Module) JacocoReportClassesFile() android.Path {
-	return j.jacocoReportClassesFile
-}
-
-func (j *Module) IsInstallable() bool {
-	return Bool(j.properties.Installable)
-}
-
 //
 // Java libraries (.jar file)
 //
@@ -3412,16 +1661,6 @@
 var String = proptools.String
 var inList = android.InList
 
-// TODO(b/132357300) Generalize SdkLibrarComponentDependency to non-SDK libraries and merge with
-// this interface.
-type ProvidesUsesLib interface {
-	ProvidesUsesLib() *string
-}
-
-func (j *Module) ProvidesUsesLib() *string {
-	return j.usesLibraryProperties.Provides_uses_lib
-}
-
 // Add class loader context (CLC) of a given dependency to the current CLC.
 func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
 	clcMap dexpreopt.ClassLoaderContextMap) {
