diff --git a/java/app.go b/java/app.go
index bcb610c..4369865 100755
--- a/java/app.go
+++ b/java/app.go
@@ -14,13 +14,12 @@
 
 package java
 
-// This file contains the module types for compiling Android apps.
+// This file contains the module implementations for android_app, android_test, and some more
+// related module types, including their override variants.
 
 import (
 	"path/filepath"
-	"reflect"
 	"sort"
-	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -32,12 +31,8 @@
 	"android/soong/tradefed"
 )
 
-var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}
-
 func init() {
 	RegisterAppBuildComponents(android.InitRegistrationContext)
-
-	initAndroidAppImportVariantGroupTypes()
 }
 
 func RegisterAppBuildComponents(ctx android.RegistrationContext) {
@@ -47,139 +42,6 @@
 	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
 	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
-	ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
-	ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
-	ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
-	ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory)
-	ctx.RegisterModuleType("android_app_set", AndroidApkSetFactory)
-}
-
-type AndroidAppSetProperties struct {
-	// APK Set path
-	Set *string
-
-	// Specifies that this app should be installed to the priv-app directory,
-	// where the system will grant it additional privileges not available to
-	// normal apps.
-	Privileged *bool
-
-	// APKs in this set use prerelease SDK version
-	Prerelease *bool
-
-	// Names of modules to be overridden. Listed modules can only be other apps
-	//	(in Make or Soong).
-	Overrides []string
-}
-
-type AndroidAppSet struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	prebuilt android.Prebuilt
-
-	properties   AndroidAppSetProperties
-	packedOutput android.WritablePath
-	installFile  string
-	apkcertsFile android.ModuleOutPath
-}
-
-func (as *AndroidAppSet) Name() string {
-	return as.prebuilt.Name(as.ModuleBase.Name())
-}
-
-func (as *AndroidAppSet) IsInstallable() bool {
-	return true
-}
-
-func (as *AndroidAppSet) Prebuilt() *android.Prebuilt {
-	return &as.prebuilt
-}
-
-func (as *AndroidAppSet) Privileged() bool {
-	return Bool(as.properties.Privileged)
-}
-
-func (as *AndroidAppSet) OutputFile() android.Path {
-	return as.packedOutput
-}
-
-func (as *AndroidAppSet) InstallFile() string {
-	return as.installFile
-}
-
-func (as *AndroidAppSet) APKCertsFile() android.Path {
-	return as.apkcertsFile
-}
-
-var TargetCpuAbi = map[string]string{
-	"arm":    "ARMEABI_V7A",
-	"arm64":  "ARM64_V8A",
-	"x86":    "X86",
-	"x86_64": "X86_64",
-}
-
-func SupportedAbis(ctx android.ModuleContext) []string {
-	abiName := func(targetIdx int, deviceArch string) string {
-		if abi, found := TargetCpuAbi[deviceArch]; found {
-			return abi
-		}
-		ctx.ModuleErrorf("Target %d has invalid Arch: %s", targetIdx, deviceArch)
-		return "BAD_ABI"
-	}
-
-	var result []string
-	for i, target := range ctx.Config().Targets[android.Android] {
-		result = append(result, abiName(i, target.Arch.ArchType.String()))
-	}
-	return result
-}
-
-func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
-	as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
-	// We are assuming here that the install file in the APK
-	// set has `.apk` suffix. If it doesn't the build will fail.
-	// APK sets containing APEX files are handled elsewhere.
-	as.installFile = as.BaseModuleName() + ".apk"
-	screenDensities := "all"
-	if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
-		screenDensities = strings.ToUpper(strings.Join(dpis, ","))
-	}
-	// TODO(asmundak): handle locales.
-	// TODO(asmundak): do we support device features
-	ctx.Build(pctx,
-		android.BuildParams{
-			Rule:           extractMatchingApks,
-			Description:    "Extract APKs from APK set",
-			Output:         as.packedOutput,
-			ImplicitOutput: as.apkcertsFile,
-			Inputs:         android.Paths{as.prebuilt.SingleSourcePath(ctx)},
-			Args: map[string]string{
-				"abis":              strings.Join(SupportedAbis(ctx), ","),
-				"allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)),
-				"screen-densities":  screenDensities,
-				"sdk-version":       ctx.Config().PlatformSdkVersion().String(),
-				"stem":              as.BaseModuleName(),
-				"apkcerts":          as.apkcertsFile.String(),
-				"partition":         as.PartitionTag(ctx.DeviceConfig()),
-			},
-		})
-}
-
-// android_app_set extracts a set of APKs based on the target device
-// configuration and installs this set as "split APKs".
-// The extracted set always contains an APK whose name is
-// _module_name_.apk and every split APK matching target device.
-// The extraction of the density-specific splits depends on
-// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
-// be a list density names: LDPI, MDPI, HDPI, etc.), only listed
-// splits will be extracted. Otherwise all density-specific splits
-// will be extracted.
-func AndroidApkSetFactory() android.Module {
-	module := &AndroidAppSet{}
-	module.AddProperties(&module.properties)
-	InitJavaModule(module, android.DeviceSupported)
-	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set")
-	return module
 }
 
 // AndroidManifest.xml merging
@@ -273,15 +135,6 @@
 	Rename_resources_package *bool
 }
 
-// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
-type OverridableRuntimeResourceOverlayProperties struct {
-	// the package name of this app. The package name in the manifest file is used if one was not given.
-	Package_name *string
-
-	// the target package name of this overlay app. The target package name in the manifest file is used if one was not given.
-	Target_package_name *string
-}
-
 type AndroidApp struct {
 	Library
 	aapt
@@ -1298,629 +1151,6 @@
 	return m
 }
 
-type OverrideRuntimeResourceOverlay struct {
-	android.ModuleBase
-	android.OverrideModuleBase
-}
-
-func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) {
-	// All the overrides happen in the base module.
-	// TODO(jungjw): Check the base module type.
-}
-
-// override_runtime_resource_overlay is used to create a module based on another
-// runtime_resource_overlay module by overriding some of its properties.
-func OverrideRuntimeResourceOverlayModuleFactory() android.Module {
-	m := &OverrideRuntimeResourceOverlay{}
-	m.AddProperties(&OverridableRuntimeResourceOverlayProperties{})
-
-	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
-	android.InitOverrideModule(m)
-	return m
-}
-
-type AndroidAppImport struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	android.ApexModuleBase
-	prebuilt android.Prebuilt
-
-	properties   AndroidAppImportProperties
-	dpiVariants  interface{}
-	archVariants interface{}
-
-	outputFile  android.Path
-	certificate Certificate
-
-	dexpreopter
-
-	usesLibrary usesLibrary
-
-	preprocessed bool
-
-	installPath android.InstallPath
-
-	hideApexVariantFromMake bool
-}
-
-type AndroidAppImportProperties struct {
-	// A prebuilt apk to import
-	Apk *string
-
-	// The name of a certificate in the default certificate directory or an android_app_certificate
-	// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
-	Certificate *string
-
-	// Set this flag to true if the prebuilt apk is already signed. The certificate property must not
-	// be set for presigned modules.
-	Presigned *bool
-
-	// Name of the signing certificate lineage file.
-	Lineage *string
-
-	// Sign with the default system dev certificate. Must be used judiciously. Most imported apps
-	// need to either specify a specific certificate or be presigned.
-	Default_dev_cert *bool
-
-	// Specifies that this app should be installed to the priv-app directory,
-	// where the system will grant it additional privileges not available to
-	// normal apps.
-	Privileged *bool
-
-	// Names of modules to be overridden. Listed modules can only be other binaries
-	// (in Make or Soong).
-	// This does not completely prevent installation of the overridden binaries, but if both
-	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
-	// from PRODUCT_PACKAGES.
-	Overrides []string
-
-	// Optional name for the installed app. If unspecified, it is derived from the module name.
-	Filename *string
-}
-
-func (a *AndroidAppImport) IsInstallable() bool {
-	return true
-}
-
-// Updates properties with variant-specific values.
-func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
-	config := ctx.Config()
-
-	dpiProps := reflect.ValueOf(a.dpiVariants).Elem().FieldByName("Dpi_variants")
-	// Try DPI variant matches in the reverse-priority order so that the highest priority match
-	// overwrites everything else.
-	// TODO(jungjw): Can we optimize this by making it priority order?
-	for i := len(config.ProductAAPTPrebuiltDPI()) - 1; i >= 0; i-- {
-		MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPrebuiltDPI()[i])
-	}
-	if config.ProductAAPTPreferredConfig() != "" {
-		MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPreferredConfig())
-	}
-
-	archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch")
-	archType := ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType
-	MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name)
-
-	if String(a.properties.Apk) == "" {
-		// Disable this module since the apk property is still empty after processing all matching
-		// variants. This likely means there is no matching variant, and the default variant doesn't
-		// have an apk property value either.
-		a.Disable()
-	}
-}
-
-func MergePropertiesFromVariant(ctx android.EarlyModuleContext,
-	dst interface{}, variantGroup reflect.Value, variant string) {
-	src := variantGroup.FieldByName(proptools.FieldNameForProperty(variant))
-	if !src.IsValid() {
-		return
-	}
-
-	err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, proptools.OrderAppend)
-	if err != nil {
-		if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
-			ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
-		} else {
-			panic(err)
-		}
-	}
-}
-
-func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
-	cert := android.SrcIsModule(String(a.properties.Certificate))
-	if cert != "" {
-		ctx.AddDependency(ctx.Module(), certificateTag, cert)
-	}
-
-	a.usesLibrary.deps(ctx, true)
-}
-
-func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
-	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
-	// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
-	// with them may invalidate pre-existing signature data.
-	if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || a.preprocessed) {
-		ctx.Build(pctx, android.BuildParams{
-			Rule:   android.Cp,
-			Output: outputPath,
-			Input:  inputPath,
-		})
-		return
-	}
-	rule := android.NewRuleBuilder(pctx, ctx)
-	rule.Command().
-		Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
-		BuiltTool("zip2zip").
-		FlagWithInput("-i ", inputPath).
-		FlagWithOutput("-o ", outputPath).
-		FlagWithArg("-0 ", "'lib/**/*.so'").
-		Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
-	rule.Build("uncompress-embedded-jni-libs", "Uncompress embedded JIN libs")
-}
-
-// Returns whether this module should have the dex file stored uncompressed in the APK.
-func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
-	if ctx.Config().UnbundledBuild() || a.preprocessed {
-		return false
-	}
-
-	// Uncompress dex in APKs of privileged apps
-	if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
-		return true
-	}
-
-	return shouldUncompressDex(ctx, &a.dexpreopter)
-}
-
-func (a *AndroidAppImport) uncompressDex(
-	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
-	rule := android.NewRuleBuilder(pctx, ctx)
-	rule.Command().
-		Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
-		BuiltTool("zip2zip").
-		FlagWithInput("-i ", inputPath).
-		FlagWithOutput("-o ", outputPath).
-		FlagWithArg("-0 ", "'classes*.dex'").
-		Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
-	rule.Build("uncompress-dex", "Uncompress dex files")
-}
-
-func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	a.generateAndroidBuildActions(ctx)
-}
-
-func (a *AndroidAppImport) InstallApkName() string {
-	return a.BaseModuleName()
-}
-
-func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) {
-	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
-	if !apexInfo.IsForPlatform() {
-		a.hideApexVariantFromMake = true
-	}
-
-	numCertPropsSet := 0
-	if String(a.properties.Certificate) != "" {
-		numCertPropsSet++
-	}
-	if Bool(a.properties.Presigned) {
-		numCertPropsSet++
-	}
-	if Bool(a.properties.Default_dev_cert) {
-		numCertPropsSet++
-	}
-	if numCertPropsSet != 1 {
-		ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set")
-	}
-
-	_, certificates := collectAppDeps(ctx, a, false, false)
-
-	// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
-	// TODO: LOCAL_PACKAGE_SPLITS
-
-	srcApk := a.prebuilt.SingleSourcePath(ctx)
-
-	if a.usesLibrary.enforceUsesLibraries() {
-		srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
-	}
-
-	// TODO: Install or embed JNI libraries
-
-	// Uncompress JNI libraries in the apk
-	jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
-	a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath)
-
-	var installDir android.InstallPath
-	if Bool(a.properties.Privileged) {
-		installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
-	} else if ctx.InstallInTestcases() {
-		installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
-	} else {
-		installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
-	}
-
-	a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk")
-	a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
-	a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
-
-	a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
-	a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
-
-	a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
-	if a.dexpreopter.uncompressedDex {
-		dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
-		a.uncompressDex(ctx, jnisUncompressed, dexUncompressed.OutputPath)
-		jnisUncompressed = dexUncompressed
-	}
-
-	apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
-
-	// TODO: Handle EXTERNAL
-
-	// Sign or align the package if package has not been preprocessed
-	if a.preprocessed {
-		a.outputFile = srcApk
-		a.certificate = PresignedCertificate
-	} else if !Bool(a.properties.Presigned) {
-		// If the certificate property is empty at this point, default_dev_cert must be set to true.
-		// Which makes processMainCert's behavior for the empty cert string WAI.
-		certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
-		if len(certificates) != 1 {
-			ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
-		}
-		a.certificate = certificates[0]
-		signed := android.PathForModuleOut(ctx, "signed", apkFilename)
-		var lineageFile android.Path
-		if lineage := String(a.properties.Lineage); lineage != "" {
-			lineageFile = android.PathForModuleSrc(ctx, lineage)
-		}
-		SignAppPackage(ctx, signed, jnisUncompressed, certificates, nil, lineageFile)
-		a.outputFile = signed
-	} else {
-		alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
-		TransformZipAlign(ctx, alignedApk, jnisUncompressed)
-		a.outputFile = alignedApk
-		a.certificate = PresignedCertificate
-	}
-
-	// TODO: Optionally compress the output apk.
-
-	if apexInfo.IsForPlatform() {
-		a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
-	}
-
-	// TODO: androidmk converter jni libs
-}
-
-func (a *AndroidAppImport) Prebuilt() *android.Prebuilt {
-	return &a.prebuilt
-}
-
-func (a *AndroidAppImport) Name() string {
-	return a.prebuilt.Name(a.ModuleBase.Name())
-}
-
-func (a *AndroidAppImport) OutputFile() android.Path {
-	return a.outputFile
-}
-
-func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
-	return nil
-}
-
-func (a *AndroidAppImport) Certificate() Certificate {
-	return a.certificate
-}
-
-var dpiVariantGroupType reflect.Type
-var archVariantGroupType reflect.Type
-
-func initAndroidAppImportVariantGroupTypes() {
-	dpiVariantGroupType = createVariantGroupType(supportedDpis, "Dpi_variants")
-
-	archNames := make([]string, len(android.ArchTypeList()))
-	for i, archType := range android.ArchTypeList() {
-		archNames[i] = archType.Name
-	}
-	archVariantGroupType = createVariantGroupType(archNames, "Arch")
-}
-
-// Populates all variant struct properties at creation time.
-func (a *AndroidAppImport) populateAllVariantStructs() {
-	a.dpiVariants = reflect.New(dpiVariantGroupType).Interface()
-	a.AddProperties(a.dpiVariants)
-
-	a.archVariants = reflect.New(archVariantGroupType).Interface()
-	a.AddProperties(a.archVariants)
-}
-
-func (a *AndroidAppImport) Privileged() bool {
-	return Bool(a.properties.Privileged)
-}
-
-func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
-	// android_app_import might have extra dependencies via uses_libs property.
-	// Don't track the dependency as we don't automatically add those libraries
-	// to the classpath. It should be explicitly added to java_libs property of APEX
-	return false
-}
-
-func (a *AndroidAppImport) sdkVersion() sdkSpec {
-	return sdkSpecFrom("")
-}
-
-func (a *AndroidAppImport) minSdkVersion() sdkSpec {
-	return sdkSpecFrom("")
-}
-
-var _ android.ApexModule = (*AndroidAppImport)(nil)
-
-// Implements android.ApexModule
-func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
-	sdkVersion android.ApiLevel) error {
-	// Do not check for prebuilts against the min_sdk_version of enclosing APEX
-	return nil
-}
-
-func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
-	props := reflect.TypeOf((*AndroidAppImportProperties)(nil))
-
-	variantFields := make([]reflect.StructField, len(variants))
-	for i, variant := range variants {
-		variantFields[i] = reflect.StructField{
-			Name: proptools.FieldNameForProperty(variant),
-			Type: props,
-		}
-	}
-
-	variantGroupStruct := reflect.StructOf(variantFields)
-	return reflect.StructOf([]reflect.StructField{
-		{
-			Name: variantGroupName,
-			Type: variantGroupStruct,
-		},
-	})
-}
-
-// android_app_import imports a prebuilt apk with additional processing specified in the module.
-// DPI-specific apk source files can be specified using dpi_variants. Example:
-//
-//     android_app_import {
-//         name: "example_import",
-//         apk: "prebuilts/example.apk",
-//         dpi_variants: {
-//             mdpi: {
-//                 apk: "prebuilts/example_mdpi.apk",
-//             },
-//             xhdpi: {
-//                 apk: "prebuilts/example_xhdpi.apk",
-//             },
-//         },
-//         certificate: "PRESIGNED",
-//     }
-func AndroidAppImportFactory() android.Module {
-	module := &AndroidAppImport{}
-	module.AddProperties(&module.properties)
-	module.AddProperties(&module.dexpreoptProperties)
-	module.AddProperties(&module.usesLibrary.usesLibraryProperties)
-	module.populateAllVariantStructs()
-	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
-		module.processVariants(ctx)
-	})
-
-	android.InitApexModule(module)
-	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-	android.InitDefaultableModule(module)
-	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
-
-	return module
-}
-
-type androidTestImportProperties struct {
-	// Whether the prebuilt apk can be installed without additional processing. Default is false.
-	Preprocessed *bool
-}
-
-type AndroidTestImport struct {
-	AndroidAppImport
-
-	testProperties testProperties
-
-	testImportProperties androidTestImportProperties
-
-	data android.Paths
-}
-
-func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	a.preprocessed = Bool(a.testImportProperties.Preprocessed)
-
-	a.generateAndroidBuildActions(ctx)
-
-	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
-}
-
-func (a *AndroidTestImport) InstallInTestcases() bool {
-	return true
-}
-
-// android_test_import imports a prebuilt test apk with additional processing specified in the
-// module. DPI or arch variant configurations can be made as with android_app_import.
-func AndroidTestImportFactory() android.Module {
-	module := &AndroidTestImport{}
-	module.AddProperties(&module.properties)
-	module.AddProperties(&module.dexpreoptProperties)
-	module.AddProperties(&module.testProperties)
-	module.AddProperties(&module.testImportProperties)
-	module.populateAllVariantStructs()
-	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
-		module.processVariants(ctx)
-	})
-
-	module.dexpreopter.isTest = true
-
-	android.InitApexModule(module)
-	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-	android.InitDefaultableModule(module)
-	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
-
-	return module
-}
-
-type RuntimeResourceOverlay struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
-	android.OverridableModuleBase
-	aapt
-
-	properties            RuntimeResourceOverlayProperties
-	overridableProperties OverridableRuntimeResourceOverlayProperties
-
-	certificate Certificate
-
-	outputFile android.Path
-	installDir android.InstallPath
-}
-
-type RuntimeResourceOverlayProperties struct {
-	// the name of a certificate in the default certificate directory or an android_app_certificate
-	// module name in the form ":module".
-	Certificate *string
-
-	// Name of the signing certificate lineage file.
-	Lineage *string
-
-	// optional theme name. If specified, the overlay package will be applied
-	// only when the ro.boot.vendor.overlay.theme system property is set to the same value.
-	Theme *string
-
-	// 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
-
-	// list of android_library modules whose resources are extracted and linked against statically
-	Static_libs []string
-
-	// list of android_app modules whose resources are extracted and linked against
-	Resource_libs []string
-
-	// Names of modules to be overridden. Listed modules can only be other overlays
-	// (in Make or Soong).
-	// This does not completely prevent installation of the overridden overlays, but if both
-	// overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed
-	// from PRODUCT_PACKAGES.
-	Overrides []string
-}
-
-// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
-// a RuntimeResourceOverlay module.
-type RuntimeResourceOverlayModule interface {
-	android.Module
-	OutputFile() android.Path
-	Certificate() Certificate
-	Theme() string
-}
-
-func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
-	sdkDep := decodeSdkDep(ctx, sdkContext(r))
-	if sdkDep.hasFrameworkLibs() {
-		r.aapt.deps(ctx, sdkDep)
-	}
-
-	cert := android.SrcIsModule(String(r.properties.Certificate))
-	if cert != "" {
-		ctx.AddDependency(ctx.Module(), certificateTag, cert)
-	}
-
-	ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
-	ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
-}
-
-func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// Compile and link resources
-	r.aapt.hasNoCode = true
-	// Do not remove resources without default values nor dedupe resource configurations with the same value
-	aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
-	// Allow the override of "package name" and "overlay target package name"
-	manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
-	if overridden || r.overridableProperties.Package_name != nil {
-		// The product override variable has a priority over the package_name property.
-		if !overridden {
-			manifestPackageName = *r.overridableProperties.Package_name
-		}
-		aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...)
-	}
-	if r.overridableProperties.Target_package_name != nil {
-		aaptLinkFlags = append(aaptLinkFlags,
-			"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
-	}
-	r.aapt.buildActions(ctx, r, nil, aaptLinkFlags...)
-
-	// Sign the built package
-	_, certificates := collectAppDeps(ctx, r, false, false)
-	certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
-	signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
-	var lineageFile android.Path
-	if lineage := String(r.properties.Lineage); lineage != "" {
-		lineageFile = android.PathForModuleSrc(ctx, lineage)
-	}
-	SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile)
-	r.certificate = certificates[0]
-
-	r.outputFile = signed
-	r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme))
-	ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
-}
-
-func (r *RuntimeResourceOverlay) sdkVersion() sdkSpec {
-	return sdkSpecFrom(String(r.properties.Sdk_version))
-}
-
-func (r *RuntimeResourceOverlay) systemModules() string {
-	return ""
-}
-
-func (r *RuntimeResourceOverlay) minSdkVersion() sdkSpec {
-	if r.properties.Min_sdk_version != nil {
-		return sdkSpecFrom(*r.properties.Min_sdk_version)
-	}
-	return r.sdkVersion()
-}
-
-func (r *RuntimeResourceOverlay) targetSdkVersion() sdkSpec {
-	return r.sdkVersion()
-}
-
-func (r *RuntimeResourceOverlay) Certificate() Certificate {
-	return r.certificate
-}
-
-func (r *RuntimeResourceOverlay) OutputFile() android.Path {
-	return r.outputFile
-}
-
-func (r *RuntimeResourceOverlay) Theme() string {
-	return String(r.properties.Theme)
-}
-
-// runtime_resource_overlay generates a resource-only apk file that can overlay application and
-// system resources at run time.
-func RuntimeResourceOverlayFactory() android.Module {
-	module := &RuntimeResourceOverlay{}
-	module.AddProperties(
-		&module.properties,
-		&module.aaptProperties,
-		&module.overridableProperties)
-
-	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-	android.InitDefaultableModule(module)
-	android.InitOverridableModule(module, &module.properties.Overrides)
-	return module
-}
-
 type UsesLibraryProperties struct {
 	// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
 	Uses_libs []string
