diff --git a/android/Android.bp b/android/Android.bp
index 62f534c..2ac1d5f 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -12,14 +12,11 @@
         "sbox_proto",
         "soong",
         "soong-android-soongconfig",
-        "soong-bazel",
-        "soong-cquery",
         "soong-remoteexec",
         "soong-response",
         "soong-shared",
         "soong-starlark",
         "soong-starlark-format",
-        "soong-ui-bp2build_metrics_proto",
         "soong-ui-metrics_proto",
         "soong-android-allowlists",
 
@@ -38,9 +35,6 @@
         "arch.go",
         "arch_list.go",
         "base_module_context.go",
-        "bazel.go",
-        "bazel_handler.go",
-        "bazel_paths.go",
         "buildinfo_prop.go",
         "config.go",
         "test_config.go",
@@ -106,9 +100,6 @@
         "androidmk_test.go",
         "apex_test.go",
         "arch_test.go",
-        "bazel_handler_test.go",
-        "bazel_paths_test.go",
-        "bazel_test.go",
         "config_test.go",
         "config_bp2build_test.go",
         "configured_jars_test.go",
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index 9b188de..f13659a 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -111,9 +111,6 @@
 		}
 	}
 
-	if ctx.Config().Bp2buildMode() { // Skip bp2build
-		return
-	}
 	p := PrebuiltSelectionInfoMap{}
 	ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
 		if m, ok := child.(*apexContributions); ok {
diff --git a/android/arch.go b/android/arch.go
index 152016c..7436660 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -425,7 +425,7 @@
 	// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
 	// filters out non-Soong modules.  Now that we've handled them, create a
 	// normal android.BottomUpMutatorContext.
-	mctx := bottomUpMutatorContextFactory(bpctx, module, false, false)
+	mctx := bottomUpMutatorContextFactory(bpctx, module, false)
 
 	base := module.base()
 
@@ -570,7 +570,7 @@
 	// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
 	// filters out non-Soong modules.  Now that we've handled them, create a
 	// normal android.BottomUpMutatorContext.
-	mctx := bottomUpMutatorContextFactory(bpctx, module, false, false)
+	mctx := bottomUpMutatorContextFactory(bpctx, module, false)
 
 	base := module.base()
 
diff --git a/android/base_module_context.go b/android/base_module_context.go
index ec9c888..4312e9b 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -112,8 +112,6 @@
 	// the first DependencyTag.
 	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
 
-	ModuleFromName(name string) (blueprint.Module, bool)
-
 	// VisitDirectDepsBlueprint calls visit for each direct dependency.  If there are multiple
 	// direct dependencies on the same module visit will be called multiple times on that module
 	// and OtherModuleDependencyTag will return a different tag for each.
@@ -209,12 +207,6 @@
 	// Calling this function prevents adding new dependencies.
 	getMissingDependencies() []string
 
-	// AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build
-	AddUnconvertedBp2buildDep(dep string)
-
-	// AddMissingBp2buildDep stores the module name of a direct dependency that was not found.
-	AddMissingBp2buildDep(dep string)
-
 	Target() Target
 	TargetPrimary() bool
 
@@ -243,12 +235,8 @@
 
 	strictVisitDeps bool // If true, enforce that all dependencies are enabled
 
-	bazelConversionMode bool
 }
 
-func (b *baseModuleContext) isBazelConversionMode() bool {
-	return b.bazelConversionMode
-}
 func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
 	return b.bp.OtherModuleName(m)
 }
@@ -296,18 +284,6 @@
 	return b.bp
 }
 
-// AddUnconvertedBp2buildDep stores module name of a dependency that was not converted to Bazel.
-func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) {
-	unconvertedDeps := &b.Module().base().commonProperties.BazelConversionStatus.UnconvertedDeps
-	*unconvertedDeps = append(*unconvertedDeps, dep)
-}
-
-// AddMissingBp2buildDep stores module name of a dependency that was not found in a Android.bp file.
-func (b *baseModuleContext) AddMissingBp2buildDep(dep string) {
-	missingDeps := &b.Module().base().commonProperties.BazelConversionStatus.MissingDeps
-	*missingDeps = append(*missingDeps, dep)
-}
-
 func (b *baseModuleContext) AddMissingDependencies(deps []string) {
 	if deps != nil {
 		missingDeps := &b.Module().base().commonProperties.MissingDeps
@@ -435,27 +411,6 @@
 	return b.getDirectDepFirstTag(name)
 }
 
-func (b *baseModuleContext) ModuleFromName(name string) (blueprint.Module, bool) {
-	if !b.isBazelConversionMode() {
-		panic("cannot call ModuleFromName if not in bazel conversion mode")
-	}
-	var m blueprint.Module
-	var ok bool
-	if moduleName, _ := SrcIsModuleWithTag(name); moduleName != "" {
-		m, ok = b.bp.ModuleFromName(moduleName)
-	} else {
-		m, ok = b.bp.ModuleFromName(name)
-	}
-	if !ok {
-		return m, ok
-	}
-	// If this module is not preferred, tried to get the prebuilt version instead
-	if a, aOk := m.(Module); aOk && !IsModulePrebuilt(a) && !IsModulePreferred(a) {
-		return b.ModuleFromName("prebuilt_" + name)
-	}
-	return m, ok
-}
-
 func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
 	b.bp.VisitDirectDeps(visit)
 }
diff --git a/android/bazel.go b/android/bazel.go
deleted file mode 100644
index 1602b9b..0000000
--- a/android/bazel.go
+++ /dev/null
@@ -1,784 +0,0 @@
-// Copyright 2021 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
-	"bufio"
-	"errors"
-	"fmt"
-	"strings"
-
-	"android/soong/ui/metrics/bp2build_metrics_proto"
-
-	"github.com/google/blueprint"
-	"github.com/google/blueprint/bootstrap"
-	"github.com/google/blueprint/proptools"
-
-	"android/soong/android/allowlists"
-)
-
-const (
-	// A sentinel value to be used as a key in Bp2BuildConfig for modules with
-	// no package path. This is also the module dir for top level Android.bp
-	// modules.
-	Bp2BuildTopLevel = "."
-)
-
-type MixedBuildEnabledStatus int
-
-const (
-	// This module can be mixed_built.
-	MixedBuildEnabled = iota
-
-	// There is a technical incompatibility preventing this module from being
-	// bazel-analyzed. Note: the module might also be incompatible.
-	TechnicalIncompatibility
-
-	// This module cannot be mixed_built due to some incompatibility with it
-	// that is not a platform incompatibility. Example: the module-type is not
-	// enabled, or is not bp2build-converted.
-	ModuleIncompatibility
-
-	// Missing dependencies. We can't query Bazel for modules if it has missing dependencies, there
-	// will be failures.
-	ModuleMissingDeps
-)
-
-// FileGroupAsLibrary describes a filegroup module that is converted to some library
-// such as aidl_library or proto_library.
-type FileGroupAsLibrary interface {
-	ShouldConvertToAidlLibrary(ctx BazelConversionPathContext) bool
-	ShouldConvertToProtoLibrary(ctx BazelConversionPathContext) bool
-	GetAidlLibraryLabel(ctx BazelConversionPathContext) string
-	GetProtoLibraryLabel(ctx BazelConversionPathContext) string
-}
-
-type BazelConversionStatus struct {
-	// Information about _all_ bp2build targets generated by this module. Multiple targets are
-	// supported as Soong handles some things within a single target that we may choose to split into
-	// multiple targets, e.g. renderscript, protos, yacc within a cc module.
-	Bp2buildInfo []bp2buildInfo `blueprint:"mutated"`
-
-	// UnconvertedBp2buildDep stores the module names of direct dependency that were not converted to
-	// Bazel
-	UnconvertedDeps []string `blueprint:"mutated"`
-
-	// MissingBp2buildDep stores the module names of direct dependency that were not found
-	MissingDeps []string `blueprint:"mutated"`
-
-	// If non-nil, indicates that the module could not be converted successfully
-	// with bp2build. This will describe the reason the module could not be converted.
-	UnconvertedReason *UnconvertedReason
-
-	// The Partition this module will be installed on.
-	// TODO(b/306200980) Investigate how to handle modules that are installed in multiple
-	// partitions.
-	Partition string `blueprint:"mutated"`
-}
-
-// The reason a module could not be converted to a BUILD target via bp2build.
-// This should match bp2build_metrics_proto.UnconvertedReason, but omits private
-// proto-related fields that prevent copying this struct.
-type UnconvertedReason struct {
-	// Should correspond to a valid value in bp2build_metrics_proto.UnconvertedReasonType.
-	// A raw int is used here instead, because blueprint logic requires that all transitive
-	// fields of module definitions be primitives.
-	ReasonType int
-	Detail     string
-}
-
-type BazelModuleProperties struct {
-	// The label of the Bazel target replacing this Soong module. When run in conversion mode, this
-	// will import the handcrafted build target into the autogenerated file. Note: this may result in
-	// a conflict due to duplicate targets if bp2build_available is also set.
-	Label *string
-
-	// If true, bp2build will generate the converted Bazel target for this module. Note: this may
-	// cause a conflict due to the duplicate targets if label is also set.
-	//
-	// This is a bool pointer to support tristates: true, false, not set.
-	//
-	// To opt in a module, set bazel_module: { bp2build_available: true }
-	// To opt out a module, set bazel_module: { bp2build_available: false }
-	// To defer the default setting for the directory, do not set the value.
-	Bp2build_available *bool
-
-	// CanConvertToBazel is set via InitBazelModule to indicate that a module type can be converted to
-	// Bazel with Bp2build.
-	CanConvertToBazel bool `blueprint:"mutated"`
-}
-
-// Properties contains common module properties for Bazel migration purposes.
-type properties struct {
-	// In "Bazel mixed build" mode, this represents the Bazel target replacing
-	// this Soong module.
-	Bazel_module BazelModuleProperties
-}
-
-// namespacedVariableProperties is a map from a string representing a Soong
-// config variable namespace, like "android" or "vendor_name" to a slice of
-// pointer to a struct containing a single field called Soong_config_variables
-// whose value mirrors the structure in the Blueprint file.
-type namespacedVariableProperties map[string][]interface{}
-
-// BazelModuleBase contains the property structs with metadata for modules which can be converted to
-// Bazel.
-type BazelModuleBase struct {
-	bazelProperties properties
-
-	// namespacedVariableProperties is used for soong_config_module_type support
-	// in bp2build. Soong config modules allow users to set module properties
-	// based on custom product variables defined in Android.bp files. These
-	// variables are namespaced to prevent clobbering, especially when set from
-	// Makefiles.
-	namespacedVariableProperties namespacedVariableProperties
-
-	// baseModuleType is set when this module was created from a module type
-	// defined by a soong_config_module_type. Every soong_config_module_type
-	// "wraps" another module type, e.g. a soong_config_module_type can wrap a
-	// cc_defaults to a custom_cc_defaults, or cc_binary to a custom_cc_binary.
-	// This baseModuleType is set to the wrapped module type.
-	baseModuleType string
-}
-
-// Bazelable is specifies the interface for modules that can be converted to Bazel.
-type Bazelable interface {
-	bazelProps() *properties
-	HasHandcraftedLabel() bool
-	HandcraftedLabel() string
-	GetBazelLabel(ctx BazelConversionPathContext, module blueprint.Module) string
-	ShouldConvertWithBp2build(ctx ShouldConvertWithBazelContext) bool
-	shouldConvertWithBp2build(shouldConvertModuleContext, shouldConvertParams) bool
-
-	// ConvertWithBp2build either converts the module to a Bazel build target or
-	// declares the module as unconvertible (for logging and metrics).
-	// Modules must implement this function to be bp2build convertible. The function
-	// must either create at least one Bazel target module (using ctx.CreateBazelTargetModule or
-	// its related functions), or declare itself unconvertible using ctx.MarkBp2buildUnconvertible.
-	ConvertWithBp2build(ctx Bp2buildMutatorContext)
-
-	// namespacedVariableProps is a map from a soong config variable namespace
-	// (e.g. acme, android) to a map of interfaces{}, which are really
-	// reflect.Struct pointers, representing the value of the
-	// soong_config_variables property of a module. The struct pointer is the
-	// one with the single member called Soong_config_variables, which itself is
-	// a struct containing fields for each supported feature in that namespace.
-	//
-	// The reason for using a slice of interface{} is to support defaults
-	// propagation of the struct pointers.
-	namespacedVariableProps() namespacedVariableProperties
-	setNamespacedVariableProps(props namespacedVariableProperties)
-	BaseModuleType() string
-	SetBaseModuleType(baseModuleType string)
-}
-
-// ApiProvider is implemented by modules that contribute to an API surface
-type ApiProvider interface {
-	ConvertWithApiBp2build(ctx TopDownMutatorContext)
-}
-
-// MixedBuildBuildable is an interface that module types should implement in order
-// to be "handled by Bazel" in a mixed build.
-type MixedBuildBuildable interface {
-	// IsMixedBuildSupported returns true if and only if this module should be
-	// "handled by Bazel" in a mixed build.
-	// This "escape hatch" allows modules with corner-case scenarios to opt out
-	// of being built with Bazel.
-	IsMixedBuildSupported(ctx BaseModuleContext) bool
-
-	// QueueBazelCall invokes request-queueing functions on the BazelContext
-	// so that these requests are handled when Bazel's cquery is invoked.
-	QueueBazelCall(ctx BaseModuleContext)
-
-	// ProcessBazelQueryResponse uses Bazel information (obtained from the BazelContext)
-	// to set module fields and providers to propagate this module's metadata upstream.
-	// This effectively "bridges the gap" between Bazel and Soong in a mixed build.
-	// Soong modules depending on this module should be oblivious to the fact that
-	// this module was handled by Bazel.
-	ProcessBazelQueryResponse(ctx ModuleContext)
-}
-
-// BazelModule is a lightweight wrapper interface around Module for Bazel-convertible modules.
-type BazelModule interface {
-	Module
-	Bazelable
-}
-
-// InitBazelModule is a wrapper function that decorates a BazelModule with Bazel-conversion
-// properties.
-func InitBazelModule(module BazelModule) {
-	module.AddProperties(module.bazelProps())
-	module.bazelProps().Bazel_module.CanConvertToBazel = true
-}
-
-// BazelHandcraftedHook is a load hook to possibly register the current module as
-// a "handcrafted" Bazel target of a given name. If the current module should be
-// registered in this way, the hook function should return the target name. If
-// it should not be registered in this way, this function should return the empty string.
-type BazelHandcraftedHook func(ctx LoadHookContext) string
-
-// AddBazelHandcraftedHook adds a load hook to (maybe) mark the given module so that
-// it is treated by bp2build as if it has a handcrafted Bazel target.
-func AddBazelHandcraftedHook(module BazelModule, hook BazelHandcraftedHook) {
-	AddLoadHook(module, func(ctx LoadHookContext) {
-		var targetName string = hook(ctx)
-		if len(targetName) > 0 {
-			moduleDir := ctx.ModuleDir()
-			if moduleDir == Bp2BuildTopLevel {
-				moduleDir = ""
-			}
-			label := fmt.Sprintf("//%s:%s", moduleDir, targetName)
-			module.bazelProps().Bazel_module.Label = &label
-		}
-	})
-}
-
-// bazelProps returns the Bazel properties for the given BazelModuleBase.
-func (b *BazelModuleBase) bazelProps() *properties {
-	return &b.bazelProperties
-}
-
-func (b *BazelModuleBase) namespacedVariableProps() namespacedVariableProperties {
-	return b.namespacedVariableProperties
-}
-
-func (b *BazelModuleBase) setNamespacedVariableProps(props namespacedVariableProperties) {
-	b.namespacedVariableProperties = props
-}
-
-func (b *BazelModuleBase) BaseModuleType() string {
-	return b.baseModuleType
-}
-
-func (b *BazelModuleBase) SetBaseModuleType(baseModuleType string) {
-	b.baseModuleType = baseModuleType
-}
-
-// HasHandcraftedLabel returns whether this module has a handcrafted Bazel label.
-func (b *BazelModuleBase) HasHandcraftedLabel() bool {
-	return b.bazelProperties.Bazel_module.Label != nil
-}
-
-// HandcraftedLabel returns the handcrafted label for this module, or empty string if there is none
-func (b *BazelModuleBase) HandcraftedLabel() string {
-	return proptools.String(b.bazelProperties.Bazel_module.Label)
-}
-
-// GetBazelLabel returns the Bazel label for the given BazelModuleBase.
-func (b *BazelModuleBase) GetBazelLabel(ctx BazelConversionPathContext, module blueprint.Module) string {
-	if b.HasHandcraftedLabel() {
-		return b.HandcraftedLabel()
-	}
-	if b.ShouldConvertWithBp2build(ctx) {
-		return bp2buildModuleLabel(ctx, module)
-	}
-	panic(fmt.Errorf("requested non-existent label for module %s", module.Name()))
-}
-
-type Bp2BuildConversionAllowlist struct {
-	// Configure modules in these directories to enable bp2build_available: true or false by default.
-	defaultConfig allowlists.Bp2BuildConfig
-
-	// Keep any existing BUILD files (and do not generate new BUILD files) for these directories
-	// in the synthetic Bazel workspace.
-	keepExistingBuildFile map[string]bool
-
-	// Per-module allowlist to always opt modules into both bp2build and Bazel Dev Mode mixed
-	// builds. These modules are usually in directories with many other modules that are not ready
-	// for conversion.
-	//
-	// A module can either be in this list or its directory allowlisted entirely
-	// in bp2buildDefaultConfig, but not both at the same time.
-	moduleAlwaysConvert map[string]bool
-
-	// Per-module-type allowlist to always opt modules in to both bp2build and
-	// Bazel Dev Mode mixed builds when they have the same type as one listed.
-	moduleTypeAlwaysConvert map[string]bool
-
-	// Per-module denylist to always opt modules out of bp2build conversion.
-	moduleDoNotConvert map[string]bool
-}
-
-// NewBp2BuildAllowlist creates a new, empty Bp2BuildConversionAllowlist
-// which can be populated using builder pattern Set* methods
-func NewBp2BuildAllowlist() Bp2BuildConversionAllowlist {
-	return Bp2BuildConversionAllowlist{
-		allowlists.Bp2BuildConfig{},
-		map[string]bool{},
-		map[string]bool{},
-		map[string]bool{},
-		map[string]bool{},
-	}
-}
-
-// SetDefaultConfig copies the entries from defaultConfig into the allowlist
-func (a Bp2BuildConversionAllowlist) SetDefaultConfig(defaultConfig allowlists.Bp2BuildConfig) Bp2BuildConversionAllowlist {
-	if a.defaultConfig == nil {
-		a.defaultConfig = allowlists.Bp2BuildConfig{}
-	}
-	for k, v := range defaultConfig {
-		a.defaultConfig[k] = v
-	}
-
-	return a
-}
-
-// SetKeepExistingBuildFile copies the entries from keepExistingBuildFile into the allowlist
-func (a Bp2BuildConversionAllowlist) SetKeepExistingBuildFile(keepExistingBuildFile map[string]bool) Bp2BuildConversionAllowlist {
-	if a.keepExistingBuildFile == nil {
-		a.keepExistingBuildFile = map[string]bool{}
-	}
-	for k, v := range keepExistingBuildFile {
-		a.keepExistingBuildFile[k] = v
-	}
-
-	return a
-}
-
-// SetModuleAlwaysConvertList copies the entries from moduleAlwaysConvert into the allowlist
-func (a Bp2BuildConversionAllowlist) SetModuleAlwaysConvertList(moduleAlwaysConvert []string) Bp2BuildConversionAllowlist {
-	if a.moduleAlwaysConvert == nil {
-		a.moduleAlwaysConvert = map[string]bool{}
-	}
-	for _, m := range moduleAlwaysConvert {
-		a.moduleAlwaysConvert[m] = true
-	}
-
-	return a
-}
-
-// SetModuleTypeAlwaysConvertList copies the entries from moduleTypeAlwaysConvert into the allowlist
-func (a Bp2BuildConversionAllowlist) SetModuleTypeAlwaysConvertList(moduleTypeAlwaysConvert []string) Bp2BuildConversionAllowlist {
-	if a.moduleTypeAlwaysConvert == nil {
-		a.moduleTypeAlwaysConvert = map[string]bool{}
-	}
-	for _, m := range moduleTypeAlwaysConvert {
-		a.moduleTypeAlwaysConvert[m] = true
-	}
-
-	return a
-}
-
-// SetModuleDoNotConvertList copies the entries from moduleDoNotConvert into the allowlist
-func (a Bp2BuildConversionAllowlist) SetModuleDoNotConvertList(moduleDoNotConvert []string) Bp2BuildConversionAllowlist {
-	if a.moduleDoNotConvert == nil {
-		a.moduleDoNotConvert = map[string]bool{}
-	}
-	for _, m := range moduleDoNotConvert {
-		a.moduleDoNotConvert[m] = true
-	}
-
-	return a
-}
-
-// ShouldKeepExistingBuildFileForDir returns whether an existing BUILD file should be
-// added to the build symlink forest based on the current global configuration.
-func (a Bp2BuildConversionAllowlist) ShouldKeepExistingBuildFileForDir(dir string) bool {
-	if _, ok := a.keepExistingBuildFile[dir]; ok {
-		// Exact dir match
-		return true
-	}
-	var i int
-	// Check if subtree match
-	for {
-		j := strings.Index(dir[i:], "/")
-		if j == -1 {
-			return false //default
-		}
-		prefix := dir[0 : i+j]
-		i = i + j + 1 // skip the "/"
-		if recursive, ok := a.keepExistingBuildFile[prefix]; ok && recursive {
-			return true
-		}
-	}
-}
-
-var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
-var bp2buildAllowlist OncePer
-
-func GetBp2BuildAllowList() Bp2BuildConversionAllowlist {
-	return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
-		return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
-			SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
-			SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
-			SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
-			SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList)
-	}).(Bp2BuildConversionAllowlist)
-}
-
-// MixedBuildsEnabled returns a MixedBuildEnabledStatus regarding whether
-// a module is ready to be replaced by a converted or handcrafted Bazel target.
-// As a side effect, calling this method will also log whether this module is
-// mixed build enabled for metrics reporting.
-func MixedBuildsEnabled(ctx BaseModuleContext) MixedBuildEnabledStatus {
-	platformIncompatible := isPlatformIncompatible(ctx.Os(), ctx.Arch().ArchType)
-	if platformIncompatible {
-		ctx.Config().LogMixedBuild(ctx, false)
-		return TechnicalIncompatibility
-	}
-
-	if ctx.Config().AllowMissingDependencies() {
-		missingDeps := ctx.getMissingDependencies()
-		// If there are missing dependencies, querying Bazel will fail. Soong instead fails at execution
-		// time, not loading/analysis. disable mixed builds and fall back to Soong to maintain that
-		// behavior.
-		if len(missingDeps) > 0 {
-			ctx.Config().LogMixedBuild(ctx, false)
-			return ModuleMissingDeps
-		}
-	}
-
-	module := ctx.Module()
-	apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo)
-	withinApex := !apexInfo.IsForPlatform()
-	mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() &&
-		module.Enabled() &&
-		convertedToBazel(ctx, module) &&
-		ctx.Config().BazelContext.IsModuleNameAllowed(module.Name(), withinApex)
-	ctx.Config().LogMixedBuild(ctx, mixedBuildEnabled)
-
-	if mixedBuildEnabled {
-		return MixedBuildEnabled
-	}
-	return ModuleIncompatibility
-}
-
-func isGoModule(module blueprint.Module) bool {
-	if _, ok := module.(*bootstrap.GoPackage); ok {
-		return true
-	}
-	if _, ok := module.(*bootstrap.GoBinary); ok {
-		return true
-	}
-	return false
-}
-
-// ConvertedToBazel returns whether this module has been converted (with bp2build or manually) to Bazel.
-func convertedToBazel(ctx BazelConversionContext, module blueprint.Module) bool {
-	// Special-case bootstrap_go_package and bootstrap_go_binary
-	// These do not implement Bazelable, but have been converted
-	if isGoModule(module) {
-		return true
-	}
-	b, ok := module.(Bazelable)
-	if !ok {
-		return false
-	}
-
-	return b.HasHandcraftedLabel() || b.shouldConvertWithBp2build(ctx, shouldConvertParams{
-		module:     module,
-		moduleDir:  ctx.OtherModuleDir(module),
-		moduleName: ctx.OtherModuleName(module),
-		moduleType: ctx.OtherModuleType(module),
-	})
-}
-
-type ShouldConvertWithBazelContext interface {
-	ModuleErrorf(format string, args ...interface{})
-	Module() Module
-	Config() Config
-	ModuleType() string
-	ModuleName() string
-	ModuleDir() string
-}
-
-// ShouldConvertWithBp2build returns whether the given BazelModuleBase should be converted with bp2build
-func (b *BazelModuleBase) ShouldConvertWithBp2build(ctx ShouldConvertWithBazelContext) bool {
-	return b.shouldConvertWithBp2build(ctx, shouldConvertParams{
-		module:     ctx.Module(),
-		moduleDir:  ctx.ModuleDir(),
-		moduleName: ctx.ModuleName(),
-		moduleType: ctx.ModuleType(),
-	})
-}
-
-type bazelOtherModuleContext interface {
-	ModuleErrorf(format string, args ...interface{})
-	Config() Config
-	OtherModuleType(m blueprint.Module) string
-	OtherModuleName(m blueprint.Module) string
-	OtherModuleDir(m blueprint.Module) string
-}
-
-func isPlatformIncompatible(osType OsType, arch ArchType) bool {
-	return osType == Windows || // Windows toolchains are not currently supported.
-		osType == LinuxBionic || // Linux Bionic toolchains are not currently supported.
-		osType == LinuxMusl || // Linux musl toolchains are not currently supported (b/259266326).
-		arch == Riscv64 // TODO(b/262192655) Riscv64 toolchains are not currently supported.
-}
-
-type shouldConvertModuleContext interface {
-	ModuleErrorf(format string, args ...interface{})
-	Config() Config
-}
-
-type shouldConvertParams struct {
-	module     blueprint.Module
-	moduleType string
-	moduleDir  string
-	moduleName string
-}
-
-func (b *BazelModuleBase) shouldConvertWithBp2build(ctx shouldConvertModuleContext, p shouldConvertParams) bool {
-	if !b.bazelProps().Bazel_module.CanConvertToBazel {
-		return false
-	}
-
-	module := p.module
-
-	propValue := b.bazelProperties.Bazel_module.Bp2build_available
-	packagePath := moduleDirWithPossibleOverride(ctx, module, p.moduleDir)
-
-	// Modules in unit tests which are enabled in the allowlist by type or name
-	// trigger this conditional because unit tests run under the "." package path
-	isTestModule := packagePath == Bp2BuildTopLevel && proptools.BoolDefault(propValue, false)
-	if isTestModule {
-		return true
-	}
-
-	moduleName := moduleNameWithPossibleOverride(ctx, module, p.moduleName)
-	// use "prebuilt_" + original module name as the java_import(_host) module name,
-	// to avoid the failure that a normal module and a prebuilt module with
-	// the same name are both allowlisted. This cannot be applied to all the *_import
-	// module types. For example, android_library_import has to use original module
-	// name here otherwise the *-nodeps targets cannot be handled correctly.
-	// TODO(b/304385140): remove this special casing
-	if p.moduleType == "java_import" || p.moduleType == "java_import_host" {
-		moduleName = module.Name()
-	}
-
-	allowlist := ctx.Config().Bp2buildPackageConfig
-
-	moduleNameAllowed := allowlist.moduleAlwaysConvert[moduleName]
-	moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[p.moduleType]
-	allowlistConvert := moduleNameAllowed || moduleTypeAllowed
-	if moduleNameAllowed && moduleTypeAllowed {
-		ctx.ModuleErrorf("A module %q of type %q cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert", moduleName, p.moduleType)
-		return false
-	}
-
-	if allowlist.moduleDoNotConvert[moduleName] {
-		if moduleNameAllowed {
-			ctx.ModuleErrorf("a module %q cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert", moduleName)
-		}
-		return false
-	}
-
-	// This is a tristate value: true, false, or unset.
-	if ok, directoryPath := bp2buildDefaultTrueRecursively(packagePath, allowlist.defaultConfig); ok {
-		if moduleNameAllowed {
-			ctx.ModuleErrorf("A module cannot be in a directory marked Bp2BuildDefaultTrue"+
-				" or Bp2BuildDefaultTrueRecursively and also be in moduleAlwaysConvert. Directory: '%s'"+
-				" Module: '%s'", directoryPath, moduleName)
-			return false
-		}
-
-		// Allow modules to explicitly opt-out.
-		return proptools.BoolDefault(propValue, true)
-	}
-
-	// Allow modules to explicitly opt-in.
-	return proptools.BoolDefault(propValue, allowlistConvert)
-}
-
-// bp2buildDefaultTrueRecursively checks that the package contains a prefix from the
-// set of package prefixes where all modules must be converted. That is, if the
-// package is x/y/z, and the list contains either x, x/y, or x/y/z, this function will
-// return true.
-//
-// However, if the package is x/y, and it matches a Bp2BuildDefaultFalse "x/y" entry
-// exactly, this module will return false early.
-//
-// This function will also return false if the package doesn't match anything in
-// the config.
-//
-// This function will also return the allowlist entry which caused a particular
-// package to be enabled. Since packages can be enabled via a recursive declaration,
-// the path returned will not always be the same as the one provided.
-func bp2buildDefaultTrueRecursively(packagePath string, config allowlists.Bp2BuildConfig) (bool, string) {
-	// Check if the package path has an exact match in the config.
-	if config[packagePath] == allowlists.Bp2BuildDefaultTrue || config[packagePath] == allowlists.Bp2BuildDefaultTrueRecursively {
-		return true, packagePath
-	} else if config[packagePath] == allowlists.Bp2BuildDefaultFalse || config[packagePath] == allowlists.Bp2BuildDefaultFalseRecursively {
-		return false, packagePath
-	}
-
-	// If not, check for the config recursively.
-	packagePrefix := packagePath
-
-	// e.g. for x/y/z, iterate over x/y, then x, taking the most-specific value from the allowlist.
-	for strings.Contains(packagePrefix, "/") {
-		dirIndex := strings.LastIndex(packagePrefix, "/")
-		packagePrefix = packagePrefix[:dirIndex]
-		switch value := config[packagePrefix]; value {
-		case allowlists.Bp2BuildDefaultTrueRecursively:
-			// package contains this prefix and this prefix should convert all modules
-			return true, packagePrefix
-		case allowlists.Bp2BuildDefaultFalseRecursively:
-			//package contains this prefix and this prefix should NOT convert any modules
-			return false, packagePrefix
-		}
-		// Continue to the next part of the package dir.
-
-	}
-
-	return false, packagePath
-}
-
-func registerBp2buildConversionMutator(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("bp2build_conversion", bp2buildConversionMutator).Parallel()
-	ctx.BottomUp("bp2build_deps", bp2buildDepsMutator).Parallel()
-}
-
-func bp2buildConversionMutator(ctx BottomUpMutatorContext) {
-	// If an existing BUILD file in the module directory has a target defined
-	// with this same name as this module, assume that this is an existing
-	// definition for this target.
-	if ctx.Config().HasBazelBuildTargetInSource(ctx.ModuleDir(), ctx.ModuleName()) {
-		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE, ctx.ModuleName())
-		return
-	}
-	bModule, ok := ctx.Module().(Bazelable)
-	if !ok {
-		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
-		return
-	}
-	// There may be cases where the target is created by a macro rather than in a BUILD file, those
-	// should be captured as well.
-	if bModule.HasHandcraftedLabel() {
-		// Defer to the BUILD target. Generating an additional target would
-		// cause a BUILD file conflict.
-		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE, "")
-		return
-	}
-	// TODO: b/285631638 - Differentiate between denylisted modules and missing bp2build capabilities.
-	if !bModule.shouldConvertWithBp2build(ctx, shouldConvertParams{
-		module:     ctx.Module(),
-		moduleDir:  ctx.ModuleDir(),
-		moduleName: ctx.ModuleName(),
-		moduleType: ctx.ModuleType(),
-	}) {
-		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, "")
-		return
-	}
-	if ctx.Module().base().GetUnconvertedReason() != nil {
-		return
-	}
-
-	bModule.ConvertWithBp2build(ctx)
-
-	installCtx := &baseModuleContextToModuleInstallPathContext{ctx}
-	ctx.Module().base().setPartitionForBp2build(modulePartition(installCtx, true))
-
-	if len(ctx.Module().base().Bp2buildTargets()) == 0 && ctx.Module().base().GetUnconvertedReason() == nil {
-		panic(fmt.Errorf("illegal bp2build invariant: module '%s' was neither converted nor marked unconvertible", ctx.ModuleName()))
-	}
-
-	// If an existing BUILD file in the module directory has a target defined
-	// with the same name as any target generated by this module, assume that this
-	// is an existing definition for this target. (These generated target names
-	// may be different than the module name, as checked at the beginning of this function!)
-	for _, targetInfo := range ctx.Module().base().Bp2buildTargets() {
-		if ctx.Config().HasBazelBuildTargetInSource(targetInfo.TargetPackage(), targetInfo.TargetName()) {
-			// Defer to the BUILD target. Generating an additional target would
-			// cause a BUILD file conflict.
-			ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE, targetInfo.TargetName())
-			return
-		}
-	}
-}
-
-// TODO: b/285631638 - Add this as a new mutator to the bp2build conversion mutators.
-// Currently, this only exists to prepare test coverage for the launch of this feature.
-func bp2buildDepsMutator(ctx BottomUpMutatorContext) {
-	if ctx.Module().base().GetUnconvertedReason() != nil {
-		return
-	}
-
-	if len(ctx.Module().GetMissingBp2buildDeps()) > 0 {
-		exampleDep := ctx.Module().GetMissingBp2buildDeps()[0]
-		ctx.MarkBp2buildUnconvertible(
-			bp2build_metrics_proto.UnconvertedReasonType_UNCONVERTED_DEP, exampleDep)
-	}
-
-	// Transitively mark modules unconvertible with the following set of conditions.
-	ctx.VisitDirectDeps(func(dep Module) {
-		if dep.base().GetUnconvertedReason() == nil {
-			return
-		}
-
-		if dep.base().GetUnconvertedReason().ReasonType ==
-			int(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE) {
-			return
-		}
-
-		if ctx.OtherModuleDependencyTag(dep) != Bp2buildDepTag {
-			return
-		}
-
-		ctx.MarkBp2buildUnconvertible(
-			bp2build_metrics_proto.UnconvertedReasonType_UNCONVERTED_DEP, dep.Name())
-	})
-}
-
-// GetMainClassInManifest scans the manifest file specified in filepath and returns
-// the value of attribute Main-Class in the manifest file if it exists, or returns error.
-// WARNING: this is for bp2build converters of java_* modules only.
-func GetMainClassInManifest(c Config, filepath string) (string, error) {
-	file, err := c.fs.Open(filepath)
-	if err != nil {
-		return "", err
-	}
-	defer file.Close()
-	scanner := bufio.NewScanner(file)
-	for scanner.Scan() {
-		line := scanner.Text()
-		if strings.HasPrefix(line, "Main-Class:") {
-			return strings.TrimSpace(line[len("Main-Class:"):]), nil
-		}
-	}
-
-	return "", errors.New("Main-Class is not found.")
-}
-
-func AttachValidationActions(ctx ModuleContext, outputFilePath Path, validations Paths) ModuleOutPath {
-	validatedOutputFilePath := PathForModuleOut(ctx, "validated", outputFilePath.Base())
-	ctx.Build(pctx, BuildParams{
-		Rule:        CpNoPreserveSymlink,
-		Description: "run validations " + outputFilePath.Base(),
-		Output:      validatedOutputFilePath,
-		Input:       outputFilePath,
-		Validations: validations,
-	})
-	return validatedOutputFilePath
-}
-
-func RunsOn(hostSupported bool, deviceSupported bool, unitTest bool) []string {
-	var runsOn []string
-
-	if hostSupported && deviceSupported {
-		runsOn = []string{"host_without_device", "device"}
-	} else if hostSupported {
-		if unitTest {
-			runsOn = []string{"host_without_device"}
-		} else {
-			runsOn = []string{"host_with_device"}
-		}
-	} else if deviceSupported {
-		runsOn = []string{"device"}
-	}
-
-	return runsOn
-}
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
deleted file mode 100644
index 0c65415..0000000
--- a/android/bazel_handler.go
+++ /dev/null
@@ -1,1593 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
-	"bytes"
-	"crypto/sha1"
-	"encoding/hex"
-	"fmt"
-	"os"
-	"path"
-	"path/filepath"
-	"regexp"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-
-	"android/soong/android/allowlists"
-	"android/soong/bazel/cquery"
-	"android/soong/shared"
-	"android/soong/starlark_import"
-
-	"android/soong/bazel"
-
-	"github.com/google/blueprint"
-	"github.com/google/blueprint/metrics"
-)
-
-var (
-	_                 = pctx.HostBinToolVariable("bazelBuildRunfilesTool", "build-runfiles")
-	buildRunfilesRule = pctx.AndroidStaticRule("bazelBuildRunfiles", blueprint.RuleParams{
-		Command:     "${bazelBuildRunfilesTool} ${in} ${outDir}",
-		Depfile:     "",
-		Description: "",
-		CommandDeps: []string{"${bazelBuildRunfilesTool}"},
-	}, "outDir")
-)
-
-func registerMixedBuildsMutator(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
-}
-
-func RegisterMixedBuildsMutator(ctx RegistrationContext) {
-	ctx.FinalDepsMutators(registerMixedBuildsMutator)
-}
-
-func mixedBuildsPrepareMutator(ctx BottomUpMutatorContext) {
-	if m := ctx.Module(); m.Enabled() {
-		if mixedBuildMod, ok := m.(MixedBuildBuildable); ok {
-			mixedBuildEnabled := MixedBuildsEnabled(ctx)
-			queueMixedBuild := mixedBuildMod.IsMixedBuildSupported(ctx) && mixedBuildEnabled == MixedBuildEnabled
-			if queueMixedBuild {
-				mixedBuildMod.QueueBazelCall(ctx)
-			}
-		}
-	}
-}
-
-type cqueryRequest interface {
-	// Name returns a string name for this request type. Such request type names must be unique,
-	// and must only consist of alphanumeric characters.
-	Name() string
-
-	// StarlarkFunctionBody returns a starlark function body to process this request type.
-	// The returned string is the body of a Starlark function which obtains
-	// all request-relevant information about a target and returns a string containing
-	// this information.
-	// The function should have the following properties:
-	//   - The arguments are `target` (a configured target) and `id_string` (the label + configuration).
-	//   - The return value must be a string.
-	//   - The function body should not be indented outside of its own scope.
-	StarlarkFunctionBody() string
-}
-
-// Portion of cquery map key to describe target configuration.
-type configKey struct {
-	arch    string
-	osType  OsType
-	apexKey ApexConfigKey
-}
-
-type ApexConfigKey struct {
-	WithinApex     bool
-	ApexSdkVersion string
-	ApiDomain      string
-}
-
-func (c ApexConfigKey) String() string {
-	return fmt.Sprintf("%s_%s_%s", withinApexToString(c.WithinApex), c.ApexSdkVersion, c.ApiDomain)
-}
-
-func withinApexToString(withinApex bool) string {
-	if withinApex {
-		return "within_apex"
-	}
-	return ""
-}
-
-func (c configKey) String() string {
-	return fmt.Sprintf("%s::%s::%s", c.arch, c.osType, c.apexKey)
-}
-
-// Map key to describe bazel cquery requests.
-type cqueryKey struct {
-	label       string
-	requestType cqueryRequest
-	configKey   configKey
-}
-
-func makeCqueryKey(label string, cqueryRequest cqueryRequest, cfgKey configKey) cqueryKey {
-	if strings.HasPrefix(label, "//") {
-		// Normalize Bazel labels to specify main repository explicitly.
-		label = "@" + label
-	}
-	return cqueryKey{label, cqueryRequest, cfgKey}
-}
-
-func (c cqueryKey) String() string {
-	return fmt.Sprintf("cquery(%s,%s,%s)", c.label, c.requestType.Name(), c.configKey)
-}
-
-type invokeBazelContext interface {
-	GetEventHandler() *metrics.EventHandler
-}
-
-// BazelContext is a context object useful for interacting with Bazel during
-// the course of a build. Use of Bazel to evaluate part of the build graph
-// is referred to as a "mixed build". (Some modules are managed by Soong,
-// some are managed by Bazel). To facilitate interop between these build
-// subgraphs, Soong may make requests to Bazel and evaluate their responses
-// so that Soong modules may accurately depend on Bazel targets.
-type BazelContext interface {
-	// Add a cquery request to the bazel request queue. All queued requests
-	// will be sent to Bazel on a subsequent invocation of InvokeBazel.
-	QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey)
-
-	// ** Cquery Results Retrieval Functions
-	// The below functions pertain to retrieving cquery results from a prior
-	// InvokeBazel function call and parsing the results.
-
-	// Returns result files built by building the given bazel target label.
-	GetOutputFiles(label string, cfgKey configKey) ([]string, error)
-
-	// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
-	GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error)
-
-	// Returns the results of the GetApexInfo query (including output files)
-	GetApexInfo(label string, cfgkey configKey) (cquery.ApexInfo, error)
-
-	// Returns the results of the GetCcUnstrippedInfo query
-	GetCcUnstrippedInfo(label string, cfgkey configKey) (cquery.CcUnstrippedInfo, error)
-
-	// Returns the results of the GetPrebuiltFileInfo query
-	GetPrebuiltFileInfo(label string, cfgKey configKey) (cquery.PrebuiltFileInfo, error)
-
-	// ** end Cquery Results Retrieval Functions
-
-	// Issues commands to Bazel to receive results for all cquery requests
-	// queued in the BazelContext. The ctx argument is optional and is only
-	// used for performance data collection
-	InvokeBazel(config Config, ctx invokeBazelContext) error
-
-	// Returns true if Bazel handling is enabled for the module with the given name.
-	// Note that this only implies "bazel mixed build" allowlisting. The caller
-	// should independently verify the module is eligible for Bazel handling
-	// (for example, that it is MixedBuildBuildable).
-	IsModuleNameAllowed(moduleName string, withinApex bool) bool
-
-	// Returns the bazel output base (the root directory for all bazel intermediate outputs).
-	OutputBase() string
-
-	// Returns build statements which should get registered to reflect Bazel's outputs.
-	BuildStatementsToRegister() []*bazel.BuildStatement
-
-	// Returns the depsets defined in Bazel's aquery response.
-	AqueryDepsets() []bazel.AqueryDepset
-
-	QueueBazelSandwichCqueryRequests(config Config) error
-}
-
-type bazelRunner interface {
-	issueBazelCommand(cmdRequest bazel.CmdRequest, paths *bazelPaths, eventHandler *metrics.EventHandler) (output string, errorMessage string, error error)
-}
-
-type bazelPaths struct {
-	homeDir       string
-	bazelPath     string
-	outputBase    string
-	workspaceDir  string
-	soongOutDir   string
-	metricsDir    string
-	bazelDepsFile string
-}
-
-// A context object which tracks queued requests that need to be made to Bazel,
-// and their results after the requests have been made.
-type mixedBuildBazelContext struct {
-	bazelRunner
-	paths *bazelPaths
-	// cquery requests that have not yet been issued to Bazel. This list is maintained
-	// in a sorted state, and is guaranteed to have no duplicates.
-	requests     []cqueryKey
-	requestMutex sync.Mutex // requests can be written in parallel
-
-	results map[cqueryKey]string // Results of cquery requests after Bazel invocations
-
-	// Build statements which should get registered to reflect Bazel's outputs.
-	buildStatements []*bazel.BuildStatement
-
-	// Depsets which should be used for Bazel's build statements.
-	depsets []bazel.AqueryDepset
-
-	// Per-module allowlist/denylist functionality to control whether analysis of
-	// modules are handled by Bazel. For modules which do not have a Bazel definition
-	// (or do not sufficiently support bazel handling via MixedBuildBuildable),
-	// this allowlist will have no effect, even if the module is explicitly allowlisted here.
-	// Per-module denylist to opt modules out of bazel handling.
-	bazelDisabledModules map[string]bool
-	// Per-module allowlist to opt modules in to bazel handling.
-	bazelEnabledModules map[string]bool
-	// DCLA modules are enabled when used in apex.
-	bazelDclaEnabledModules map[string]bool
-
-	targetProduct      string
-	targetBuildVariant string
-}
-
-var _ BazelContext = &mixedBuildBazelContext{}
-
-// A bazel context to use when Bazel is disabled.
-type noopBazelContext struct{}
-
-var _ BazelContext = noopBazelContext{}
-
-func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
-	panic("unimplemented")
-}
-
-func (n noopBazelContext) QueueBazelSandwichCqueryRequests(config Config) error {
-	panic("unimplemented")
-}
-
-func (n noopBazelContext) GetOutputFiles(_ string, _ configKey) ([]string, error) {
-	panic("unimplemented")
-}
-
-func (n noopBazelContext) GetCcInfo(_ string, _ configKey) (cquery.CcInfo, error) {
-	panic("unimplemented")
-}
-
-func (n noopBazelContext) GetApexInfo(_ string, _ configKey) (cquery.ApexInfo, error) {
-	panic("unimplemented")
-}
-
-func (n noopBazelContext) GetCcUnstrippedInfo(_ string, _ configKey) (cquery.CcUnstrippedInfo, error) {
-	//TODO implement me
-	panic("implement me")
-}
-
-func (n noopBazelContext) GetPrebuiltFileInfo(_ string, _ configKey) (cquery.PrebuiltFileInfo, error) {
-	panic("implement me")
-}
-
-func (n noopBazelContext) InvokeBazel(_ Config, _ invokeBazelContext) error {
-	panic("unimplemented")
-}
-
-func (m noopBazelContext) OutputBase() string {
-	return ""
-}
-
-func (n noopBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
-	return false
-}
-
-func (m noopBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
-	return []*bazel.BuildStatement{}
-}
-
-func (m noopBazelContext) AqueryDepsets() []bazel.AqueryDepset {
-	return []bazel.AqueryDepset{}
-}
-
-// A bazel context to use for tests.
-type MockBazelContext struct {
-	OutputBaseDir string
-
-	LabelToOutputFiles      map[string][]string
-	LabelToCcInfo           map[string]cquery.CcInfo
-	LabelToPythonBinary     map[string]string
-	LabelToApexInfo         map[string]cquery.ApexInfo
-	LabelToCcBinary         map[string]cquery.CcUnstrippedInfo
-	LabelToPrebuiltFileInfo map[string]cquery.PrebuiltFileInfo
-
-	BazelRequests map[string]bool
-}
-
-func (m MockBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) {
-	key := BuildMockBazelContextRequestKey(label, requestType, cfgKey.arch, cfgKey.osType, cfgKey.apexKey)
-	if m.BazelRequests == nil {
-		m.BazelRequests = make(map[string]bool)
-	}
-	m.BazelRequests[key] = true
-}
-
-func (m MockBazelContext) QueueBazelSandwichCqueryRequests(config Config) error {
-	panic("unimplemented")
-}
-
-func (m MockBazelContext) GetOutputFiles(label string, _ configKey) ([]string, error) {
-	result, ok := m.LabelToOutputFiles[label]
-	if !ok {
-		return []string{}, fmt.Errorf("no target with label %q in LabelToOutputFiles", label)
-	}
-	return result, nil
-}
-
-func (m MockBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) {
-	result, ok := m.LabelToCcInfo[label]
-	if !ok {
-		key := BuildMockBazelContextResultKey(label, cfgKey.arch, cfgKey.osType, cfgKey.apexKey)
-		result, ok = m.LabelToCcInfo[key]
-		if !ok {
-			return cquery.CcInfo{}, fmt.Errorf("no target with label %q in LabelToCcInfo", label)
-		}
-	}
-	return result, nil
-}
-
-func (m MockBazelContext) GetApexInfo(label string, _ configKey) (cquery.ApexInfo, error) {
-	result, ok := m.LabelToApexInfo[label]
-	if !ok {
-		return cquery.ApexInfo{}, fmt.Errorf("no target with label %q in LabelToApexInfo", label)
-	}
-	return result, nil
-}
-
-func (m MockBazelContext) GetCcUnstrippedInfo(label string, _ configKey) (cquery.CcUnstrippedInfo, error) {
-	result, ok := m.LabelToCcBinary[label]
-	if !ok {
-		return cquery.CcUnstrippedInfo{}, fmt.Errorf("no target with label %q in LabelToCcBinary", label)
-	}
-	return result, nil
-}
-
-func (m MockBazelContext) GetPrebuiltFileInfo(label string, _ configKey) (cquery.PrebuiltFileInfo, error) {
-	result, ok := m.LabelToPrebuiltFileInfo[label]
-	if !ok {
-		return cquery.PrebuiltFileInfo{}, fmt.Errorf("no target with label %q in LabelToPrebuiltFileInfo", label)
-	}
-	return result, nil
-}
-
-func (m MockBazelContext) InvokeBazel(_ Config, _ invokeBazelContext) error {
-	panic("unimplemented")
-}
-
-func (m MockBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
-	return true
-}
-
-func (m MockBazelContext) OutputBase() string { return m.OutputBaseDir }
-
-func (m MockBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
-	return []*bazel.BuildStatement{}
-}
-
-func (m MockBazelContext) AqueryDepsets() []bazel.AqueryDepset {
-	return []bazel.AqueryDepset{}
-}
-
-var _ BazelContext = MockBazelContext{}
-
-func BuildMockBazelContextRequestKey(label string, request cqueryRequest, arch string, osType OsType, apexKey ApexConfigKey) string {
-	cfgKey := configKey{
-		arch:    arch,
-		osType:  osType,
-		apexKey: apexKey,
-	}
-
-	return strings.Join([]string{label, request.Name(), cfgKey.String()}, "_")
-}
-
-func BuildMockBazelContextResultKey(label string, arch string, osType OsType, apexKey ApexConfigKey) string {
-	cfgKey := configKey{
-		arch:    arch,
-		osType:  osType,
-		apexKey: apexKey,
-	}
-
-	return strings.Join([]string{label, cfgKey.String()}, "_")
-}
-
-func (bazelCtx *mixedBuildBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) {
-	key := makeCqueryKey(label, requestType, cfgKey)
-	bazelCtx.requestMutex.Lock()
-	defer bazelCtx.requestMutex.Unlock()
-
-	// Insert key into requests, maintaining the sort, and only if it's not duplicate.
-	keyString := key.String()
-	foundEqual := false
-	notLessThanKeyString := func(i int) bool {
-		s := bazelCtx.requests[i].String()
-		v := strings.Compare(s, keyString)
-		if v == 0 {
-			foundEqual = true
-		}
-		return v >= 0
-	}
-	targetIndex := sort.Search(len(bazelCtx.requests), notLessThanKeyString)
-	if foundEqual {
-		return
-	}
-
-	if targetIndex == len(bazelCtx.requests) {
-		bazelCtx.requests = append(bazelCtx.requests, key)
-	} else {
-		bazelCtx.requests = append(bazelCtx.requests[:targetIndex+1], bazelCtx.requests[targetIndex:]...)
-		bazelCtx.requests[targetIndex] = key
-	}
-}
-
-func (bazelCtx *mixedBuildBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, error) {
-	key := makeCqueryKey(label, cquery.GetOutputFiles, cfgKey)
-	if rawString, ok := bazelCtx.results[key]; ok {
-		bazelOutput := strings.TrimSpace(rawString)
-
-		return cquery.GetOutputFiles.ParseResult(bazelOutput), nil
-	}
-	return nil, fmt.Errorf("no bazel response found for %v", key)
-}
-
-func (bazelCtx *mixedBuildBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) {
-	key := makeCqueryKey(label, cquery.GetCcInfo, cfgKey)
-	if rawString, ok := bazelCtx.results[key]; ok {
-		bazelOutput := strings.TrimSpace(rawString)
-		return cquery.GetCcInfo.ParseResult(bazelOutput)
-	}
-	return cquery.CcInfo{}, fmt.Errorf("no bazel response found for %v", key)
-}
-
-func (bazelCtx *mixedBuildBazelContext) GetApexInfo(label string, cfgKey configKey) (cquery.ApexInfo, error) {
-	key := makeCqueryKey(label, cquery.GetApexInfo, cfgKey)
-	if rawString, ok := bazelCtx.results[key]; ok {
-		return cquery.GetApexInfo.ParseResult(strings.TrimSpace(rawString))
-	}
-	return cquery.ApexInfo{}, fmt.Errorf("no bazel response found for %v", key)
-}
-
-func (bazelCtx *mixedBuildBazelContext) GetCcUnstrippedInfo(label string, cfgKey configKey) (cquery.CcUnstrippedInfo, error) {
-	key := makeCqueryKey(label, cquery.GetCcUnstrippedInfo, cfgKey)
-	if rawString, ok := bazelCtx.results[key]; ok {
-		return cquery.GetCcUnstrippedInfo.ParseResult(strings.TrimSpace(rawString))
-	}
-	return cquery.CcUnstrippedInfo{}, fmt.Errorf("no bazel response for %s", key)
-}
-
-func (bazelCtx *mixedBuildBazelContext) GetPrebuiltFileInfo(label string, cfgKey configKey) (cquery.PrebuiltFileInfo, error) {
-	key := makeCqueryKey(label, cquery.GetPrebuiltFileInfo, cfgKey)
-	if rawString, ok := bazelCtx.results[key]; ok {
-		return cquery.GetPrebuiltFileInfo.ParseResult(strings.TrimSpace(rawString))
-	}
-	return cquery.PrebuiltFileInfo{}, fmt.Errorf("no bazel response for %s", key)
-}
-
-func AddToStringSet(set map[string]bool, items []string) {
-	for _, item := range items {
-		set[item] = true
-	}
-}
-
-func GetBazelEnabledAndDisabledModules(buildMode SoongBuildMode, forceEnabled map[string]struct{}) (map[string]bool, map[string]bool) {
-	disabledModules := map[string]bool{}
-	enabledModules := map[string]bool{}
-
-	switch buildMode {
-	case BazelProdMode:
-		AddToStringSet(enabledModules, allowlists.ProdMixedBuildsEnabledList)
-		for enabledAdHocModule := range forceEnabled {
-			enabledModules[enabledAdHocModule] = true
-		}
-	case BazelStagingMode:
-		// Staging mode includes all prod modules plus all staging modules.
-		AddToStringSet(enabledModules, allowlists.ProdMixedBuildsEnabledList)
-		AddToStringSet(enabledModules, allowlists.StagingMixedBuildsEnabledList)
-		for enabledAdHocModule := range forceEnabled {
-			enabledModules[enabledAdHocModule] = true
-		}
-	default:
-		panic("Expected BazelProdMode or BazelStagingMode")
-	}
-	return enabledModules, disabledModules
-}
-
-func GetBazelEnabledModules(buildMode SoongBuildMode) []string {
-	enabledModules, disabledModules := GetBazelEnabledAndDisabledModules(buildMode, nil)
-	enabledList := make([]string, 0, len(enabledModules))
-	for module := range enabledModules {
-		if !disabledModules[module] {
-			enabledList = append(enabledList, module)
-		}
-	}
-	sort.Strings(enabledList)
-	return enabledList
-}
-
-func NewBazelContext(c *config) (BazelContext, error) {
-	if c.BuildMode != BazelProdMode && c.BuildMode != BazelStagingMode {
-		return noopBazelContext{}, nil
-	}
-
-	enabledModules, disabledModules := GetBazelEnabledAndDisabledModules(c.BuildMode, c.BazelModulesForceEnabledByFlag())
-
-	paths := bazelPaths{
-		soongOutDir: c.soongOutDir,
-	}
-	var missing []string
-	vars := []struct {
-		name string
-		ptr  *string
-
-		// True if the environment variable needs to be tracked so that changes to the variable
-		// cause the ninja file to be regenerated, false otherwise. False should only be set for
-		// environment variables that have no effect on the generated ninja file.
-		track bool
-	}{
-		{"BAZEL_HOME", &paths.homeDir, true},
-		{"BAZEL_PATH", &paths.bazelPath, true},
-		{"BAZEL_OUTPUT_BASE", &paths.outputBase, true},
-		{"BAZEL_WORKSPACE", &paths.workspaceDir, true},
-		{"BAZEL_METRICS_DIR", &paths.metricsDir, false},
-		{"BAZEL_DEPS_FILE", &paths.bazelDepsFile, true},
-	}
-	for _, v := range vars {
-		if v.track {
-			if s := c.Getenv(v.name); len(s) > 1 {
-				*v.ptr = s
-				continue
-			}
-		} else if s, ok := c.env[v.name]; ok {
-			*v.ptr = s
-		} else {
-			missing = append(missing, v.name)
-		}
-	}
-	if len(missing) > 0 {
-		return nil, fmt.Errorf("missing required env vars to use bazel: %s", missing)
-	}
-
-	targetBuildVariant := "user"
-	if c.Eng() {
-		targetBuildVariant = "eng"
-	} else if c.Debuggable() {
-		targetBuildVariant = "userdebug"
-	}
-	targetProduct := "unknown"
-	if c.HasDeviceProduct() {
-		targetProduct = c.DeviceProduct()
-	}
-	dclaMixedBuildsEnabledList := []string{}
-	if c.BuildMode == BazelProdMode {
-		dclaMixedBuildsEnabledList = allowlists.ProdDclaMixedBuildsEnabledList
-	} else if c.BuildMode == BazelStagingMode {
-		dclaMixedBuildsEnabledList = append(allowlists.ProdDclaMixedBuildsEnabledList,
-			allowlists.StagingDclaMixedBuildsEnabledList...)
-	}
-	dclaEnabledModules := map[string]bool{}
-	AddToStringSet(dclaEnabledModules, dclaMixedBuildsEnabledList)
-	return &mixedBuildBazelContext{
-		bazelRunner:             &builtinBazelRunner{c.UseBazelProxy, absolutePath(c.outDir)},
-		paths:                   &paths,
-		bazelEnabledModules:     enabledModules,
-		bazelDisabledModules:    disabledModules,
-		bazelDclaEnabledModules: dclaEnabledModules,
-		targetProduct:           targetProduct,
-		targetBuildVariant:      targetBuildVariant,
-	}, nil
-}
-
-func (p *bazelPaths) BazelMetricsDir() string {
-	return p.metricsDir
-}
-
-func (context *mixedBuildBazelContext) IsModuleNameAllowed(moduleName string, withinApex bool) bool {
-	if context.bazelDisabledModules[moduleName] {
-		return false
-	}
-	if context.bazelEnabledModules[moduleName] {
-		return true
-	}
-	if withinApex && context.bazelDclaEnabledModules[moduleName] {
-		return true
-	}
-
-	return false
-}
-
-func pwdPrefix() string {
-	// Darwin doesn't have /proc
-	if runtime.GOOS != "darwin" {
-		return "PWD=/proc/self/cwd"
-	}
-	return ""
-}
-
-type bazelCommand struct {
-	command string
-	// query or label
-	expression string
-}
-
-type builtinBazelRunner struct {
-	useBazelProxy bool
-	outDir        string
-}
-
-// Issues the given bazel command with given build label and additional flags.
-// Returns (stdout, stderr, error). The first and second return values are strings
-// containing the stdout and stderr of the run command, and an error is returned if
-// the invocation returned an error code.
-func (r *builtinBazelRunner) issueBazelCommand(cmdRequest bazel.CmdRequest, paths *bazelPaths, eventHandler *metrics.EventHandler) (string, string, error) {
-	if r.useBazelProxy {
-		eventHandler.Begin("client_proxy")
-		defer eventHandler.End("client_proxy")
-		proxyClient := bazel.NewProxyClient(r.outDir)
-		resp, err := proxyClient.IssueCommand(cmdRequest)
-
-		if err != nil {
-			return "", "", err
-		}
-		if len(resp.ErrorString) > 0 {
-			return "", "", fmt.Errorf(resp.ErrorString)
-		}
-		return resp.Stdout, resp.Stderr, nil
-	} else {
-		eventHandler.Begin("bazel command")
-		defer eventHandler.End("bazel command")
-
-		stdout, stderr, err := bazel.ExecBazel(paths.bazelPath, absolutePath(paths.syntheticWorkspaceDir()), cmdRequest)
-		return string(stdout), string(stderr), err
-	}
-}
-
-func (context *mixedBuildBazelContext) createBazelCommand(config Config, runName bazel.RunName, command bazelCommand,
-	extraFlags ...string) bazel.CmdRequest {
-	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
-		panic("Unknown GOOS: " + runtime.GOOS)
-	}
-	cmdFlags := []string{
-		"--output_base=" + absolutePath(context.paths.outputBase),
-		command.command,
-		command.expression,
-		"--profile=" + shared.BazelMetricsFilename(context.paths, runName),
-
-		"--host_platform=@soong_injection//product_config_platforms:mixed_builds_product_" + runtime.GOOS + "_x86_64",
-		"--//build/bazel/product_config:target_build_variant=" + context.targetBuildVariant,
-		// Don't specify --platforms, because on some products/branches (like kernel-build-tools)
-		// the main platform for mixed_builds_product-variant doesn't exist because an arch isn't
-		// specified in product config. The derivative platforms that config_node transitions into
-		// will still work.
-
-		// Suppress noise
-		"--ui_event_filters=-INFO",
-		"--noshow_progress",
-		"--norun_validations",
-	}
-	cmdFlags = append(cmdFlags, extraFlags...)
-
-	extraEnv := []string{
-		"HOME=" + context.paths.homeDir,
-		pwdPrefix(),
-		"BUILD_DIR=" + absolutePath(context.paths.soongOutDir),
-		// Make OUT_DIR absolute here so build/bazel/bin/bazel uses the correct
-		// OUT_DIR at <root>/out, instead of <root>/out/soong/workspace/out.
-		"OUT_DIR=" + absolutePath(context.paths.outDir()),
-		// Disables local host detection of gcc; toolchain information is defined
-		// explicitly in BUILD files.
-		"BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1",
-	}
-	capturedEnvVars, err := starlark_import.GetStarlarkValue[[]string]("captured_env_vars")
-	if err != nil {
-		panic(err)
-	}
-	for _, envvar := range capturedEnvVars {
-		val := config.Getenv(envvar)
-		if val == "" {
-			continue
-		}
-		extraEnv = append(extraEnv, fmt.Sprintf("%s=%s", envvar, val))
-	}
-	envVars := append(os.Environ(), extraEnv...)
-
-	return bazel.CmdRequest{cmdFlags, envVars}
-}
-
-func (context *mixedBuildBazelContext) printableCqueryCommand(bazelCmd bazel.CmdRequest) string {
-	args := append([]string{context.paths.bazelPath}, bazelCmd.Argv...)
-	outputString := strings.Join(bazelCmd.Env, " ") + " \"" + strings.Join(args, "\" \"") + "\""
-	return outputString
-}
-
-func (context *mixedBuildBazelContext) mainBzlFileContents() []byte {
-	// TODO(cparsons): Define configuration transitions programmatically based
-	// on available archs.
-	contents := `
-#####################################################
-# This file is generated by soong_build. Do not edit.
-#####################################################
-def _config_node_transition_impl(settings, attr):
-    if attr.os == "android" and attr.arch == "target":
-        target = "mixed_builds_product"
-    else:
-        target = "mixed_builds_product_%s_%s" % (attr.os, attr.arch)
-    apex_name = ""
-    if attr.within_apex:
-        # //build/bazel/rules/apex:apex_name has to be set to a non_empty value,
-        # otherwise //build/bazel/rules/apex:non_apex will be true and the
-        # "-D__ANDROID_APEX__" compiler flag will be missing. Apex_name is used
-        # in some validation on bazel side which don't really apply in mixed
-        # build because soong will do the work, so we just set it to a fixed
-        # value here.
-        apex_name = "dcla_apex"
-    outputs = {
-        "//command_line_option:platforms": "@soong_injection//product_config_platforms:%s" % target,
-        "@//build/bazel/rules/apex:within_apex": attr.within_apex,
-        "@//build/bazel/rules/apex:min_sdk_version": attr.apex_sdk_version,
-        "@//build/bazel/rules/apex:apex_name": apex_name,
-        "@//build/bazel/rules/apex:api_domain": attr.api_domain,
-    }
-
-    return outputs
-
-_config_node_transition = transition(
-    implementation = _config_node_transition_impl,
-    inputs = [],
-    outputs = [
-        "//command_line_option:platforms",
-        "@//build/bazel/rules/apex:within_apex",
-        "@//build/bazel/rules/apex:min_sdk_version",
-        "@//build/bazel/rules/apex:apex_name",
-        "@//build/bazel/rules/apex:api_domain",
-    ],
-)
-
-def _passthrough_rule_impl(ctx):
-    return [DefaultInfo(files = depset(ctx.files.deps))]
-
-config_node = rule(
-    implementation = _passthrough_rule_impl,
-    attrs = {
-        "arch"    : attr.string(mandatory = True),
-        "os"      : attr.string(mandatory = True),
-        "within_apex" : attr.bool(default = False),
-        "apex_sdk_version" : attr.string(mandatory = True),
-        "api_domain" : attr.string(mandatory = True),
-        "deps"    : attr.label_list(cfg = _config_node_transition, allow_files = True),
-        "_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
-    },
-)
-
-
-# Rule representing the root of the build, to depend on all Bazel targets that
-# are required for the build. Building this target will build the entire Bazel
-# build tree.
-mixed_build_root = rule(
-    implementation = _passthrough_rule_impl,
-    attrs = {
-        "deps" : attr.label_list(),
-    },
-)
-
-def _phony_root_impl(ctx):
-    return []
-
-# Rule to depend on other targets but build nothing.
-# This is useful as follows: building a target of this rule will generate
-# symlink forests for all dependencies of the target, without executing any
-# actions of the build.
-phony_root = rule(
-    implementation = _phony_root_impl,
-    attrs = {"deps" : attr.label_list()},
-)
-`
-
-	return []byte(contents)
-}
-
-func (context *mixedBuildBazelContext) mainBuildFileContents() []byte {
-	// TODO(cparsons): Map label to attribute programmatically; don't use hard-coded
-	// architecture mapping.
-	formatString := `
-# This file is generated by soong_build. Do not edit.
-load(":main.bzl", "config_node", "mixed_build_root", "phony_root")
-
-%s
-
-mixed_build_root(name = "buildroot",
-    deps = [%s],
-    testonly = True, # Unblocks testonly deps.
-)
-
-phony_root(name = "phonyroot",
-    deps = [":buildroot"],
-    testonly = True, # Unblocks testonly deps.
-)
-`
-	configNodeFormatString := `
-config_node(name = "%s",
-    arch = "%s",
-    os = "%s",
-    within_apex = %s,
-    apex_sdk_version = "%s",
-    api_domain = "%s",
-    deps = [%s],
-    testonly = True, # Unblocks testonly deps.
-)
-`
-
-	configNodesSection := ""
-
-	labelsByConfig := map[string][]string{}
-
-	for _, val := range context.requests {
-		labelString := fmt.Sprintf("\"@%s\"", val.label)
-		configString := getConfigString(val)
-		labelsByConfig[configString] = append(labelsByConfig[configString], labelString)
-	}
-
-	// Configs need to be sorted to maintain determinism of the BUILD file.
-	sortedConfigs := make([]string, 0, len(labelsByConfig))
-	for val := range labelsByConfig {
-		sortedConfigs = append(sortedConfigs, val)
-	}
-	sort.Slice(sortedConfigs, func(i, j int) bool { return sortedConfigs[i] < sortedConfigs[j] })
-
-	allLabels := []string{}
-	for _, configString := range sortedConfigs {
-		labels := labelsByConfig[configString]
-		configTokens := strings.Split(configString, "|")
-		if len(configTokens) < 2 {
-			panic(fmt.Errorf("Unexpected config string format: %s", configString))
-		}
-		archString := configTokens[0]
-		osString := configTokens[1]
-		withinApex := "False"
-		apexSdkVerString := ""
-		apiDomainString := ""
-		if osString == "android" {
-			// api domains are meaningful only for device variants
-			apiDomainString = "system"
-		}
-		targetString := fmt.Sprintf("%s_%s", osString, archString)
-		if len(configTokens) > 2 {
-			targetString += "_" + configTokens[2]
-			if configTokens[2] == withinApexToString(true) {
-				withinApex = "True"
-			}
-		}
-		if len(configTokens) > 3 {
-			targetString += "_" + configTokens[3]
-			apexSdkVerString = configTokens[3]
-		}
-		if len(configTokens) > 4 {
-			apiDomainString = configTokens[4]
-			targetString += "_" + apiDomainString
-		}
-		allLabels = append(allLabels, fmt.Sprintf("\":%s\"", targetString))
-		labelsString := strings.Join(labels, ",\n            ")
-		configNodesSection += fmt.Sprintf(configNodeFormatString, targetString, archString, osString, withinApex, apexSdkVerString, apiDomainString,
-			labelsString)
-	}
-
-	return []byte(fmt.Sprintf(formatString, configNodesSection, strings.Join(allLabels, ",\n            ")))
-}
-
-func indent(original string) string {
-	result := ""
-	for _, line := range strings.Split(original, "\n") {
-		result += "  " + line + "\n"
-	}
-	return result
-}
-
-// Returns the file contents of the buildroot.cquery file that should be used for the cquery
-// expression in order to obtain information about buildroot and its dependencies.
-// The contents of this file depend on the mixedBuildBazelContext's requests; requests are enumerated
-// and grouped by their request type. The data retrieved for each label depends on its
-// request type.
-func (context *mixedBuildBazelContext) cqueryStarlarkFileContents() []byte {
-	requestTypeToCqueryIdEntries := map[cqueryRequest][]string{}
-	requestTypes := []cqueryRequest{}
-	for _, val := range context.requests {
-		cqueryId := getCqueryId(val)
-		mapEntryString := fmt.Sprintf("%q : True", cqueryId)
-		if _, seenKey := requestTypeToCqueryIdEntries[val.requestType]; !seenKey {
-			requestTypes = append(requestTypes, val.requestType)
-		}
-		requestTypeToCqueryIdEntries[val.requestType] =
-			append(requestTypeToCqueryIdEntries[val.requestType], mapEntryString)
-	}
-	labelRegistrationMapSection := ""
-	functionDefSection := ""
-	mainSwitchSection := ""
-
-	mapDeclarationFormatString := `
-%s = {
-  %s
-}
-`
-	functionDefFormatString := `
-def %s(target, id_string):
-%s
-`
-	mainSwitchSectionFormatString := `
-  if id_string in %s:
-    return id_string + ">>" + %s(target, id_string)
-`
-
-	for _, requestType := range requestTypes {
-		labelMapName := requestType.Name() + "_Labels"
-		functionName := requestType.Name() + "_Fn"
-		labelRegistrationMapSection += fmt.Sprintf(mapDeclarationFormatString,
-			labelMapName,
-			strings.Join(requestTypeToCqueryIdEntries[requestType], ",\n  "))
-		functionDefSection += fmt.Sprintf(functionDefFormatString,
-			functionName,
-			indent(requestType.StarlarkFunctionBody()))
-		mainSwitchSection += fmt.Sprintf(mainSwitchSectionFormatString,
-			labelMapName, functionName)
-	}
-
-	formatString := `
-# This file is generated by soong_build. Do not edit.
-
-{LABEL_REGISTRATION_MAP_SECTION}
-
-{FUNCTION_DEF_SECTION}
-
-def get_arch(target):
-  # TODO(b/199363072): filegroups and file targets aren't associated with any
-  # specific platform architecture in mixed builds. This is consistent with how
-  # Soong treats filegroups, but it may not be the case with manually-written
-  # filegroup BUILD targets.
-  buildoptions = build_options(target)
-
-  if buildoptions == None:
-    # File targets do not have buildoptions. File targets aren't associated with
-    #  any specific platform architecture in mixed builds, so use the host.
-    return "x86_64|linux"
-  platforms = buildoptions["//command_line_option:platforms"]
-  if len(platforms) != 1:
-    # An individual configured target should have only one platform architecture.
-    # Note that it's fine for there to be multiple architectures for the same label,
-    # but each is its own configured target.
-    fail("expected exactly 1 platform for " + str(target.label) + " but got " + str(platforms))
-  platform_name = platforms[0].name
-  if platform_name == "host":
-    return "HOST"
-  if not platform_name.startswith("mixed_builds_product"):
-    fail("expected platform name of the form 'mixed_builds_product_android_<arch>' or 'mixed_builds_product_linux_<arch>', but was " + str(platforms))
-  platform_name = platform_name.removeprefix("mixed_builds_product").removeprefix("_")
-  config_key = ""
-  if not platform_name:
-    config_key = "target|android"
-  elif platform_name.startswith("android_"):
-    config_key = platform_name.removeprefix("android_") + "|android"
-  elif platform_name.startswith("linux_"):
-    config_key = platform_name.removeprefix("linux_") + "|linux"
-  else:
-    fail("expected platform name of the form 'mixed_builds_product_android_<arch>' or 'mixed_builds_product_linux_<arch>', but was " + str(platforms))
-
-  within_apex = buildoptions.get("//build/bazel/rules/apex:within_apex")
-  apex_sdk_version = buildoptions.get("//build/bazel/rules/apex:min_sdk_version")
-  api_domain = buildoptions.get("//build/bazel/rules/apex:api_domain")
-
-  if within_apex:
-    config_key += "|within_apex"
-  if apex_sdk_version != None and len(apex_sdk_version) > 0:
-    config_key += "|" + apex_sdk_version
-  if api_domain != None and len(api_domain) > 0:
-    config_key += "|" + api_domain
-
-  return config_key
-
-def format(target):
-  id_string = str(target.label) + "|" + get_arch(target)
-
-  # TODO(b/248106697): Remove once Bazel is updated to always normalize labels.
-  if id_string.startswith("//"):
-    id_string = "@" + id_string
-
-  {MAIN_SWITCH_SECTION}
-
-  # This target was not requested via cquery, and thus must be a dependency
-  # of a requested target.
-  return id_string + ">>NONE"
-`
-	replacer := strings.NewReplacer(
-		"{LABEL_REGISTRATION_MAP_SECTION}", labelRegistrationMapSection,
-		"{FUNCTION_DEF_SECTION}", functionDefSection,
-		"{MAIN_SWITCH_SECTION}", mainSwitchSection)
-
-	return []byte(replacer.Replace(formatString))
-}
-
-// Returns a path containing build-related metadata required for interfacing
-// with Bazel. Example: out/soong/bazel.
-func (p *bazelPaths) intermediatesDir() string {
-	return filepath.Join(p.soongOutDir, "bazel")
-}
-
-// Returns the path where the contents of the @soong_injection repository live.
-// It is used by Soong to tell Bazel things it cannot over the command line.
-func (p *bazelPaths) injectedFilesDir() string {
-	return filepath.Join(p.soongOutDir, bazel.SoongInjectionDirName)
-}
-
-// Returns the path of the synthetic Bazel workspace that contains a symlink
-// forest composed the whole source tree and BUILD files generated by bp2build.
-func (p *bazelPaths) syntheticWorkspaceDir() string {
-	return filepath.Join(p.soongOutDir, "workspace")
-}
-
-// Returns the path to the top level out dir ($OUT_DIR).
-func (p *bazelPaths) outDir() string {
-	return filepath.Dir(p.soongOutDir)
-}
-
-const buildrootLabel = "@soong_injection//mixed_builds:buildroot"
-
-var (
-	cqueryCmd        = bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)}
-	aqueryCmd        = bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)}
-	buildCmd         = bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"}
-	allBazelCommands = []bazelCommand{aqueryCmd, cqueryCmd, buildCmd}
-)
-
-// This can't be part of bp2build_product_config.go because it would create a circular go package dependency
-func getLabelsForBazelSandwichPartitions(variables *ProductVariables) []string {
-	targetProduct := "unknown"
-	if variables.DeviceProduct != nil {
-		targetProduct = *variables.DeviceProduct
-	}
-	currentProductFolder := fmt.Sprintf("build/bazel/products/%s", targetProduct)
-	if len(variables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory) > 0 {
-		currentProductFolder = fmt.Sprintf("%s%s", variables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory, targetProduct)
-	}
-	var ret []string
-	if variables.PartitionVarsForBazelMigrationOnlyDoNotUse.PartitionQualifiedVariables["system"].BuildingImage {
-		ret = append(ret, "@//"+currentProductFolder+":system_image")
-		ret = append(ret, "@//"+currentProductFolder+":run_system_image_test")
-	}
-	return ret
-}
-
-func GetBazelSandwichCqueryRequests(config Config) ([]cqueryKey, error) {
-	partitionLabels := getLabelsForBazelSandwichPartitions(&config.productVariables)
-	result := make([]cqueryKey, 0, len(partitionLabels))
-	labelRegex := regexp.MustCompile("^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$")
-	// Note that bazel "targets" are different from soong "targets", the bazel targets are
-	// synonymous with soong modules, and soong targets are a configuration a module is built in.
-	for _, target := range partitionLabels {
-		match := labelRegex.FindStringSubmatch(target)
-		if match == nil {
-			return nil, fmt.Errorf("invalid label, must match `^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$`: %s", target)
-		}
-
-		// change this to config.BuildOSTarget if we add host targets
-		soongTarget := config.AndroidCommonTarget
-		if soongTarget.Os.Class != Device {
-			// kernel-build-tools seems to set the AndroidCommonTarget to a linux host
-			// target for some reason, disable device builds in that case.
-			continue
-		}
-
-		result = append(result, cqueryKey{
-			label:       target,
-			requestType: cquery.GetOutputFiles,
-			configKey: configKey{
-				arch:   soongTarget.Arch.String(),
-				osType: soongTarget.Os,
-			},
-		})
-	}
-	return result, nil
-}
-
-// QueueBazelSandwichCqueryRequests queues cquery requests for all the bazel labels in
-// bazel_sandwich_targets. These will later be given phony targets so that they can be built on the
-// command line.
-func (context *mixedBuildBazelContext) QueueBazelSandwichCqueryRequests(config Config) error {
-	requests, err := GetBazelSandwichCqueryRequests(config)
-	if err != nil {
-		return err
-	}
-	for _, request := range requests {
-		context.QueueBazelRequest(request.label, request.requestType, request.configKey)
-	}
-
-	return nil
-}
-
-// Issues commands to Bazel to receive results for all cquery requests
-// queued in the BazelContext.
-func (context *mixedBuildBazelContext) InvokeBazel(config Config, ctx invokeBazelContext) error {
-	eventHandler := ctx.GetEventHandler()
-	eventHandler.Begin("bazel")
-	defer eventHandler.End("bazel")
-
-	if metricsDir := context.paths.BazelMetricsDir(); metricsDir != "" {
-		if err := os.MkdirAll(metricsDir, 0777); err != nil {
-			return err
-		}
-	}
-	context.results = make(map[cqueryKey]string)
-	if err := context.runCquery(config, ctx); err != nil {
-		return err
-	}
-	if err := context.runAquery(config, ctx); err != nil {
-		return err
-	}
-	if err := context.generateBazelSymlinks(config, ctx); err != nil {
-		return err
-	}
-
-	// Clear requests.
-	context.requests = []cqueryKey{}
-	return nil
-}
-
-func (context *mixedBuildBazelContext) runCquery(config Config, ctx invokeBazelContext) error {
-	eventHandler := ctx.GetEventHandler()
-	eventHandler.Begin("cquery")
-	defer eventHandler.End("cquery")
-	soongInjectionPath := absolutePath(context.paths.injectedFilesDir())
-	mixedBuildsPath := filepath.Join(soongInjectionPath, "mixed_builds")
-	if _, err := os.Stat(mixedBuildsPath); os.IsNotExist(err) {
-		err = os.MkdirAll(mixedBuildsPath, 0777)
-		if err != nil {
-			return err
-		}
-	}
-	if err := writeFileBytesIfChanged(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666); err != nil {
-		return err
-	}
-	if err := writeFileBytesIfChanged(filepath.Join(mixedBuildsPath, "main.bzl"), context.mainBzlFileContents(), 0666); err != nil {
-		return err
-	}
-	if err := writeFileBytesIfChanged(filepath.Join(mixedBuildsPath, "BUILD.bazel"), context.mainBuildFileContents(), 0666); err != nil {
-		return err
-	}
-	cqueryFileRelpath := filepath.Join(context.paths.injectedFilesDir(), "buildroot.cquery")
-	if err := writeFileBytesIfChanged(absolutePath(cqueryFileRelpath), context.cqueryStarlarkFileContents(), 0666); err != nil {
-		return err
-	}
-
-	extraFlags := []string{"--output=starlark", "--starlark:file=" + absolutePath(cqueryFileRelpath)}
-	if Bool(config.productVariables.ClangCoverage) {
-		extraFlags = append(extraFlags, "--collect_code_coverage")
-	}
-
-	cqueryCmdRequest := context.createBazelCommand(config, bazel.CqueryBuildRootRunName, cqueryCmd, extraFlags...)
-	cqueryOutput, cqueryErrorMessage, cqueryErr := context.issueBazelCommand(cqueryCmdRequest, context.paths, eventHandler)
-	if cqueryErr != nil {
-		return cqueryErr
-	}
-	cqueryCommandPrint := fmt.Sprintf("cquery command line:\n  %s \n\n\n", context.printableCqueryCommand(cqueryCmdRequest))
-	if err := os.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), []byte(cqueryCommandPrint+cqueryOutput), 0666); err != nil {
-		return err
-	}
-	cqueryResults := map[string]string{}
-	for _, outputLine := range strings.Split(cqueryOutput, "\n") {
-		if strings.Contains(outputLine, ">>") {
-			splitLine := strings.SplitN(outputLine, ">>", 2)
-			cqueryResults[splitLine[0]] = splitLine[1]
-		}
-	}
-	for _, val := range context.requests {
-		if cqueryResult, ok := cqueryResults[getCqueryId(val)]; ok {
-			context.results[val] = cqueryResult
-		} else {
-			return fmt.Errorf("missing result for bazel target %s. query output: [%s], cquery err: [%s]",
-				getCqueryId(val), cqueryOutput, cqueryErrorMessage)
-		}
-	}
-	return nil
-}
-
-func writeFileBytesIfChanged(path string, contents []byte, perm os.FileMode) error {
-	oldContents, err := os.ReadFile(path)
-	if err != nil || !bytes.Equal(contents, oldContents) {
-		err = os.WriteFile(path, contents, perm)
-	}
-	return nil
-}
-
-func (context *mixedBuildBazelContext) runAquery(config Config, ctx invokeBazelContext) error {
-	eventHandler := ctx.GetEventHandler()
-	eventHandler.Begin("aquery")
-	defer eventHandler.End("aquery")
-	// Issue an aquery command to retrieve action information about the bazel build tree.
-	//
-	// Use jsonproto instead of proto; actual proto parsing would require a dependency on Bazel's
-	// proto sources, which would add a number of unnecessary dependencies.
-	extraFlags := []string{"--output=proto", "--include_file_write_contents"}
-	if Bool(config.productVariables.ClangCoverage) {
-		extraFlags = append(extraFlags, "--collect_code_coverage")
-		paths := make([]string, 0, 2)
-		if p := config.productVariables.NativeCoveragePaths; len(p) > 0 {
-			for i := range p {
-				// TODO(b/259404593) convert path wildcard to regex values
-				if p[i] == "*" {
-					p[i] = ".*"
-				}
-			}
-			paths = append(paths, JoinWithPrefixAndSeparator(p, "+", ","))
-		}
-		if p := config.productVariables.NativeCoverageExcludePaths; len(p) > 0 {
-			paths = append(paths, JoinWithPrefixAndSeparator(p, "-", ","))
-		}
-		if len(paths) > 0 {
-			extraFlags = append(extraFlags, "--instrumentation_filter="+strings.Join(paths, ","))
-		}
-	}
-	aqueryOutput, _, err := context.issueBazelCommand(context.createBazelCommand(config, bazel.AqueryBuildRootRunName, aqueryCmd,
-		extraFlags...), context.paths, eventHandler)
-	if err != nil {
-		return err
-	}
-	context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput), eventHandler)
-	return err
-}
-
-func (context *mixedBuildBazelContext) generateBazelSymlinks(config Config, ctx invokeBazelContext) error {
-	eventHandler := ctx.GetEventHandler()
-	eventHandler.Begin("symlinks")
-	defer eventHandler.End("symlinks")
-	// Issue a build command of the phony root to generate symlink forests for dependencies of the
-	// Bazel build. This is necessary because aquery invocations do not generate this symlink forest,
-	// but some of symlinks may be required to resolve source dependencies of the build.
-	_, _, err := context.issueBazelCommand(context.createBazelCommand(config, bazel.BazelBuildPhonyRootRunName, buildCmd), context.paths, eventHandler)
-	return err
-}
-
-func (context *mixedBuildBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
-	return context.buildStatements
-}
-
-func (context *mixedBuildBazelContext) AqueryDepsets() []bazel.AqueryDepset {
-	return context.depsets
-}
-
-func (context *mixedBuildBazelContext) OutputBase() string {
-	return context.paths.outputBase
-}
-
-// Singleton used for registering BUILD file ninja dependencies (needed
-// for correctness of builds which use Bazel.
-func BazelSingleton() Singleton {
-	return &bazelSingleton{}
-}
-
-type bazelSingleton struct{}
-
-func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
-	// bazelSingleton is a no-op if mixed-soong-bazel-builds are disabled.
-	if !ctx.Config().IsMixedBuildsEnabled() {
-		return
-	}
-
-	// Add ninja file dependencies for files which all bazel invocations require.
-	bazelBuildList := absolutePath(filepath.Join(
-		filepath.Dir(ctx.Config().moduleListFile), "bazel.list"))
-	ctx.AddNinjaFileDeps(bazelBuildList)
-
-	data, err := os.ReadFile(bazelBuildList)
-	if err != nil {
-		ctx.Errorf(err.Error())
-	}
-	files := strings.Split(strings.TrimSpace(string(data)), "\n")
-	for _, file := range files {
-		ctx.AddNinjaFileDeps(file)
-	}
-
-	depsetHashToDepset := map[string]bazel.AqueryDepset{}
-
-	for _, depset := range ctx.Config().BazelContext.AqueryDepsets() {
-		depsetHashToDepset[depset.ContentHash] = depset
-
-		var outputs []Path
-		var orderOnlies []Path
-		for _, depsetDepHash := range depset.TransitiveDepSetHashes {
-			otherDepsetName := bazelDepsetName(depsetDepHash)
-			outputs = append(outputs, PathForPhony(ctx, otherDepsetName))
-		}
-		for _, artifactPath := range depset.DirectArtifacts {
-			pathInBazelOut := PathForBazelOut(ctx, artifactPath)
-			if artifactPath == "bazel-out/volatile-status.txt" {
-				// See https://bazel.build/docs/user-manual#workspace-status
-				orderOnlies = append(orderOnlies, pathInBazelOut)
-			} else {
-				outputs = append(outputs, pathInBazelOut)
-			}
-		}
-		thisDepsetName := bazelDepsetName(depset.ContentHash)
-		ctx.Build(pctx, BuildParams{
-			Rule:      blueprint.Phony,
-			Outputs:   []WritablePath{PathForPhony(ctx, thisDepsetName)},
-			Implicits: outputs,
-			OrderOnly: orderOnlies,
-		})
-	}
-
-	executionRoot := path.Join(ctx.Config().BazelContext.OutputBase(), "execroot", "__main__")
-	bazelOutDir := path.Join(executionRoot, "bazel-out")
-	rel, err := filepath.Rel(ctx.Config().OutDir(), executionRoot)
-	if err != nil {
-		ctx.Errorf("%s", err.Error())
-	}
-	dotdotsToOutRoot := strings.Repeat("../", strings.Count(rel, "/")+1)
-	for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() {
-		// nil build statements are a valid case where we do not create an action because it is
-		// unnecessary or handled by other processing
-		if buildStatement == nil {
-			continue
-		}
-		if len(buildStatement.Command) > 0 {
-			rule := NewRuleBuilder(pctx, ctx)
-			intermediateDir, intermediateDirHash := intermediatePathForSboxMixedBuildAction(ctx, buildStatement)
-			if buildStatement.ShouldRunInSbox {
-				// Create a rule to build the output inside a sandbox
-				// This will create two changes of working directory
-				// 1. From ANDROID_BUILD_TOP to sbox top
-				// 2. From sbox top to a a synthetic mixed build execution root relative to it
-				// Finally, the outputs will be copied to intermediateDir
-				rule.Sbox(intermediateDir,
-					PathForOutput(ctx, "mixed_build_sbox_intermediates", intermediateDirHash+".textproto")).
-					SandboxInputs().
-					// Since we will cd to mixed build execution root, set sbox's out subdir to empty
-					// Without this, we will try to copy from $SBOX_SANDBOX_DIR/out/out/bazel/output/execroot/__main__/...
-					SetSboxOutDirDirAsEmpty()
-
-				// Create another set of rules to copy files from the intermediate dir to mixed build execution root
-				for _, outputPath := range buildStatement.OutputPaths {
-					ctx.Build(pctx, BuildParams{
-						Rule:   CpIfChanged,
-						Input:  intermediateDir.Join(ctx, executionRoot, outputPath),
-						Output: PathForBazelOut(ctx, outputPath),
-					})
-				}
-			}
-			createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx, depsetHashToDepset, dotdotsToOutRoot)
-
-			desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths)
-			rule.Build(fmt.Sprintf("bazel %d", index), desc)
-			continue
-		}
-		// Certain actions returned by aquery (for instance FileWrite) do not contain a command
-		// and thus require special treatment. If BuildStatement were an interface implementing
-		// buildRule(ctx) function, the code here would just call it.
-		// Unfortunately, the BuildStatement is defined in
-		// the 'bazel' package, which cannot depend on 'android' package where ctx is defined,
-		// because this would cause circular dependency. So, until we move aquery processing
-		// to the 'android' package, we need to handle special cases here.
-		switch buildStatement.Mnemonic {
-		case "RepoMappingManifest":
-			// It appears RepoMappingManifest files currently have
-			// non-deterministic content. Just emit empty files for
-			// now because they're unused.
-			out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
-			WriteFileRuleVerbatim(ctx, out, "")
-		case "FileWrite", "SourceSymlinkManifest":
-			out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
-			if buildStatement.IsExecutable {
-				WriteExecutableFileRuleVerbatim(ctx, out, buildStatement.FileContents)
-			} else {
-				WriteFileRuleVerbatim(ctx, out, buildStatement.FileContents)
-			}
-		case "SymlinkTree":
-			// build-runfiles arguments are the manifest file and the target directory
-			// where it creates the symlink tree according to this manifest (and then
-			// writes the MANIFEST file to it).
-			outManifest := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
-			outManifestPath := outManifest.String()
-			if !strings.HasSuffix(outManifestPath, "MANIFEST") {
-				panic("the base name of the symlink tree action should be MANIFEST, got " + outManifestPath)
-			}
-			outDir := filepath.Dir(outManifestPath)
-			ctx.Build(pctx, BuildParams{
-				Rule:        buildRunfilesRule,
-				Output:      outManifest,
-				Inputs:      []Path{PathForBazelOut(ctx, buildStatement.InputPaths[0])},
-				Description: "symlink tree for " + outDir,
-				Args: map[string]string{
-					"outDir": outDir,
-				},
-			})
-		default:
-			panic(fmt.Sprintf("unhandled build statement: %v", buildStatement))
-		}
-	}
-
-	// Create phony targets for all the bazel sandwich output files
-	requests, err := GetBazelSandwichCqueryRequests(ctx.Config())
-	if err != nil {
-		ctx.Errorf(err.Error())
-	}
-	for _, request := range requests {
-		files, err := ctx.Config().BazelContext.GetOutputFiles(request.label, request.configKey)
-		if err != nil {
-			ctx.Errorf(err.Error())
-		}
-		filesAsPaths := make([]Path, 0, len(files))
-		for _, file := range files {
-			filesAsPaths = append(filesAsPaths, PathForBazelOut(ctx, file))
-		}
-		ctx.Phony("bazel_sandwich", filesAsPaths...)
-	}
-	ctx.Phony("checkbuild", PathForPhony(ctx, "bazel_sandwich"))
-}
-
-// Returns a out dir path for a sandboxed mixed build action
-func intermediatePathForSboxMixedBuildAction(ctx PathContext, statement *bazel.BuildStatement) (OutputPath, string) {
-	// An artifact can be generated by a single buildstatement.
-	// Use the hash of the first artifact to create a unique path
-	uniqueDir := sha1.New()
-	uniqueDir.Write([]byte(statement.OutputPaths[0]))
-	uniqueDirHashString := hex.EncodeToString(uniqueDir.Sum(nil))
-	return PathForOutput(ctx, "mixed_build_sbox_intermediates", uniqueDirHashString), uniqueDirHashString
-}
-
-// Register bazel-owned build statements (obtained from the aquery invocation).
-func createCommand(cmd *RuleBuilderCommand, buildStatement *bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx BuilderContext, depsetHashToDepset map[string]bazel.AqueryDepset, dotdotsToOutRoot string) {
-	// executionRoot is the action cwd.
-	if buildStatement.ShouldRunInSbox {
-		// mkdir -p ensures that the directory exists when run via sbox
-		cmd.Text(fmt.Sprintf("mkdir -p '%s' && cd '%s' &&", executionRoot, executionRoot))
-	} else {
-		cmd.Text(fmt.Sprintf("cd '%s' &&", executionRoot))
-	}
-
-	// Remove old outputs, as some actions might not rerun if the outputs are detected.
-	if len(buildStatement.OutputPaths) > 0 {
-		cmd.Text("rm -rf") // -r because outputs can be Bazel dir/tree artifacts.
-		for _, outputPath := range buildStatement.OutputPaths {
-			cmd.Text(fmt.Sprintf("'%s'", outputPath))
-		}
-		cmd.Text("&&")
-	}
-
-	for _, pair := range buildStatement.Env {
-		// Set per-action env variables, if any.
-		cmd.Flag(pair.Key + "=" + pair.Value)
-	}
-
-	command := buildStatement.Command
-	command = strings.ReplaceAll(command, "{DOTDOTS_TO_OUTPUT_ROOT}", dotdotsToOutRoot)
-
-	// The actual Bazel action.
-	if len(command) > 16*1024 {
-		commandFile := PathForBazelOut(ctx, buildStatement.OutputPaths[0]+".sh")
-		WriteFileRule(ctx, commandFile, command)
-
-		cmd.Text("bash").Text(buildStatement.OutputPaths[0] + ".sh").Implicit(commandFile)
-	} else {
-		cmd.Text(command)
-	}
-
-	for _, outputPath := range buildStatement.OutputPaths {
-		if buildStatement.ShouldRunInSbox {
-			// The full path has three components that get joined together
-			// 1. intermediate output dir that `sbox` will place the artifacts at
-			// 2. mixed build execution root
-			// 3. artifact path returned by aquery
-			intermediateDir, _ := intermediatePathForSboxMixedBuildAction(ctx, buildStatement)
-			cmd.ImplicitOutput(intermediateDir.Join(ctx, executionRoot, outputPath))
-		} else {
-			cmd.ImplicitOutput(PathForBazelOut(ctx, outputPath))
-		}
-	}
-	for _, inputPath := range buildStatement.InputPaths {
-		cmd.Implicit(PathForBazelOut(ctx, inputPath))
-	}
-	for _, inputDepsetHash := range buildStatement.InputDepsetHashes {
-		if buildStatement.ShouldRunInSbox {
-			// Bazel depsets are phony targets that are used to group files.
-			// We need to copy the grouped files into the sandbox
-			ds, _ := depsetHashToDepset[inputDepsetHash]
-			cmd.Implicits(PathsForBazelOut(ctx, ds.DirectArtifacts))
-		} else {
-			otherDepsetName := bazelDepsetName(inputDepsetHash)
-			cmd.Implicit(PathForPhony(ctx, otherDepsetName))
-		}
-	}
-	for _, implicitPath := range buildStatement.ImplicitDeps {
-		cmd.Implicit(PathForArbitraryOutput(ctx, implicitPath))
-	}
-
-	if depfile := buildStatement.Depfile; depfile != nil {
-		// The paths in depfile are relative to `executionRoot`.
-		// Hence, they need to be corrected by replacing "bazel-out"
-		// with the full `bazelOutDir`.
-		// Otherwise, implicit outputs and implicit inputs under "bazel-out/"
-		// would be deemed missing.
-		// (Note: The regexp uses a capture group because the version of sed
-		//  does not support a look-behind pattern.)
-		replacement := fmt.Sprintf(`&& sed -i'' -E 's@(^|\s|")bazel-out/@\1%s/@g' '%s'`,
-			bazelOutDir, *depfile)
-		cmd.Text(replacement)
-		cmd.ImplicitDepFile(PathForBazelOut(ctx, *depfile))
-	}
-
-	for _, symlinkPath := range buildStatement.SymlinkPaths {
-		cmd.ImplicitSymlinkOutput(PathForBazelOut(ctx, symlinkPath))
-	}
-}
-
-func getCqueryId(key cqueryKey) string {
-	return key.label + "|" + getConfigString(key)
-}
-
-func getConfigString(key cqueryKey) string {
-	arch := key.configKey.arch
-	if len(arch) == 0 || arch == "common" {
-		if key.configKey.osType.Class == Device {
-			// For the generic Android, the expected result is "target|android", which
-			// corresponds to the product_variable_config named "android_target" in
-			// build/bazel/platforms/BUILD.bazel.
-			arch = "target"
-		} else {
-			// Use host platform, which is currently hardcoded to be x86_64.
-			arch = "x86_64"
-		}
-	}
-	osName := key.configKey.osType.Name
-	if len(osName) == 0 || osName == "common_os" || osName == "linux_glibc" || osName == "linux_musl" {
-		// Use host OS, which is currently hardcoded to be linux.
-		osName = "linux"
-	}
-	keyString := arch + "|" + osName
-	if key.configKey.apexKey.WithinApex {
-		keyString += "|" + withinApexToString(key.configKey.apexKey.WithinApex)
-	}
-
-	if len(key.configKey.apexKey.ApexSdkVersion) > 0 {
-		keyString += "|" + key.configKey.apexKey.ApexSdkVersion
-	}
-
-	if len(key.configKey.apexKey.ApiDomain) > 0 {
-		keyString += "|" + key.configKey.apexKey.ApiDomain
-	}
-
-	return keyString
-}
-
-func GetConfigKey(ctx BaseModuleContext) configKey {
-	return configKey{
-		// use string because Arch is not a valid key in go
-		arch:   ctx.Arch().String(),
-		osType: ctx.Os(),
-	}
-}
-
-func GetConfigKeyApexVariant(ctx BaseModuleContext, apexKey *ApexConfigKey) configKey {
-	configKey := GetConfigKey(ctx)
-
-	if apexKey != nil {
-		configKey.apexKey = ApexConfigKey{
-			WithinApex:     apexKey.WithinApex,
-			ApexSdkVersion: apexKey.ApexSdkVersion,
-			ApiDomain:      apexKey.ApiDomain,
-		}
-	}
-
-	return configKey
-}
-
-func bazelDepsetName(contentHash string) string {
-	return fmt.Sprintf("bazel_depset_%s", contentHash)
-}
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
deleted file mode 100644
index 9a3c8fc..0000000
--- a/android/bazel_handler_test.go
+++ /dev/null
@@ -1,426 +0,0 @@
-package android
-
-import (
-	"encoding/json"
-	"os"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"testing"
-
-	"android/soong/bazel"
-	"android/soong/bazel/cquery"
-	analysis_v2_proto "prebuilts/bazel/common/proto/analysis_v2"
-
-	"github.com/google/blueprint/metrics"
-	"google.golang.org/protobuf/proto"
-)
-
-var testConfig = TestConfig("out", nil, "", nil)
-
-type testInvokeBazelContext struct{}
-
-type mockBazelRunner struct {
-	testHelper *testing.T
-	// Stores mock behavior. If an issueBazelCommand request is made for command
-	// k, and {k:v} is present in this map, then the mock will return v.
-	bazelCommandResults map[bazelCommand]string
-	// Requests actually made of the mockBazelRunner with issueBazelCommand,
-	// keyed by the command they represent.
-	bazelCommandRequests map[bazelCommand]bazel.CmdRequest
-}
-
-func (r *mockBazelRunner) bazelCommandForRequest(cmdRequest bazel.CmdRequest) bazelCommand {
-	for _, arg := range cmdRequest.Argv {
-		for _, cmdType := range allBazelCommands {
-			if arg == cmdType.command {
-				return cmdType
-			}
-		}
-	}
-	r.testHelper.Fatalf("Unrecognized bazel request: %s", cmdRequest)
-	return cqueryCmd
-}
-
-func (r *mockBazelRunner) issueBazelCommand(cmdRequest bazel.CmdRequest, paths *bazelPaths, eventHandler *metrics.EventHandler) (string, string, error) {
-	command := r.bazelCommandForRequest(cmdRequest)
-	r.bazelCommandRequests[command] = cmdRequest
-	return r.bazelCommandResults[command], "", nil
-}
-
-func (t *testInvokeBazelContext) GetEventHandler() *metrics.EventHandler {
-	return &metrics.EventHandler{}
-}
-
-func TestRequestResultsAfterInvokeBazel(t *testing.T) {
-	label_foo := "@//foo:foo"
-	label_bar := "@//foo:bar"
-	apexKey := ApexConfigKey{
-		WithinApex:     true,
-		ApexSdkVersion: "29",
-		ApiDomain:      "myapex",
-	}
-	cfg_foo := configKey{"arm64_armv8-a", Android, apexKey}
-	cfg_bar := configKey{arch: "arm64_armv8-a", osType: Android}
-	cmd_results := []string{
-		`@//foo:foo|arm64_armv8-a|android|within_apex|29|myapex>>out/foo/foo.txt`,
-		`@//foo:bar|arm64_armv8-a|android>>out/foo/bar.txt`,
-	}
-	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{cqueryCmd: strings.Join(cmd_results, "\n")})
-
-	bazelContext.QueueBazelRequest(label_foo, cquery.GetOutputFiles, cfg_foo)
-	bazelContext.QueueBazelRequest(label_bar, cquery.GetOutputFiles, cfg_bar)
-	err := bazelContext.InvokeBazel(testConfig, &testInvokeBazelContext{})
-	if err != nil {
-		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
-	}
-	verifyCqueryResult(t, bazelContext, label_foo, cfg_foo, "out/foo/foo.txt")
-	verifyCqueryResult(t, bazelContext, label_bar, cfg_bar, "out/foo/bar.txt")
-}
-
-func verifyCqueryResult(t *testing.T, ctx *mixedBuildBazelContext, label string, cfg configKey, result string) {
-	g, err := ctx.GetOutputFiles(label, cfg)
-	if err != nil {
-		t.Errorf("Expected cquery results after running InvokeBazel(), but got err %v", err)
-	} else if w := []string{result}; !reflect.DeepEqual(w, g) {
-		t.Errorf("Expected output %s, got %s", w, g)
-	}
-}
-
-func TestInvokeBazelWritesBazelFiles(t *testing.T) {
-	bazelContext, baseDir := testBazelContext(t, map[bazelCommand]string{})
-	err := bazelContext.InvokeBazel(testConfig, &testInvokeBazelContext{})
-	if err != nil {
-		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
-	}
-	if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "main.bzl")); os.IsNotExist(err) {
-		t.Errorf("Expected main.bzl to exist, but it does not")
-	} else if err != nil {
-		t.Errorf("Unexpected error stating main.bzl %s", err)
-	}
-
-	if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "mixed_builds", "BUILD.bazel")); os.IsNotExist(err) {
-		t.Errorf("Expected BUILD.bazel to exist, but it does not")
-	} else if err != nil {
-		t.Errorf("Unexpected error stating BUILD.bazel %s", err)
-	}
-
-	if _, err := os.Stat(filepath.Join(baseDir, "soong_injection", "WORKSPACE.bazel")); os.IsNotExist(err) {
-		t.Errorf("Expected WORKSPACE.bazel to exist, but it does not")
-	} else if err != nil {
-		t.Errorf("Unexpected error stating WORKSPACE.bazel %s", err)
-	}
-}
-
-func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
-	type testCase struct {
-		input   string
-		command string
-	}
-
-	var testCases = []testCase{
-		{`
-{
- "artifacts": [
-   { "id": 1, "path_fragment_id": 1 },
-   { "id": 2, "path_fragment_id": 2 }],
- "actions": [{
-   "target_Id": 1,
-   "action_Key": "x",
-   "mnemonic": "x",
-   "arguments": ["touch", "foo"],
-   "input_dep_set_ids": [1],
-   "output_Ids": [1],
-   "primary_output_id": 1
- }],
- "dep_set_of_files": [
-   { "id": 1, "direct_artifact_ids": [1, 2] }],
- "path_fragments": [
-   { "id": 1, "label": "one" },
-   { "id": 2, "label": "two" }]
-}`,
-			"cd 'test/exec_root' && rm -rf 'one' && touch foo",
-		}, {`
-{
- "artifacts": [
-   { "id": 1, "path_fragment_id": 10 },
-   { "id": 2, "path_fragment_id": 20 }],
- "actions": [{
-   "target_Id": 100,
-   "action_Key": "x",
-   "mnemonic": "x",
-   "arguments": ["bogus", "command"],
-   "output_Ids": [1, 2],
-   "primary_output_id": 1
- }],
- "path_fragments": [
-   { "id": 10, "label": "one", "parent_id": 30 },
-   { "id": 20, "label": "one.d", "parent_id": 30 },
-   { "id": 30, "label": "parent" }]
-}`,
-			`cd 'test/exec_root' && rm -rf 'parent/one' && bogus command && sed -i'' -E 's@(^|\s|")bazel-out/@\1test/bazel_out/@g' 'parent/one.d'`,
-		},
-	}
-
-	for i, testCase := range testCases {
-		data, err := JsonToActionGraphContainer(testCase.input)
-		if err != nil {
-			t.Error(err)
-		}
-		bazelContext, _ := testBazelContext(t, map[bazelCommand]string{aqueryCmd: string(data)})
-
-		err = bazelContext.InvokeBazel(testConfig, &testInvokeBazelContext{})
-		if err != nil {
-			t.Fatalf("testCase #%d: did not expect error invoking Bazel, but got %s", i+1, err)
-		}
-
-		got := bazelContext.BuildStatementsToRegister()
-		if want := 1; len(got) != want {
-			t.Fatalf("expected %d registered build statements, but got %#v", want, got)
-		}
-
-		cmd := RuleBuilderCommand{}
-		ctx := builderContextForTests{PathContextForTesting(TestConfig("out", nil, "", nil))}
-		createCommand(&cmd, got[0], "test/exec_root", "test/bazel_out", ctx, map[string]bazel.AqueryDepset{}, "")
-		if actual, expected := cmd.buf.String(), testCase.command; expected != actual {
-			t.Errorf("expected: [%s], actual: [%s]", expected, actual)
-		}
-	}
-}
-
-func TestMixedBuildSandboxedAction(t *testing.T) {
-	input := `{
- "artifacts": [
-   { "id": 1, "path_fragment_id": 1 },
-   { "id": 2, "path_fragment_id": 2 }],
- "actions": [{
-   "target_Id": 1,
-   "action_Key": "x",
-   "mnemonic": "x",
-   "arguments": ["touch", "foo"],
-   "input_dep_set_ids": [1],
-   "output_Ids": [1],
-   "primary_output_id": 1
- }],
- "dep_set_of_files": [
-   { "id": 1, "direct_artifact_ids": [1, 2] }],
- "path_fragments": [
-   { "id": 1, "label": "one" },
-   { "id": 2, "label": "two" }]
-}`
-	data, err := JsonToActionGraphContainer(input)
-	if err != nil {
-		t.Error(err)
-	}
-	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{aqueryCmd: string(data)})
-
-	err = bazelContext.InvokeBazel(testConfig, &testInvokeBazelContext{})
-	if err != nil {
-		t.Fatalf("TestMixedBuildSandboxedAction did not expect error invoking Bazel, but got %s", err)
-	}
-
-	statement := bazelContext.BuildStatementsToRegister()[0]
-	statement.ShouldRunInSbox = true
-
-	cmd := RuleBuilderCommand{}
-	ctx := builderContextForTests{PathContextForTesting(TestConfig("out", nil, "", nil))}
-	createCommand(&cmd, statement, "test/exec_root", "test/bazel_out", ctx, map[string]bazel.AqueryDepset{}, "")
-	// Assert that the output is generated in an intermediate directory
-	// fe05bcdcdc4928012781a5f1a2a77cbb5398e106 is the sha1 checksum of "one"
-	if actual, expected := cmd.outputs[0].String(), "out/soong/mixed_build_sbox_intermediates/fe05bcdcdc4928012781a5f1a2a77cbb5398e106/test/exec_root/one"; expected != actual {
-		t.Errorf("expected: [%s], actual: [%s]", expected, actual)
-	}
-
-	// Assert the actual command remains unchanged inside the sandbox
-	if actual, expected := cmd.buf.String(), "mkdir -p 'test/exec_root' && cd 'test/exec_root' && rm -rf 'one' && touch foo"; expected != actual {
-		t.Errorf("expected: [%s], actual: [%s]", expected, actual)
-	}
-}
-
-func TestCoverageFlagsAfterInvokeBazel(t *testing.T) {
-	testConfig.productVariables.ClangCoverage = boolPtr(true)
-
-	testConfig.productVariables.NativeCoveragePaths = []string{"foo1", "foo2"}
-	testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1", "bar2"}
-	verifyAqueryContainsFlags(t, testConfig, "--collect_code_coverage", "--instrumentation_filter=+foo1,+foo2,-bar1,-bar2")
-
-	testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
-	testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
-	verifyAqueryContainsFlags(t, testConfig, "--collect_code_coverage", "--instrumentation_filter=+foo1,-bar1")
-
-	testConfig.productVariables.NativeCoveragePaths = []string{"foo1"}
-	testConfig.productVariables.NativeCoverageExcludePaths = nil
-	verifyAqueryContainsFlags(t, testConfig, "--collect_code_coverage", "--instrumentation_filter=+foo1")
-
-	testConfig.productVariables.NativeCoveragePaths = nil
-	testConfig.productVariables.NativeCoverageExcludePaths = []string{"bar1"}
-	verifyAqueryContainsFlags(t, testConfig, "--collect_code_coverage", "--instrumentation_filter=-bar1")
-
-	testConfig.productVariables.NativeCoveragePaths = []string{"*"}
-	testConfig.productVariables.NativeCoverageExcludePaths = nil
-	verifyAqueryContainsFlags(t, testConfig, "--collect_code_coverage", "--instrumentation_filter=+.*")
-
-	testConfig.productVariables.ClangCoverage = boolPtr(false)
-	verifyAqueryDoesNotContainSubstrings(t, testConfig, "collect_code_coverage", "instrumentation_filter")
-}
-
-func TestBazelRequestsSorted(t *testing.T) {
-	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
-
-	cfgKeyArm64Android := configKey{arch: "arm64_armv8-a", osType: Android}
-	cfgKeyArm64Linux := configKey{arch: "arm64_armv8-a", osType: Linux}
-	cfgKeyOtherAndroid := configKey{arch: "otherarch", osType: Android}
-
-	bazelContext.QueueBazelRequest("zzz", cquery.GetOutputFiles, cfgKeyArm64Android)
-	bazelContext.QueueBazelRequest("ccc", cquery.GetApexInfo, cfgKeyArm64Android)
-	bazelContext.QueueBazelRequest("duplicate", cquery.GetOutputFiles, cfgKeyArm64Android)
-	bazelContext.QueueBazelRequest("duplicate", cquery.GetOutputFiles, cfgKeyArm64Android)
-	bazelContext.QueueBazelRequest("xxx", cquery.GetOutputFiles, cfgKeyArm64Linux)
-	bazelContext.QueueBazelRequest("aaa", cquery.GetOutputFiles, cfgKeyArm64Android)
-	bazelContext.QueueBazelRequest("aaa", cquery.GetOutputFiles, cfgKeyOtherAndroid)
-	bazelContext.QueueBazelRequest("bbb", cquery.GetOutputFiles, cfgKeyOtherAndroid)
-
-	if len(bazelContext.requests) != 7 {
-		t.Error("Expected 7 request elements, but got", len(bazelContext.requests))
-	}
-
-	lastString := ""
-	for _, val := range bazelContext.requests {
-		thisString := val.String()
-		if thisString <= lastString {
-			t.Errorf("Requests are not ordered correctly. '%s' came before '%s'", lastString, thisString)
-		}
-		lastString = thisString
-	}
-}
-
-func TestIsModuleNameAllowed(t *testing.T) {
-	libDisabled := "lib_disabled"
-	libEnabled := "lib_enabled"
-	libDclaWithinApex := "lib_dcla_within_apex"
-	libDclaNonApex := "lib_dcla_non_apex"
-	libNotConverted := "lib_not_converted"
-
-	disabledModules := map[string]bool{
-		libDisabled: true,
-	}
-	enabledModules := map[string]bool{
-		libEnabled: true,
-	}
-	dclaEnabledModules := map[string]bool{
-		libDclaWithinApex: true,
-		libDclaNonApex:    true,
-	}
-
-	bazelContext := &mixedBuildBazelContext{
-		bazelEnabledModules:     enabledModules,
-		bazelDisabledModules:    disabledModules,
-		bazelDclaEnabledModules: dclaEnabledModules,
-	}
-
-	if bazelContext.IsModuleNameAllowed(libDisabled, true) {
-		t.Fatalf("%s shouldn't be allowed for mixed build", libDisabled)
-	}
-
-	if !bazelContext.IsModuleNameAllowed(libEnabled, true) {
-		t.Fatalf("%s should be allowed for mixed build", libEnabled)
-	}
-
-	if !bazelContext.IsModuleNameAllowed(libDclaWithinApex, true) {
-		t.Fatalf("%s should be allowed for mixed build", libDclaWithinApex)
-	}
-
-	if bazelContext.IsModuleNameAllowed(libDclaNonApex, false) {
-		t.Fatalf("%s shouldn't be allowed for mixed build", libDclaNonApex)
-	}
-
-	if bazelContext.IsModuleNameAllowed(libNotConverted, true) {
-		t.Fatalf("%s shouldn't be allowed for mixed build", libNotConverted)
-	}
-}
-
-func verifyAqueryContainsFlags(t *testing.T, config Config, expected ...string) {
-	t.Helper()
-	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
-
-	err := bazelContext.InvokeBazel(config, &testInvokeBazelContext{})
-	if err != nil {
-		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
-	}
-
-	sliceContains := func(slice []string, x string) bool {
-		for _, s := range slice {
-			if s == x {
-				return true
-			}
-		}
-		return false
-	}
-
-	aqueryArgv := bazelContext.bazelRunner.(*mockBazelRunner).bazelCommandRequests[aqueryCmd].Argv
-
-	for _, expectedFlag := range expected {
-		if !sliceContains(aqueryArgv, expectedFlag) {
-			t.Errorf("aquery does not contain expected flag %#v. Argv was: %#v", expectedFlag, aqueryArgv)
-		}
-	}
-}
-
-func verifyAqueryDoesNotContainSubstrings(t *testing.T, config Config, substrings ...string) {
-	t.Helper()
-	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
-
-	err := bazelContext.InvokeBazel(config, &testInvokeBazelContext{})
-	if err != nil {
-		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
-	}
-
-	sliceContainsSubstring := func(slice []string, substring string) bool {
-		for _, s := range slice {
-			if strings.Contains(s, substring) {
-				return true
-			}
-		}
-		return false
-	}
-
-	aqueryArgv := bazelContext.bazelRunner.(*mockBazelRunner).bazelCommandRequests[aqueryCmd].Argv
-
-	for _, substring := range substrings {
-		if sliceContainsSubstring(aqueryArgv, substring) {
-			t.Errorf("aquery contains unexpected substring %#v. Argv was: %#v", substring, aqueryArgv)
-		}
-	}
-}
-
-func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*mixedBuildBazelContext, string) {
-	t.Helper()
-	p := bazelPaths{
-		soongOutDir:  t.TempDir(),
-		outputBase:   "outputbase",
-		workspaceDir: "workspace_dir",
-	}
-	if _, exists := bazelCommandResults[aqueryCmd]; !exists {
-		bazelCommandResults[aqueryCmd] = ""
-	}
-	runner := &mockBazelRunner{
-		testHelper:           t,
-		bazelCommandResults:  bazelCommandResults,
-		bazelCommandRequests: map[bazelCommand]bazel.CmdRequest{},
-	}
-	return &mixedBuildBazelContext{
-		bazelRunner: runner,
-		paths:       &p,
-	}, p.soongOutDir
-}
-
-// Transform the json format to ActionGraphContainer
-func JsonToActionGraphContainer(inputString string) ([]byte, error) {
-	var aqueryProtoResult analysis_v2_proto.ActionGraphContainer
-	err := json.Unmarshal([]byte(inputString), &aqueryProtoResult)
-	if err != nil {
-		return []byte(""), err
-	}
-	data, _ := proto.Marshal(&aqueryProtoResult)
-	return data, err
-}
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
deleted file mode 100644
index f25803c..0000000
--- a/android/bazel_paths.go
+++ /dev/null
@@ -1,675 +0,0 @@
-// Copyright 2015 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"android/soong/bazel"
-
-	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
-)
-
-// bazel_paths contains methods to:
-//   * resolve Soong path and module references into bazel.LabelList
-//   * resolve Bazel path references into Soong-compatible paths
-//
-// There is often a similar method for Bazel as there is for Soong path handling and should be used
-// in similar circumstances
-//
-//   Bazel                                Soong
-//   ==============================================================
-//   BazelLabelForModuleSrc               PathForModuleSrc
-//   BazelLabelForModuleSrcExcludes       PathForModuleSrcExcludes
-//   BazelLabelForModuleDeps              n/a
-//   tbd                                  PathForSource
-//   tbd                                  ExistentPathsForSources
-//   PathForBazelOut                      PathForModuleOut
-//
-// Use cases:
-//  * Module contains a property (often tagged `android:"path"`) that expects paths *relative to the
-//    module directory*:
-//     * BazelLabelForModuleSrcExcludes, if the module also contains an excludes_<propname> property
-//     * BazelLabelForModuleSrc, otherwise
-//  * Converting references to other modules to Bazel Labels:
-//     BazelLabelForModuleDeps
-//  * Converting a path obtained from bazel_handler cquery results:
-//     PathForBazelOut
-//
-// NOTE: all Soong globs are expanded within Soong rather than being converted to a Bazel glob
-//       syntax. This occurs because Soong does not have a concept of crossing package boundaries,
-//       so the glob as computed by Soong may contain paths that cross package-boundaries. These
-//       would be unknowingly omitted if the glob were handled by Bazel. By expanding globs within
-//       Soong, we support identification and detection (within Bazel) use of paths that cross
-//       package boundaries.
-//
-// Path resolution:
-// * filepath/globs: resolves as itself or is converted to an absolute Bazel label (e.g.
-//   //path/to/dir:<filepath>) if path exists in a separate package or subpackage.
-// * references to other modules (using the ":name{.tag}" syntax). These resolve as a Bazel label
-//   for a target. If the Bazel target is in the local module directory, it will be returned
-//   relative to the current package (e.g.  ":<target>"). Otherwise, it will be returned as an
-//   absolute Bazel label (e.g.  "//path/to/dir:<target>"). If the reference to another module
-//   cannot be resolved,the function will panic. This is often due to the dependency not being added
-//   via an AddDependency* method.
-
-// BazelConversionContext is a minimal context interface to check if a module should be converted by bp2build,
-// with functions containing information to match against allowlists and denylists.
-// If a module is deemed to be convertible by bp2build, then it should rely on a
-// BazelConversionPathContext for more functions for dep/path features.
-type BazelConversionContext interface {
-	Config() Config
-
-	Module() Module
-	OtherModuleType(m blueprint.Module) string
-	OtherModuleName(m blueprint.Module) string
-	OtherModuleDir(m blueprint.Module) string
-	ModuleErrorf(format string, args ...interface{})
-}
-
-// A subset of the ModuleContext methods which are sufficient to resolve references to paths/deps in
-// order to form a Bazel-compatible label for conversion.
-type BazelConversionPathContext interface {
-	EarlyModulePathContext
-	BazelConversionContext
-
-	ModuleName() string
-	ModuleType() string
-	ModuleErrorf(fmt string, args ...interface{})
-	PropertyErrorf(property, fmt string, args ...interface{})
-	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
-	ModuleFromName(name string) (blueprint.Module, bool)
-	AddUnconvertedBp2buildDep(string)
-	AddMissingBp2buildDep(dep string)
-}
-
-// BazelLabelForModuleDeps expects a list of reference to other modules, ("<module>"
-// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
-// module within the given ctx.
-func BazelLabelForModuleDeps(ctx Bp2buildMutatorContext, modules []string) bazel.LabelList {
-	return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel, true)
-}
-
-// BazelLabelForModuleWholeDepsExcludes expects two lists: modules (containing modules to include in
-// the list), and excludes (modules to exclude from the list). Both of these should contain
-// references to other modules, ("<module>" or ":<module>"). It returns a Bazel-compatible label
-// list which corresponds to dependencies on the module within the given ctx, and the excluded
-// dependencies.  Prebuilt dependencies will be appended with _alwayslink so they can be handled as
-// whole static libraries.
-func BazelLabelForModuleDepsExcludes(ctx Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
-	return BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, BazelModuleLabel)
-}
-
-// BazelLabelForModuleDepsWithFn expects a list of reference to other modules, ("<module>"
-// or ":<module>") and applies moduleToLabelFn to determine and return a Bazel-compatible label
-// which corresponds to dependencies on the module within the given ctx.
-func BazelLabelForModuleDepsWithFn(ctx Bp2buildMutatorContext, modules []string,
-	moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string,
-	markAsDeps bool) bazel.LabelList {
-	var labels bazel.LabelList
-	// In some cases, a nil string list is different than an explicitly empty list.
-	if len(modules) == 0 && modules != nil {
-		labels.Includes = []bazel.Label{}
-		return labels
-	}
-	modules = FirstUniqueStrings(modules)
-	for _, module := range modules {
-		bpText := module
-		if m := SrcIsModule(module); m == "" {
-			module = ":" + module
-		}
-		if m, t := SrcIsModuleWithTag(module); m != "" {
-			l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn, markAsDeps)
-			if l != nil {
-				l.OriginalModuleName = bpText
-				labels.Includes = append(labels.Includes, *l)
-			}
-		} else {
-			ctx.ModuleErrorf("%q, is not a module reference", module)
-		}
-	}
-	return labels
-}
-
-// BazelLabelForModuleDepsExcludesWithFn expects two lists: modules (containing modules to include in the
-// list), and excludes (modules to exclude from the list). Both of these should contain references
-// to other modules, ("<module>" or ":<module>"). It applies moduleToLabelFn to determine and return a
-// Bazel-compatible label list which corresponds to dependencies on the module within the given ctx, and
-// the excluded dependencies.
-func BazelLabelForModuleDepsExcludesWithFn(ctx Bp2buildMutatorContext, modules, excludes []string,
-	moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string) bazel.LabelList {
-	moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn, true)
-	if len(excludes) == 0 {
-		return moduleLabels
-	}
-	excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn, false)
-	return bazel.LabelList{
-		Includes: moduleLabels.Includes,
-		Excludes: excludeLabels.Includes,
-	}
-}
-
-func BazelLabelForModuleSrcSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
-	if srcs := BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
-		return srcs[0]
-	}
-	return bazel.Label{}
-}
-
-func BazelLabelForModuleDepSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
-	if srcs := BazelLabelForModuleDepsExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
-		return srcs[0]
-	}
-	return bazel.Label{}
-}
-
-// BazelLabelForModuleSrc expects a list of path (relative to local module directory) and module
-// references (":<module>") and returns a bazel.LabelList{} containing the resolved references in
-// paths, relative to the local module, or Bazel-labels (absolute if in a different package or
-// relative if within the same package).
-// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
-// will have already been handled by the pathdeps mutator.
-func BazelLabelForModuleSrc(ctx Bp2buildMutatorContext, paths []string) bazel.LabelList {
-	return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
-}
-
-// BazelLabelForModuleSrc expects lists of path and excludes (relative to local module directory)
-// and module references (":<module>") and returns a bazel.LabelList{} containing the resolved
-// references in paths, minus those in excludes, relative to the local module, or Bazel-labels
-// (absolute if in a different package or relative if within the same package).
-// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
-// will have already been handled by the pathdeps mutator.
-func BazelLabelForModuleSrcExcludes(ctx Bp2buildMutatorContext, paths, excludes []string) bazel.LabelList {
-	excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil), false)
-	excluded := make([]string, 0, len(excludeLabels.Includes))
-	for _, e := range excludeLabels.Includes {
-		excluded = append(excluded, e.Label)
-	}
-	labels := expandSrcsForBazel(ctx, paths, excluded, true)
-	labels.Excludes = excludeLabels.Includes
-	labels = TransformSubpackagePaths(ctx.Config(), ctx.ModuleDir(), labels)
-	return labels
-}
-
-func BazelLabelForSrcPatternExcludes(ctx BazelConversionPathContext, dir, pattern string, excludes []string) bazel.LabelList {
-	topRelPaths, err := ctx.GlobWithDeps(filepath.Join(dir, pattern), excludes)
-	if err != nil {
-		ctx.ModuleErrorf("Could not search dir: %s for pattern %s due to %v\n", dir, pattern, err)
-	}
-	// An intermediate list of labels relative to `dir` that assumes that there no subpacakges beneath `dir`
-	dirRelLabels := []bazel.Label{}
-	for _, topRelPath := range topRelPaths {
-		dirRelPath := Rel(ctx, dir, topRelPath)
-		dirRelLabels = append(dirRelLabels, bazel.Label{Label: "./" + dirRelPath})
-	}
-	// Return the package boudary resolved labels
-	return TransformSubpackagePaths(ctx.Config(), dir, bazel.MakeLabelList(dirRelLabels))
-}
-
-// Returns true if a prefix + components[:i] is a package boundary.
-//
-// A package boundary is determined by a BUILD file in the directory. This can happen in 2 cases:
-//
-//  1. An Android.bp exists, which bp2build will always convert to a sibling BUILD file.
-//  2. An Android.bp doesn't exist, but a checked-in BUILD/BUILD.bazel file exists, and that file
-//     is allowlisted by the bp2build configuration to be merged into the symlink forest workspace.
-func isPackageBoundary(config Config, prefix string, components []string, componentIndex int) bool {
-	isSymlink := func(c Config, path string) bool {
-		f, err := c.fs.Lstat(path)
-		if err != nil {
-			// The file does not exist
-			return false
-		}
-		return f.Mode()&os.ModeSymlink == os.ModeSymlink
-	}
-	prefix = filepath.Join(prefix, filepath.Join(components[:componentIndex+1]...))
-	if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "Android.bp")); exists {
-		return true
-	} else if config.Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(prefix) || isSymlink(config, prefix) {
-		if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "BUILD")); exists {
-			return true
-		} else if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "BUILD.bazel")); exists {
-			return true
-		}
-	}
-
-	return false
-}
-
-// Transform a path (if necessary) to acknowledge package boundaries
-//
-// e.g. something like
-//
-//	async_safe/include/async_safe/CHECK.h
-//
-// might become
-//
-//	//bionic/libc/async_safe:include/async_safe/CHECK.h
-//
-// if the "async_safe" directory is actually a package and not just a directory.
-//
-// In particular, paths that extend into packages are transformed into absolute labels beginning with //.
-func transformSubpackagePath(cfg Config, dir string, path bazel.Label) bazel.Label {
-	var newPath bazel.Label
-
-	// Don't transform OriginalModuleName
-	newPath.OriginalModuleName = path.OriginalModuleName
-	// if it wasn't a module, store the original path. We may need the original path to replace
-	// references if it is actually in another package
-	if path.OriginalModuleName == "" {
-		newPath.OriginalModuleName = path.Label
-	}
-
-	if strings.HasPrefix(path.Label, "//") {
-		// Assume absolute labels are already correct (e.g. //path/to/some/package:foo.h)
-		newPath.Label = path.Label
-		return newPath
-	}
-	if strings.HasPrefix(path.Label, "./") {
-		// Drop "./" for consistent handling of paths.
-		// Specifically, to not let "." be considered a package boundary.
-		// Say `inputPath` is `x/Android.bp` and that file has some module
-		// with `srcs=["y/a.c", "z/b.c"]`.
-		// And say the directory tree is:
-		//     x
-		//     ├── Android.bp
-		//     ├── y
-		//     │   ├── a.c
-		//     │   └── Android.bp
-		//     └── z
-		//         └── b.c
-		// Then bazel equivalent labels in srcs should be:
-		//   //x/y:a.c, x/z/b.c
-		// The above should still be the case if `x/Android.bp` had
-		//   srcs=["./y/a.c", "./z/b.c"]
-		// However, if we didn't strip "./", we'd get
-		//   //x/./y:a.c, //x/.:z/b.c
-		path.Label = strings.TrimPrefix(path.Label, "./")
-	}
-	pathComponents := strings.Split(path.Label, "/")
-	newLabel := ""
-	foundPackageBoundary := false
-	// Check the deepest subdirectory first and work upwards
-	for i := len(pathComponents) - 1; i >= 0; i-- {
-		pathComponent := pathComponents[i]
-		var sep string
-		if !foundPackageBoundary && isPackageBoundary(cfg, dir, pathComponents, i) {
-			sep = ":"
-			foundPackageBoundary = true
-		} else {
-			sep = "/"
-		}
-		if newLabel == "" {
-			newLabel = pathComponent
-		} else {
-			newLabel = pathComponent + sep + newLabel
-		}
-	}
-	if foundPackageBoundary {
-		// Ensure paths end up looking like //bionic/... instead of //./bionic/...
-		moduleDir := dir
-		if strings.HasPrefix(moduleDir, ".") {
-			moduleDir = moduleDir[1:]
-		}
-		// Make the path into an absolute label (e.g. //bionic/libc/foo:bar.h instead of just foo:bar.h)
-		if moduleDir == "" {
-			newLabel = "//" + newLabel
-		} else {
-			newLabel = "//" + moduleDir + "/" + newLabel
-		}
-	}
-	newPath.Label = newLabel
-
-	return newPath
-}
-
-// Transform paths to acknowledge package boundaries
-// See transformSubpackagePath() for more information
-func TransformSubpackagePaths(cfg Config, dir string, paths bazel.LabelList) bazel.LabelList {
-	var newPaths bazel.LabelList
-	for _, include := range paths.Includes {
-		newPaths.Includes = append(newPaths.Includes, transformSubpackagePath(cfg, dir, include))
-	}
-	for _, exclude := range paths.Excludes {
-		newPaths.Excludes = append(newPaths.Excludes, transformSubpackagePath(cfg, dir, exclude))
-	}
-	return newPaths
-}
-
-// Converts root-relative Paths to a list of bazel.Label relative to the module in ctx.
-func RootToModuleRelativePaths(ctx BazelConversionPathContext, paths Paths) []bazel.Label {
-	var newPaths []bazel.Label
-	for _, path := range PathsWithModuleSrcSubDir(ctx, paths, "") {
-		s := path.Rel()
-		newPaths = append(newPaths, bazel.Label{Label: s})
-	}
-	return newPaths
-}
-
-var Bp2buildDepTag bp2buildDepTag
-
-type bp2buildDepTag struct {
-	blueprint.BaseDependencyTag
-}
-
-// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
-// directory and Bazel target labels, excluding those included in the excludes argument (which
-// should already be expanded to resolve references to Soong-modules). Valid elements of paths
-// include:
-//   - filepath, relative to local module directory, resolves as a filepath relative to the local
-//     source directory
-//   - glob, relative to the local module directory, resolves as filepath(s), relative to the local
-//     module directory. Because Soong does not have a concept of crossing package boundaries, the
-//     glob as computed by Soong may contain paths that cross package-boundaries that would be
-//     unknowingly omitted if the glob were handled by Bazel. To allow identification and detect
-//     (within Bazel) use of paths that cross package boundaries, we expand globs within Soong rather
-//     than converting Soong glob syntax to Bazel glob syntax. **Invalid for excludes.**
-//   - other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer
-//     or OutputFileProducer. These resolve as a Bazel label for a target. If the Bazel target is in
-//     the local module directory, it will be returned relative to the current package (e.g.
-//     ":<target>"). Otherwise, it will be returned as an absolute Bazel label (e.g.
-//     "//path/to/dir:<target>"). If the reference to another module cannot be resolved,the function
-//     will panic.
-//
-// Properties passed as the paths or excludes argument must have been annotated with struct tag
-// `android:"path"` so that dependencies on other modules will have already been handled by the
-// pathdeps mutator.
-func expandSrcsForBazel(ctx Bp2buildMutatorContext, paths, expandedExcludes []string, markAsDeps bool) bazel.LabelList {
-	if paths == nil {
-		return bazel.LabelList{}
-	}
-	labels := bazel.LabelList{
-		Includes: []bazel.Label{},
-	}
-
-	// expandedExcludes contain module-dir relative paths, but root-relative paths
-	// are needed for GlobFiles later.
-	var rootRelativeExpandedExcludes []string
-	for _, e := range expandedExcludes {
-		rootRelativeExpandedExcludes = append(rootRelativeExpandedExcludes, filepath.Join(ctx.ModuleDir(), e))
-	}
-
-	for _, p := range paths {
-		if m, tag := SrcIsModuleWithTag(p); m != "" {
-			l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel, markAsDeps)
-			if l != nil && !InList(l.Label, expandedExcludes) {
-				if strings.HasPrefix(m, "//") {
-					// this is a module in a soong namespace
-					// It appears as //<namespace>:<module_name> in srcs, and not ://<namespace>:<module_name>
-					l.OriginalModuleName = m
-				} else {
-					l.OriginalModuleName = fmt.Sprintf(":%s", m)
-				}
-				labels.Includes = append(labels.Includes, *l)
-			}
-		} else {
-			var expandedPaths []bazel.Label
-			if pathtools.IsGlob(p) {
-				// e.g. turn "math/*.c" in
-				// external/arm-optimized-routines to external/arm-optimized-routines/math/*.c
-				rootRelativeGlobPath := pathForModuleSrc(ctx, p).String()
-				expandedPaths = RootToModuleRelativePaths(ctx, GlobFiles(ctx, rootRelativeGlobPath, rootRelativeExpandedExcludes))
-			} else {
-				if !InList(p, expandedExcludes) {
-					expandedPaths = append(expandedPaths, bazel.Label{Label: p})
-				}
-			}
-			labels.Includes = append(labels.Includes, expandedPaths...)
-		}
-	}
-	return labels
-}
-
-// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
-// module. The label will be relative to the current directory if appropriate. The dependency must
-// already be resolved by either deps mutator or path deps mutator.
-func getOtherModuleLabel(ctx Bp2buildMutatorContext, dep, tag string,
-	labelFromModule func(BazelConversionPathContext, blueprint.Module) string,
-	markAsDep bool) *bazel.Label {
-	m, _ := ctx.ModuleFromName(dep)
-	// The module was not found in an Android.bp file, this is often due to:
-	//		* a limited manifest
-	//		* a required module not being converted from Android.mk
-	if m == nil {
-		ctx.AddMissingBp2buildDep(dep)
-		return &bazel.Label{
-			Label: ":" + dep + "__BP2BUILD__MISSING__DEP",
-		}
-	}
-	// Returns true if a dependency from the current module to the target module
-	// should be skipped; doing so is a hack to circumvent certain problematic
-	// scenarios that will be addressed in the future.
-	shouldSkipDep := func(dep string) bool {
-		// Don't count dependencies of "libc". This is a hack to circumvent the
-		// fact that, in a variantless build graph, "libc" has a dependency on itself.
-		if ctx.ModuleName() == "libc" {
-			return true
-		}
-
-		// TODO: b/303307672: Dependencies on this module happen to "work" because
-		// there is a source file with the same name as this module in the
-		// same directory. We should remove this hack and enforce the underlying
-		// module of this name is the actual one used.
-		if dep == "mke2fs.conf" {
-			return true
-		}
-
-		// TODO: b/303310285: Remove this special-casing once all dependencies of
-		// crtbegin_dynamic are convertible
-		if ctx.ModuleName() == "crtbegin_dynamic" {
-			return true
-		}
-
-		return false
-	}
-	if markAsDep && !shouldSkipDep(dep) {
-		ctx.AddDependency(ctx.Module(), Bp2buildDepTag, dep)
-	}
-	if !convertedToBazel(ctx, m) {
-		ctx.AddUnconvertedBp2buildDep(dep)
-	}
-	label := BazelModuleLabel(ctx, ctx.Module())
-	otherLabel := labelFromModule(ctx, m)
-
-	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
-	if (tag != "" && m.Name() == "framework-res") ||
-		(tag == ".generated_srcjars" && ctx.OtherModuleType(m) == "java_aconfig_library") {
-		otherLabel += tag
-	}
-
-	if samePackage(label, otherLabel) {
-		otherLabel = bazelShortLabel(otherLabel)
-	}
-
-	return &bazel.Label{
-		Label: otherLabel,
-	}
-}
-
-func BazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module) string {
-	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
-	if !convertedToBazel(ctx, module) || isGoModule(module) {
-		return bp2buildModuleLabel(ctx, module)
-	}
-	b, _ := module.(Bazelable)
-	return b.GetBazelLabel(ctx, module)
-}
-
-func bazelShortLabel(label string) string {
-	i := strings.Index(label, ":")
-	if i == -1 {
-		panic(fmt.Errorf("Could not find the ':' character in '%s', expected a fully qualified label.", label))
-	}
-	return label[i:]
-}
-
-func bazelPackage(label string) string {
-	i := strings.Index(label, ":")
-	if i == -1 {
-		panic(fmt.Errorf("Could not find the ':' character in '%s', expected a fully qualified label.", label))
-	}
-	return label[0:i]
-}
-
-func samePackage(label1, label2 string) bool {
-	return bazelPackage(label1) == bazelPackage(label2)
-}
-
-func bp2buildModuleLabel(ctx BazelConversionContext, module blueprint.Module) string {
-	moduleName := moduleNameWithPossibleOverride(ctx, module, ctx.OtherModuleName(module))
-	moduleDir := moduleDirWithPossibleOverride(ctx, module, ctx.OtherModuleDir(module))
-	if moduleDir == Bp2BuildTopLevel {
-		moduleDir = ""
-	}
-	if a, ok := module.(Module); ok && IsModulePrebuilt(a) {
-		moduleName = RemoveOptionalPrebuiltPrefix(moduleName)
-	}
-	return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
-}
-
-// BazelOutPath is a Bazel output path compatible to be used for mixed builds within Soong/Ninja.
-type BazelOutPath struct {
-	OutputPath
-}
-
-// ensure BazelOutPath implements Path
-var _ Path = BazelOutPath{}
-
-// ensure BazelOutPath implements genPathProvider
-var _ genPathProvider = BazelOutPath{}
-
-// ensure BazelOutPath implements objPathProvider
-var _ objPathProvider = BazelOutPath{}
-
-func (p BazelOutPath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleGenPath {
-	return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
-}
-
-func (p BazelOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
-	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
-}
-
-// PathForBazelOutRelative returns a BazelOutPath representing the path under an output directory dedicated to
-// bazel-owned outputs. Calling .Rel() on the result will give the input path as relative to the given
-// relativeRoot.
-func PathForBazelOutRelative(ctx PathContext, relativeRoot string, path string) BazelOutPath {
-	validatedPath, err := validatePath(filepath.Join("execroot", "__main__", path))
-	if err != nil {
-		reportPathError(ctx, err)
-	}
-	var relativeRootPath string
-	if pathComponents := strings.SplitN(path, "/", 4); len(pathComponents) >= 3 &&
-		pathComponents[0] == "bazel-out" && pathComponents[2] == "bin" {
-		// If the path starts with something like: bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/
-		// make it relative to that folder. bazel-out/volatile-status.txt is an example
-		// of something that starts with bazel-out but is not relative to the bin folder
-		relativeRootPath = filepath.Join("execroot", "__main__", pathComponents[0], pathComponents[1], pathComponents[2], relativeRoot)
-	} else {
-		relativeRootPath = filepath.Join("execroot", "__main__", relativeRoot)
-	}
-
-	var relPath string
-	if relPath, err = filepath.Rel(relativeRootPath, validatedPath); err != nil || strings.HasPrefix(relPath, "../") {
-		// We failed to make this path relative to execroot/__main__, fall back to a non-relative path
-		// One case where this happens is when path is ../bazel_tools/something
-		relativeRootPath = ""
-		relPath = validatedPath
-	}
-
-	outputPath := OutputPath{
-		basePath{"", ""},
-		ctx.Config().soongOutDir,
-		ctx.Config().BazelContext.OutputBase(),
-	}
-
-	return BazelOutPath{
-		// .withRel() appends its argument onto the current path, and only the most
-		// recently appended part is returned by outputPath.rel().
-		// So outputPath.rel() will return relPath.
-		OutputPath: outputPath.withRel(relativeRootPath).withRel(relPath),
-	}
-}
-
-// PathForBazelOut returns a BazelOutPath representing the path under an output directory dedicated to
-// bazel-owned outputs.
-func PathForBazelOut(ctx PathContext, path string) BazelOutPath {
-	return PathForBazelOutRelative(ctx, "", path)
-}
-
-// PathsForBazelOut returns a list of paths representing the paths under an output directory
-// dedicated to Bazel-owned outputs.
-func PathsForBazelOut(ctx PathContext, paths []string) Paths {
-	outs := make(Paths, 0, len(paths))
-	for _, p := range paths {
-		outs = append(outs, PathForBazelOut(ctx, p))
-	}
-	return outs
-}
-
-// BazelStringOrLabelFromProp splits a Soong module property that can be
-// either a string literal, path (with android:path tag) or a module reference
-// into separate bazel string or label attributes. Bazel treats string and label
-// attributes as distinct types, so this function categorizes a string property
-// into either one of them.
-//
-// e.g. apex.private_key = "foo.pem" can either refer to:
-//
-// 1. "foo.pem" in the current directory -> file target
-// 2. "foo.pem" module -> rule target
-// 3. "foo.pem" file in a different directory, prefixed by a product variable handled
-// in a bazel macro. -> string literal
-//
-// For the first two cases, they are defined using the label attribute. For the third case,
-// it's defined with the string attribute.
-func BazelStringOrLabelFromProp(
-	ctx Bp2buildMutatorContext,
-	propToDistinguish *string) (bazel.LabelAttribute, bazel.StringAttribute) {
-
-	var labelAttr bazel.LabelAttribute
-	var strAttr bazel.StringAttribute
-
-	if propToDistinguish == nil {
-		// nil pointer
-		return labelAttr, strAttr
-	}
-
-	prop := String(propToDistinguish)
-	if SrcIsModule(prop) != "" {
-		// If it's a module (SrcIsModule will return the module name), set the
-		// resolved label to the label attribute.
-		labelAttr.SetValue(BazelLabelForModuleDepSingle(ctx, prop))
-	} else {
-		// Not a module name. This could be a string literal or a file target in
-		// the current dir. Check if the path exists:
-		path := ExistentPathForSource(ctx, ctx.ModuleDir(), prop)
-
-		if path.Valid() && parentDir(path.String()) == ctx.ModuleDir() {
-			// If it exists and the path is relative to the current dir, resolve the bazel label
-			// for the _file target_ and set it to the label attribute.
-			//
-			// Resolution is necessary because this could be a file in a subpackage.
-			labelAttr.SetValue(BazelLabelForModuleSrcSingle(ctx, prop))
-		} else {
-			// Otherwise, treat it as a string literal and assign to the string attribute.
-			strAttr.Value = propToDistinguish
-		}
-	}
-
-	return labelAttr, strAttr
-}
diff --git a/android/bazel_paths_test.go b/android/bazel_paths_test.go
deleted file mode 100644
index bed719c..0000000
--- a/android/bazel_paths_test.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2022 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
-	"fmt"
-	"path/filepath"
-	"testing"
-
-	"android/soong/bazel"
-
-	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
-)
-
-type TestBazelPathContext struct{}
-
-func (*TestBazelPathContext) Config() Config {
-	cfg := NullConfig("out", "out/soong")
-	cfg.BazelContext = MockBazelContext{
-		OutputBaseDir: "out/bazel",
-	}
-	return cfg
-}
-
-func (*TestBazelPathContext) AddNinjaFileDeps(...string) {
-	panic("Unimplemented")
-}
-
-func TestPathForBazelOut(t *testing.T) {
-	ctx := &TestBazelPathContext{}
-	out := PathForBazelOut(ctx, "foo/bar/baz/boq.txt")
-	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/__main__/foo/bar/baz/boq.txt")
-	if out.String() != expectedPath {
-		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
-	}
-
-	expectedRelPath := "foo/bar/baz/boq.txt"
-	if out.Rel() != expectedRelPath {
-		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
-	}
-}
-
-func TestPathForBazelOutRelative(t *testing.T) {
-	ctx := &TestBazelPathContext{}
-	out := PathForBazelOutRelative(ctx, "foo/bar", "foo/bar/baz/boq.txt")
-
-	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/__main__/foo/bar/baz/boq.txt")
-	if out.String() != expectedPath {
-		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
-	}
-
-	expectedRelPath := "baz/boq.txt"
-	if out.Rel() != expectedRelPath {
-		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
-	}
-}
-
-func TestPathForBazelOutRelativeUnderBinFolder(t *testing.T) {
-	ctx := &TestBazelPathContext{}
-	out := PathForBazelOutRelative(ctx, "foo/bar", "bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/foo/bar/baz/boq.txt")
-
-	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/__main__/bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/foo/bar/baz/boq.txt")
-	if out.String() != expectedPath {
-		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
-	}
-
-	expectedRelPath := "baz/boq.txt"
-	if out.Rel() != expectedRelPath {
-		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
-	}
-}
-
-func TestPathForBazelOutOutsideOfExecroot(t *testing.T) {
-	ctx := &TestBazelPathContext{}
-	out := PathForBazelOut(ctx, "../bazel_tools/linux_x86_64-fastbuild/bin/tools/android/java_base_extras.jar")
-
-	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/bazel_tools/linux_x86_64-fastbuild/bin/tools/android/java_base_extras.jar")
-	if out.String() != expectedPath {
-		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
-	}
-
-	expectedRelPath := "execroot/bazel_tools/linux_x86_64-fastbuild/bin/tools/android/java_base_extras.jar"
-	if out.Rel() != expectedRelPath {
-		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
-	}
-}
-
-func TestPathForBazelOutRelativeWithParentDirectoryRoot(t *testing.T) {
-	ctx := &TestBazelPathContext{}
-	out := PathForBazelOutRelative(ctx, "../bazel_tools", "../bazel_tools/foo/bar/baz.sh")
-
-	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/bazel_tools/foo/bar/baz.sh")
-	if out.String() != expectedPath {
-		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
-	}
-
-	expectedRelPath := "foo/bar/baz.sh"
-	if out.Rel() != expectedRelPath {
-		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
-	}
-}
-
-type TestBazelConversionPathContext struct {
-	TestBazelConversionContext
-	moduleDir       string
-	cfg             Config
-	mockGlobResults *[]string
-}
-
-func (ctx *TestBazelConversionPathContext) AddNinjaFileDeps(...string) {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) GlobWithDeps(string, []string) ([]string, error) {
-	if ctx.mockGlobResults == nil {
-		return []string{}, fmt.Errorf("Set mock glob results first")
-	}
-	return *ctx.mockGlobResults, nil
-}
-
-func (ctx *TestBazelConversionPathContext) PropertyErrorf(string, string, ...interface{}) {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) GetDirectDep(string) (blueprint.Module, blueprint.DependencyTag) {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) ModuleFromName(string) (blueprint.Module, bool) {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) AddUnconvertedBp2buildDep(string) {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) AddMissingBp2buildDep(string) {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) Module() Module {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) Config() Config {
-	return ctx.cfg
-}
-
-func (ctx *TestBazelConversionPathContext) ModuleDir() string {
-	return ctx.moduleDir
-}
-
-func (ctx *TestBazelConversionPathContext) ModuleName() string {
-	panic("Unimplemented")
-}
-
-func (ctx *TestBazelConversionPathContext) ModuleType() string {
-	panic("Unimplemented")
-}
-
-func TestTransformSubpackagePath(t *testing.T) {
-	cfg := NullConfig("out", "out/soong")
-	cfg.fs = pathtools.MockFs(map[string][]byte{
-		"x/Android.bp":   nil,
-		"x/y/Android.bp": nil,
-	})
-
-	var ctx BazelConversionPathContext = &TestBazelConversionPathContext{
-		moduleDir: "x",
-		cfg:       cfg,
-	}
-	pairs := map[string]string{
-		"y/a.c":   "//x/y:a.c",
-		"./y/a.c": "//x/y:a.c",
-		"z/b.c":   "z/b.c",
-		"./z/b.c": "z/b.c",
-	}
-	for in, out := range pairs {
-		actual := transformSubpackagePath(ctx.Config(), ctx.ModuleDir(), bazel.Label{Label: in}).Label
-		if actual != out {
-			t.Errorf("expected:\n%v\nactual:\n%v", out, actual)
-		}
-	}
-}
-
-// Check that the files in a specific directory are returned with labels that respect package boundaries
-// Since the test uses a mock for GlobWithDeps, the params passed to BazelLabelForSrcPatternExcludes are no-ops
-func TestBazelLabelForSrcPatternExcludes(t *testing.T) {
-	cfg := NullConfig("out", "out/soong")
-	cfg.fs = pathtools.MockFs(map[string][]byte{
-		"x/Android.bp":   nil,
-		"x/y/Android.bp": nil,
-		// .proto files
-		"foo.proto":     nil,
-		"x/bar.proto":   nil,
-		"x/baz.proto":   nil,
-		"x/y/qux.proto": nil,
-	})
-
-	var ctx BazelConversionPathContext = &TestBazelConversionPathContext{
-		cfg: cfg,
-	}
-
-	// Root dir
-	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"foo.proto", "x/bar.proto", "x/baz.proto", "x/y/qux.proto"}
-	actualLabelsFromRoot := BazelLabelForSrcPatternExcludes(ctx, ".", "**/*.proto", []string{})
-	expectedLabelsAsString := []string{"foo.proto", "//x:bar.proto", "//x:baz.proto", "//x/y:qux.proto"}
-	for i, actual := range actualLabelsFromRoot.Includes {
-		AssertStringEquals(t, "Error in finding src labels relative to root directory", expectedLabelsAsString[i], actual.Label)
-	}
-
-	// x dir
-	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"x/bar.proto", "x/baz.proto", "x/y/qux.proto"}
-	actualLabelsFromRoot = BazelLabelForSrcPatternExcludes(ctx, "x", "**/*.proto", []string{})
-	expectedLabelsAsString = []string{"bar.proto", "baz.proto", "//x/y:qux.proto"}
-	for i, actual := range actualLabelsFromRoot.Includes {
-		AssertStringEquals(t, "Error in finding src labels relative to x directory", expectedLabelsAsString[i], actual.Label)
-	}
-
-	// y dir
-	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"x/y/qux.proto"}
-	actualLabelsFromRoot = BazelLabelForSrcPatternExcludes(ctx, "x/y", "**/*.proto", []string{})
-	expectedLabelsAsString = []string{"qux.proto"}
-	for i, actual := range actualLabelsFromRoot.Includes {
-		AssertStringEquals(t, "Error in finding src labels relative to x/y directory", expectedLabelsAsString[i], actual.Label)
-	}
-}
diff --git a/android/bazel_test.go b/android/bazel_test.go
deleted file mode 100644
index e0145b5..0000000
--- a/android/bazel_test.go
+++ /dev/null
@@ -1,592 +0,0 @@
-// Copyright 2021 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//	http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package android
-
-import (
-	"fmt"
-	"testing"
-
-	"android/soong/android/allowlists"
-	"android/soong/bazel"
-
-	"github.com/google/blueprint"
-	"github.com/google/blueprint/proptools"
-)
-
-func TestConvertAllModulesInPackage(t *testing.T) {
-	testCases := []struct {
-		prefixes   allowlists.Bp2BuildConfig
-		packageDir string
-	}{
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a/b": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a/b":   allowlists.Bp2BuildDefaultTrueRecursively,
-				"a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":     allowlists.Bp2BuildDefaultTrueRecursively,
-				"d/e/f": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":     allowlists.Bp2BuildDefaultFalse,
-				"a/b":   allowlists.Bp2BuildDefaultTrueRecursively,
-				"a/b/c": allowlists.Bp2BuildDefaultFalse,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":     allowlists.Bp2BuildDefaultTrueRecursively,
-				"a/b":   allowlists.Bp2BuildDefaultFalse,
-				"a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":   allowlists.Bp2BuildDefaultFalseRecursively,
-				"a/b": allowlists.Bp2BuildDefaultTrue,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":   allowlists.Bp2BuildDefaultFalseRecursively,
-				"a/b": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a/b/c",
-		},
-	}
-
-	for _, test := range testCases {
-		if ok, _ := bp2buildDefaultTrueRecursively(test.packageDir, test.prefixes); !ok {
-			t.Errorf("Expected to convert all modules in %s based on %v, but failed.", test.packageDir, test.prefixes)
-		}
-	}
-}
-
-func TestModuleOptIn(t *testing.T) {
-	testCases := []struct {
-		prefixes   allowlists.Bp2BuildConfig
-		packageDir string
-	}{
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a/b": allowlists.Bp2BuildDefaultFalse,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":   allowlists.Bp2BuildDefaultFalse,
-				"a/b": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a/b": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a", // opt-in by default
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":     allowlists.Bp2BuildDefaultTrueRecursively,
-				"d/e/f": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "foo/bar",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":     allowlists.Bp2BuildDefaultTrueRecursively,
-				"a/b":   allowlists.Bp2BuildDefaultFalse,
-				"a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
-			},
-			packageDir: "a/b",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":     allowlists.Bp2BuildDefaultFalse,
-				"a/b":   allowlists.Bp2BuildDefaultTrueRecursively,
-				"a/b/c": allowlists.Bp2BuildDefaultFalse,
-			},
-			packageDir: "a",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":   allowlists.Bp2BuildDefaultFalseRecursively,
-				"a/b": allowlists.Bp2BuildDefaultTrue,
-			},
-			packageDir: "a/b/c",
-		},
-		{
-			prefixes: allowlists.Bp2BuildConfig{
-				"a":   allowlists.Bp2BuildDefaultTrueRecursively,
-				"a/b": allowlists.Bp2BuildDefaultFalseRecursively,
-			},
-			packageDir: "a/b/c",
-		},
-	}
-
-	for _, test := range testCases {
-		if ok, _ := bp2buildDefaultTrueRecursively(test.packageDir, test.prefixes); ok {
-			t.Errorf("Expected to allow module opt-in in %s based on %v, but failed.", test.packageDir, test.prefixes)
-		}
-	}
-}
-
-type TestBazelModule struct {
-	bazel.TestModuleInfo
-	BazelModuleBase
-}
-
-var _ blueprint.Module = TestBazelModule{}
-
-func (m TestBazelModule) Name() string {
-	return m.TestModuleInfo.ModuleName
-}
-
-func (m TestBazelModule) GenerateBuildActions(blueprint.ModuleContext) {
-}
-
-type TestBazelConversionContext struct {
-	omc       bazel.OtherModuleTestContext
-	allowlist Bp2BuildConversionAllowlist
-	errors    []string
-}
-
-var _ bazelOtherModuleContext = &TestBazelConversionContext{}
-
-func (bcc *TestBazelConversionContext) OtherModuleType(m blueprint.Module) string {
-	return bcc.omc.OtherModuleType(m)
-}
-
-func (bcc *TestBazelConversionContext) OtherModuleName(m blueprint.Module) string {
-	return bcc.omc.OtherModuleName(m)
-}
-
-func (bcc *TestBazelConversionContext) OtherModuleDir(m blueprint.Module) string {
-	return bcc.omc.OtherModuleDir(m)
-}
-
-func (bcc *TestBazelConversionContext) ModuleErrorf(format string, args ...interface{}) {
-	bcc.errors = append(bcc.errors, fmt.Sprintf(format, args...))
-}
-
-func (bcc *TestBazelConversionContext) Config() Config {
-	return Config{
-		&config{
-			Bp2buildPackageConfig: bcc.allowlist,
-		},
-	}
-}
-
-var bazelableBazelModuleBase = BazelModuleBase{
-	bazelProperties: properties{
-		Bazel_module: BazelModuleProperties{
-			CanConvertToBazel: true,
-		},
-	},
-}
-
-func TestBp2BuildAllowlist(t *testing.T) {
-	testCases := []struct {
-		description    string
-		shouldConvert  bool
-		expectedErrors []string
-		module         TestBazelModule
-		allowlist      Bp2BuildConversionAllowlist
-	}{
-		{
-			description:   "allowlist enables module",
-			shouldConvert: true,
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        "dir1",
-				},
-				BazelModuleBase: bazelableBazelModuleBase,
-			},
-			allowlist: Bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-			},
-		},
-		{
-			description:    "module in name allowlist and type allowlist fails",
-			shouldConvert:  false,
-			expectedErrors: []string{"A module \"foo\" of type \"rule1\" cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert"},
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        "dir1",
-				},
-				BazelModuleBase: bazelableBazelModuleBase,
-			},
-			allowlist: Bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-				moduleTypeAlwaysConvert: map[string]bool{
-					"rule1": true,
-				},
-			},
-		},
-		{
-			description:    "module in allowlist and denylist fails",
-			shouldConvert:  false,
-			expectedErrors: []string{"a module \"foo\" cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert"},
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        "dir1",
-				},
-				BazelModuleBase: bazelableBazelModuleBase,
-			},
-			allowlist: Bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-				moduleDoNotConvert: map[string]bool{
-					"foo": true,
-				},
-			},
-		},
-		{
-			description:    "module allowlist and enabled directory",
-			shouldConvert:  false,
-			expectedErrors: []string{"A module cannot be in a directory marked Bp2BuildDefaultTrue or Bp2BuildDefaultTrueRecursively and also be in moduleAlwaysConvert. Directory: 'existing/build/dir' Module: 'foo'"},
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        "existing/build/dir",
-				},
-				BazelModuleBase: bazelableBazelModuleBase,
-			},
-			allowlist: Bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-				defaultConfig: allowlists.Bp2BuildConfig{
-					"existing/build/dir": allowlists.Bp2BuildDefaultTrue,
-				},
-			},
-		},
-		{
-			description:    "module allowlist and enabled subdirectory",
-			shouldConvert:  false,
-			expectedErrors: []string{"A module cannot be in a directory marked Bp2BuildDefaultTrue or Bp2BuildDefaultTrueRecursively and also be in moduleAlwaysConvert. Directory: 'existing/build/dir' Module: 'foo'"},
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        "existing/build/dir/subdir",
-				},
-				BazelModuleBase: bazelableBazelModuleBase,
-			},
-			allowlist: Bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-				defaultConfig: allowlists.Bp2BuildConfig{
-					"existing/build/dir": allowlists.Bp2BuildDefaultTrueRecursively,
-				},
-			},
-		},
-		{
-			description:   "module enabled in unit test short-circuits other allowlists",
-			shouldConvert: true,
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        ".",
-				},
-				BazelModuleBase: BazelModuleBase{
-					bazelProperties: properties{
-						Bazel_module: BazelModuleProperties{
-							CanConvertToBazel:  true,
-							Bp2build_available: proptools.BoolPtr(true),
-						},
-					},
-				},
-			},
-			allowlist: Bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-				moduleDoNotConvert: map[string]bool{
-					"foo": true,
-				},
-			},
-		},
-	}
-
-	for _, test := range testCases {
-		t.Run(test.description, func(t *testing.T) {
-			bcc := &TestBazelConversionContext{
-				omc: bazel.OtherModuleTestContext{
-					Modules: []bazel.TestModuleInfo{
-						test.module.TestModuleInfo,
-					},
-				},
-				allowlist: test.allowlist,
-			}
-
-			shouldConvert := test.module.shouldConvertWithBp2build(bcc,
-				shouldConvertParams{
-					module:     test.module.TestModuleInfo,
-					moduleDir:  test.module.TestModuleInfo.Dir,
-					moduleType: test.module.TestModuleInfo.Typ,
-					moduleName: test.module.TestModuleInfo.ModuleName,
-				},
-			)
-			if test.shouldConvert != shouldConvert {
-				t.Errorf("Module shouldConvert expected to be: %v, but was: %v", test.shouldConvert, shouldConvert)
-			}
-
-			errorsMatch := true
-			if len(test.expectedErrors) != len(bcc.errors) {
-				errorsMatch = false
-			} else {
-				for i, err := range test.expectedErrors {
-					if err != bcc.errors[i] {
-						errorsMatch = false
-					}
-				}
-			}
-			if !errorsMatch {
-				t.Errorf("Expected errors to be: %v, but were: %v", test.expectedErrors, bcc.errors)
-			}
-		})
-	}
-}
-
-func TestBp2buildAllowList(t *testing.T) {
-	allowlist := GetBp2BuildAllowList()
-	for k, v := range allowlists.Bp2buildDefaultConfig {
-		if allowlist.defaultConfig[k] != v {
-			t.Errorf("bp2build default config of %s: expected: %v, got: %v", k, v, allowlist.defaultConfig[k])
-		}
-	}
-	for k, v := range allowlists.Bp2buildKeepExistingBuildFile {
-		if allowlist.keepExistingBuildFile[k] != v {
-			t.Errorf("bp2build keep existing build file of %s: expected: %v, got: %v", k, v, allowlist.keepExistingBuildFile[k])
-		}
-	}
-	for _, k := range allowlists.Bp2buildModuleTypeAlwaysConvertList {
-		if !allowlist.moduleTypeAlwaysConvert[k] {
-			t.Errorf("bp2build module type always convert of %s: expected: true, got: %v", k, allowlist.moduleTypeAlwaysConvert[k])
-		}
-	}
-	for _, k := range allowlists.Bp2buildModuleDoNotConvertList {
-		if !allowlist.moduleDoNotConvert[k] {
-			t.Errorf("bp2build module do not convert of %s: expected: true, got: %v", k, allowlist.moduleDoNotConvert[k])
-		}
-	}
-}
-
-func TestShouldKeepExistingBuildFileForDir(t *testing.T) {
-	allowlist := NewBp2BuildAllowlist()
-	// entry "a/b2/c2" is moot because of its parent "a/b2"
-	allowlist.SetKeepExistingBuildFile(map[string]bool{"a": false, "a/b1": false, "a/b2": true, "a/b1/c1": true, "a/b2/c2": false})
-	truths := []string{"a", "a/b1", "a/b2", "a/b1/c1", "a/b2/c", "a/b2/c2", "a/b2/c2/d"}
-	falsities := []string{"a1", "a/b", "a/b1/c"}
-	for _, dir := range truths {
-		if !allowlist.ShouldKeepExistingBuildFileForDir(dir) {
-			t.Errorf("%s expected TRUE but was FALSE", dir)
-		}
-	}
-	for _, dir := range falsities {
-		if allowlist.ShouldKeepExistingBuildFileForDir(dir) {
-			t.Errorf("%s expected FALSE but was TRUE", dir)
-		}
-	}
-}
-
-type mixedBuildModule struct {
-	ModuleBase
-	BazelModuleBase
-	props struct {
-		Deps                     []string
-		Mixed_build_incompatible *bool
-		QueuedBazelCall          bool `blueprint:"mutated"`
-	}
-}
-
-type mixedBuildModuleInfo struct {
-	QueuedBazelCall bool
-}
-
-var mixedBuildModuleProvider = blueprint.NewProvider(mixedBuildModuleInfo{})
-
-func mixedBuildModuleFactory() Module {
-	m := &mixedBuildModule{}
-	m.AddProperties(&m.props)
-	InitAndroidArchModule(m, HostAndDeviceDefault, MultilibBoth)
-	InitBazelModule(m)
-
-	return m
-}
-
-func (m *mixedBuildModule) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
-}
-
-func (m *mixedBuildModule) DepsMutator(ctx BottomUpMutatorContext) {
-	ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
-}
-
-func (m *mixedBuildModule) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
-
-func (m *mixedBuildModule) IsMixedBuildSupported(ctx BaseModuleContext) bool {
-	return !proptools.Bool(m.props.Mixed_build_incompatible)
-}
-
-func (m *mixedBuildModule) QueueBazelCall(ctx BaseModuleContext) {
-	m.props.QueuedBazelCall = true
-}
-
-func (m *mixedBuildModule) ProcessBazelQueryResponse(ctx ModuleContext) {
-	ctx.SetProvider(mixedBuildModuleProvider, mixedBuildModuleInfo{
-		QueuedBazelCall: m.props.QueuedBazelCall,
-	})
-}
-
-var prepareForMixedBuildTests = FixtureRegisterWithContext(func(ctx RegistrationContext) {
-	ctx.RegisterModuleType("deps", mixedBuildModuleFactory)
-	RegisterMixedBuildsMutator(ctx)
-})
-
-func TestMixedBuildsEnabledForType(t *testing.T) {
-	baseBp := `
-	deps {
-		name: "foo",
-		deps: ["bar"],
-		target: { windows: { enabled: true } },
-		%s
-	}
-`
-	depBp := `
-	deps {
-		name: "bar",
-		target: {
-			windows: {
-				enabled: true,
-			},
-		},
-	}
-`
-	testCases := []struct {
-		desc               string
-		variant            *string
-		missingDeps        bool
-		extraBpInfo        string
-		mixedBuildsEnabled bool
-	}{
-		{
-			desc:               "mixed builds works",
-			mixedBuildsEnabled: true,
-			extraBpInfo:        `bazel_module: { bp2build_available: true },`,
-		},
-		{
-			desc:               "missing deps",
-			missingDeps:        true,
-			mixedBuildsEnabled: false,
-			extraBpInfo:        `bazel_module: { bp2build_available: true },`,
-		},
-		{
-			desc:               "windows no mixed builds",
-			mixedBuildsEnabled: false,
-			variant:            proptools.StringPtr("windows_x86"),
-			extraBpInfo:        `bazel_module: { bp2build_available: true },`,
-		},
-		{
-			desc:               "mixed builds disabled by type",
-			mixedBuildsEnabled: false,
-			extraBpInfo: `mixed_build_incompatible: true,
-		bazel_module: { bp2build_available: true },`,
-		},
-		{
-			desc:               "mixed builds not bp2build available",
-			mixedBuildsEnabled: false,
-			extraBpInfo:        `bazel_module: { bp2build_available: false },`,
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.desc, func(t *testing.T) {
-			handlers := GroupFixturePreparers(
-				prepareForMixedBuildTests,
-				PrepareForTestWithArchMutator,
-				FixtureModifyConfig(func(config Config) {
-					config.BazelContext = MockBazelContext{
-						OutputBaseDir: "base",
-					}
-					config.Targets[Windows] = []Target{
-						{Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true},
-						{Windows, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", true},
-					}
-				}),
-			)
-			bp := fmt.Sprintf(baseBp, tc.extraBpInfo)
-			if tc.missingDeps {
-				handlers = GroupFixturePreparers(
-					handlers,
-					PrepareForTestWithAllowMissingDependencies,
-				)
-			} else {
-				bp += depBp
-			}
-			result := handlers.RunTestWithBp(t, bp)
-
-			variant := proptools.StringDefault(tc.variant, "android_arm64_armv8-a")
-
-			m := result.ModuleForTests("foo", variant)
-			mixedBuildModuleInfo := result.TestContext.ModuleProvider(m.Module(), mixedBuildModuleProvider).(mixedBuildModuleInfo)
-			if w, g := tc.mixedBuildsEnabled, mixedBuildModuleInfo.QueuedBazelCall; w != g {
-				t.Errorf("Expected mixed builds enabled %t, got mixed builds enabled %t", w, g)
-			}
-		})
-	}
-}
diff --git a/android/config.go b/android/config.go
index 9293505..0fec792 100644
--- a/android/config.go
+++ b/android/config.go
@@ -84,21 +84,13 @@
 	SoongOutDir    string
 	SoongVariables string
 
-	SymlinkForestMarker string
-	Bp2buildMarker      string
-	BazelQueryViewDir   string
-	ModuleGraphFile     string
-	ModuleActionsFile   string
-	DocFile             string
+	BazelQueryViewDir string
+	ModuleGraphFile   string
+	ModuleActionsFile string
+	DocFile           string
 
 	MultitreeBuild bool
 
-	BazelMode                bool
-	BazelModeStaging         bool
-	BazelForceEnabledModules string
-
-	UseBazelProxy bool
-
 	BuildFromSourceStub bool
 
 	EnsureAllowlistIntegrity bool
@@ -109,12 +101,6 @@
 	// Don't use bazel at all during module analysis.
 	AnalysisNoBazel SoongBuildMode = iota
 
-	// Symlink fores mode: merge two directory trees into a symlink forest
-	SymlinkForest
-
-	// Bp2build mode: Generate BUILD files from blueprint files and exit.
-	Bp2build
-
 	// Generate BUILD files which faithfully represent the dependency graph of
 	// blueprint modules. Individual BUILD targets will not, however, faitfhully
 	// express build semantics.
@@ -125,15 +111,6 @@
 
 	// Generate a documentation file for module type definitions and exit.
 	GenerateDocFile
-
-	// Use bazel during analysis of a few allowlisted build modules. The allowlist
-	// is considered "staging, as these are modules being prepared to be released
-	// into prod mode shortly after.
-	BazelStagingMode
-
-	// Use bazel during analysis of build modules from an allowlist carefully
-	// curated by the build team to be proven stable.
-	BazelProdMode
 )
 
 // SoongOutDir returns the build output directory for the configuration.
@@ -265,10 +242,6 @@
 	// Only available on configs created by TestConfig
 	TestProductVariables *ProductVariables
 
-	// A specialized context object for Bazel/Soong mixed builds and migration
-	// purposes.
-	BazelContext BazelContext
-
 	ProductVariablesFileName string
 
 	// BuildOS stores the OsType for the OS that the build is running on.
@@ -310,9 +283,7 @@
 	fs         pathtools.FileSystem
 	mockBpList string
 
-	BuildMode                      SoongBuildMode
-	Bp2buildPackageConfig          Bp2BuildConversionAllowlist
-	Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions
+	BuildMode SoongBuildMode
 
 	// If MultitreeBuild is true then this is one inner tree of a multitree
 	// build directed by the multitree orchestrator.
@@ -328,29 +299,6 @@
 
 	OncePer
 
-	// These fields are only used for metrics collection. A module should be added
-	// to these maps only if its implementation supports Bazel handling in mixed
-	// builds. A module being in the "enabled" list indicates that there is a
-	// variant of that module for which bazel-handling actually took place.
-	// A module being in the "disabled" list indicates that there is a variant of
-	// that module for which bazel-handling was denied.
-	mixedBuildsLock           sync.Mutex
-	mixedBuildEnabledModules  map[string]struct{}
-	mixedBuildDisabledModules map[string]struct{}
-
-	// These are modules to be built with Bazel beyond the allowlisted/build-mode
-	// specified modules. They are passed via the command-line flag
-	// "--bazel-force-enabled-modules"
-	bazelForceEnabledModules map[string]struct{}
-
-	// Names of Bazel targets as defined by BUILD files in the source tree,
-	// keyed by the directory in which they are defined.
-	bazelTargetsByDir map[string][]string
-
-	// If true, for any requests to Bazel, communicate with a Bazel proxy using
-	// unix sockets, instead of spawning Bazel as a subprocess.
-	UseBazelProxy bool
-
 	// If buildFromSourceStub is true then the Java API stubs are
 	// built from the source Java files, not the signature text files.
 	buildFromSourceStub bool
@@ -561,14 +509,10 @@
 		runGoTests:        cmdArgs.RunGoTests,
 		multilibConflicts: make(map[ArchType]bool),
 
-		moduleListFile:            cmdArgs.ModuleListFile,
-		fs:                        pathtools.NewOsFs(absSrcDir),
-		mixedBuildDisabledModules: make(map[string]struct{}),
-		mixedBuildEnabledModules:  make(map[string]struct{}),
-		bazelForceEnabledModules:  make(map[string]struct{}),
+		moduleListFile: cmdArgs.ModuleListFile,
+		fs:             pathtools.NewOsFs(absSrcDir),
 
 		MultitreeBuild: cmdArgs.MultitreeBuild,
-		UseBazelProxy:  cmdArgs.UseBazelProxy,
 
 		buildFromSourceStub: cmdArgs.BuildFromSourceStub,
 	}
@@ -661,28 +605,9 @@
 			config.BuildMode = mode
 		}
 	}
-	setBazelMode := func(arg bool, argName string, mode SoongBuildMode) {
-		if arg {
-			if config.BuildMode != AnalysisNoBazel {
-				fmt.Fprintf(os.Stderr, "buildMode is already set, illegal argument: %s", argName)
-				os.Exit(1)
-			}
-			config.BuildMode = mode
-		}
-	}
-	setBuildMode(cmdArgs.SymlinkForestMarker, SymlinkForest)
-	setBuildMode(cmdArgs.Bp2buildMarker, Bp2build)
 	setBuildMode(cmdArgs.BazelQueryViewDir, GenerateQueryView)
 	setBuildMode(cmdArgs.ModuleGraphFile, GenerateModuleGraph)
 	setBuildMode(cmdArgs.DocFile, GenerateDocFile)
-	setBazelMode(cmdArgs.BazelMode, "--bazel-mode", BazelProdMode)
-	setBazelMode(cmdArgs.BazelModeStaging, "--bazel-mode-staging", BazelStagingMode)
-
-	for _, module := range getForceEnabledModulesFromFlag(cmdArgs.BazelForceEnabledModules) {
-		config.bazelForceEnabledModules[module] = struct{}{}
-	}
-	config.BazelContext, err = NewBazelContext(config)
-	config.Bp2buildPackageConfig = GetBp2BuildAllowList()
 
 	// TODO(b/276958307): Replace the hardcoded list to a sdk_library local prop.
 	config.apiLibraries = map[string]struct{}{
@@ -719,13 +644,6 @@
 	return Config{config}, err
 }
 
-func getForceEnabledModulesFromFlag(forceEnabledFlag string) []string {
-	if forceEnabledFlag == "" {
-		return []string{}
-	}
-	return strings.Split(forceEnabledFlag, ",")
-}
-
 // mockFileSystem replaces all reads with accesses to the provided map of
 // filenames to contents stored as a byte slice.
 func (c *config) mockFileSystem(bp string, fs map[string][]byte) {
@@ -756,41 +674,6 @@
 	c.mockBpList = blueprint.MockModuleListFile
 }
 
-// TODO(b/265062549): Add a field to our collected (and uploaded) metrics which
-// describes a reason that we fell back to non-mixed builds.
-// Returns true if "Bazel builds" is enabled. In this mode, part of build
-// analysis is handled by Bazel.
-func (c *config) IsMixedBuildsEnabled() bool {
-	globalMixedBuildsSupport := c.Once(OnceKey{"globalMixedBuildsSupport"}, func() interface{} {
-		if c.productVariables.DeviceArch != nil && *c.productVariables.DeviceArch == "riscv64" {
-			return false
-		}
-		// Disable Bazel when Kythe is running
-		if c.EmitXrefRules() {
-			return false
-		}
-		if c.IsEnvTrue("GLOBAL_THINLTO") {
-			return false
-		}
-		if len(c.productVariables.SanitizeHost) > 0 {
-			return false
-		}
-		if len(c.productVariables.SanitizeDevice) > 0 {
-			return false
-		}
-		if len(c.productVariables.SanitizeDeviceDiag) > 0 {
-			return false
-		}
-		if len(c.productVariables.SanitizeDeviceArch) > 0 {
-			return false
-		}
-		return true
-	}).(bool)
-
-	bazelModeEnabled := c.BuildMode == BazelProdMode || c.BuildMode == BazelStagingMode
-	return globalMixedBuildsSupport && bazelModeEnabled
-}
-
 func (c *config) SetAllowMissingDependencies() {
 	c.productVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
 }
@@ -1066,8 +949,6 @@
 // DefaultAppTargetSdk returns the API level that platform apps are targeting.
 // This converts a codename to the exact ApiLevel it represents.
 func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel {
-	// This logic is replicated in starlark, if changing logic here update starlark code too
-	// https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=72;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
 	if Bool(c.productVariables.Platform_sdk_final) {
 		return c.PlatformSdkVersion()
 	}
@@ -1425,10 +1306,6 @@
 	return String(c.productVariables.PrebuiltHiddenApiDir)
 }
 
-func (c *config) BazelModulesForceEnabledByFlag() map[string]struct{} {
-	return c.bazelForceEnabledModules
-}
-
 func (c *config) IsVndkDeprecated() bool {
 	return !Bool(c.productVariables.KeepVndk)
 }
@@ -2041,38 +1918,6 @@
 	return Bool(c.productVariables.HostMusl)
 }
 
-func (c *config) GetMixedBuildsEnabledModules() map[string]struct{} {
-	return c.mixedBuildEnabledModules
-}
-
-func (c *config) GetMixedBuildsDisabledModules() map[string]struct{} {
-	return c.mixedBuildDisabledModules
-}
-
-func (c *config) LogMixedBuild(ctx BaseModuleContext, useBazel bool) {
-	moduleName := ctx.Module().Name()
-	c.mixedBuildsLock.Lock()
-	defer c.mixedBuildsLock.Unlock()
-	if useBazel {
-		c.mixedBuildEnabledModules[moduleName] = struct{}{}
-	} else {
-		c.mixedBuildDisabledModules[moduleName] = struct{}{}
-	}
-}
-
-func (c *config) HasBazelBuildTargetInSource(dir string, target string) bool {
-	for _, existingTarget := range c.bazelTargetsByDir[dir] {
-		if target == existingTarget {
-			return true
-		}
-	}
-	return false
-}
-
-func (c *config) SetBazelBuildFileTargets(bazelTargetsByDir map[string][]string) {
-	c.bazelTargetsByDir = bazelTargetsByDir
-}
-
 // ApiSurfaces directory returns the source path inside the api_surfaces repo
 // (relative to workspace root).
 func (c *config) ApiSurfacesDir(s ApiSurface, version string) string {
@@ -2106,12 +1951,6 @@
 	c.productVariables.Build_from_text_stub = boolPtr(b)
 }
 
-func (c *config) AddForceEnabledModules(forceEnabled []string) {
-	for _, forceEnabledModule := range forceEnabled {
-		c.bazelForceEnabledModules[forceEnabledModule] = struct{}{}
-	}
-}
-
 func (c *config) SetApiLibraries(libs []string) {
 	c.apiLibraries = make(map[string]struct{})
 	for _, lib := range libs {
@@ -2123,11 +1962,6 @@
 	return c.apiLibraries
 }
 
-// Bp2buildMode indicates whether the config is for bp2build mode of Soong
-func (c *config) Bp2buildMode() bool {
-	return c.BuildMode == Bp2build
-}
-
 func (c *deviceConfig) CheckVendorSeappViolations() bool {
 	return Bool(c.config.productVariables.CheckVendorSeappViolations)
 }
diff --git a/android/metrics.go b/android/metrics.go
index 3571272..6834b1b 100644
--- a/android/metrics.go
+++ b/android/metrics.go
@@ -19,7 +19,6 @@
 	"io/ioutil"
 	"os"
 	"runtime"
-	"sort"
 	"strconv"
 	"time"
 
@@ -93,23 +92,6 @@
 		}
 		metrics.Events = append(metrics.Events, &perfInfo)
 	}
-	mixedBuildsInfo := soong_metrics_proto.MixedBuildsInfo{}
-	mixedBuildEnabledModules := make([]string, 0, len(config.mixedBuildEnabledModules))
-	for module, _ := range config.mixedBuildEnabledModules {
-		mixedBuildEnabledModules = append(mixedBuildEnabledModules, module)
-	}
-
-	mixedBuildDisabledModules := make([]string, 0, len(config.mixedBuildDisabledModules))
-	for module, _ := range config.mixedBuildDisabledModules {
-		mixedBuildDisabledModules = append(mixedBuildDisabledModules, module)
-	}
-	// Sorted for deterministic output.
-	sort.Strings(mixedBuildEnabledModules)
-	sort.Strings(mixedBuildDisabledModules)
-
-	mixedBuildsInfo.MixedBuildEnabledModules = mixedBuildEnabledModules
-	mixedBuildsInfo.MixedBuildDisabledModules = mixedBuildDisabledModules
-	metrics.MixedBuildsInfo = &mixedBuildsInfo
 
 	return metrics
 }
diff --git a/android/module.go b/android/module.go
index 9d74642..f571157 100644
--- a/android/module.go
+++ b/android/module.go
@@ -16,7 +16,6 @@
 
 import (
 	"android/soong/bazel"
-	"android/soong/ui/metrics/bp2build_metrics_proto"
 	"crypto/md5"
 	"encoding/hex"
 	"encoding/json"
@@ -96,16 +95,6 @@
 	AddProperties(props ...interface{})
 	GetProperties() []interface{}
 
-	// If this module should not have bazel BUILD definitions generated by bp2build,
-	// GetUnconvertedReason returns a reason this is the case.
-	GetUnconvertedReason() *UnconvertedReason
-
-	// Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module
-	Bp2buildTargets() []bp2buildInfo
-	GetUnconvertedBp2buildDeps() []string
-	GetMissingBp2buildDeps() []string
-	GetPartitionForBp2build() string
-
 	BuildParamsForTests() []BuildParams
 	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
 	VariablesForTests() map[string]string
@@ -520,9 +509,6 @@
 	// constants in image.go, but can also be set to a custom value by individual module types.
 	ImageVariation string `blueprint:"mutated"`
 
-	// Bazel conversion status
-	BazelConversionStatus BazelConversionStatus `blueprint:"mutated"`
-
 	// SoongConfigTrace records accesses to VendorVars (soong_config). The trace will be hashed
 	// and used as a subdir of PathForModuleOut.  Note that we mainly focus on incremental
 	// builds among similar products (e.g. aosp_cf_x86_64_phone and aosp_cf_x86_64_foldable),
@@ -532,41 +518,6 @@
 	SoongConfigTraceHash string           `blueprint:"mutated"`
 }
 
-// CommonAttributes represents the common Bazel attributes from which properties
-// in `commonProperties` are translated/mapped; such properties are annotated in
-// a list their corresponding attribute. It is embedded within `bp2buildInfo`.
-type CommonAttributes struct {
-	// Soong nameProperties -> Bazel name
-	Name string
-
-	// Data mapped from: Required
-	Data bazel.LabelListAttribute
-
-	// SkipData is neither a Soong nor Bazel target attribute
-	// If true, this will not fill the data attribute automatically
-	// This is useful for Soong modules that have 1:many Bazel targets
-	// Some of the generated Bazel targets might not have a data attribute
-	SkipData *bool
-
-	Tags bazel.StringListAttribute
-
-	Applicable_licenses bazel.LabelListAttribute
-
-	Testonly *bool
-
-	// Dir is neither a Soong nor Bazel target attribute
-	// If set, the bazel target will be created in this directory
-	// If unset, the bazel target will default to be created in the directory of the visited soong module
-	Dir *string
-}
-
-// constraintAttributes represents Bazel attributes pertaining to build constraints,
-// which make restrict building a Bazel target for some set of platforms.
-type constraintAttributes struct {
-	// Constraint values this target can be built for.
-	Target_compatible_with bazel.LabelListAttribute
-}
-
 type distProperties struct {
 	// configuration to distribute output files from this module to the distribution
 	// directory (default: $OUT/dist, configurable with $DIST_DIR)
@@ -804,234 +755,6 @@
 	m.base().commonProperties.CreateCommonOSVariant = true
 }
 
-func (attrs *CommonAttributes) getRequiredWithoutCycles(ctx *bottomUpMutatorContext, props *commonProperties) []string {
-	// Treat `required` as if it's empty if data should be skipped for this target,
-	// as `required` is only used for the `data` attribute at this time, and we want
-	// to avoid lookups of labels that won't actually be dependencies of this target.
-	// TODO: b/202299295 - Refactor this to use `required` dependencies, once they
-	// are handled other than passing to `data`.
-	if proptools.Bool(attrs.SkipData) {
-		return []string{}
-	}
-	// The required property can contain the module itself. This causes a cycle
-	// when generated as the 'data' label list attribute in Bazel. Remove it if
-	// it exists. See b/247985196.
-	_, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), props.Required)
-	return FirstUniqueStrings(requiredWithoutCycles)
-}
-
-func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *bottomUpMutatorContext,
-	enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes {
-
-	mod := ctx.Module().base()
-	// Assert passed-in attributes include Name
-	if len(attrs.Name) == 0 {
-		if ctx.ModuleType() != "package" {
-			ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!")
-		}
-	}
-
-	depsToLabelList := func(deps []string) bazel.LabelListAttribute {
-		return bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, deps))
-	}
-
-	var enabledProperty bazel.BoolAttribute
-
-	onlyAndroid := false
-	neitherHostNorDevice := false
-
-	osSupport := map[string]bool{}
-
-	// if the target is enabled and supports arch variance, determine the defaults based on the module
-	// type's host or device property and host_supported/device_supported properties
-	if mod.commonProperties.ArchSpecific {
-		moduleSupportsDevice := mod.DeviceSupported()
-		moduleSupportsHost := mod.HostSupported()
-		if moduleSupportsHost && !moduleSupportsDevice {
-			// for host only, we specify as unsupported on android rather than listing all host osSupport
-			// TODO(b/220874839): consider replacing this with a constraint that covers all host osSupport
-			// instead
-			enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(false))
-		} else if moduleSupportsDevice && !moduleSupportsHost {
-			enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(true))
-			// specify as a positive to ensure any target-specific enabled can be resolved
-			// also save that a target is only android, as if there is only the positive restriction on
-			// android, it'll be dropped, so we may need to add it back later
-			onlyAndroid = true
-		} else if !moduleSupportsHost && !moduleSupportsDevice {
-			neitherHostNorDevice = true
-		}
-
-		for _, osType := range OsTypeList() {
-			if osType.Class == Host {
-				osSupport[osType.Name] = moduleSupportsHost
-			} else if osType.Class == Device {
-				osSupport[osType.Name] = moduleSupportsDevice
-			}
-		}
-	}
-
-	if neitherHostNorDevice {
-		// we can't build this, disable
-		enabledProperty.Value = proptools.BoolPtr(false)
-	} else if mod.commonProperties.Enabled != nil {
-		enabledProperty.SetValue(mod.commonProperties.Enabled)
-		if !*mod.commonProperties.Enabled {
-			for oss, enabled := range osSupport {
-				if val := enabledProperty.SelectValue(bazel.OsConfigurationAxis, oss); enabled && val != nil && *val {
-					// if this should be disabled by default, clear out any enabling we've done
-					enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, oss, nil)
-				}
-			}
-		}
-	}
-
-	attrs.Applicable_licenses = bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, mod.commonProperties.Licenses))
-
-	requiredWithoutCycles := attrs.getRequiredWithoutCycles(ctx, &mod.commonProperties)
-	required := depsToLabelList(requiredWithoutCycles)
-	archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{})
-	for axis, configToProps := range archVariantProps {
-		for config, _props := range configToProps {
-			if archProps, ok := _props.(*commonProperties); ok {
-				requiredWithoutCycles := attrs.getRequiredWithoutCycles(ctx, archProps)
-				required.SetSelectValue(axis, config, depsToLabelList(requiredWithoutCycles).Value)
-				if !neitherHostNorDevice {
-					if archProps.Enabled != nil {
-						if axis != bazel.OsConfigurationAxis || osSupport[config] {
-							enabledProperty.SetSelectValue(axis, config, archProps.Enabled)
-						}
-					}
-				}
-			}
-		}
-	}
-
-	if !neitherHostNorDevice {
-		if enabledPropertyOverrides.Value != nil {
-			enabledProperty.Value = enabledPropertyOverrides.Value
-		}
-		for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() {
-			configToBools := enabledPropertyOverrides.ConfigurableValues[axis]
-			for cfg, val := range configToBools {
-				if axis != bazel.OsConfigurationAxis || osSupport[cfg] || val /*If enabled is explicitly requested via overrides */ {
-					enabledProperty.SetSelectValue(axis, cfg, &val)
-				}
-			}
-		}
-	}
-
-	productConfigEnabledAttribute := bazel.LabelListAttribute{}
-	// TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we
-	// should handle it correctly
-	if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice {
-		// If the module is not enabled by default, then we can check if a
-		// product variable enables it
-		productConfigEnabledAttribute = productVariableConfigEnableAttribute(ctx)
-
-		if len(productConfigEnabledAttribute.ConfigurableValues) > 0 {
-			// In this case, an existing product variable configuration overrides any
-			// module-level `enable: false` definition
-			newValue := true
-			enabledProperty.Value = &newValue
-		}
-	}
-
-	platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute(
-		bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil},
-		bazel.LabelList{[]bazel.Label{}, nil})
-	if err != nil {
-		ctx.ModuleErrorf("Error processing platform enabled attribute: %s", err)
-	}
-
-	// if android is the only arch/os enabled, then add a restriction to only be compatible with android
-	if platformEnabledAttribute.IsNil() && onlyAndroid {
-		l := bazel.LabelAttribute{}
-		l.SetValue(bazel.Label{Label: bazel.OsConfigurationAxis.SelectKey(Android.Name)})
-		platformEnabledAttribute.Add(&l)
-	}
-
-	attrs.Data.Append(required)
-
-	// SkipData is not an attribute of any Bazel target
-	// Set this to nil so that it does not appear in the generated build file
-	attrs.SkipData = nil
-
-	moduleEnableConstraints := bazel.LabelListAttribute{}
-	moduleEnableConstraints.Append(platformEnabledAttribute)
-	moduleEnableConstraints.Append(productConfigEnabledAttribute)
-	addCompatibilityConstraintForCompileMultilib(ctx, &moduleEnableConstraints)
-
-	return constraintAttributes{Target_compatible_with: moduleEnableConstraints}
-}
-
-var (
-	incompatible = bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}
-)
-
-// If compile_mulitilib is set to
-// 1. 32: Add an incompatibility constraint for non-32 arches
-// 1. 64: Add an incompatibility constraint for non-64 arches
-func addCompatibilityConstraintForCompileMultilib(ctx *bottomUpMutatorContext, enabled *bazel.LabelListAttribute) {
-	mod := ctx.Module().base()
-	multilib, _ := decodeMultilib(mod, mod.commonProperties.CompileOS, ctx.Config().IgnorePrefer32OnDevice())
-
-	switch multilib {
-	case "32":
-		// Add an incompatibility constraint for all known 64-bit arches
-		enabled.SetSelectValue(bazel.ArchConfigurationAxis, "arm64", incompatible)
-		enabled.SetSelectValue(bazel.ArchConfigurationAxis, "x86_64", incompatible)
-		enabled.SetSelectValue(bazel.ArchConfigurationAxis, "riscv64", incompatible)
-	case "64":
-		// Add an incompatibility constraint for all known 32-bit arches
-		enabled.SetSelectValue(bazel.ArchConfigurationAxis, "arm", incompatible)
-		enabled.SetSelectValue(bazel.ArchConfigurationAxis, "x86", incompatible)
-	case "both":
-		// Do nothing: "both" is trivially compatible with 32-bit and 64-bit
-		// The top level rule (e.g. apex/partition) will be responsible for building this module in both variants via an
-		// outgoing_transition.
-	default: // e.g. first, common
-		// TODO - b/299135307: Add bp2build support for these properties.
-	}
-
-}
-
-// Check product variables for `enabled: true` flag override.
-// Returns a list of the constraint_value targets who enable this override.
-func productVariableConfigEnableAttribute(ctx *bottomUpMutatorContext) bazel.LabelListAttribute {
-	result := bazel.LabelListAttribute{}
-	productVariableProps, errs := ProductVariableProperties(ctx, ctx.Module())
-	for _, err := range errs {
-		ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
-	}
-	if productConfigProps, exists := productVariableProps["Enabled"]; exists {
-		for productConfigProp, prop := range productConfigProps {
-			flag, ok := prop.(*bool)
-			if !ok {
-				ctx.ModuleErrorf("Could not convert product variable enabled property")
-			}
-
-			if flag == nil {
-				// soong config var is not used to set `enabled`. nothing to do.
-				continue
-			} else if *flag {
-				axis := productConfigProp.ConfigurationAxis()
-				result.SetSelectValue(axis, bazel.ConditionsDefaultConfigKey, bazel.MakeLabelList([]bazel.Label{{Label: "@platforms//:incompatible"}}))
-				result.SetSelectValue(axis, productConfigProp.SelectKey(), bazel.LabelList{Includes: []bazel.Label{}})
-			} else if scp, isSoongConfigProperty := productConfigProp.(SoongConfigProperty); isSoongConfigProperty && scp.value == bazel.ConditionsDefaultConfigKey {
-				// productVariableConfigEnableAttribute runs only if `enabled: false` is set at the top-level outside soong_config_variables
-				// conditions_default { enabled: false} is a no-op in this case
-				continue
-			} else {
-				// TODO(b/210546943): handle negative case where `enabled: false`
-				ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943")
-			}
-		}
-	}
-
-	return result
-}
-
 // A ModuleBase object contains the properties that are common to all Android
 // modules.  It should be included as an anonymous field in every module
 // struct definition.  InitAndroidModule should then be called from the module's
@@ -1146,81 +869,6 @@
 	licenseMetadataFile WritablePath
 }
 
-// A struct containing all relevant information about a Bazel target converted via bp2build.
-type bp2buildInfo struct {
-	Dir             string
-	BazelProps      bazel.BazelTargetModuleProperties
-	CommonAttrs     CommonAttributes
-	ConstraintAttrs constraintAttributes
-	Attrs           interface{}
-}
-
-// TargetName returns the Bazel target name of a bp2build converted target.
-func (b bp2buildInfo) TargetName() string {
-	return b.CommonAttrs.Name
-}
-
-// TargetPackage returns the Bazel package of a bp2build converted target.
-func (b bp2buildInfo) TargetPackage() string {
-	return b.Dir
-}
-
-// BazelRuleClass returns the Bazel rule class of a bp2build converted target.
-func (b bp2buildInfo) BazelRuleClass() string {
-	return b.BazelProps.Rule_class
-}
-
-// BazelRuleLoadLocation returns the location of the  Bazel rule of a bp2build converted target.
-// This may be empty as native Bazel rules do not need to be loaded.
-func (b bp2buildInfo) BazelRuleLoadLocation() string {
-	return b.BazelProps.Bzl_load_location
-}
-
-// BazelAttributes returns the Bazel attributes of a bp2build converted target.
-func (b bp2buildInfo) BazelAttributes() []interface{} {
-	return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs}
-}
-
-func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
-	m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info)
-}
-
-func (m *ModuleBase) setPartitionForBp2build(partition string) {
-	m.commonProperties.BazelConversionStatus.Partition = partition
-}
-
-func (m *ModuleBase) setBp2buildUnconvertible(reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string) {
-	m.commonProperties.BazelConversionStatus.UnconvertedReason = &UnconvertedReason{
-		ReasonType: int(reasonType),
-		Detail:     detail,
-	}
-}
-
-func (m *ModuleBase) GetUnconvertedReason() *UnconvertedReason {
-	return m.commonProperties.BazelConversionStatus.UnconvertedReason
-}
-
-// Bp2buildTargets returns the Bazel targets bp2build generated for this module.
-func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo {
-	return m.commonProperties.BazelConversionStatus.Bp2buildInfo
-}
-
-// Bp2buildTargets returns the Bazel targets bp2build generated for this module.
-func (m *ModuleBase) GetPartitionForBp2build() string {
-	return m.commonProperties.BazelConversionStatus.Partition
-}
-
-// GetUnconvertedBp2buildDeps returns the list of module names of this module's direct dependencies that
-// were not converted to Bazel.
-func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string {
-	return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.UnconvertedDeps)
-}
-
-// GetMissingBp2buildDeps returns the list of module names that were not found in Android.bp files.
-func (m *ModuleBase) GetMissingBp2buildDeps() []string {
-	return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.MissingDeps)
-}
-
 func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
 	(*d)["Android"] = map[string]interface{}{
 		// Properties set in Blueprint or in blueprint of a defaults modules
@@ -2031,11 +1679,7 @@
 			return
 		}
 
-		if mixedBuildMod, handled := m.isHandledByBazel(ctx); handled {
-			mixedBuildMod.ProcessBazelQueryResponse(ctx)
-		} else {
-			m.module.GenerateAndroidBuildActions(ctx)
-		}
+		m.module.GenerateAndroidBuildActions(ctx)
 		if ctx.Failed() {
 			return
 		}
@@ -2092,15 +1736,6 @@
 	m.variables = ctx.variables
 }
 
-func (m *ModuleBase) isHandledByBazel(ctx ModuleContext) (MixedBuildBuildable, bool) {
-	if mixedBuildMod, ok := m.module.(MixedBuildBuildable); ok {
-		if mixedBuildMod.IsMixedBuildSupported(ctx) && (MixedBuildsEnabled(ctx) == MixedBuildEnabled) {
-			return mixedBuildMod, true
-		}
-	}
-	return nil, false
-}
-
 // Check the supplied dist structure to make sure that it is valid.
 //
 // property - the base property, e.g. dist or dists[1], which is combined with the
@@ -2193,6 +1828,18 @@
 	return proptools.Bool(m.commonProperties.Native_bridge_supported)
 }
 
+// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
+// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
+// or if this variant is not overridden.
+func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string {
+	if overridable, ok := ctx.Module().(OverridableModule); ok {
+		if o := overridable.GetOverriddenBy(); o != "" {
+			return o
+		}
+	}
+	return ctx.ModuleName()
+}
+
 // SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
 // into the module name, or empty string if the input was not a module reference.
 func SrcIsModule(s string) (module string) {
@@ -2615,36 +2262,3 @@
 	WriteFileRule(ctx, outFile, string(j))
 	ctx.Phony("soong_config_trace", outFile)
 }
-
-// Interface implemented by xsd_config which has 1:many mappings in bp2build workspace
-// This interface exists because we want to
-// 1. Determine the name of the additional targets generated by the primary soong module
-// 2. Enable distinguishing an xsd_config module from other Soong modules using type assertion
-type XsdConfigBp2buildTargets interface {
-	CppBp2buildTargetName() string
-	JavaBp2buildTargetName() string
-}
-
-// XsdModuleToTargetName is a function that takes an XsdConfigBp2buildTarget
-type XsdModuleToTargetName func(xsd XsdConfigBp2buildTargets) string
-
-// XsdLabelMapper returns a bazel.LabelMapper for partitioning XSD sources/headers given an
-// XsdModuleToTargetName function.
-func XsdLabelMapper(targetName XsdModuleToTargetName) bazel.LabelMapper {
-	return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
-		mod, exists := ctx.ModuleFromName(label.OriginalModuleName)
-		if !exists {
-			return label.Label, false
-		}
-		xsdMod, isXsd := mod.(XsdConfigBp2buildTargets)
-		if !isXsd {
-			return label.Label, false
-		}
-
-		// Remove the base module name
-		ret := strings.TrimSuffix(label.Label, mod.Name())
-		// Append the language specific target name
-		ret += targetName(xsdMod)
-		return ret, true
-	}
-}
diff --git a/android/mutator.go b/android/mutator.go
index 3ff9e61..0d391a4 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,11 +15,6 @@
 package android
 
 import (
-	"path/filepath"
-
-	"android/soong/bazel"
-	"android/soong/ui/metrics/bp2build_metrics_proto"
-
 	"github.com/google/blueprint"
 )
 
@@ -32,40 +27,9 @@
 //   run FinalDeps mutators (CreateVariations disallowed in this phase)
 //   continue on to GenerateAndroidBuildActions
 
-// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
-func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
-	bp2buildMutators := append(preArchMutators, registerBp2buildConversionMutator)
-	registerMutatorsForBazelConversion(ctx, bp2buildMutators)
-}
-
-func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []RegisterMutatorFunc) {
-	mctx := &registerMutatorsContext{
-		bazelConversionMode: true,
-	}
-
-	allMutators := append([]RegisterMutatorFunc{
-		RegisterNamespaceMutator,
-		RegisterDefaultsPreArchMutators,
-		// TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should
-		// evaluate the impact on conversion.
-		RegisterPrebuiltsPreArchMutators,
-		RegisterPrebuiltsPostDepsMutators,
-	},
-		bp2buildMutators...)
-
-	// Register bp2build mutators
-	for _, f := range allMutators {
-		f(mctx)
-	}
-
-	mctx.mutators.registerAll(ctx)
-}
-
 // collateGloballyRegisteredMutators constructs the list of mutators that have been registered
 // with the InitRegistrationContext and will be used at runtime.
 func collateGloballyRegisteredMutators() sortableComponents {
-	// ensure mixed builds mutator is the last mutator
-	finalDeps = append(finalDeps, registerMixedBuildsMutator)
 	return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
 }
 
@@ -94,9 +58,8 @@
 }
 
 type registerMutatorsContext struct {
-	mutators            sortableComponents
-	finalPhase          bool
-	bazelConversionMode bool
+	mutators   sortableComponents
+	finalPhase bool
 }
 
 type RegisterMutatorsContext interface {
@@ -219,58 +182,6 @@
 	finalDeps = append(finalDeps, f)
 }
 
-var bp2buildPreArchMutators = []RegisterMutatorFunc{}
-
-// A minimal context for Bp2build conversion
-type Bp2buildMutatorContext interface {
-	BazelConversionPathContext
-	BaseMutatorContext
-
-	// AddDependency adds a dependency to the given module.  It returns a slice of modules for each
-	// dependency (some entries may be nil).
-	//
-	// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
-	// new dependencies have had the current mutator called on them.  If the mutator is not
-	// parallel this method does not affect the ordering of the current mutator pass, but will
-	// be ordered correctly for all future mutator passes.
-	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
-
-	// CreateBazelTargetModule creates a BazelTargetModule by calling the
-	// factory method, just like in CreateModule, but also requires
-	// BazelTargetModuleProperties containing additional metadata for the
-	// bp2build codegenerator.
-	CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
-
-	// CreateBazelTargetModuleWithRestrictions creates a BazelTargetModule by calling the
-	// factory method, just like in CreateModule, but also requires
-	// BazelTargetModuleProperties containing additional metadata for the
-	// bp2build codegenerator. The generated target is restricted to only be buildable for certain
-	// platforms, as dictated by a given bool attribute: the target will not be buildable in
-	// any platform for which this bool attribute is false.
-	CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute)
-
-	// MarkBp2buildUnconvertible registers the current module as "unconvertible to bp2build" for the
-	// given reason.
-	MarkBp2buildUnconvertible(reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string)
-
-	// CreateBazelTargetAliasInDir creates an alias definition in `dir` directory.
-	// This function can be used to create alias definitions in a directory that is different
-	// from the directory of the visited Soong module.
-	CreateBazelTargetAliasInDir(dir string, name string, actual bazel.Label)
-
-	// CreateBazelConfigSetting creates a config_setting in <dir>/BUILD.bazel
-	// build/bazel has several static config_setting(s) that are used in Bazel builds.
-	// This function can be used to createa additional config_setting(s) based on the build graph
-	// (e.g. a config_setting specific to an apex variant)
-	CreateBazelConfigSetting(csa bazel.ConfigSettingAttributes, ca CommonAttributes, dir string)
-}
-
-// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
-// into Bazel BUILD targets that should run prior to deps and conversion.
-func PreArchBp2BuildMutators(f RegisterMutatorFunc) {
-	bp2buildPreArchMutators = append(bp2buildPreArchMutators, f)
-}
-
 type BaseMutatorContext interface {
 	BaseModuleContext
 
@@ -301,7 +212,15 @@
 
 type BottomUpMutatorContext interface {
 	BaseMutatorContext
-	Bp2buildMutatorContext
+
+	// AddDependency adds a dependency to the given module.  It returns a slice of modules for each
+	// dependency (some entries may be nil).
+	//
+	// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
+	// new dependencies have had the current mutator called on them.  If the mutator is not
+	// parallel this method does not affect the ordering of the current mutator pass, but will
+	// be ordered correctly for all future mutator passes.
+	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
 
 	// AddReverseDependency adds a dependency from the destination to the given module.
 	// Does not affect the ordering of the current mutator pass, but will be ordered
@@ -416,10 +335,9 @@
 }
 
 func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
-	finalPhase, bazelConversionMode bool) BottomUpMutatorContext {
+	finalPhase bool) BottomUpMutatorContext {
 
 	moduleContext := a.base().baseModuleContextFactory(ctx)
-	moduleContext.bazelConversionMode = bazelConversionMode
 
 	return &bottomUpMutatorContext{
 		bp:                ctx,
@@ -430,10 +348,9 @@
 
 func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
 	finalPhase := x.finalPhase
-	bazelConversionMode := x.bazelConversionMode
 	f := func(ctx blueprint.BottomUpMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
-			m(bottomUpMutatorContextFactory(ctx, a, finalPhase, bazelConversionMode))
+			m(bottomUpMutatorContextFactory(ctx, a, finalPhase))
 		}
 	}
 	mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f}
@@ -550,15 +467,13 @@
 }
 
 type androidTransitionMutator struct {
-	finalPhase          bool
-	bazelConversionMode bool
-	mutator             TransitionMutator
+	finalPhase bool
+	mutator    TransitionMutator
 }
 
 func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
 	if m, ok := ctx.Module().(Module); ok {
 		moduleContext := m.base().baseModuleContextFactory(ctx)
-		moduleContext.bazelConversionMode = a.bazelConversionMode
 		return a.mutator.Split(&moduleContext)
 	} else {
 		return []string{""}
@@ -607,15 +522,14 @@
 
 func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) {
 	if am, ok := ctx.Module().(Module); ok {
-		a.mutator.Mutate(bottomUpMutatorContextFactory(ctx, am, a.finalPhase, a.bazelConversionMode), variation)
+		a.mutator.Mutate(bottomUpMutatorContextFactory(ctx, am, a.finalPhase), variation)
 	}
 }
 
 func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) {
 	atm := &androidTransitionMutator{
-		finalPhase:          x.finalPhase,
-		bazelConversionMode: x.bazelConversionMode,
-		mutator:             m,
+		finalPhase: x.finalPhase,
+		mutator:    m,
 	}
 	mutator := &mutator{
 		name:              name,
@@ -624,9 +538,6 @@
 }
 
 func (x *registerMutatorsContext) mutatorName(name string) string {
-	if x.bazelConversionMode {
-		return name + "_bp2build"
-	}
 	return name
 }
 
@@ -634,7 +545,6 @@
 	f := func(ctx blueprint.TopDownMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
 			moduleContext := a.base().baseModuleContextFactory(ctx)
-			moduleContext.bazelConversionMode = x.bazelConversionMode
 			actx := &topDownMutatorContext{
 				bp:                ctx,
 				baseModuleContext: moduleContext,
@@ -698,179 +608,6 @@
 	ctx.BottomUp("deps", depsMutator).Parallel()
 }
 
-func (t *bottomUpMutatorContext) CreateBazelTargetModule(
-	bazelProps bazel.BazelTargetModuleProperties,
-	commonAttrs CommonAttributes,
-	attrs interface{}) {
-	t.createBazelTargetModule(bazelProps, commonAttrs, attrs, bazel.BoolAttribute{})
-}
-
-func (t *bottomUpMutatorContext) CreateBazelTargetModuleWithRestrictions(
-	bazelProps bazel.BazelTargetModuleProperties,
-	commonAttrs CommonAttributes,
-	attrs interface{},
-	enabledProperty bazel.BoolAttribute) {
-	t.createBazelTargetModule(bazelProps, commonAttrs, attrs, enabledProperty)
-}
-
-func (t *bottomUpMutatorContext) MarkBp2buildUnconvertible(
-	reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string) {
-	mod := t.Module()
-	mod.base().setBp2buildUnconvertible(reasonType, detail)
-}
-
-var (
-	bazelAliasModuleProperties = bazel.BazelTargetModuleProperties{
-		Rule_class: "alias",
-	}
-)
-
-type bazelAliasAttributes struct {
-	Actual *bazel.LabelAttribute
-}
-
-func (t *bottomUpMutatorContext) CreateBazelTargetAliasInDir(
-	dir string,
-	name string,
-	actual bazel.Label) {
-	mod := t.Module()
-	attrs := &bazelAliasAttributes{
-		Actual: bazel.MakeLabelAttribute(actual.Label),
-	}
-	info := bp2buildInfo{
-		Dir:             dir,
-		BazelProps:      bazelAliasModuleProperties,
-		CommonAttrs:     CommonAttributes{Name: name},
-		ConstraintAttrs: constraintAttributes{},
-		Attrs:           attrs,
-	}
-	mod.base().addBp2buildInfo(info)
-}
-
-// Returns the directory in which the bazel target will be generated
-// If ca.Dir is not nil, use that
-// Otherwise default to the directory of the soong module
-func dirForBazelTargetGeneration(t *bottomUpMutatorContext, ca *CommonAttributes) string {
-	dir := t.OtherModuleDir(t.Module())
-	if ca.Dir != nil {
-		dir = *ca.Dir
-		// Restrict its use to dirs that contain an Android.bp file.
-		// There are several places in bp2build where we use the existence of Android.bp/BUILD on the filesystem
-		// to curate a compatible label for src files (e.g. headers for cc).
-		// If we arbritrarily create BUILD files, then it might render those curated labels incompatible.
-		if exists, _, _ := t.Config().fs.Exists(filepath.Join(dir, "Android.bp")); !exists {
-			t.ModuleErrorf("Cannot use ca.Dir to create a BazelTarget in dir: %v since it does not contain an Android.bp file", dir)
-		}
-
-		// Set ca.Dir to nil so that it does not get emitted to the BUILD files
-		ca.Dir = nil
-	}
-	return dir
-}
-
-func (t *bottomUpMutatorContext) CreateBazelConfigSetting(
-	csa bazel.ConfigSettingAttributes,
-	ca CommonAttributes,
-	dir string) {
-	mod := t.Module()
-	info := bp2buildInfo{
-		Dir: dir,
-		BazelProps: bazel.BazelTargetModuleProperties{
-			Rule_class: "config_setting",
-		},
-		CommonAttrs:     ca,
-		ConstraintAttrs: constraintAttributes{},
-		Attrs:           &csa,
-	}
-	mod.base().addBp2buildInfo(info)
-}
-
-// ApexAvailableTags converts the apex_available property value of an ApexModule
-// module and returns it as a list of keyed tags.
-func ApexAvailableTags(mod Module) bazel.StringListAttribute {
-	attr := bazel.StringListAttribute{}
-	// Transform specific attributes into tags.
-	if am, ok := mod.(ApexModule); ok {
-		// TODO(b/218841706): hidl_interface has the apex_available prop, but it's
-		// defined directly as a prop and not via ApexModule, so this doesn't
-		// pick those props up.
-		apexAvailable := am.apexModuleBase().ApexAvailable()
-		// If a user does not specify apex_available in Android.bp, then soong provides a default.
-		// To avoid verbosity of BUILD files, remove this default from user-facing BUILD files.
-		if len(am.apexModuleBase().ApexProperties.Apex_available) == 0 {
-			apexAvailable = []string{}
-		}
-		attr.Value = ConvertApexAvailableToTags(apexAvailable)
-	}
-	return attr
-}
-
-func ApexAvailableTagsWithoutTestApexes(ctx BaseModuleContext, mod Module) bazel.StringListAttribute {
-	attr := bazel.StringListAttribute{}
-	if am, ok := mod.(ApexModule); ok {
-		apexAvailableWithoutTestApexes := removeTestApexes(ctx, am.apexModuleBase().ApexAvailable())
-		// If a user does not specify apex_available in Android.bp, then soong provides a default.
-		// To avoid verbosity of BUILD files, remove this default from user-facing BUILD files.
-		if len(am.apexModuleBase().ApexProperties.Apex_available) == 0 {
-			apexAvailableWithoutTestApexes = []string{}
-		}
-		attr.Value = ConvertApexAvailableToTags(apexAvailableWithoutTestApexes)
-	}
-	return attr
-}
-
-func removeTestApexes(ctx BaseModuleContext, apex_available []string) []string {
-	testApexes := []string{}
-	for _, aa := range apex_available {
-		// ignore the wildcards
-		if InList(aa, AvailableToRecognziedWildcards) {
-			continue
-		}
-		mod, _ := ctx.ModuleFromName(aa)
-		if apex, ok := mod.(ApexTestInterface); ok && apex.IsTestApex() {
-			testApexes = append(testApexes, aa)
-		}
-	}
-	return RemoveListFromList(CopyOf(apex_available), testApexes)
-}
-
-func ConvertApexAvailableToTags(apexAvailable []string) []string {
-	if len(apexAvailable) == 0 {
-		// We need nil specifically to make bp2build not add the tags property at all,
-		// instead of adding it with an empty list
-		return nil
-	}
-	result := make([]string, 0, len(apexAvailable))
-	for _, a := range apexAvailable {
-		result = append(result, "apex_available="+a)
-	}
-	return result
-}
-
-// ConvertApexAvailableToTagsWithoutTestApexes converts a list of apex names to a list of bazel tags
-// This function drops any test apexes from the input.
-func ConvertApexAvailableToTagsWithoutTestApexes(ctx BaseModuleContext, apexAvailable []string) []string {
-	noTestApexes := removeTestApexes(ctx, apexAvailable)
-	return ConvertApexAvailableToTags(noTestApexes)
-}
-
-func (t *bottomUpMutatorContext) createBazelTargetModule(
-	bazelProps bazel.BazelTargetModuleProperties,
-	commonAttrs CommonAttributes,
-	attrs interface{},
-	enabledProperty bazel.BoolAttribute) {
-	constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty)
-	mod := t.Module()
-	info := bp2buildInfo{
-		Dir:             dirForBazelTargetGeneration(t, &commonAttrs),
-		BazelProps:      bazelProps,
-		CommonAttrs:     commonAttrs,
-		ConstraintAttrs: constraintAttributes,
-		Attrs:           attrs,
-	}
-	mod.base().addBp2buildInfo(info)
-}
-
 // android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
 // has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
 // ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
diff --git a/android/mutator_test.go b/android/mutator_test.go
index dbdfa33..21eebd2 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -16,7 +16,6 @@
 
 import (
 	"fmt"
-	"reflect"
 	"strings"
 	"testing"
 
@@ -268,22 +267,3 @@
 		FixtureWithRootAndroidBp(`test {name: "foo"}`),
 	).RunTest(t)
 }
-
-func TestConvertApexAvailableToTags(t *testing.T) {
-	input := []string{
-		"com.android.adbd",
-		"//apex_available:platform",
-	}
-	actual := ConvertApexAvailableToTags(input)
-	expected := []string{
-		"apex_available=com.android.adbd",
-		"apex_available=//apex_available:platform",
-	}
-	if !reflect.DeepEqual(actual, expected) {
-		t.Errorf("Expected: %v, actual: %v", expected, actual)
-	}
-
-	if ConvertApexAvailableToTags(nil) != nil {
-		t.Errorf("Expected providing nil to return nil")
-	}
-}
diff --git a/android/override_module.go b/android/override_module.go
index 9e0de6f..1341f53 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -214,17 +214,6 @@
 	}
 	b.overridableModuleProperties.OverriddenBy = o.Name()
 	b.overridableModuleProperties.OverriddenByModuleDir = o.ModuleDir()
-
-	if oBazelable, ok := o.base().module.(Bazelable); ok {
-		if bBazelable, ok := m.(Bazelable); ok {
-			oProps := oBazelable.bazelProps()
-			bProps := bBazelable.bazelProps()
-			bProps.Bazel_module.Bp2build_available = oProps.Bazel_module.Bp2build_available
-			bProps.Bazel_module.Label = oProps.Bazel_module.Label
-		} else {
-			ctx.ModuleErrorf("Override type cannot be Bazelable if original module type is not Bazelable %v %v.", o.Name(), m.Name())
-		}
-	}
 }
 
 // GetOverriddenBy returns the name of the override module that has overridden this module.
@@ -348,31 +337,3 @@
 		}
 	}
 }
-
-// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
-// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
-// or if this variant is not overridden.
-func ModuleNameWithPossibleOverride(ctx BazelConversionContext) string {
-	return moduleNameWithPossibleOverride(ctx, ctx.Module(), ctx.OtherModuleName(ctx.Module()))
-}
-
-func moduleNameWithPossibleOverride(ctx shouldConvertModuleContext, module blueprint.Module, name string) string {
-	if overridable, ok := module.(OverridableModule); ok {
-		if o := overridable.GetOverriddenBy(); o != "" {
-			return o
-		}
-	}
-	return name
-}
-
-// moduleDirWithPossibleOverride returns the dir of the OverrideModule that overrides the current
-// variant of the given OverridableModule, or ctx.OtherModuleName() if the module is not an
-// OverridableModule or if the variant is not overridden.
-func moduleDirWithPossibleOverride(ctx shouldConvertModuleContext, module blueprint.Module, dir string) string {
-	if overridable, ok := module.(OverridableModule); ok {
-		if o := overridable.GetOverriddenByModuleDir(); o != "" {
-			return o
-		}
-	}
-	return dir
-}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 91c0aa1..a32a37d 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -461,10 +461,6 @@
 		// Propagate the provider received from `all_apex_contributions`
 		// to the source module
 		ctx.VisitDirectDepsWithTag(acDepTag, func(am Module) {
-			if ctx.Config().Bp2buildMode() {
-				// This provider key is not applicable in bp2build
-				return
-			}
 			psi := ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
 			ctx.SetProvider(PrebuiltSelectionInfoProvider, psi)
 		})
@@ -570,55 +566,20 @@
 	// fall back to the existing source vs prebuilt selection.
 	// TODO: Drop the fallback mechanisms
 
-	if !ctx.Config().Bp2buildMode() {
-		if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
-			return false
-		}
+	if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
+		return false
+	}
 
-		// Skip prebuilt modules under unexported namespaces so that we won't
-		// end up shadowing non-prebuilt module when prebuilt module under same
-		// name happens to have a `Prefer` property set to true.
-		if ctx.Config().KatiEnabled() && !prebuilt.ExportedToMake() {
-			return false
-		}
+	// Skip prebuilt modules under unexported namespaces so that we won't
+	// end up shadowing non-prebuilt module when prebuilt module under same
+	// name happens to have a `Prefer` property set to true.
+	if ctx.Config().KatiEnabled() && !prebuilt.ExportedToMake() {
+		return false
 	}
 
 	// If source is not available or is disabled then always use the prebuilt.
 	if source == nil || !source.Enabled() {
-		// If in bp2build mode, we need to check product variables & Soong config variables, which may
-		// have overridden the "enabled" property but have not been merged into the property value as
-		// they would in a non-bp2build mode invocation
-		if ctx.Config().Bp2buildMode() && source != nil {
-			productVariableProps, errs := ProductVariableProperties(ctx, source)
-			if productConfigProps, exists := productVariableProps["Enabled"]; len(errs) == 0 && exists && len(productConfigProps) == 1 {
-				var prop ProductConfigOrSoongConfigProperty
-				var value bool
-				for p, v := range productConfigProps {
-					prop = p
-					actual, ok := v.(*bool)
-					if ok {
-						value = proptools.Bool(actual)
-					}
-				}
-				if scv, ok := prop.(SoongConfigProperty); ok {
-					// If the product config var is enabled but the value of enabled is false still, the
-					// prebuilt is preferred. Otherwise, check if the prebulit is explicitly preferred
-					if ctx.Config().VendorConfig(scv.namespace).Bool(strings.ToLower(scv.name)) && !value {
-						return true
-					}
-				} else {
-					// TODO: b/300998219 - handle product vars
-					// We don't handle product variables yet, so return based on the non-product specific
-					// value of enabled
-					return true
-				}
-			} else {
-				// No "enabled" property override, return true since this module isn't enabled
-				return true
-			}
-		} else {
-			return true
-		}
+		return true
 	}
 
 	// If the use_source_config_var property is set then it overrides the prefer property setting.
diff --git a/android/register.go b/android/register.go
index de31353..cd968cd 100644
--- a/android/register.go
+++ b/android/register.go
@@ -15,15 +15,9 @@
 package android
 
 import (
-	"bufio"
 	"fmt"
-	"path/filepath"
-	"reflect"
-	"regexp"
-
-	"android/soong/shared"
-
 	"github.com/google/blueprint"
+	"reflect"
 )
 
 // A sortable component is one whose registration order affects the order in which it is executed
@@ -166,75 +160,6 @@
 	return ctx
 }
 
-// Helper function to register the module types used in bp2build.
-func registerModuleTypes(ctx *Context) {
-	for _, t := range moduleTypes {
-		t.register(ctx)
-	}
-	// Required for SingletonModule types, even though we are not using them.
-	for _, t := range singletons {
-		t.register(ctx)
-	}
-}
-
-// RegisterForBazelConversion registers an alternate shadow pipeline of
-// singletons, module types and mutators to register for converting Blueprint
-// files to semantically equivalent BUILD files.
-func (ctx *Context) RegisterForBazelConversion() {
-	registerModuleTypes(ctx)
-	RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators)
-}
-
-// RegisterExistingBazelTargets reads Bazel BUILD.bazel and BUILD files under
-// the workspace, and returns a map containing names of Bazel targets defined in
-// these BUILD files.
-// For example, maps "//foo/bar" to ["baz", "qux"] if `//foo/bar:{baz,qux}` exist.
-func (c *Context) RegisterExistingBazelTargets(topDir string, existingBazelFiles []string) error {
-	result := map[string][]string{}
-
-	// Search for instances of `name = "$NAME"` (with arbitrary spacing).
-	targetNameRegex := regexp.MustCompile(`(?m)^\s*name\s*=\s*\"([^\"]+)\"`)
-
-	parseBuildFile := func(path string) error {
-		fullPath := shared.JoinPath(topDir, path)
-		sourceDir := filepath.Dir(path)
-
-		fileInfo, err := c.Config().fs.Stat(fullPath)
-		if err != nil {
-			return fmt.Errorf("Error accessing Bazel file '%s': %s", path, err)
-		}
-		if !fileInfo.IsDir() &&
-			(fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
-			f, err := c.Config().fs.Open(fullPath)
-			if err != nil {
-				return fmt.Errorf("Error reading Bazel file '%s': %s", path, err)
-			}
-			defer f.Close()
-			scanner := bufio.NewScanner(f)
-			for scanner.Scan() {
-				line := scanner.Text()
-				matches := targetNameRegex.FindAllStringSubmatch(line, -1)
-				for _, match := range matches {
-					result[sourceDir] = append(result[sourceDir], match[1])
-				}
-			}
-		}
-		return nil
-	}
-
-	for _, path := range existingBazelFiles {
-		if !c.Config().Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(filepath.Dir(path)) {
-			continue
-		}
-		err := parseBuildFile(path)
-		if err != nil {
-			return err
-		}
-	}
-	c.Config().SetBazelBuildFileTargets(result)
-	return nil
-}
-
 // Register the pipeline of singletons, module types, and mutators for
 // generating build.ninja and other files for Kati, from Android.bp files.
 func (ctx *Context) Register() {
@@ -260,8 +185,6 @@
 func collateGloballyRegisteredSingletons() sortableComponents {
 	allSingletons := append(sortableComponents(nil), singletons...)
 	allSingletons = append(allSingletons,
-		singleton{parallel: true, name: "bazeldeps", factory: BazelSingleton},
-
 		// Register phony just before makevars so it can write out its phony rules as Make rules
 		singleton{parallel: false, name: "phony", factory: phonySingletonFactory},
 
diff --git a/android/test_config.go b/android/test_config.go
index 2a59d92..9e1ac70 100644
--- a/android/test_config.go
+++ b/android/test_config.go
@@ -61,11 +61,7 @@
 		// passed to PathForSource or PathForModuleSrc.
 		TestAllowNonExistentPaths: true,
 
-		BazelContext:              noopBazelContext{},
-		BuildMode:                 BazelProdMode,
-		mixedBuildDisabledModules: make(map[string]struct{}),
-		mixedBuildEnabledModules:  make(map[string]struct{}),
-		bazelForceEnabledModules:  make(map[string]struct{}),
+		BuildMode: AnalysisNoBazel,
 	}
 	config.deviceConfig = &deviceConfig{
 		config: config,
diff --git a/android/testing.go b/android/testing.go
index c596468..fa4dffd 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -219,10 +219,6 @@
 	ctx.finalDeps = append(ctx.finalDeps, f)
 }
 
-func (ctx *TestContext) RegisterBp2BuildConfig(config Bp2BuildConversionAllowlist) {
-	ctx.config.Bp2buildPackageConfig = config
-}
-
 // PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
 // into Bazel BUILD targets that should run prior to deps and conversion.
 func (ctx *TestContext) PreArchBp2BuildMutators(f RegisterMutatorFunc) {
@@ -449,12 +445,6 @@
 	ctx.singletonOrder = componentsToNames(singletons)
 }
 
-// RegisterForBazelConversion prepares a test context for bp2build conversion.
-func (ctx *TestContext) RegisterForBazelConversion() {
-	ctx.config.BuildMode = Bp2build
-	RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch)
-}
-
 func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {
 	// This function adapts the old style ParseFileList calls that are spread throughout the tests
 	// to the new style that takes a config.
diff --git a/android/util.go b/android/util.go
index f687bca..ae1c657 100644
--- a/android/util.go
+++ b/android/util.go
@@ -591,3 +591,9 @@
 	}
 	return "", false
 }
+
+func AddToStringSet(set map[string]bool, items []string) {
+	for _, item := range items {
+		set[item] = true
+	}
+}
diff --git a/android/variable.go b/android/variable.go
index aecad3b..fa4cfc1 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -20,7 +20,6 @@
 	"runtime"
 	"strings"
 
-	"android/soong/android/soongconfig"
 	"android/soong/bazel"
 
 	"github.com/google/blueprint/proptools"
@@ -746,44 +745,6 @@
 // property, like ["-DDEFINES"] for cflags.
 type ProductConfigProperties map[string]map[ProductConfigOrSoongConfigProperty]interface{}
 
-// ProductVariableProperties returns a ProductConfigProperties containing only the properties which
-// have been set for the given module.
-func ProductVariableProperties(ctx ArchVariantContext, module Module) (ProductConfigProperties, []error) {
-	var errs []error
-	moduleBase := module.base()
-
-	productConfigProperties := ProductConfigProperties{}
-
-	if moduleBase.variableProperties != nil {
-		productVariablesProperty := proptools.FieldNameForProperty("product_variables")
-		if moduleBase.ArchSpecific() {
-			for /* axis */ _, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
-				for config, props := range configToProps {
-					variableValues := reflect.ValueOf(props).Elem().FieldByName(productVariablesProperty)
-					productConfigProperties.AddProductConfigProperties(variableValues, config)
-				}
-			}
-		} else {
-			variableValues := reflect.ValueOf(moduleBase.variableProperties).Elem().FieldByName(productVariablesProperty)
-			productConfigProperties.AddProductConfigProperties(variableValues, "")
-		}
-	}
-
-	if m, ok := module.(Bazelable); ok && m.namespacedVariableProps() != nil {
-		for namespace, namespacedVariableProps := range m.namespacedVariableProps() {
-			for _, namespacedVariableProp := range namespacedVariableProps {
-				variableValues := reflect.ValueOf(namespacedVariableProp).Elem().FieldByName(soongconfig.SoongConfigProperty)
-				err := productConfigProperties.AddSoongConfigProperties(namespace, variableValues)
-				if err != nil {
-					errs = append(errs, err)
-				}
-			}
-		}
-	}
-
-	return productConfigProperties, errs
-}
-
 func (p *ProductConfigProperties) AddProductConfigProperty(
 	propertyName, productVariableName, arch string, propertyValue interface{}) {
 
@@ -833,10 +794,6 @@
 	}
 }
 
-var (
-	conditionsDefaultField string = proptools.FieldNameForProperty(bazel.ConditionsDefaultConfigKey)
-)
-
 // maybeExtractConfigVarProp attempts to read this value as a config var struct
 // wrapped by interfaces and ptrs. If it's not the right type, the second return
 // value is false.
