diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index 6bfbf37..cb88e01 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -187,6 +187,20 @@
 	}
 }
 
+func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod Module, infos *AndroidMkProviderInfo) {
+	info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey)
+	if !ok || len(info.AconfigFiles) == 0 {
+		return
+	}
+	// All of the files in the module potentially depend on the aconfig flag values.
+	infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
+	if len(infos.ExtraInfo) > 0 {
+		for _, ei := range (*infos).ExtraInfo {
+			ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
+		}
+	}
+}
+
 func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, generateRule bool) Paths {
 	inputs = SortedUniquePaths(inputs)
 	if len(inputs) == 1 {
diff --git a/android/androidmk.go b/android/androidmk.go
index fc628cb..2185e45 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -806,15 +806,21 @@
 
 	// Additional cases here require review for correct license propagation to make.
 	var err error
-	switch x := mod.(type) {
-	case AndroidMkDataProvider:
-		err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
-	case bootstrap.GoBinaryTool:
-		err = translateGoBinaryModule(ctx, w, mod, x)
-	case AndroidMkEntriesProvider:
-		err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x)
-	default:
-		// Not exported to make so no make variables to set.
+
+	if info, ok := ctx.otherModuleProvider(mod, AndroidMkInfoProvider); ok {
+		androidMkEntriesInfos := info.(*AndroidMkProviderInfo)
+		err = translateAndroidMkEntriesInfoModule(ctx, w, moduleInfoJSONs, mod, androidMkEntriesInfos)
+	} else {
+		switch x := mod.(type) {
+		case AndroidMkDataProvider:
+			err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
+		case bootstrap.GoBinaryTool:
+			err = translateGoBinaryModule(ctx, w, mod, x)
+		case AndroidMkEntriesProvider:
+			err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x)
+		default:
+			// Not exported to make so no make variables to set.
+		}
 	}
 
 	if err != nil {
@@ -1063,3 +1069,564 @@
 	}
 	fmt.Fprintln(w)
 }
+
+type AndroidMkProviderInfo struct {
+	PrimaryInfo AndroidMkInfo
+	ExtraInfo   []AndroidMkInfo
+}
+
+type AndroidMkInfo struct {
+	// Android.mk class string, e.g. EXECUTABLES, JAVA_LIBRARIES, ETC
+	Class string
+	// Optional suffix to append to the module name. Useful when a module wants to return multiple
+	// AndroidMkEntries objects. For example, when a java_library returns an additional entry for
+	// its hostdex sub-module, this SubName field is set to "-hostdex" so that it can have a
+	// different name than the parent's.
+	SubName string
+	// If set, this value overrides the base module name. SubName is still appended.
+	OverrideName string
+	// Dist files to output
+	DistFiles TaggedDistFiles
+	// The output file for Kati to process and/or install. If absent, the module is skipped.
+	OutputFile OptionalPath
+	// If true, the module is skipped and does not appear on the final Android-<product name>.mk
+	// file. Useful when a module needs to be skipped conditionally.
+	Disabled bool
+	// The postprocessing mk file to include, e.g. $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk
+	// If not set, $(BUILD_SYSTEM)/prebuilt.mk is used.
+	Include string
+	// Required modules that need to be built and included in the final build output when building
+	// this module.
+	Required []string
+	// Required host modules that need to be built and included in the final build output when
+	// building this module.
+	Host_required []string
+	// Required device modules that need to be built and included in the final build output when
+	// building this module.
+	Target_required []string
+
+	HeaderStrings []string
+	FooterStrings []string
+
+	// A map that holds the up-to-date Make variable values. Can be accessed from tests.
+	EntryMap map[string][]string
+	// A list of EntryMap keys in insertion order. This serves a few purposes:
+	// 1. Prevents churns. Golang map doesn't provide consistent iteration order, so without this,
+	// the outputted Android-*.mk file may change even though there have been no content changes.
+	// 2. Allows modules to refer to other variables, like LOCAL_BAR_VAR := $(LOCAL_FOO_VAR),
+	// without worrying about the variables being mixed up in the actual mk file.
+	// 3. Makes troubleshooting and spotting errors easier.
+	EntryOrder []string
+}
+
+// TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone.
+var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]()
+
+func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
+	mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error {
+	if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
+		return nil
+	}
+
+	// Deep copy the provider info since we need to modify the info later
+	info := deepCopyAndroidMkProviderInfo(providerInfo)
+
+	aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info)
+
+	// Any new or special cases here need review to verify correct propagation of license information.
+	info.PrimaryInfo.fillInEntries(ctx, mod)
+	info.PrimaryInfo.write(w)
+	if len(info.ExtraInfo) > 0 {
+		for _, ei := range info.ExtraInfo {
+			ei.fillInEntries(ctx, mod)
+			ei.write(w)
+		}
+	}
+
+	if !info.PrimaryInfo.disabled() {
+		if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+			*moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
+		}
+	}
+
+	return nil
+}
+
+// Utility funcs to manipulate Android.mk variable entries.
+
+// SetString sets a Make variable with the given name to the given value.
+func (a *AndroidMkInfo) SetString(name, value string) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = []string{value}
+}
+
+// SetPath sets a Make variable with the given name to the given path string.
+func (a *AndroidMkInfo) SetPath(name string, path Path) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = []string{path.String()}
+}
+
+// SetOptionalPath sets a Make variable with the given name to the given path string if it is valid.
+// It is a no-op if the given path is invalid.
+func (a *AndroidMkInfo) SetOptionalPath(name string, path OptionalPath) {
+	if path.Valid() {
+		a.SetPath(name, path.Path())
+	}
+}
+
+// AddPath appends the given path string to a Make variable with the given name.
+func (a *AndroidMkInfo) AddPath(name string, path Path) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], path.String())
+}
+
+// AddOptionalPath appends the given path string to a Make variable with the given name if it is
+// valid. It is a no-op if the given path is invalid.
+func (a *AndroidMkInfo) AddOptionalPath(name string, path OptionalPath) {
+	if path.Valid() {
+		a.AddPath(name, path.Path())
+	}
+}
+
+// SetPaths sets a Make variable with the given name to a slice of the given path strings.
+func (a *AndroidMkInfo) SetPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = paths.Strings()
+}
+
+// SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings
+// only if there are a non-zero amount of paths.
+func (a *AndroidMkInfo) SetOptionalPaths(name string, paths Paths) {
+	if len(paths) > 0 {
+		a.SetPaths(name, paths)
+	}
+}
+
+// AddPaths appends the given path strings to a Make variable with the given name.
+func (a *AndroidMkInfo) AddPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
+}
+
+// SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true.
+// It is a no-op if the given flag is false.
+func (a *AndroidMkInfo) SetBoolIfTrue(name string, flag bool) {
+	if flag {
+		if _, ok := a.EntryMap[name]; !ok {
+			a.EntryOrder = append(a.EntryOrder, name)
+		}
+		a.EntryMap[name] = []string{"true"}
+	}
+}
+
+// SetBool sets a Make variable with the given name to if the given bool flag value.
+func (a *AndroidMkInfo) SetBool(name string, flag bool) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	if flag {
+		a.EntryMap[name] = []string{"true"}
+	} else {
+		a.EntryMap[name] = []string{"false"}
+	}
+}
+
+// AddStrings appends the given strings to a Make variable with the given name.
+func (a *AndroidMkInfo) AddStrings(name string, value ...string) {
+	if len(value) == 0 {
+		return
+	}
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], value...)
+}
+
+// AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
+// for partial MTS and MCTS test suites.
+func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) {
+	// M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
+	// To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
+	// we add the full test suite to our list.
+	if PrefixInList(suites, "mts-") && !InList("mts", suites) {
+		suites = append(suites, "mts")
+	}
+	if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
+		suites = append(suites, "mcts")
+	}
+	a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
+}
+
+func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
+	helperInfo := AndroidMkInfo{
+		EntryMap: make(map[string][]string),
+	}
+
+	amod := mod.(Module)
+	base := amod.base()
+	name := base.BaseModuleName()
+	if a.OverrideName != "" {
+		name = a.OverrideName
+	}
+
+	if a.Include == "" {
+		a.Include = "$(BUILD_PREBUILT)"
+	}
+	a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
+	a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
+	a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
+	a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
+
+	for _, distString := range a.GetDistForGoals(ctx, mod) {
+		a.HeaderStrings = append(a.HeaderStrings, distString)
+	}
+
+	a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS)  # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod)))
+
+	// Collect make variable assignment entries.
+	helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
+	helperInfo.SetString("LOCAL_MODULE", name+a.SubName)
+	helperInfo.SetString("LOCAL_MODULE_CLASS", a.Class)
+	helperInfo.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
+	helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
+	helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
+	helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+	helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
+
+	// If the install rule was generated by Soong tell Make about it.
+	info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
+	if len(info.KatiInstalls) > 0 {
+		// Assume the primary install file is last since it probably needs to depend on any other
+		// installed files.  If that is not the case we can add a method to specify the primary
+		// installed file.
+		helperInfo.SetPath("LOCAL_SOONG_INSTALLED_MODULE", info.KatiInstalls[len(info.KatiInstalls)-1].to)
+		helperInfo.SetString("LOCAL_SOONG_INSTALL_PAIRS", info.KatiInstalls.BuiltInstalled())
+		helperInfo.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", info.KatiSymlinks.InstallPaths().Paths())
+	} else {
+		// Soong may not have generated the install rule also when `no_full_install: true`.
+		// Mark this module as uninstallable in order to prevent Make from creating an
+		// install rule there.
+		helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
+	}
+
+	if len(info.TestData) > 0 {
+		helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...)
+	}
+
+	if am, ok := mod.(ApexModule); ok {
+		helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
+	}
+
+	archStr := base.Arch().ArchType.String()
+	host := false
+	switch base.Os().Class {
+	case Host:
+		if base.Target().HostCross {
+			// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
+			if base.Arch().ArchType != Common {
+				helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
+			}
+		} else {
+			// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
+			if base.Arch().ArchType != Common {
+				helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
+			}
+		}
+		host = true
+	case Device:
+		// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
+		if base.Arch().ArchType != Common {
+			if base.Target().NativeBridge {
+				hostArchStr := base.Target().NativeBridgeHostArchName
+				if hostArchStr != "" {
+					helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
+				}
+			} else {
+				helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
+			}
+		}
+
+		if !base.InVendorRamdisk() {
+			helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
+		}
+		if len(info.VintfFragmentsPaths) > 0 {
+			helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
+		}
+		helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
+		if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
+			helperInfo.SetString("LOCAL_VENDOR_MODULE", "true")
+		}
+		helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
+		helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
+		helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
+		if base.commonProperties.Owner != nil {
+			helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
+		}
+	}
+
+	if host {
+		makeOs := base.Os().String()
+		if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
+			makeOs = "linux"
+		}
+		helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs)
+		helperInfo.SetString("LOCAL_IS_HOST_MODULE", "true")
+	}
+
+	prefix := ""
+	if base.ArchSpecific() {
+		switch base.Os().Class {
+		case Host:
+			if base.Target().HostCross {
+				prefix = "HOST_CROSS_"
+			} else {
+				prefix = "HOST_"
+			}
+		case Device:
+			prefix = "TARGET_"
+
+		}
+
+		if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
+			prefix = "2ND_" + prefix
+		}
+	}
+
+	if licenseMetadata, ok := OtherModuleProvider(ctx, mod, LicenseMetadataProvider); ok {
+		helperInfo.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath)
+	}
+
+	if _, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+		helperInfo.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true)
+	}
+
+	a.mergeEntries(&helperInfo)
+
+	// Write to footer.
+	a.FooterStrings = append([]string{"include " + a.Include}, a.FooterStrings...)
+}
+
+// This method merges the entries to helperInfo, then replaces a's EntryMap and
+// EntryOrder with helperInfo's
+func (a *AndroidMkInfo) mergeEntries(helperInfo *AndroidMkInfo) {
+	for _, extraEntry := range a.EntryOrder {
+		if v, ok := helperInfo.EntryMap[extraEntry]; ok {
+			v = append(v, a.EntryMap[extraEntry]...)
+		} else {
+			helperInfo.EntryMap[extraEntry] = a.EntryMap[extraEntry]
+			helperInfo.EntryOrder = append(helperInfo.EntryOrder, extraEntry)
+		}
+	}
+	a.EntryOrder = helperInfo.EntryOrder
+	a.EntryMap = helperInfo.EntryMap
+}
+
+func (a *AndroidMkInfo) disabled() bool {
+	return a.Disabled || !a.OutputFile.Valid()
+}
+
+// write  flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the
+// given Writer object.
+func (a *AndroidMkInfo) write(w io.Writer) {
+	if a.disabled() {
+		return
+	}
+
+	combinedHeaderString := strings.Join(a.HeaderStrings, "\n")
+	combinedFooterString := strings.Join(a.FooterStrings, "\n")
+	w.Write([]byte(combinedHeaderString))
+	for _, name := range a.EntryOrder {
+		AndroidMkEmitAssignList(w, name, a.EntryMap[name])
+	}
+	w.Write([]byte(combinedFooterString))
+}
+
+// Compute the list of Make strings to declare phony goals and dist-for-goals
+// calls from the module's dist and dists properties.
+func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string {
+	distContributions := a.getDistContributions(ctx, mod)
+	if distContributions == nil {
+		return nil
+	}
+
+	return generateDistContributionsForMake(distContributions)
+}
+
+// Compute the contributions that the module makes to the dist.
+func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions {
+	amod := mod.(Module).base()
+	name := amod.BaseModuleName()
+
+	// Collate the set of associated tag/paths available for copying to the dist.
+	// Start with an empty (nil) set.
+	var availableTaggedDists TaggedDistFiles
+
+	// Then merge in any that are provided explicitly by the module.
+	if a.DistFiles != nil {
+		// Merge the DistFiles into the set.
+		availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
+	}
+
+	// If no paths have been provided for the DefaultDistTag and the output file is
+	// valid then add that as the default dist path.
+	if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
+		availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
+	}
+
+	info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
+	// If the distFiles created by GenerateTaggedDistFiles contains paths for the
+	// DefaultDistTag then that takes priority so delete any existing paths.
+	if _, ok := info.DistFiles[DefaultDistTag]; ok {
+		delete(availableTaggedDists, DefaultDistTag)
+	}
+
+	// Finally, merge the distFiles created by GenerateTaggedDistFiles.
+	availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
+
+	if len(availableTaggedDists) == 0 {
+		// Nothing dist-able for this module.
+		return nil
+	}
+
+	// Collate the contributions this module makes to the dist.
+	distContributions := &distContributions{}
+
+	if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
+		distContributions.licenseMetadataFile = info.LicenseMetadataFile
+	}
+
+	// Iterate over this module's dist structs, merged from the dist and dists properties.
+	for _, dist := range amod.Dists() {
+		// Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
+		goals := strings.Join(dist.Targets, " ")
+
+		// Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
+		var tag string
+		if dist.Tag == nil {
+			// If the dist struct does not specify a tag, use the default output files tag.
+			tag = DefaultDistTag
+		} else {
+			tag = *dist.Tag
+		}
+
+		// Get the paths of the output files to be dist'd, represented by the tag.
+		// Can be an empty list.
+		tagPaths := availableTaggedDists[tag]
+		if len(tagPaths) == 0 {
+			// Nothing to dist for this tag, continue to the next dist.
+			continue
+		}
+
+		if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
+			errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
+				"file for %q goals tag %q in module %s. The list of dist files, " +
+				"which should have a single element, is:\n%s"
+			panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
+		}
+
+		copiesForGoals := distContributions.getCopiesForGoals(goals)
+
+		// Iterate over each path adding a copy instruction to copiesForGoals
+		for _, path := range tagPaths {
+			// It's possible that the Path is nil from errant modules. Be defensive here.
+			if path == nil {
+				tagName := "default" // for error message readability
+				if dist.Tag != nil {
+					tagName = *dist.Tag
+				}
+				panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
+			}
+
+			dest := filepath.Base(path.String())
+
+			if dist.Dest != nil {
+				var err error
+				if dest, err = validateSafePath(*dist.Dest); err != nil {
+					// This was checked in ModuleBase.GenerateBuildActions
+					panic(err)
+				}
+			}
+
+			ext := filepath.Ext(dest)
+			suffix := ""
+			if dist.Suffix != nil {
+				suffix = *dist.Suffix
+			}
+
+			productString := ""
+			if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
+				productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct())
+			}
+
+			if suffix != "" || productString != "" {
+				dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext
+			}
+
+			if dist.Dir != nil {
+				var err error
+				if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
+					// This was checked in ModuleBase.GenerateBuildActions
+					panic(err)
+				}
+			}
+
+			copiesForGoals.addCopyInstruction(path, dest)
+		}
+	}
+
+	return distContributions
+}
+
+func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo {
+	info := AndroidMkProviderInfo{
+		PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo),
+	}
+	if len(providerInfo.ExtraInfo) > 0 {
+		for _, i := range providerInfo.ExtraInfo {
+			info.ExtraInfo = append(info.ExtraInfo, deepCopyAndroidMkInfo(&i))
+		}
+	}
+	return info
+}
+
+func deepCopyAndroidMkInfo(mkinfo *AndroidMkInfo) AndroidMkInfo {
+	info := AndroidMkInfo{
+		Class:        mkinfo.Class,
+		SubName:      mkinfo.SubName,
+		OverrideName: mkinfo.OverrideName,
+		// There is no modification on DistFiles or OutputFile, so no need to
+		// make their deep copy.
+		DistFiles:       mkinfo.DistFiles,
+		OutputFile:      mkinfo.OutputFile,
+		Disabled:        mkinfo.Disabled,
+		Include:         mkinfo.Include,
+		Required:        deepCopyStringSlice(mkinfo.Required),
+		Host_required:   deepCopyStringSlice(mkinfo.Host_required),
+		Target_required: deepCopyStringSlice(mkinfo.Target_required),
+		HeaderStrings:   deepCopyStringSlice(mkinfo.HeaderStrings),
+		FooterStrings:   deepCopyStringSlice(mkinfo.FooterStrings),
+		EntryOrder:      deepCopyStringSlice(mkinfo.EntryOrder),
+	}
+	info.EntryMap = make(map[string][]string)
+	for k, v := range mkinfo.EntryMap {
+		info.EntryMap[k] = deepCopyStringSlice(v)
+	}
+
+	return info
+}
+
+func deepCopyStringSlice(original []string) []string {
+	result := make([]string, len(original))
+	copy(result, original)
+	return result
+}
