diff --git a/bazel/Android.bp b/bazel/Android.bp
deleted file mode 100644
index f8273a8..0000000
--- a/bazel/Android.bp
+++ /dev/null
@@ -1,22 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-bootstrap_go_package {
-    name: "soong-bazel",
-    pkgPath: "android/soong/bazel",
-    srcs: [
-        "configurability.go",
-        "properties.go",
-        "testing.go",
-    ],
-    testSrcs: [
-        "properties_test.go",
-    ],
-    pluginFor: [
-        "soong_build",
-    ],
-    deps: [
-        "blueprint",
-    ],
-}
diff --git a/bazel/configurability.go b/bazel/configurability.go
deleted file mode 100644
index 3a65614..0000000
--- a/bazel/configurability.go
+++ /dev/null
@@ -1,391 +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 bazel
-
-import (
-	"fmt"
-	"math"
-	"sort"
-	"strings"
-)
-
-const (
-	// ArchType names in arch.go
-	archArm     = "arm"
-	archArm64   = "arm64"
-	archRiscv64 = "riscv64"
-	archX86     = "x86"
-	archX86_64  = "x86_64"
-
-	// OsType names in arch.go
-	OsAndroid     = "android"
-	OsDarwin      = "darwin"
-	OsLinux       = "linux_glibc"
-	osLinuxMusl   = "linux_musl"
-	osLinuxBionic = "linux_bionic"
-	OsWindows     = "windows"
-
-	// Targets in arch.go
-	osArchAndroidArm        = "android_arm"
-	OsArchAndroidArm64      = "android_arm64"
-	osArchAndroidRiscv64    = "android_riscv64"
-	osArchAndroidX86        = "android_x86"
-	osArchAndroidX86_64     = "android_x86_64"
-	osArchDarwinArm64       = "darwin_arm64"
-	osArchDarwinX86_64      = "darwin_x86_64"
-	osArchLinuxX86          = "linux_glibc_x86"
-	osArchLinuxX86_64       = "linux_glibc_x86_64"
-	osArchLinuxMuslArm      = "linux_musl_arm"
-	osArchLinuxMuslArm64    = "linux_musl_arm64"
-	osArchLinuxMuslX86      = "linux_musl_x86"
-	osArchLinuxMuslX86_64   = "linux_musl_x86_64"
-	osArchLinuxBionicArm64  = "linux_bionic_arm64"
-	osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
-	osArchWindowsX86        = "windows_x86"
-	osArchWindowsX86_64     = "windows_x86_64"
-
-	// This is the string representation of the default condition wherever a
-	// configurable attribute is used in a select statement, i.e.
-	// //conditions:default for Bazel.
-	//
-	// This is consistently named "conditions_default" to mirror the Soong
-	// config variable default key in an Android.bp file, although there's no
-	// integration with Soong config variables (yet).
-	ConditionsDefaultConfigKey = "conditions_default"
-
-	ConditionsDefaultSelectKey = "//conditions:default"
-
-	productVariableBazelPackage = "//build/bazel/product_config/config_settings"
-
-	AndroidAndInApex = "android-in_apex"
-	AndroidPlatform  = "system"
-	Unbundled_app    = "unbundled_app"
-
-	InApex  = "in_apex"
-	NonApex = "non_apex"
-
-	ErrorproneDisabled = "errorprone_disabled"
-	// TODO: b/294868620 - Remove when completing the bug
-	SanitizersEnabled = "sanitizers_enabled"
-)
-
-func PowerSetWithoutEmptySet[T any](items []T) [][]T {
-	resultSize := int(math.Pow(2, float64(len(items))))
-	powerSet := make([][]T, 0, resultSize-1)
-	for i := 1; i < resultSize; i++ {
-		combination := make([]T, 0)
-		for j := 0; j < len(items); j++ {
-			if (i>>j)%2 == 1 {
-				combination = append(combination, items[j])
-			}
-		}
-		powerSet = append(powerSet, combination)
-	}
-	return powerSet
-}
-
-func createPlatformArchMap() map[string]string {
-	// Copy of archFeatures from android/arch_list.go because the bazel
-	// package can't access the android package
-	archFeatures := map[string][]string{
-		"arm": {},
-		"arm64": {
-			"dotprod",
-		},
-		"riscv64": {},
-		"x86": {
-			"ssse3",
-			"sse4",
-			"sse4_1",
-			"sse4_2",
-			"aes_ni",
-			"avx",
-			"avx2",
-			"avx512",
-			"popcnt",
-			"movbe",
-		},
-		"x86_64": {
-			"ssse3",
-			"sse4",
-			"sse4_1",
-			"sse4_2",
-			"aes_ni",
-			"avx",
-			"avx2",
-			"avx512",
-			"popcnt",
-		},
-	}
-	result := make(map[string]string)
-	for arch, allFeatures := range archFeatures {
-		result[arch] = "//build/bazel_common_rules/platforms/arch:" + arch
-		// Sometimes we want to select on multiple features being active, so
-		// add the power set of all possible features to the map. More details
-		// in android.ModuleBase.GetArchVariantProperties
-		for _, features := range PowerSetWithoutEmptySet(allFeatures) {
-			sort.Strings(features)
-			archFeaturesName := arch + "-" + strings.Join(features, "-")
-			result[archFeaturesName] = "//build/bazel/platforms/arch/variants:" + archFeaturesName
-		}
-	}
-	result[ConditionsDefaultConfigKey] = ConditionsDefaultSelectKey
-	return result
-}
-
-var (
-	// These are the list of OSes and architectures with a Bazel config_setting
-	// and constraint value equivalent. These exist in arch.go, but the android
-	// package depends on the bazel package, so a cyclic dependency prevents
-	// using those variables here.
-
-	// A map of architectures to the Bazel label of the constraint_value
-	// for the @platforms//cpu:cpu constraint_setting
-	platformArchMap = createPlatformArchMap()
-
-	// A map of target operating systems to the Bazel label of the
-	// constraint_value for the @platforms//os:os constraint_setting
-	platformOsMap = map[string]string{
-		OsAndroid:                  "//build/bazel_common_rules/platforms/os:android",
-		OsDarwin:                   "//build/bazel_common_rules/platforms/os:darwin",
-		OsLinux:                    "//build/bazel_common_rules/platforms/os:linux_glibc",
-		osLinuxMusl:                "//build/bazel_common_rules/platforms/os:linux_musl",
-		osLinuxBionic:              "//build/bazel_common_rules/platforms/os:linux_bionic",
-		OsWindows:                  "//build/bazel_common_rules/platforms/os:windows",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
-	}
-
-	platformOsArchMap = map[string]string{
-		osArchAndroidArm:           "//build/bazel_common_rules/platforms/os_arch:android_arm",
-		OsArchAndroidArm64:         "//build/bazel_common_rules/platforms/os_arch:android_arm64",
-		osArchAndroidRiscv64:       "//build/bazel_common_rules/platforms/os_arch:android_riscv64",
-		osArchAndroidX86:           "//build/bazel_common_rules/platforms/os_arch:android_x86",
-		osArchAndroidX86_64:        "//build/bazel_common_rules/platforms/os_arch:android_x86_64",
-		osArchDarwinArm64:          "//build/bazel_common_rules/platforms/os_arch:darwin_arm64",
-		osArchDarwinX86_64:         "//build/bazel_common_rules/platforms/os_arch:darwin_x86_64",
-		osArchLinuxX86:             "//build/bazel_common_rules/platforms/os_arch:linux_glibc_x86",
-		osArchLinuxX86_64:          "//build/bazel_common_rules/platforms/os_arch:linux_glibc_x86_64",
-		osArchLinuxMuslArm:         "//build/bazel_common_rules/platforms/os_arch:linux_musl_arm",
-		osArchLinuxMuslArm64:       "//build/bazel_common_rules/platforms/os_arch:linux_musl_arm64",
-		osArchLinuxMuslX86:         "//build/bazel_common_rules/platforms/os_arch:linux_musl_x86",
-		osArchLinuxMuslX86_64:      "//build/bazel_common_rules/platforms/os_arch:linux_musl_x86_64",
-		osArchLinuxBionicArm64:     "//build/bazel_common_rules/platforms/os_arch:linux_bionic_arm64",
-		osArchLinuxBionicX86_64:    "//build/bazel_common_rules/platforms/os_arch:linux_bionic_x86_64",
-		osArchWindowsX86:           "//build/bazel_common_rules/platforms/os_arch:windows_x86",
-		osArchWindowsX86_64:        "//build/bazel_common_rules/platforms/os_arch:windows_x86_64",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
-	}
-
-	// Map where keys are OsType names, and values are slices containing the archs
-	// that that OS supports.
-	// These definitions copied from arch.go.
-	// TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results
-	// in a cyclic dependency.
-	osToArchMap = map[string][]string{
-		OsAndroid:     {archArm, archArm64, archRiscv64, archX86, archX86_64},
-		OsLinux:       {archX86, archX86_64},
-		osLinuxMusl:   {archX86, archX86_64},
-		OsDarwin:      {archArm64, archX86_64},
-		osLinuxBionic: {archArm64, archX86_64},
-		// TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
-		OsWindows: {archX86, archX86_64},
-	}
-
-	osAndInApexMap = map[string]string{
-		AndroidAndInApex:           "//build/bazel/rules/apex:android-in_apex",
-		AndroidPlatform:            "//build/bazel/rules/apex:system",
-		Unbundled_app:              "//build/bazel/rules/apex:unbundled_app",
-		OsDarwin:                   "//build/bazel_common_rules/platforms/os:darwin",
-		OsLinux:                    "//build/bazel_common_rules/platforms/os:linux_glibc",
-		osLinuxMusl:                "//build/bazel_common_rules/platforms/os:linux_musl",
-		osLinuxBionic:              "//build/bazel_common_rules/platforms/os:linux_bionic",
-		OsWindows:                  "//build/bazel_common_rules/platforms/os:windows",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
-	}
-
-	inApexMap = map[string]string{
-		InApex:                     "//build/bazel/rules/apex:in_apex",
-		NonApex:                    "//build/bazel/rules/apex:non_apex",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
-	}
-
-	errorProneMap = map[string]string{
-		ErrorproneDisabled:         "//build/bazel/rules/java/errorprone:errorprone_globally_disabled",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
-	}
-
-	// TODO: b/294868620 - Remove when completing the bug
-	sanitizersEnabledMap = map[string]string{
-		SanitizersEnabled:          "//build/bazel/rules/cc:sanitizers_enabled",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
-	}
-)
-
-// basic configuration types
-type configurationType int
-
-const (
-	noConfig configurationType = iota
-	arch
-	os
-	osArch
-	productVariables
-	osAndInApex
-	inApex
-	errorProneDisabled
-	// TODO: b/294868620 - Remove when completing the bug
-	sanitizersEnabled
-)
-
-func osArchString(os string, arch string) string {
-	return fmt.Sprintf("%s_%s", os, arch)
-}
-
-func (ct configurationType) String() string {
-	return map[configurationType]string{
-		noConfig:           "no_config",
-		arch:               "arch",
-		os:                 "os",
-		osArch:             "arch_os",
-		productVariables:   "product_variables",
-		osAndInApex:        "os_in_apex",
-		inApex:             "in_apex",
-		errorProneDisabled: "errorprone_disabled",
-		// TODO: b/294868620 - Remove when completing the bug
-		sanitizersEnabled: "sanitizers_enabled",
-	}[ct]
-}
-
-func (ct configurationType) validateConfig(config string) {
-	switch ct {
-	case noConfig:
-		if config != "" {
-			panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
-		}
-	case arch:
-		if _, ok := platformArchMap[config]; !ok {
-			panic(fmt.Errorf("Unknown arch: %s", config))
-		}
-	case os:
-		if _, ok := platformOsMap[config]; !ok {
-			panic(fmt.Errorf("Unknown os: %s", config))
-		}
-	case osArch:
-		if _, ok := platformOsArchMap[config]; !ok {
-			panic(fmt.Errorf("Unknown os+arch: %s", config))
-		}
-	case productVariables:
-		// do nothing
-	case osAndInApex:
-		// do nothing
-		// this axis can contain additional per-apex keys
-	case inApex:
-		if _, ok := inApexMap[config]; !ok {
-			panic(fmt.Errorf("Unknown in_apex config: %s", config))
-		}
-	case errorProneDisabled:
-		if _, ok := errorProneMap[config]; !ok {
-			panic(fmt.Errorf("Unknown errorprone config: %s", config))
-		}
-	// TODO: b/294868620 - Remove when completing the bug
-	case sanitizersEnabled:
-		if _, ok := sanitizersEnabledMap[config]; !ok {
-			panic(fmt.Errorf("Unknown sanitizers_enabled config: %s", config))
-		}
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
-	}
-}
-
-// SelectKey returns the Bazel select key for a given configurationType and config string.
-func (ca ConfigurationAxis) SelectKey(config string) string {
-	ca.validateConfig(config)
-	switch ca.configurationType {
-	case noConfig:
-		panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
-	case arch:
-		return platformArchMap[config]
-	case os:
-		return platformOsMap[config]
-	case osArch:
-		return platformOsArchMap[config]
-	case productVariables:
-		if config == ConditionsDefaultConfigKey {
-			return ConditionsDefaultSelectKey
-		}
-		return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
-	case osAndInApex:
-		if ret, exists := osAndInApexMap[config]; exists {
-			return ret
-		}
-		return config
-	case inApex:
-		return inApexMap[config]
-	case errorProneDisabled:
-		return errorProneMap[config]
-	// TODO: b/294868620 - Remove when completing the bug
-	case sanitizersEnabled:
-		return sanitizersEnabledMap[config]
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationType %d", ca.configurationType))
-	}
-}
-
-var (
-	// Indicating there is no configuration axis
-	NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
-	// An axis for architecture-specific configurations
-	ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
-	// An axis for os-specific configurations
-	OsConfigurationAxis = ConfigurationAxis{configurationType: os}
-	// An axis for arch+os-specific configurations
-	OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
-	// An axis for os+in_apex-specific configurations
-	OsAndInApexAxis = ConfigurationAxis{configurationType: osAndInApex}
-	// An axis for in_apex-specific configurations
-	InApexAxis = ConfigurationAxis{configurationType: inApex}
-
-	ErrorProneAxis = ConfigurationAxis{configurationType: errorProneDisabled}
-
-	// TODO: b/294868620 - Remove when completing the bug
-	SanitizersEnabledAxis = ConfigurationAxis{configurationType: sanitizersEnabled}
-)
-
-// ProductVariableConfigurationAxis returns an axis for the given product variable
-func ProductVariableConfigurationAxis(archVariant bool, variable string) ConfigurationAxis {
-	return ConfigurationAxis{
-		configurationType: productVariables,
-		subType:           variable,
-		archVariant:       archVariant,
-	}
-}
-
-// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
-// elements within an axis.
-type ConfigurationAxis struct {
-	configurationType
-	// some configuration types (e.g. productVariables) have multiple independent axes, subType helps
-	// distinguish between them without needing to list all 17 product variables.
-	subType string
-
-	archVariant bool
-}
-
-func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
-	if ca.configurationType == other.configurationType {
-		return ca.subType < other.subType
-	}
-	return ca.configurationType < other.configurationType
-}
diff --git a/bazel/properties.go b/bazel/properties.go
deleted file mode 100644
index 9c63bc0..0000000
--- a/bazel/properties.go
+++ /dev/null
@@ -1,1467 +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 bazel
-
-import (
-	"fmt"
-	"path/filepath"
-	"reflect"
-	"regexp"
-	"sort"
-	"strings"
-
-	"github.com/google/blueprint"
-)
-
-// BazelTargetModuleProperties contain properties and metadata used for
-// Blueprint to BUILD file conversion.
-type BazelTargetModuleProperties struct {
-	// The Bazel rule class for this target.
-	Rule_class string `blueprint:"mutated"`
-
-	// The target label for the bzl file containing the definition of the rule class.
-	Bzl_load_location string `blueprint:"mutated"`
-}
-
-var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
-
-// Label is used to represent a Bazel compatible Label. Also stores the original
-// bp text to support string replacement.
-type Label struct {
-	// The string representation of a Bazel target label. This can be a relative
-	// or fully qualified label. These labels are used for generating BUILD
-	// files with bp2build.
-	Label string
-
-	// The original Soong/Blueprint module name that the label was derived from.
-	// This is used for replacing references to the original name with the new
-	// label, for example in genrule cmds.
-	//
-	// While there is a reversible 1:1 mapping from the module name to Bazel
-	// label with bp2build that could make computing the original module name
-	// from the label automatic, it is not the case for handcrafted targets,
-	// where modules can have a custom label mapping through the { bazel_module:
-	// { label: <label> } } property.
-	//
-	// With handcrafted labels, those modules don't go through bp2build
-	// conversion, but relies on handcrafted targets in the source tree.
-	OriginalModuleName string
-}
-
-// LabelList is used to represent a list of Bazel labels.
-type LabelList struct {
-	Includes []Label
-	Excludes []Label
-}
-
-// MakeLabelList creates a LabelList from a list Label
-func MakeLabelList(labels []Label) LabelList {
-	return LabelList{
-		Includes: labels,
-		Excludes: nil,
-	}
-}
-
-func SortedConfigurationAxes[T any](m map[ConfigurationAxis]T) []ConfigurationAxis {
-	keys := make([]ConfigurationAxis, 0, len(m))
-	for k := range m {
-		keys = append(keys, k)
-	}
-
-	sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
-	return keys
-}
-
-// MakeLabelListFromTargetNames creates a LabelList from unqualified target names
-// This is a utiltity function for bp2build converters of Soong modules that have 1:many generated targets
-func MakeLabelListFromTargetNames(targetNames []string) LabelList {
-	labels := []Label{}
-	for _, name := range targetNames {
-		label := Label{Label: ":" + name}
-		labels = append(labels, label)
-	}
-	return MakeLabelList(labels)
-}
-
-func (ll *LabelList) Equals(other LabelList) bool {
-	if len(ll.Includes) != len(other.Includes) || len(ll.Excludes) != len(other.Excludes) {
-		return false
-	}
-	for i, _ := range ll.Includes {
-		if ll.Includes[i] != other.Includes[i] {
-			return false
-		}
-	}
-	for i, _ := range ll.Excludes {
-		if ll.Excludes[i] != other.Excludes[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func (ll *LabelList) IsNil() bool {
-	return ll.Includes == nil && ll.Excludes == nil
-}
-
-func (ll *LabelList) IsEmpty() bool {
-	return len(ll.Includes) == 0 && len(ll.Excludes) == 0
-}
-
-func (ll *LabelList) deepCopy() LabelList {
-	return LabelList{
-		Includes: ll.Includes[:],
-		Excludes: ll.Excludes[:],
-	}
-}
-
-// uniqueParentDirectories returns a list of the unique parent directories for
-// all files in ll.Includes.
-func (ll *LabelList) uniqueParentDirectories() []string {
-	dirMap := map[string]bool{}
-	for _, label := range ll.Includes {
-		dirMap[filepath.Dir(label.Label)] = true
-	}
-	dirs := []string{}
-	for dir := range dirMap {
-		dirs = append(dirs, dir)
-	}
-	return dirs
-}
-
-// Add inserts the label Label at the end of the LabelList.Includes.
-func (ll *LabelList) Add(label *Label) {
-	if label == nil {
-		return
-	}
-	ll.Includes = append(ll.Includes, *label)
-}
-
-// AddExclude inserts the label Label at the end of the LabelList.Excludes.
-func (ll *LabelList) AddExclude(label *Label) {
-	if label == nil {
-		return
-	}
-	ll.Excludes = append(ll.Excludes, *label)
-}
-
-// Append appends the fields of other labelList to the corresponding fields of ll.
-func (ll *LabelList) Append(other LabelList) {
-	if len(ll.Includes) > 0 || len(other.Includes) > 0 {
-		ll.Includes = append(ll.Includes, other.Includes...)
-	}
-	if len(ll.Excludes) > 0 || len(other.Excludes) > 0 {
-		ll.Excludes = append(ll.Excludes, other.Excludes...)
-	}
-}
-
-// Partition splits a LabelList into two LabelLists depending on the return value
-// of the predicate.
-// This function preserves the Includes and Excludes, but it does not provide
-// that information to the partition function.
-func (ll *LabelList) Partition(predicate func(label Label) bool) (LabelList, LabelList) {
-	predicated := LabelList{}
-	unpredicated := LabelList{}
-	for _, include := range ll.Includes {
-		if predicate(include) {
-			predicated.Add(&include)
-		} else {
-			unpredicated.Add(&include)
-		}
-	}
-	for _, exclude := range ll.Excludes {
-		if predicate(exclude) {
-			predicated.AddExclude(&exclude)
-		} else {
-			unpredicated.AddExclude(&exclude)
-		}
-	}
-	return predicated, unpredicated
-}
-
-// UniqueSortedBazelLabels takes a []Label and deduplicates the labels, and returns
-// the slice in a sorted order.
-func UniqueSortedBazelLabels(originalLabels []Label) []Label {
-	uniqueLabels := FirstUniqueBazelLabels(originalLabels)
-	sort.SliceStable(uniqueLabels, func(i, j int) bool {
-		return uniqueLabels[i].Label < uniqueLabels[j].Label
-	})
-	return uniqueLabels
-}
-
-func FirstUniqueBazelLabels(originalLabels []Label) []Label {
-	var labels []Label
-	found := make(map[string]bool, len(originalLabels))
-	for _, l := range originalLabels {
-		if _, ok := found[l.Label]; ok {
-			continue
-		}
-		labels = append(labels, l)
-		found[l.Label] = true
-	}
-	return labels
-}
-
-func FirstUniqueBazelLabelList(originalLabelList LabelList) LabelList {
-	var uniqueLabelList LabelList
-	uniqueLabelList.Includes = FirstUniqueBazelLabels(originalLabelList.Includes)
-	uniqueLabelList.Excludes = FirstUniqueBazelLabels(originalLabelList.Excludes)
-	return uniqueLabelList
-}
-
-func UniqueSortedBazelLabelList(originalLabelList LabelList) LabelList {
-	var uniqueLabelList LabelList
-	uniqueLabelList.Includes = UniqueSortedBazelLabels(originalLabelList.Includes)
-	uniqueLabelList.Excludes = UniqueSortedBazelLabels(originalLabelList.Excludes)
-	return uniqueLabelList
-}
-
-// Subtract needle from haystack
-func SubtractStrings(haystack []string, needle []string) []string {
-	// This is really a set
-	needleMap := make(map[string]bool)
-	for _, s := range needle {
-		needleMap[s] = true
-	}
-
-	var strings []string
-	for _, s := range haystack {
-		if exclude := needleMap[s]; !exclude {
-			strings = append(strings, s)
-		}
-	}
-
-	return strings
-}
-
-// Subtract needle from haystack
-func SubtractBazelLabels(haystack []Label, needle []Label) []Label {
-	// This is really a set
-	needleMap := make(map[Label]bool)
-	for _, s := range needle {
-		needleMap[s] = true
-	}
-
-	var labels []Label
-	for _, label := range haystack {
-		if exclude := needleMap[label]; !exclude {
-			labels = append(labels, label)
-		}
-	}
-
-	return labels
-}
-
-// Appends two LabelLists, returning the combined list.
-func AppendBazelLabelLists(a LabelList, b LabelList) LabelList {
-	var result LabelList
-	result.Includes = append(a.Includes, b.Includes...)
-	result.Excludes = append(a.Excludes, b.Excludes...)
-	return result
-}
-
-// Subtract needle from haystack
-func SubtractBazelLabelList(haystack LabelList, needle LabelList) LabelList {
-	var result LabelList
-	result.Includes = SubtractBazelLabels(haystack.Includes, needle.Includes)
-	// NOTE: Excludes are intentionally not subtracted
-	result.Excludes = haystack.Excludes
-	return result
-}
-
-// FirstUniqueBazelLabelListAttribute takes a LabelListAttribute and makes the LabelList for
-// each axis/configuration by keeping the first instance of a Label and omitting all subsequent
-// repetitions.
-func FirstUniqueBazelLabelListAttribute(attr LabelListAttribute) LabelListAttribute {
-	var result LabelListAttribute
-	result.Value = FirstUniqueBazelLabelList(attr.Value)
-	if attr.HasConfigurableValues() {
-		result.ConfigurableValues = make(configurableLabelLists)
-	}
-	for axis, configToLabels := range attr.ConfigurableValues {
-		for c, l := range configToLabels {
-			result.SetSelectValue(axis, c, FirstUniqueBazelLabelList(l))
-		}
-	}
-
-	return result
-}
-
-// SubtractBazelLabelListAttribute subtract needle from haystack for LabelList in each
-// axis/configuration.
-func SubtractBazelLabelListAttribute(haystack LabelListAttribute, needle LabelListAttribute) LabelListAttribute {
-	var result LabelListAttribute
-	result.Value = SubtractBazelLabelList(haystack.Value, needle.Value)
-	if haystack.HasConfigurableValues() {
-		result.ConfigurableValues = make(configurableLabelLists)
-	}
-	for axis, configToLabels := range haystack.ConfigurableValues {
-		for haystackConfig, haystackLabels := range configToLabels {
-			result.SetSelectValue(axis, haystackConfig, SubtractBazelLabelList(haystackLabels, needle.SelectValue(axis, haystackConfig)))
-		}
-	}
-
-	return result
-}
-
-type Attribute interface {
-	HasConfigurableValues() bool
-}
-
-type labelSelectValues map[string]*Label
-
-type configurableLabels map[ConfigurationAxis]labelSelectValues
-
-func (cl configurableLabels) setValueForAxis(axis ConfigurationAxis, config string, value *Label) {
-	if cl[axis] == nil {
-		cl[axis] = make(labelSelectValues)
-	}
-	cl[axis][config] = value
-}
-
-// Represents an attribute whose value is a single label
-type LabelAttribute struct {
-	Value *Label
-
-	ConfigurableValues configurableLabels
-}
-
-func (la *LabelAttribute) axisTypes() map[configurationType]bool {
-	types := map[configurationType]bool{}
-	for k := range la.ConfigurableValues {
-		if len(la.ConfigurableValues[k]) > 0 {
-			types[k.configurationType] = true
-		}
-	}
-	return types
-}
-
-// Collapse reduces the configurable axes of the label attribute to a single axis.
-// This is necessary for final writing to bp2build, as a configurable label
-// attribute can only be comprised by a single select.
-func (la *LabelAttribute) Collapse() error {
-	axisTypes := la.axisTypes()
-	_, containsOs := axisTypes[os]
-	_, containsArch := axisTypes[arch]
-	_, containsOsArch := axisTypes[osArch]
-	_, containsProductVariables := axisTypes[productVariables]
-	if containsProductVariables {
-		if containsOs || containsArch || containsOsArch {
-			if containsArch {
-				allProductVariablesAreArchVariant := true
-				for k := range la.ConfigurableValues {
-					if k.configurationType == productVariables && !k.archVariant {
-						allProductVariablesAreArchVariant = false
-					}
-				}
-				if !allProductVariablesAreArchVariant {
-					return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
-				}
-			} else {
-				return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
-			}
-		}
-	}
-	if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
-		// If a bool attribute has both os and arch configuration axes, the only
-		// way to successfully union their values is to increase the granularity
-		// of the configuration criteria to os_arch.
-		for osType, supportedArchs := range osToArchMap {
-			for _, supportedArch := range supportedArchs {
-				osArch := osArchString(osType, supportedArch)
-				if archOsVal := la.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
-					// Do nothing, as the arch_os is explicitly defined already.
-				} else {
-					archVal := la.SelectValue(ArchConfigurationAxis, supportedArch)
-					osVal := la.SelectValue(OsConfigurationAxis, osType)
-					if osVal != nil && archVal != nil {
-						// In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
-						// runs after os mutator.
-						la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal)
-					} else if osVal != nil && archVal == nil {
-						la.SetSelectValue(OsArchConfigurationAxis, osArch, *osVal)
-					} else if osVal == nil && archVal != nil {
-						la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal)
-					}
-				}
-			}
-		}
-		// All os_arch values are now set. Clear os and arch axes.
-		delete(la.ConfigurableValues, ArchConfigurationAxis)
-		delete(la.ConfigurableValues, OsConfigurationAxis)
-	}
-	return nil
-}
-
-// HasConfigurableValues returns whether there are configurable values set for this label.
-func (la LabelAttribute) HasConfigurableValues() bool {
-	for _, selectValues := range la.ConfigurableValues {
-		if len(selectValues) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// SetValue sets the base, non-configured value for the Label
-func (la *LabelAttribute) SetValue(value Label) {
-	la.SetSelectValue(NoConfigAxis, "", value)
-}
-
-// SetSelectValue set a value for a bazel select for the given axis, config and value.
-func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, value Label) {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		la.Value = &value
-	case arch, os, osArch, productVariables, osAndInApex, sanitizersEnabled:
-		if la.ConfigurableValues == nil {
-			la.ConfigurableValues = make(configurableLabels)
-		}
-		la.ConfigurableValues.setValueForAxis(axis, config, &value)
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SelectValue gets a value for a bazel select for the given axis and config.
-func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) *Label {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		return la.Value
-	case arch, os, osArch, productVariables, osAndInApex, sanitizersEnabled:
-		return la.ConfigurableValues[axis][config]
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
-func (la *LabelAttribute) SortedConfigurationAxes() []ConfigurationAxis {
-	return SortedConfigurationAxes(la.ConfigurableValues)
-}
-
-// MakeLabelAttribute turns a string into a LabelAttribute
-func MakeLabelAttribute(label string) *LabelAttribute {
-	return &LabelAttribute{
-		Value: &Label{
-			Label: label,
-		},
-	}
-}
-
-type configToBools map[string]bool
-
-func (ctb configToBools) setValue(config string, value *bool) {
-	if value == nil {
-		if _, ok := ctb[config]; ok {
-			delete(ctb, config)
-		}
-		return
-	}
-	ctb[config] = *value
-}
-
-type configurableBools map[ConfigurationAxis]configToBools
-
-func (cb configurableBools) setValueForAxis(axis ConfigurationAxis, config string, value *bool) {
-	if cb[axis] == nil {
-		cb[axis] = make(configToBools)
-	}
-	cb[axis].setValue(config, value)
-}
-
-// BoolAttribute represents an attribute whose value is a single bool but may be configurable..
-type BoolAttribute struct {
-	Value *bool
-
-	ConfigurableValues configurableBools
-}
-
-// HasConfigurableValues returns whether there are configurable values for this attribute.
-func (ba BoolAttribute) HasConfigurableValues() bool {
-	for _, cfgToBools := range ba.ConfigurableValues {
-		if len(cfgToBools) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// SetValue sets value for the no config axis
-func (ba *BoolAttribute) SetValue(value *bool) {
-	ba.SetSelectValue(NoConfigAxis, "", value)
-}
-
-// SetSelectValue sets value for the given axis/config.
-func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, value *bool) {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		ba.Value = value
-	case arch, os, osArch, productVariables, osAndInApex, sanitizersEnabled:
-		if ba.ConfigurableValues == nil {
-			ba.ConfigurableValues = make(configurableBools)
-		}
-		ba.ConfigurableValues.setValueForAxis(axis, config, value)
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// ToLabelListAttribute creates and returns a LabelListAttribute from this
-// bool attribute, where each bool in this attribute corresponds to a
-// label list value in the resultant attribute.
-func (ba *BoolAttribute) ToLabelListAttribute(falseVal LabelList, trueVal LabelList) (LabelListAttribute, error) {
-	getLabelList := func(boolPtr *bool) LabelList {
-		if boolPtr == nil {
-			return LabelList{nil, nil}
-		} else if *boolPtr {
-			return trueVal
-		} else {
-			return falseVal
-		}
-	}
-
-	mainVal := getLabelList(ba.Value)
-	if !ba.HasConfigurableValues() {
-		return MakeLabelListAttribute(mainVal), nil
-	}
-
-	result := LabelListAttribute{}
-	if err := ba.Collapse(); err != nil {
-		return result, err
-	}
-
-	for axis, configToBools := range ba.ConfigurableValues {
-		if len(configToBools) < 1 {
-			continue
-		}
-		for config, boolPtr := range configToBools {
-			val := getLabelList(&boolPtr)
-			if !val.Equals(mainVal) {
-				result.SetSelectValue(axis, config, val)
-			}
-		}
-		result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal)
-	}
-
-	return result, nil
-}
-
-// ToStringListAttribute creates a StringListAttribute from this BoolAttribute,
-// where each bool corresponds to a string list value generated by the provided
-// function.
-// TODO(b/271425661): Generalize this
-func (ba *BoolAttribute) ToStringListAttribute(valueFunc func(boolPtr *bool, axis ConfigurationAxis, config string) []string) (StringListAttribute, error) {
-	mainVal := valueFunc(ba.Value, NoConfigAxis, "")
-	if !ba.HasConfigurableValues() {
-		return MakeStringListAttribute(mainVal), nil
-	}
-
-	result := StringListAttribute{}
-	if err := ba.Collapse(); err != nil {
-		return result, err
-	}
-
-	for axis, configToBools := range ba.ConfigurableValues {
-		if len(configToBools) < 1 {
-			continue
-		}
-		for config, boolPtr := range configToBools {
-			val := valueFunc(&boolPtr, axis, config)
-			if !reflect.DeepEqual(val, mainVal) {
-				result.SetSelectValue(axis, config, val)
-			}
-		}
-		result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal)
-	}
-
-	return result, nil
-}
-
-// Collapse reduces the configurable axes of the boolean attribute to a single axis.
-// This is necessary for final writing to bp2build, as a configurable boolean
-// attribute can only be comprised by a single select.
-func (ba *BoolAttribute) Collapse() error {
-	axisTypes := ba.axisTypes()
-	_, containsOs := axisTypes[os]
-	_, containsArch := axisTypes[arch]
-	_, containsOsArch := axisTypes[osArch]
-	_, containsProductVariables := axisTypes[productVariables]
-	if containsProductVariables {
-		if containsOs || containsArch || containsOsArch {
-			return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes")
-		}
-	}
-	if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
-		// If a bool attribute has both os and arch configuration axes, the only
-		// way to successfully union their values is to increase the granularity
-		// of the configuration criteria to os_arch.
-		for osType, supportedArchs := range osToArchMap {
-			for _, supportedArch := range supportedArchs {
-				osArch := osArchString(osType, supportedArch)
-				if archOsVal := ba.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
-					// Do nothing, as the arch_os is explicitly defined already.
-				} else {
-					archVal := ba.SelectValue(ArchConfigurationAxis, supportedArch)
-					osVal := ba.SelectValue(OsConfigurationAxis, osType)
-					if osVal != nil && archVal != nil {
-						// In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
-						// runs after os mutator.
-						ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
-					} else if osVal != nil && archVal == nil {
-						ba.SetSelectValue(OsArchConfigurationAxis, osArch, osVal)
-					} else if osVal == nil && archVal != nil {
-						ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
-					}
-				}
-			}
-		}
-		// All os_arch values are now set. Clear os and arch axes.
-		delete(ba.ConfigurableValues, ArchConfigurationAxis)
-		delete(ba.ConfigurableValues, OsConfigurationAxis)
-		// Verify post-condition; this should never fail, provided no additional
-		// axes are introduced.
-		if len(ba.ConfigurableValues) > 1 {
-			panic(fmt.Errorf("error in collapsing attribute: %#v", ba))
-		}
-	}
-	return nil
-}
-
-func (ba *BoolAttribute) axisTypes() map[configurationType]bool {
-	types := map[configurationType]bool{}
-	for k := range ba.ConfigurableValues {
-		if len(ba.ConfigurableValues[k]) > 0 {
-			types[k.configurationType] = true
-		}
-	}
-	return types
-}
-
-// SelectValue gets the value for the given axis/config.
-func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		return ba.Value
-	case arch, os, osArch, productVariables, osAndInApex, sanitizersEnabled:
-		if v, ok := ba.ConfigurableValues[axis][config]; ok {
-			return &v
-		} else {
-			return nil
-		}
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
-func (ba *BoolAttribute) SortedConfigurationAxes() []ConfigurationAxis {
-	return SortedConfigurationAxes(ba.ConfigurableValues)
-}
-
-// labelListSelectValues supports config-specific label_list typed Bazel attribute values.
-type labelListSelectValues map[string]LabelList
-
-func (ll labelListSelectValues) addSelects(label labelSelectValues) {
-	for k, v := range label {
-		if label == nil {
-			continue
-		}
-		l := ll[k]
-		(&l).Add(v)
-		ll[k] = l
-	}
-}
-
-func (ll labelListSelectValues) appendSelects(other labelListSelectValues, forceSpecifyEmptyList bool) {
-	for k, v := range other {
-		l := ll[k]
-		if forceSpecifyEmptyList && l.IsNil() && !v.IsNil() {
-			l.Includes = []Label{}
-		}
-		(&l).Append(v)
-		ll[k] = l
-	}
-}
-
-// HasConfigurableValues returns whether there are configurable values within this set of selects.
-func (ll labelListSelectValues) HasConfigurableValues() bool {
-	for _, v := range ll {
-		if v.Includes != nil {
-			return true
-		}
-	}
-	return false
-}
-
-// LabelListAttribute is used to represent a list of Bazel labels as an
-// attribute.
-type LabelListAttribute struct {
-	// The non-configured attribute label list Value. Required.
-	Value LabelList
-
-	// The configured attribute label list Values. Optional
-	// a map of independent configurability axes
-	ConfigurableValues configurableLabelLists
-
-	// If true, differentiate between "nil" and "empty" list. nil means that
-	// this attribute should not be specified at all, and "empty" means that
-	// the attribute should be explicitly specified as an empty list.
-	// This mode facilitates use of attribute defaults: an empty list should
-	// override the default.
-	ForceSpecifyEmptyList bool
-
-	// If true, signal the intent to the code generator to emit all select keys,
-	// even if the Includes list for that key is empty. This mode facilitates
-	// specific select statements where an empty list for a non-default select
-	// key has a meaning.
-	EmitEmptyList bool
-
-	// If a property has struct tag "variant_prepend", this value should
-	// be set to True, so that when bp2build generates BUILD.bazel, variant
-	// properties(select ...) come before general properties.
-	Prepend bool
-}
-
-type configurableLabelLists map[ConfigurationAxis]labelListSelectValues
-
-func (cll configurableLabelLists) setValueForAxis(axis ConfigurationAxis, config string, list LabelList) {
-	if list.IsNil() {
-		if _, ok := cll[axis][config]; ok {
-			delete(cll[axis], config)
-		}
-		return
-	}
-	if cll[axis] == nil {
-		cll[axis] = make(labelListSelectValues)
-	}
-
-	cll[axis][config] = list
-}
-
-func (cll configurableLabelLists) Append(other configurableLabelLists, forceSpecifyEmptyList bool) {
-	for axis, otherSelects := range other {
-		selects := cll[axis]
-		if selects == nil {
-			selects = make(labelListSelectValues, len(otherSelects))
-		}
-		selects.appendSelects(otherSelects, forceSpecifyEmptyList)
-		cll[axis] = selects
-	}
-}
-
-func (lla *LabelListAttribute) Clone() *LabelListAttribute {
-	result := &LabelListAttribute{ForceSpecifyEmptyList: lla.ForceSpecifyEmptyList}
-	return result.Append(*lla)
-}
-
-// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
-func MakeLabelListAttribute(value LabelList) LabelListAttribute {
-	return LabelListAttribute{
-		Value:              value,
-		ConfigurableValues: make(configurableLabelLists),
-	}
-}
-
-// MakeSingleLabelListAttribute initializes a LabelListAttribute as a non-arch specific list with 1 element, the given Label.
-func MakeSingleLabelListAttribute(value Label) LabelListAttribute {
-	return MakeLabelListAttribute(MakeLabelList([]Label{value}))
-}
-
-func (lla *LabelListAttribute) SetValue(list LabelList) {
-	lla.SetSelectValue(NoConfigAxis, "", list)
-}
-
-// SetSelectValue set a value for a bazel select for the given axis, config and value.
-func (lla *LabelListAttribute) SetSelectValue(axis ConfigurationAxis, config string, list LabelList) {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		lla.Value = list
-	case arch, os, osArch, productVariables, osAndInApex, inApex, errorProneDisabled, sanitizersEnabled:
-		if lla.ConfigurableValues == nil {
-			lla.ConfigurableValues = make(configurableLabelLists)
-		}
-		lla.ConfigurableValues.setValueForAxis(axis, config, list)
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SelectValue gets a value for a bazel select for the given axis and config.
-func (lla *LabelListAttribute) SelectValue(axis ConfigurationAxis, config string) LabelList {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		return lla.Value
-	case arch, os, osArch, productVariables, osAndInApex, inApex, errorProneDisabled, sanitizersEnabled:
-		return lla.ConfigurableValues[axis][config]
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
-func (lla *LabelListAttribute) SortedConfigurationAxes() []ConfigurationAxis {
-	return SortedConfigurationAxes(lla.ConfigurableValues)
-}
-
-// Append all values, including os and arch specific ones, from another
-// LabelListAttribute to this LabelListAttribute. Returns this LabelListAttribute.
-func (lla *LabelListAttribute) Append(other LabelListAttribute) *LabelListAttribute {
-	forceSpecifyEmptyList := lla.ForceSpecifyEmptyList || other.ForceSpecifyEmptyList
-	if forceSpecifyEmptyList && lla.Value.IsNil() && !other.Value.IsNil() {
-		lla.Value.Includes = []Label{}
-	}
-	lla.Value.Append(other.Value)
-	if lla.ConfigurableValues == nil {
-		lla.ConfigurableValues = make(configurableLabelLists)
-	}
-	lla.ConfigurableValues.Append(other.ConfigurableValues, forceSpecifyEmptyList)
-	return lla
-}
-
-// Add inserts the labels for each axis of LabelAttribute at the end of corresponding axis's
-// LabelList within the LabelListAttribute
-func (lla *LabelListAttribute) Add(label *LabelAttribute) {
-	if label == nil {
-		return
-	}
-
-	lla.Value.Add(label.Value)
-	if lla.ConfigurableValues == nil && label.ConfigurableValues != nil {
-		lla.ConfigurableValues = make(configurableLabelLists)
-	}
-	for axis, _ := range label.ConfigurableValues {
-		if _, exists := lla.ConfigurableValues[axis]; !exists {
-			lla.ConfigurableValues[axis] = make(labelListSelectValues)
-		}
-		lla.ConfigurableValues[axis].addSelects(label.ConfigurableValues[axis])
-	}
-}
-
-// HasConfigurableValues returns true if the attribute contains axis-specific label list values.
-func (lla LabelListAttribute) HasConfigurableValues() bool {
-	for _, selectValues := range lla.ConfigurableValues {
-		if len(selectValues) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// HasAxisSpecificValues returns true if the attribute contains axis specific label list values from a given axis
-func (lla LabelListAttribute) HasAxisSpecificValues(axis ConfigurationAxis) bool {
-	for _, values := range lla.ConfigurableValues[axis] {
-		if !values.IsNil() {
-			return true
-		}
-	}
-	return false
-}
-
-// IsEmpty returns true if the attribute has no values under any configuration.
-func (lla LabelListAttribute) IsEmpty() bool {
-	if len(lla.Value.Includes) > 0 {
-		return false
-	}
-	for axis, _ := range lla.ConfigurableValues {
-		if lla.ConfigurableValues[axis].HasConfigurableValues() {
-			return false
-		}
-	}
-	return true
-}
-
-// IsNil returns true if the attribute has not been set for any configuration.
-func (lla LabelListAttribute) IsNil() bool {
-	if lla.Value.Includes != nil {
-		return false
-	}
-	return !lla.HasConfigurableValues()
-}
-
-// Exclude for the given axis, config, removes Includes in labelList from Includes and appends them
-// to Excludes. This is to special case any excludes that are not specified in a bp file but need to
-// be removed, e.g. if they could cause duplicate element failures.
-func (lla *LabelListAttribute) Exclude(axis ConfigurationAxis, config string, labelList LabelList) {
-	val := lla.SelectValue(axis, config)
-	newList := SubtractBazelLabelList(val, labelList)
-	newList.Excludes = append(newList.Excludes, labelList.Includes...)
-	lla.SetSelectValue(axis, config, newList)
-}
-
-// ResolveExcludes handles excludes across the various axes, ensuring that items are removed from
-// the base value and included in default values as appropriate.
-func (lla *LabelListAttribute) ResolveExcludes() {
-	// If there are OsAndInApexAxis, we need to use
-	//   * includes from the OS & in APEX Axis for non-Android configs for libraries that need to be
-	//     included in non-Android OSes
-	//   * excludes from the OS Axis for non-Android configs, to exclude libraries that should _not_
-	//     be included in the non-Android OSes
-	if _, ok := lla.ConfigurableValues[OsAndInApexAxis]; ok {
-		inApexLabels := lla.ConfigurableValues[OsAndInApexAxis][ConditionsDefaultConfigKey]
-		for config, labels := range lla.ConfigurableValues[OsConfigurationAxis] {
-			// OsAndroid has already handled its excludes.
-			// We only need to copy the excludes from other arches, so if there are none, skip it.
-			if config == OsAndroid || len(labels.Excludes) == 0 {
-				continue
-			}
-			lla.ConfigurableValues[OsAndInApexAxis][config] = LabelList{
-				Includes: inApexLabels.Includes,
-				Excludes: labels.Excludes,
-			}
-		}
-	}
-
-	for axis, configToLabels := range lla.ConfigurableValues {
-		baseLabels := lla.Value.deepCopy()
-		for config, val := range configToLabels {
-			// Exclude config-specific excludes from base value
-			lla.Value = SubtractBazelLabelList(lla.Value, LabelList{Includes: val.Excludes})
-
-			// add base values to config specific to add labels excluded by others in this axis
-			// then remove all config-specific excludes
-			allLabels := baseLabels.deepCopy()
-			allLabels.Append(val)
-			lla.ConfigurableValues[axis][config] = SubtractBazelLabelList(allLabels, LabelList{Includes: allLabels.Excludes})
-		}
-
-		// After going through all configs, delete the duplicates in the config
-		// values that are already in the base Value.
-		for config, val := range configToLabels {
-			lla.ConfigurableValues[axis][config] = SubtractBazelLabelList(val, lla.Value)
-		}
-
-		// Now that the Value list is finalized for this axis, compare it with
-		// the original list, and union the difference with the default
-		// condition for the axis.
-		difference := SubtractBazelLabelList(baseLabels, lla.Value)
-		existingDefaults := lla.ConfigurableValues[axis][ConditionsDefaultConfigKey]
-		existingDefaults.Append(difference)
-		lla.ConfigurableValues[axis][ConditionsDefaultConfigKey] = FirstUniqueBazelLabelList(existingDefaults)
-
-		// if everything ends up without includes, just delete the axis
-		if !lla.ConfigurableValues[axis].HasConfigurableValues() {
-			delete(lla.ConfigurableValues, axis)
-		}
-	}
-}
-
-// Partition splits a LabelListAttribute into two LabelListAttributes depending
-// on the return value of the predicate.
-// This function preserves the Includes and Excludes, but it does not provide
-// that information to the partition function.
-func (lla LabelListAttribute) Partition(predicate func(label Label) bool) (LabelListAttribute, LabelListAttribute) {
-	predicated := LabelListAttribute{}
-	unpredicated := LabelListAttribute{}
-
-	valuePartitionTrue, valuePartitionFalse := lla.Value.Partition(predicate)
-	predicated.SetValue(valuePartitionTrue)
-	unpredicated.SetValue(valuePartitionFalse)
-
-	for axis, selectValueLabelLists := range lla.ConfigurableValues {
-		for config, labelList := range selectValueLabelLists {
-			configPredicated, configUnpredicated := labelList.Partition(predicate)
-			predicated.SetSelectValue(axis, config, configPredicated)
-			unpredicated.SetSelectValue(axis, config, configUnpredicated)
-		}
-	}
-
-	return predicated, unpredicated
-}
-
-// OtherModuleContext is a limited context that has methods with information about other modules.
-type OtherModuleContext interface {
-	ModuleFromName(name string) (blueprint.Module, bool)
-	OtherModuleType(m blueprint.Module) string
-	OtherModuleName(m blueprint.Module) string
-	OtherModuleDir(m blueprint.Module) string
-	ModuleErrorf(fmt string, args ...interface{})
-}
-
-// LabelMapper is a function that takes a OtherModuleContext and returns a (potentially changed)
-// label and whether it was changed.
-type LabelMapper func(OtherModuleContext, Label) (string, bool)
-
-// LabelPartition contains descriptions of a partition for labels
-type LabelPartition struct {
-	// Extensions to include in this partition
-	Extensions []string
-	// LabelMapper is a function that can map a label to a new label, and indicate whether to include
-	// the mapped label in the partition
-	LabelMapper LabelMapper
-	// Whether to store files not included in any other partition in a group of LabelPartitions
-	// Only one partition in a group of LabelPartitions can enabled Keep_remainder
-	Keep_remainder bool
-}
-
-// LabelPartitions is a map of partition name to a LabelPartition describing the elements of the
-// partition
-type LabelPartitions map[string]LabelPartition
-
-// filter returns a pointer to a label if the label should be included in the partition or nil if
-// not.
-func (lf LabelPartition) filter(ctx OtherModuleContext, label Label) *Label {
-	if lf.LabelMapper != nil {
-		if newLabel, changed := lf.LabelMapper(ctx, label); changed {
-			return &Label{newLabel, label.OriginalModuleName}
-		}
-	}
-	for _, ext := range lf.Extensions {
-		if strings.HasSuffix(label.Label, ext) {
-			return &label
-		}
-	}
-
-	return nil
-}
-
-// PartitionToLabelListAttribute is map of partition name to a LabelListAttribute
-type PartitionToLabelListAttribute map[string]LabelListAttribute
-
-type partitionToLabelList map[string]*LabelList
-
-func (p partitionToLabelList) appendIncludes(partition string, label Label) {
-	if _, ok := p[partition]; !ok {
-		p[partition] = &LabelList{}
-	}
-	p[partition].Includes = append(p[partition].Includes, label)
-}
-
-func (p partitionToLabelList) excludes(partition string, excludes []Label) {
-	if _, ok := p[partition]; !ok {
-		p[partition] = &LabelList{}
-	}
-	p[partition].Excludes = excludes
-}
-
-// PartitionLabelListAttribute partitions a LabelListAttribute into the requested partitions
-func PartitionLabelListAttribute(ctx OtherModuleContext, lla *LabelListAttribute, partitions LabelPartitions) PartitionToLabelListAttribute {
-	ret := PartitionToLabelListAttribute{}
-	var partitionNames []string
-	// Stored as a pointer to distinguish nil (no remainder partition) from empty string partition
-	var remainderPartition *string
-	for p, f := range partitions {
-		partitionNames = append(partitionNames, p)
-		if f.Keep_remainder {
-			if remainderPartition != nil {
-				panic("only one partition can store the remainder")
-			}
-			// If we take the address of p in a loop, we'll end up with the last value of p in
-			// remainderPartition, we want the requested partition
-			capturePartition := p
-			remainderPartition = &capturePartition
-		}
-	}
-
-	partitionLabelList := func(axis ConfigurationAxis, config string) {
-		value := lla.SelectValue(axis, config)
-		partitionToLabels := partitionToLabelList{}
-		for _, item := range value.Includes {
-			wasFiltered := false
-			var inPartition *string
-			for partition, f := range partitions {
-				filtered := f.filter(ctx, item)
-				if filtered == nil {
-					// did not match this filter, keep looking
-					continue
-				}
-				wasFiltered = true
-				partitionToLabels.appendIncludes(partition, *filtered)
-				// don't need to check other partitions if this filter used the item,
-				// continue checking if mapped to another name
-				if *filtered == item {
-					if inPartition != nil {
-						ctx.ModuleErrorf("%q was found in multiple partitions: %q, %q", item.Label, *inPartition, partition)
-					}
-					capturePartition := partition
-					inPartition = &capturePartition
-				}
-			}
-
-			// if not specified in a partition, add to remainder partition if one exists
-			if !wasFiltered && remainderPartition != nil {
-				partitionToLabels.appendIncludes(*remainderPartition, item)
-			}
-		}
-
-		// ensure empty lists are maintained
-		if value.Excludes != nil {
-			for _, partition := range partitionNames {
-				partitionToLabels.excludes(partition, value.Excludes)
-			}
-		}
-
-		for partition, list := range partitionToLabels {
-			val := ret[partition]
-			(&val).SetSelectValue(axis, config, *list)
-			ret[partition] = val
-		}
-	}
-
-	partitionLabelList(NoConfigAxis, "")
-	for axis, configToList := range lla.ConfigurableValues {
-		for config, _ := range configToList {
-			partitionLabelList(axis, config)
-		}
-	}
-	return ret
-}
-
-// StringAttribute corresponds to the string Bazel attribute type with
-// support for additional metadata, like configurations.
-type StringAttribute struct {
-	// The base value of the string attribute.
-	Value *string
-
-	// The configured attribute label list Values. Optional
-	// a map of independent configurability axes
-	ConfigurableValues configurableStrings
-}
-
-type configurableStrings map[ConfigurationAxis]stringSelectValues
-
-func (cs configurableStrings) setValueForAxis(axis ConfigurationAxis, config string, str *string) {
-	if cs[axis] == nil {
-		cs[axis] = make(stringSelectValues)
-	}
-	cs[axis][config] = str
-}
-
-type stringSelectValues map[string]*string
-
-// HasConfigurableValues returns true if the attribute contains axis-specific string values.
-func (sa StringAttribute) HasConfigurableValues() bool {
-	for _, selectValues := range sa.ConfigurableValues {
-		if len(selectValues) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// SetValue sets the base, non-configured value for the Label
-func (sa *StringAttribute) SetValue(value string) {
-	sa.SetSelectValue(NoConfigAxis, "", &value)
-}
-
-// SetSelectValue set a value for a bazel select for the given axis, config and value.
-func (sa *StringAttribute) SetSelectValue(axis ConfigurationAxis, config string, str *string) {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		sa.Value = str
-	case arch, os, osArch, productVariables, sanitizersEnabled:
-		if sa.ConfigurableValues == nil {
-			sa.ConfigurableValues = make(configurableStrings)
-		}
-		sa.ConfigurableValues.setValueForAxis(axis, config, str)
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SelectValue gets a value for a bazel select for the given axis and config.
-func (sa *StringAttribute) SelectValue(axis ConfigurationAxis, config string) *string {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		return sa.Value
-	case arch, os, osArch, productVariables, sanitizersEnabled:
-		if v, ok := sa.ConfigurableValues[axis][config]; ok {
-			return v
-		} else {
-			return nil
-		}
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
-func (sa *StringAttribute) SortedConfigurationAxes() []ConfigurationAxis {
-	return SortedConfigurationAxes(sa.ConfigurableValues)
-}
-
-// Collapse reduces the configurable axes of the string attribute to a single axis.
-// This is necessary for final writing to bp2build, as a configurable string
-// attribute can only be comprised by a single select.
-func (sa *StringAttribute) Collapse() error {
-	axisTypes := sa.axisTypes()
-	_, containsOs := axisTypes[os]
-	_, containsArch := axisTypes[arch]
-	_, containsOsArch := axisTypes[osArch]
-	_, containsProductVariables := axisTypes[productVariables]
-	if containsProductVariables {
-		if containsOs || containsArch || containsOsArch {
-			return fmt.Errorf("string attribute could not be collapsed as it has two or more unrelated axes")
-		}
-	}
-	if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
-		// If a bool attribute has both os and arch configuration axes, the only
-		// way to successfully union their values is to increase the granularity
-		// of the configuration criteria to os_arch.
-		for osType, supportedArchs := range osToArchMap {
-			for _, supportedArch := range supportedArchs {
-				osArch := osArchString(osType, supportedArch)
-				if archOsVal := sa.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
-					// Do nothing, as the arch_os is explicitly defined already.
-				} else {
-					archVal := sa.SelectValue(ArchConfigurationAxis, supportedArch)
-					osVal := sa.SelectValue(OsConfigurationAxis, osType)
-					if osVal != nil && archVal != nil {
-						// In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
-						// runs after os mutator.
-						sa.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
-					} else if osVal != nil && archVal == nil {
-						sa.SetSelectValue(OsArchConfigurationAxis, osArch, osVal)
-					} else if osVal == nil && archVal != nil {
-						sa.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
-					}
-				}
-			}
-		}
-		/// All os_arch values are now set. Clear os and arch axes.
-		delete(sa.ConfigurableValues, ArchConfigurationAxis)
-		delete(sa.ConfigurableValues, OsConfigurationAxis)
-		// Verify post-condition; this should never fail, provided no additional
-		// axes are introduced.
-		if len(sa.ConfigurableValues) > 1 {
-			panic(fmt.Errorf("error in collapsing attribute: %#v", sa))
-		}
-	} else if containsProductVariables {
-		usedBaseValue := false
-		for a, configToProp := range sa.ConfigurableValues {
-			if a.configurationType == productVariables {
-				for c, p := range configToProp {
-					if p == nil {
-						sa.SetSelectValue(a, c, sa.Value)
-						usedBaseValue = true
-					}
-				}
-			}
-		}
-		if usedBaseValue {
-			sa.Value = nil
-		}
-	}
-	return nil
-}
-
-func (sa *StringAttribute) axisTypes() map[configurationType]bool {
-	types := map[configurationType]bool{}
-	for k := range sa.ConfigurableValues {
-		if strs := sa.ConfigurableValues[k]; len(strs) > 0 {
-			types[k.configurationType] = true
-		}
-	}
-	return types
-}
-
-// StringListAttribute corresponds to the string_list Bazel attribute type with
-// support for additional metadata, like configurations.
-type StringListAttribute struct {
-	// The base value of the string list attribute.
-	Value []string
-
-	// The configured attribute label list Values. Optional
-	// a map of independent configurability axes
-	ConfigurableValues configurableStringLists
-
-	// If a property has struct tag "variant_prepend", this value should
-	// be set to True, so that when bp2build generates BUILD.bazel, variant
-	// properties(select ...) come before general properties.
-	Prepend bool
-}
-
-// IsEmpty returns true if the attribute has no values under any configuration.
-func (sla StringListAttribute) IsEmpty() bool {
-	return len(sla.Value) == 0 && !sla.HasConfigurableValues()
-}
-
-type configurableStringLists map[ConfigurationAxis]stringListSelectValues
-
-func (csl configurableStringLists) Append(other configurableStringLists) {
-	for axis, otherSelects := range other {
-		selects := csl[axis]
-		if selects == nil {
-			selects = make(stringListSelectValues, len(otherSelects))
-		}
-		selects.appendSelects(otherSelects)
-		csl[axis] = selects
-	}
-}
-
-func (csl configurableStringLists) setValueForAxis(axis ConfigurationAxis, config string, list []string) {
-	if csl[axis] == nil {
-		csl[axis] = make(stringListSelectValues)
-	}
-	csl[axis][config] = list
-}
-
-type stringListSelectValues map[string][]string
-
-func (sl stringListSelectValues) appendSelects(other stringListSelectValues) {
-	for k, v := range other {
-		sl[k] = append(sl[k], v...)
-	}
-}
-
-func (sl stringListSelectValues) hasConfigurableValues(other stringListSelectValues) bool {
-	for _, val := range sl {
-		if len(val) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// MakeStringListAttribute initializes a StringListAttribute with the non-arch specific value.
-func MakeStringListAttribute(value []string) StringListAttribute {
-	// NOTE: These strings are not necessarily unique or sorted.
-	return StringListAttribute{
-		Value:              value,
-		ConfigurableValues: make(configurableStringLists),
-	}
-}
-
-// HasConfigurableValues returns true if the attribute contains axis-specific string_list values.
-func (sla StringListAttribute) HasConfigurableValues() bool {
-	for _, selectValues := range sla.ConfigurableValues {
-		if len(selectValues) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// Append appends all values, including os and arch specific ones, from another
-// StringListAttribute to this StringListAttribute
-func (sla *StringListAttribute) Append(other StringListAttribute) *StringListAttribute {
-	sla.Value = append(sla.Value, other.Value...)
-	if sla.ConfigurableValues == nil {
-		sla.ConfigurableValues = make(configurableStringLists)
-	}
-	sla.ConfigurableValues.Append(other.ConfigurableValues)
-	return sla
-}
-
-func (sla *StringListAttribute) Clone() *StringListAttribute {
-	result := &StringListAttribute{}
-	return result.Append(*sla)
-}
-
-// SetSelectValue set a value for a bazel select for the given axis, config and value.
-func (sla *StringListAttribute) SetSelectValue(axis ConfigurationAxis, config string, list []string) {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		sla.Value = list
-	case arch, os, osArch, productVariables, osAndInApex, errorProneDisabled, sanitizersEnabled:
-		if sla.ConfigurableValues == nil {
-			sla.ConfigurableValues = make(configurableStringLists)
-		}
-		sla.ConfigurableValues.setValueForAxis(axis, config, list)
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SelectValue gets a value for a bazel select for the given axis and config.
-func (sla *StringListAttribute) SelectValue(axis ConfigurationAxis, config string) []string {
-	axis.validateConfig(config)
-	switch axis.configurationType {
-	case noConfig:
-		return sla.Value
-	case arch, os, osArch, productVariables, osAndInApex, errorProneDisabled, sanitizersEnabled:
-		return sla.ConfigurableValues[axis][config]
-	default:
-		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
-	}
-}
-
-// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
-func (sla *StringListAttribute) SortedConfigurationAxes() []ConfigurationAxis {
-	return SortedConfigurationAxes(sla.ConfigurableValues)
-}
-
-// DeduplicateAxesFromBase ensures no duplication of items between the no-configuration value and
-// configuration-specific values. For example, if we would convert this StringListAttribute as:
-//
-//	["a", "b", "c"] + select({
-//	   "//condition:one": ["a", "d"],
-//	   "//conditions:default": [],
-//	})
-//
-// after this function, we would convert this StringListAttribute as:
-//
-//	["a", "b", "c"] + select({
-//	   "//condition:one": ["d"],
-//	   "//conditions:default": [],
-//	})
-func (sla *StringListAttribute) DeduplicateAxesFromBase() {
-	base := sla.Value
-	for axis, configToList := range sla.ConfigurableValues {
-		for config, list := range configToList {
-			remaining := SubtractStrings(list, base)
-			if len(remaining) == 0 {
-				delete(sla.ConfigurableValues[axis], config)
-			} else {
-				sla.ConfigurableValues[axis][config] = remaining
-			}
-		}
-	}
-}
-
-// TryVariableSubstitution, replace string substitution formatting within each string in slice with
-// Starlark string.format compatible tag for productVariable.
-func TryVariableSubstitutions(slice []string, productVariable string) ([]string, bool) {
-	if len(slice) == 0 {
-		return slice, false
-	}
-	ret := make([]string, 0, len(slice))
-	changesMade := false
-	for _, s := range slice {
-		newS, changed := TryVariableSubstitution(s, productVariable)
-		ret = append(ret, newS)
-		changesMade = changesMade || changed
-	}
-	return ret, changesMade
-}
-
-// TryVariableSubstitution, replace string substitution formatting within s with Starlark
-// string.format compatible tag for productVariable.
-func TryVariableSubstitution(s string, productVariable string) (string, bool) {
-	sub := productVariableSubstitutionPattern.ReplaceAllString(s, "$("+productVariable+")")
-	return sub, s != sub
-}
-
-// StringMapAttribute is a map of strings.
-// The use case for this is storing the flag_values in a config_setting object.
-// Bazel rules do not support map attributes, and this should NOT be used in Bazel rules.
-type StringMapAttribute map[string]string
-
-// ConfigSettingAttributes stores the keys of a config_setting object.
-type ConfigSettingAttributes struct {
-	// Each key in Flag_values is a label to a custom string_setting
-	Flag_values StringMapAttribute
-	// Each element in Constraint_values is a label to a constraint_value
-	Constraint_values LabelListAttribute
-}
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
deleted file mode 100644
index 751cb8b..0000000
--- a/bazel/properties_test.go
+++ /dev/null
@@ -1,836 +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 bazel
-
-import (
-	"reflect"
-	"strings"
-	"testing"
-
-	"github.com/google/blueprint/proptools"
-)
-
-func TestUniqueBazelLabels(t *testing.T) {
-	testCases := []struct {
-		originalLabels       []Label
-		expectedUniqueLabels []Label
-	}{
-		{
-			originalLabels: []Label{
-				{Label: "a"},
-				{Label: "b"},
-				{Label: "a"},
-				{Label: "c"},
-				// namespaces
-				{Label: "//foo:bar", OriginalModuleName: "bar"},       // when referenced from foo namespace
-				{Label: "//foo:bar", OriginalModuleName: "//foo:bar"}, // when reference from root namespace
-			},
-			expectedUniqueLabels: []Label{
-				{Label: "//foo:bar", OriginalModuleName: "bar"},
-				{Label: "a"},
-				{Label: "b"},
-				{Label: "c"},
-			},
-		},
-	}
-	for _, tc := range testCases {
-		actualUniqueLabels := UniqueSortedBazelLabels(tc.originalLabels)
-		if !reflect.DeepEqual(tc.expectedUniqueLabels, actualUniqueLabels) {
-			t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabels, actualUniqueLabels)
-		}
-	}
-}
-
-func TestSubtractStrings(t *testing.T) {
-	testCases := []struct {
-		haystack       []string
-		needle         []string
-		expectedResult []string
-	}{
-		{
-			haystack: []string{
-				"a",
-				"b",
-				"c",
-			},
-			needle: []string{
-				"a",
-			},
-			expectedResult: []string{
-				"b", "c",
-			},
-		},
-	}
-	for _, tc := range testCases {
-		actualResult := SubtractStrings(tc.haystack, tc.needle)
-		if !reflect.DeepEqual(tc.expectedResult, actualResult) {
-			t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
-		}
-	}
-}
-
-func TestSubtractBazelLabelList(t *testing.T) {
-	testCases := []struct {
-		haystack       LabelList
-		needle         LabelList
-		expectedResult LabelList
-	}{
-		{
-			haystack: LabelList{
-				Includes: []Label{
-					{Label: "a"},
-					{Label: "b"},
-					{Label: "c"},
-				},
-				Excludes: []Label{
-					{Label: "x"},
-					{Label: "y"},
-					{Label: "z"},
-				},
-			},
-			needle: LabelList{
-				Includes: []Label{
-					{Label: "a"},
-				},
-				Excludes: []Label{
-					{Label: "z"},
-				},
-			},
-			// NOTE: Excludes are intentionally not subtracted
-			expectedResult: LabelList{
-				Includes: []Label{
-					{Label: "b"},
-					{Label: "c"},
-				},
-				Excludes: []Label{
-					{Label: "x"},
-					{Label: "y"},
-					{Label: "z"},
-				},
-			},
-		},
-	}
-	for _, tc := range testCases {
-		actualResult := SubtractBazelLabelList(tc.haystack, tc.needle)
-		if !reflect.DeepEqual(tc.expectedResult, actualResult) {
-			t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
-		}
-	}
-}
-
-func TestSubtractBazelLabelListAttribute(t *testing.T) {
-	testCases := []struct {
-		haystack LabelListAttribute
-		needle   LabelListAttribute
-		expected LabelListAttribute
-	}{
-		{
-			haystack: LabelListAttribute{
-				Value: makeLabelList(
-					[]string{"a", "b", "a", "c"},
-					[]string{"x", "x", "y", "z"},
-				),
-				ConfigurableValues: configurableLabelLists{
-					ArchConfigurationAxis: labelListSelectValues{
-						"arm": makeLabelList([]string{"arm_1", "arm_2"}, []string{}),
-						"x86": makeLabelList([]string{"x86_3", "x86_4", "x86_5"}, []string{"x86_5"}),
-					},
-				},
-			},
-			needle: LabelListAttribute{
-				Value: makeLabelList(
-					[]string{"d", "a"},
-					[]string{"x", "y2", "z2"},
-				),
-				ConfigurableValues: configurableLabelLists{
-					ArchConfigurationAxis: labelListSelectValues{
-						"arm": makeLabelList([]string{"arm_1", "arm_3"}, []string{}),
-						"x86": makeLabelList([]string{"x86_3", "x86_4"}, []string{"x86_6"}),
-					},
-				},
-			},
-			expected: LabelListAttribute{
-				Value: makeLabelList(
-					[]string{"b", "c"},
-					[]string{"x", "x", "y", "z"},
-				),
-				ConfigurableValues: configurableLabelLists{
-					ArchConfigurationAxis: labelListSelectValues{
-						"arm": makeLabelList([]string{"arm_2"}, []string{}),
-						"x86": makeLabelList([]string{"x86_5"}, []string{"x86_5"}),
-					},
-				},
-				ForceSpecifyEmptyList: false,
-				EmitEmptyList:         false,
-				Prepend:               false,
-			},
-		},
-	}
-	for _, tc := range testCases {
-		got := SubtractBazelLabelListAttribute(tc.haystack, tc.needle)
-		if !reflect.DeepEqual(tc.expected, got) {
-			t.Fatalf("Expected\n%v, but got\n%v", tc.expected, got)
-		}
-	}
-}
-
-func TestFirstUniqueBazelLabelList(t *testing.T) {
-	testCases := []struct {
-		originalLabelList       LabelList
-		expectedUniqueLabelList LabelList
-	}{
-		{
-			originalLabelList: LabelList{
-				Includes: []Label{
-					{Label: "a"},
-					{Label: "b"},
-					{Label: "a"},
-					{Label: "c"},
-					// namespaces
-					{Label: "//foo:bar", OriginalModuleName: "bar"},       // when referenced from foo namespace
-					{Label: "//foo:bar", OriginalModuleName: "//foo:bar"}, // when referenced from root namespace
-				},
-				Excludes: []Label{
-					{Label: "x"},
-					{Label: "x"},
-					{Label: "y"},
-					{Label: "z"},
-				},
-			},
-			expectedUniqueLabelList: LabelList{
-				Includes: []Label{
-					{Label: "a"},
-					{Label: "b"},
-					{Label: "c"},
-					{Label: "//foo:bar", OriginalModuleName: "bar"},
-				},
-				Excludes: []Label{
-					{Label: "x"},
-					{Label: "y"},
-					{Label: "z"},
-				},
-			},
-		},
-	}
-	for _, tc := range testCases {
-		actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList)
-		if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
-			t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
-		}
-	}
-}
-
-func TestFirstUniqueBazelLabelListAttribute(t *testing.T) {
-	testCases := []struct {
-		originalLabelList       LabelListAttribute
-		expectedUniqueLabelList LabelListAttribute
-	}{
-		{
-			originalLabelList: LabelListAttribute{
-				Value: makeLabelList(
-					[]string{"a", "b", "a", "c"},
-					[]string{"x", "x", "y", "z"},
-				),
-				ConfigurableValues: configurableLabelLists{
-					ArchConfigurationAxis: labelListSelectValues{
-						"arm": makeLabelList([]string{"1", "2", "1"}, []string{}),
-						"x86": makeLabelList([]string{"3", "4", "4"}, []string{"5", "5"}),
-					},
-				},
-			},
-			expectedUniqueLabelList: LabelListAttribute{
-				Value: makeLabelList(
-					[]string{"a", "b", "c"},
-					[]string{"x", "y", "z"},
-				),
-				ConfigurableValues: configurableLabelLists{
-					ArchConfigurationAxis: labelListSelectValues{
-						"arm": makeLabelList([]string{"1", "2"}, []string{}),
-						"x86": makeLabelList([]string{"3", "4"}, []string{"5"}),
-					},
-				},
-			},
-		},
-	}
-	for _, tc := range testCases {
-		actualUniqueLabelList := FirstUniqueBazelLabelListAttribute(tc.originalLabelList)
-		if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
-			t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
-		}
-	}
-}
-
-func TestUniqueSortedBazelLabelList(t *testing.T) {
-	testCases := []struct {
-		originalLabelList       LabelList
-		expectedUniqueLabelList LabelList
-	}{
-		{
-			originalLabelList: LabelList{
-				Includes: []Label{
-					{Label: "c"},
-					{Label: "a"},
-					{Label: "a"},
-					{Label: "b"},
-				},
-				Excludes: []Label{
-					{Label: "y"},
-					{Label: "z"},
-					{Label: "x"},
-					{Label: "x"},
-				},
-			},
-			expectedUniqueLabelList: LabelList{
-				Includes: []Label{
-					{Label: "a"},
-					{Label: "b"},
-					{Label: "c"},
-				},
-				Excludes: []Label{
-					{Label: "x"},
-					{Label: "y"},
-					{Label: "z"},
-				},
-			},
-		},
-	}
-	for _, tc := range testCases {
-		actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList)
-		if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
-			t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
-		}
-	}
-}
-
-func makeLabels(labels ...string) []Label {
-	var ret []Label
-	for _, l := range labels {
-		ret = append(ret, Label{Label: l})
-	}
-	return ret
-}
-
-func makeLabelList(includes, excludes []string) LabelList {
-	return LabelList{
-		Includes: makeLabels(includes...),
-		Excludes: makeLabels(excludes...),
-	}
-}
-
-func TestResolveExcludes(t *testing.T) {
-	attr := LabelListAttribute{
-		Value: makeLabelList(
-			[]string{
-				"all_include",
-				"arm_exclude",
-				"android_exclude",
-				"product_config_exclude",
-			},
-			[]string{"all_exclude"},
-		),
-		ConfigurableValues: configurableLabelLists{
-			ArchConfigurationAxis: labelListSelectValues{
-				"arm":                      makeLabelList([]string{}, []string{"arm_exclude"}),
-				"x86":                      makeLabelList([]string{"x86_include"}, []string{}),
-				ConditionsDefaultConfigKey: makeLabelList([]string{"default_include"}, []string{}),
-			},
-			OsConfigurationAxis: labelListSelectValues{
-				"android": makeLabelList([]string{}, []string{"android_exclude"}),
-				"linux":   makeLabelList([]string{"linux_include"}, []string{}),
-			},
-			OsArchConfigurationAxis: labelListSelectValues{
-				"linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
-			},
-			ProductVariableConfigurationAxis(false, "product_with_defaults"): labelListSelectValues{
-				"a":                        makeLabelList([]string{}, []string{"not_in_value"}),
-				"b":                        makeLabelList([]string{"b_val"}, []string{}),
-				"c":                        makeLabelList([]string{"c_val"}, []string{}),
-				ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2", "all_exclude"}, []string{}),
-			},
-			ProductVariableConfigurationAxis(false, "product_only_with_excludes"): labelListSelectValues{
-				"a": makeLabelList([]string{}, []string{"product_config_exclude"}),
-			},
-		},
-	}
-
-	attr.ResolveExcludes()
-
-	expectedBaseIncludes := []Label{{Label: "all_include"}}
-	if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
-		t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
-	}
-	var nilLabels []Label
-	expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
-		ArchConfigurationAxis: {
-			"arm":                      nilLabels,
-			"x86":                      makeLabels("arm_exclude", "x86_include"),
-			ConditionsDefaultConfigKey: makeLabels("arm_exclude", "default_include"),
-		},
-		OsConfigurationAxis: {
-			"android":                  nilLabels,
-			"linux":                    makeLabels("android_exclude", "linux_include"),
-			ConditionsDefaultConfigKey: makeLabels("android_exclude"),
-		},
-		OsArchConfigurationAxis: {
-			"linux_x86":                makeLabels("linux_x86_include"),
-			ConditionsDefaultConfigKey: nilLabels,
-		},
-		ProductVariableConfigurationAxis(false, "product_with_defaults"): {
-			"a":                        nilLabels,
-			"b":                        makeLabels("b_val"),
-			"c":                        makeLabels("c_val"),
-			ConditionsDefaultConfigKey: makeLabels("c_val", "default", "default2"),
-		},
-		ProductVariableConfigurationAxis(false, "product_only_with_excludes"): {
-			"a":                        nilLabels,
-			ConditionsDefaultConfigKey: makeLabels("product_config_exclude"),
-		},
-	}
-	for _, axis := range attr.SortedConfigurationAxes() {
-		if _, ok := expectedConfiguredIncludes[axis]; !ok {
-			t.Errorf("Found unexpected axis %s", axis)
-			continue
-		}
-		expectedForAxis := expectedConfiguredIncludes[axis]
-		gotForAxis := attr.ConfigurableValues[axis]
-		if len(expectedForAxis) != len(gotForAxis) {
-			t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
-		}
-		for config, value := range gotForAxis {
-			if expected, ok := expectedForAxis[config]; ok {
-				if !reflect.DeepEqual(expected, value.Includes) {
-					t.Errorf("For %s,\nexpected: %#v\ngot %#v", axis, expected, value.Includes)
-				}
-			} else {
-				t.Errorf("Got unexpected config %q for %s", config, axis)
-			}
-		}
-	}
-}
-
-func TestLabelListAttributePartition(t *testing.T) {
-	testCases := []struct {
-		name         string
-		input        LabelListAttribute
-		predicated   LabelListAttribute
-		unpredicated LabelListAttribute
-		predicate    func(label Label) bool
-	}{
-		{
-			name: "move all to predicated partition",
-			input: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-			)),
-			predicated: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-			)),
-			unpredicated: LabelListAttribute{},
-			predicate: func(label Label) bool {
-				return true
-			},
-		},
-		{
-			name: "move all to unpredicated partition",
-			input: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-			)),
-			predicated: LabelListAttribute{},
-			unpredicated: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-			)),
-			predicate: func(label Label) bool {
-				return false
-			},
-		},
-		{
-			name: "partition includes and excludes",
-			input: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-			)),
-			predicated: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "keep2"},
-				[]string{"keep1", "keep2"},
-			)),
-			unpredicated: MakeLabelListAttribute(makeLabelList(
-				[]string{"throw1", "throw2"},
-				[]string{"throw1", "throw2"},
-			)),
-			predicate: func(label Label) bool {
-				return strings.HasPrefix(label.Label, "keep")
-			},
-		},
-		{
-			name: "partition excludes only",
-			input: MakeLabelListAttribute(makeLabelList(
-				[]string{},
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-			)),
-			predicated: MakeLabelListAttribute(makeLabelList(
-				[]string{},
-				[]string{"keep1", "keep2"},
-			)),
-			unpredicated: MakeLabelListAttribute(makeLabelList(
-				[]string{},
-				[]string{"throw1", "throw2"},
-			)),
-			predicate: func(label Label) bool {
-				return strings.HasPrefix(label.Label, "keep")
-			},
-		},
-		{
-			name: "partition includes only",
-			input: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "throw1", "keep2", "throw2"},
-				[]string{},
-			)),
-			predicated: MakeLabelListAttribute(makeLabelList(
-				[]string{"keep1", "keep2"},
-				[]string{},
-			)),
-			unpredicated: MakeLabelListAttribute(makeLabelList(
-				[]string{"throw1", "throw2"},
-				[]string{},
-			)),
-			predicate: func(label Label) bool {
-				return strings.HasPrefix(label.Label, "keep")
-			},
-		},
-		{
-			name:         "empty partition",
-			input:        MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
-			predicated:   LabelListAttribute{},
-			unpredicated: LabelListAttribute{},
-			predicate: func(label Label) bool {
-				return true
-			},
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			predicated, unpredicated := tc.input.Partition(tc.predicate)
-			if !predicated.Value.Equals(tc.predicated.Value) {
-				t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
-			}
-			for axis, configs := range predicated.ConfigurableValues {
-				tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
-				if !ok || !reflect.DeepEqual(configs, tcConfigs) {
-					t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
-				}
-			}
-			if !unpredicated.Value.Equals(tc.unpredicated.Value) {
-				t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
-			}
-			for axis, configs := range unpredicated.ConfigurableValues {
-				tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
-				if !ok || !reflect.DeepEqual(configs, tcConfigs) {
-					t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
-				}
-			}
-		})
-	}
-}
-
-// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
-// typ
-func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
-	return func(omc OtherModuleContext, label Label) (string, bool) {
-		m, ok := omc.ModuleFromName(label.Label)
-		if !ok {
-			return label.Label, false
-		}
-		mTyp := omc.OtherModuleType(m)
-		if typ == mTyp {
-			return label.Label + suffix, true
-		}
-		return label.Label, false
-	}
-}
-
-func TestPartitionLabelListAttribute(t *testing.T) {
-	testCases := []struct {
-		name           string
-		ctx            *OtherModuleTestContext
-		labelList      LabelListAttribute
-		filters        LabelPartitions
-		expected       PartitionToLabelListAttribute
-		expectedErrMsg *string
-	}{
-		{
-			name: "no configurable values",
-			ctx:  &OtherModuleTestContext{},
-			labelList: LabelListAttribute{
-				Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
-			},
-			filters: LabelPartitions{
-				"A": LabelPartition{Extensions: []string{".a"}},
-				"B": LabelPartition{Extensions: []string{".b"}},
-				"C": LabelPartition{Extensions: []string{".c"}},
-			},
-			expected: PartitionToLabelListAttribute{
-				"A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
-				"B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
-				"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
-			},
-		},
-		{
-			name: "no configurable values, remainder partition",
-			ctx:  &OtherModuleTestContext{},
-			labelList: LabelListAttribute{
-				Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
-			},
-			filters: LabelPartitions{
-				"A": LabelPartition{Extensions: []string{".a"}, Keep_remainder: true},
-				"B": LabelPartition{Extensions: []string{".b"}},
-				"C": LabelPartition{Extensions: []string{".c"}},
-			},
-			expected: PartitionToLabelListAttribute{
-				"A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "d.d", "e.e"}, []string{})},
-				"B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
-				"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
-			},
-		},
-		{
-			name: "no configurable values, empty partition",
-			ctx:  &OtherModuleTestContext{},
-			labelList: LabelListAttribute{
-				Value: makeLabelList([]string{"a.a", "c.c"}, []string{}),
-			},
-			filters: LabelPartitions{
-				"A": LabelPartition{Extensions: []string{".a"}},
-				"B": LabelPartition{Extensions: []string{".b"}},
-				"C": LabelPartition{Extensions: []string{".c"}},
-			},
-			expected: PartitionToLabelListAttribute{
-				"A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
-				"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
-			},
-		},
-		{
-			name: "no configurable values, has map",
-			ctx: &OtherModuleTestContext{
-				Modules: []TestModuleInfo{{ModuleName: "srcs", Typ: "fg", Dir: "dir"}},
-			},
-			labelList: LabelListAttribute{
-				Value: makeLabelList([]string{"a.a", "srcs", "b.b", "c.c"}, []string{}),
-			},
-			filters: LabelPartitions{
-				"A": LabelPartition{Extensions: []string{".a"}, LabelMapper: labelAddSuffixForTypeMapper("_a", "fg")},
-				"B": LabelPartition{Extensions: []string{".b"}},
-				"C": LabelPartition{Extensions: []string{".c"}},
-			},
-			expected: PartitionToLabelListAttribute{
-				"A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "srcs_a"}, []string{})},
-				"B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
-				"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
-			},
-		},
-		{
-			name: "configurable values, keeps empty if excludes",
-			ctx:  &OtherModuleTestContext{},
-			labelList: LabelListAttribute{
-				ConfigurableValues: configurableLabelLists{
-					ArchConfigurationAxis: labelListSelectValues{
-						"x86":    makeLabelList([]string{"a.a", "c.c"}, []string{}),
-						"arm":    makeLabelList([]string{"b.b"}, []string{}),
-						"x86_64": makeLabelList([]string{"b.b"}, []string{"d.d"}),
-					},
-				},
-			},
-			filters: LabelPartitions{
-				"A": LabelPartition{Extensions: []string{".a"}},
-				"B": LabelPartition{Extensions: []string{".b"}},
-				"C": LabelPartition{Extensions: []string{".c"}},
-			},
-			expected: PartitionToLabelListAttribute{
-				"A": LabelListAttribute{
-					ConfigurableValues: configurableLabelLists{
-						ArchConfigurationAxis: labelListSelectValues{
-							"x86":    makeLabelList([]string{"a.a"}, []string{}),
-							"x86_64": makeLabelList([]string{}, []string{"c.c"}),
-						},
-					},
-				},
-				"B": LabelListAttribute{
-					ConfigurableValues: configurableLabelLists{
-						ArchConfigurationAxis: labelListSelectValues{
-							"arm":    makeLabelList([]string{"b.b"}, []string{}),
-							"x86_64": makeLabelList([]string{"b.b"}, []string{"c.c"}),
-						},
-					},
-				},
-				"C": LabelListAttribute{
-					ConfigurableValues: configurableLabelLists{
-						ArchConfigurationAxis: labelListSelectValues{
-							"x86":    makeLabelList([]string{"c.c"}, []string{}),
-							"x86_64": makeLabelList([]string{}, []string{"c.c"}),
-						},
-					},
-				},
-			},
-		},
-		{
-			name: "error for multiple partitions same value",
-			ctx:  &OtherModuleTestContext{},
-			labelList: LabelListAttribute{
-				Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
-			},
-			filters: LabelPartitions{
-				"A":       LabelPartition{Extensions: []string{".a"}},
-				"other A": LabelPartition{Extensions: []string{".a"}},
-			},
-			expected:       PartitionToLabelListAttribute{},
-			expectedErrMsg: proptools.StringPtr(`"a.a" was found in multiple partitions:`),
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			got := PartitionLabelListAttribute(tc.ctx, &tc.labelList, tc.filters)
-
-			if hasErrors, expectsErr := len(tc.ctx.errors) > 0, tc.expectedErrMsg != nil; hasErrors != expectsErr {
-				t.Errorf("Unexpected error(s): %q, expected: %q", tc.ctx.errors, *tc.expectedErrMsg)
-			} else if tc.expectedErrMsg != nil {
-				found := false
-				for _, err := range tc.ctx.errors {
-					if strings.Contains(err, *tc.expectedErrMsg) {
-						found = true
-						break
-					}
-				}
-
-				if !found {
-					t.Errorf("Expected error message: %q, got %q", *tc.expectedErrMsg, tc.ctx.errors)
-				}
-				return
-			}
-
-			if len(tc.expected) != len(got) {
-				t.Errorf("Expected %d partitions, got %d partitions", len(tc.expected), len(got))
-			}
-			for partition, expectedLla := range tc.expected {
-				gotLla, ok := got[partition]
-				if !ok {
-					t.Errorf("Expected partition %q, but it was not found %v", partition, got)
-					continue
-				}
-				expectedLabelList := expectedLla.Value
-				gotLabelList := gotLla.Value
-				if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
-					t.Errorf("Expected no config includes %v, got %v", expectedLabelList.Includes, gotLabelList.Includes)
-				}
-				expectedAxes := expectedLla.SortedConfigurationAxes()
-				gotAxes := gotLla.SortedConfigurationAxes()
-				if !reflect.DeepEqual(expectedAxes, gotAxes) {
-					t.Errorf("Expected axes %v, got %v (%#v)", expectedAxes, gotAxes, gotLla)
-				}
-				for _, axis := range expectedLla.SortedConfigurationAxes() {
-					if _, exists := gotLla.ConfigurableValues[axis]; !exists {
-						t.Errorf("Expected %s to be a supported axis, but it was not found", axis)
-					}
-					if expected, got := expectedLla.ConfigurableValues[axis], gotLla.ConfigurableValues[axis]; len(expected) != len(got) {
-						t.Errorf("For axis %q: expected configs %v, got %v", axis, expected, got)
-					}
-					for config, expectedLabelList := range expectedLla.ConfigurableValues[axis] {
-						gotLabelList, exists := gotLla.ConfigurableValues[axis][config]
-						if !exists {
-							t.Errorf("Expected %s to be a supported config, but config was not found", config)
-							continue
-						}
-						if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
-							t.Errorf("Expected %s %s includes %v, got %v", axis, config, expectedLabelList.Includes, gotLabelList.Includes)
-						}
-					}
-				}
-			}
-		})
-	}
-}
-
-func TestDeduplicateAxesFromBase(t *testing.T) {
-	attr := StringListAttribute{
-		Value: []string{
-			"all_include",
-			"arm_include",
-			"android_include",
-			"linux_x86_include",
-		},
-		ConfigurableValues: configurableStringLists{
-			ArchConfigurationAxis: stringListSelectValues{
-				"arm": []string{"arm_include"},
-				"x86": []string{"x86_include"},
-			},
-			OsConfigurationAxis: stringListSelectValues{
-				"android": []string{"android_include"},
-				"linux":   []string{"linux_include"},
-			},
-			OsArchConfigurationAxis: stringListSelectValues{
-				"linux_x86": {"linux_x86_include"},
-			},
-			ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
-				"a": []string{"not_in_value"},
-			},
-		},
-	}
-
-	attr.DeduplicateAxesFromBase()
-
-	expectedBaseIncludes := []string{
-		"all_include",
-		"arm_include",
-		"android_include",
-		"linux_x86_include",
-	}
-	if !reflect.DeepEqual(expectedBaseIncludes, attr.Value) {
-		t.Errorf("Expected Value includes %q, got %q", attr.Value, expectedBaseIncludes)
-	}
-	expectedConfiguredIncludes := configurableStringLists{
-		ArchConfigurationAxis: stringListSelectValues{
-			"x86": []string{"x86_include"},
-		},
-		OsConfigurationAxis: stringListSelectValues{
-			"linux": []string{"linux_include"},
-		},
-		OsArchConfigurationAxis: stringListSelectValues{},
-		ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
-			"a": []string{"not_in_value"},
-		},
-	}
-	for _, axis := range attr.SortedConfigurationAxes() {
-		if _, ok := expectedConfiguredIncludes[axis]; !ok {
-			t.Errorf("Found unexpected axis %s", axis)
-			continue
-		}
-		expectedForAxis := expectedConfiguredIncludes[axis]
-		gotForAxis := attr.ConfigurableValues[axis]
-		if len(expectedForAxis) != len(gotForAxis) {
-			t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
-		}
-		for config, value := range gotForAxis {
-			if expected, ok := expectedForAxis[config]; ok {
-				if !reflect.DeepEqual(expected, value) {
-					t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value)
-				}
-			} else {
-				t.Errorf("Got unexpected config %q for %s", config, axis)
-			}
-		}
-	}
-}
diff --git a/bazel/testing.go b/bazel/testing.go
deleted file mode 100644
index 9a43b61..0000000
--- a/bazel/testing.go
+++ /dev/null
@@ -1,105 +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 bazel
-
-import (
-	"fmt"
-
-	"github.com/google/blueprint"
-)
-
-// TestModuleInfo implements blueprint.Module interface with sufficient information to mock a subset of
-// a blueprint ModuleContext
-type TestModuleInfo struct {
-	ModuleName string
-	Typ        string
-	Dir        string
-}
-
-// Name returns name for testModuleInfo -- required to implement blueprint.Module
-func (mi TestModuleInfo) Name() string {
-	return mi.ModuleName
-}
-
-// GenerateBuildActions unused, but required to implmeent blueprint.Module
-func (mi TestModuleInfo) GenerateBuildActions(blueprint.ModuleContext) {}
-
-func (mi TestModuleInfo) equals(other TestModuleInfo) bool {
-	return mi.ModuleName == other.ModuleName && mi.Typ == other.Typ && mi.Dir == other.Dir
-}
-
-// ensure testModuleInfo implements blueprint.Module
-var _ blueprint.Module = TestModuleInfo{}
-
-// OtherModuleTestContext is a mock context that implements OtherModuleContext
-type OtherModuleTestContext struct {
-	Modules []TestModuleInfo
-	errors  []string
-}
-
-// ModuleFromName retrieves the testModuleInfo corresponding to name, if it exists
-func (omc *OtherModuleTestContext) ModuleFromName(name string) (blueprint.Module, bool) {
-	for _, m := range omc.Modules {
-		if m.ModuleName == name {
-			return m, true
-		}
-	}
-	return TestModuleInfo{}, false
-}
-
-// testModuleInfo returns the testModuleInfo corresponding to a blueprint.Module if it exists in omc
-func (omc *OtherModuleTestContext) testModuleInfo(m blueprint.Module) (TestModuleInfo, bool) {
-	mi, ok := m.(TestModuleInfo)
-	if !ok {
-		return TestModuleInfo{}, false
-	}
-	for _, other := range omc.Modules {
-		if other.equals(mi) {
-			return mi, true
-		}
-	}
-	return TestModuleInfo{}, false
-}
-
-// OtherModuleType returns type of m if it exists in omc
-func (omc *OtherModuleTestContext) OtherModuleType(m blueprint.Module) string {
-	if mi, ok := omc.testModuleInfo(m); ok {
-		return mi.Typ
-	}
-	return ""
-}
-
-// OtherModuleName returns name of m if it exists in omc
-func (omc *OtherModuleTestContext) OtherModuleName(m blueprint.Module) string {
-	if mi, ok := omc.testModuleInfo(m); ok {
-		return mi.ModuleName
-	}
-	return ""
-}
-
-// OtherModuleDir returns dir of m if it exists in omc
-func (omc *OtherModuleTestContext) OtherModuleDir(m blueprint.Module) string {
-	if mi, ok := omc.testModuleInfo(m); ok {
-		return mi.Dir
-	}
-	return ""
-}
-
-func (omc *OtherModuleTestContext) ModuleErrorf(format string, args ...interface{}) {
-	omc.errors = append(omc.errors, fmt.Sprintf(format, args...))
-}
-
-// Ensure otherModuleTestContext implements OtherModuleContext
-var _ OtherModuleContext = &OtherModuleTestContext{}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index ba12682..28c0268 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -9,7 +9,6 @@
         "androidbp_to_build_templates.go",
         "build_conversion.go",
         "bzl_conversion.go",
-        "configurability.go",
         "constants.go",
         "conversion.go",
     ],
@@ -21,7 +20,6 @@
         "soong-android-allowlists",
         "soong-android-soongconfig",
         "soong-apex",
-        "soong-bazel",
         "soong-cc",
         "soong-cc-config",
         "soong-etc",
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index bd56768..18213a8 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -26,7 +26,6 @@
 	"strings"
 
 	"android/soong/android"
-	"android/soong/bazel"
 	"android/soong/starlark_fmt"
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -182,12 +181,11 @@
 }
 
 type CodegenContext struct {
-	config             android.Config
-	context            *android.Context
-	mode               CodegenMode
-	additionalDeps     []string
-	unconvertedDepMode unconvertedDepsMode
-	topDir             string
+	config         android.Config
+	context        *android.Context
+	mode           CodegenMode
+	additionalDeps []string
+	topDir         string
 }
 
 func (ctx *CodegenContext) Mode() CodegenMode {
@@ -207,16 +205,6 @@
 	QueryView CodegenMode = iota
 )
 
-type unconvertedDepsMode int
-
-const (
-	// Include a warning in conversion metrics about converted modules with unconverted direct deps
-	warnUnconvertedDeps unconvertedDepsMode = iota
-	// Error and fail conversion if encountering a module with unconverted direct deps
-	// Enabled by setting environment variable `BP2BUILD_ERROR_UNCONVERTED`
-	errorModulesUnconvertedDeps
-)
-
 func (mode CodegenMode) String() string {
 	switch mode {
 	case QueryView:
@@ -245,13 +233,11 @@
 // NewCodegenContext creates a wrapper context that conforms to PathContext for
 // writing BUILD files in the output directory.
 func NewCodegenContext(config android.Config, context *android.Context, mode CodegenMode, topDir string) *CodegenContext {
-	var unconvertedDeps unconvertedDepsMode
 	return &CodegenContext{
-		context:            context,
-		config:             config,
-		mode:               mode,
-		unconvertedDepMode: unconvertedDeps,
-		topDir:             topDir,
+		context: context,
+		config:  config,
+		mode:    mode,
+		topDir:  topDir,
 	}
 }
 
@@ -482,14 +468,6 @@
 		}), nil
 
 	case reflect.Struct:
-		// Special cases where the bp2build sends additional information to the codegenerator
-		// by wrapping the attributes in a custom struct type.
-		if attr, ok := propertyValue.Interface().(bazel.Attribute); ok {
-			return prettyPrintAttribute(attr, indent)
-		} else if label, ok := propertyValue.Interface().(bazel.Label); ok {
-			return fmt.Sprintf("%q", label.Label), nil
-		}
-
 		// Sort and print the struct props by the key.
 		structProps, err := extractStructProperties(propertyValue, indent)
 
@@ -506,7 +484,7 @@
 		// Interfaces are used for for arch, multilib and target properties.
 		return "", nil
 	case reflect.Map:
-		if v, ok := propertyValue.Interface().(bazel.StringMapAttribute); ok {
+		if v, ok := propertyValue.Interface().(map[string]string); ok {
 			return starlark_fmt.PrintStringStringDict(v, indent), nil
 		}
 		return "", fmt.Errorf("bp2build expects map of type map[string]string for field: %s", propertyValue)
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
deleted file mode 100644
index 3d9f0a2..0000000
--- a/bp2build/configurability.go
+++ /dev/null
@@ -1,328 +0,0 @@
-package bp2build
-
-import (
-	"fmt"
-	"reflect"
-
-	"android/soong/android"
-	"android/soong/bazel"
-	"android/soong/starlark_fmt"
-)
-
-// Configurability support for bp2build.
-
-type selects map[string]reflect.Value
-
-func getStringValue(str bazel.StringAttribute) (reflect.Value, []selects) {
-	value := reflect.ValueOf(str.Value)
-
-	if !str.HasConfigurableValues() {
-		return value, []selects{}
-	}
-
-	ret := selects{}
-	for _, axis := range str.SortedConfigurationAxes() {
-		configToStrs := str.ConfigurableValues[axis]
-		for config, strs := range configToStrs {
-			selectKey := axis.SelectKey(config)
-			ret[selectKey] = reflect.ValueOf(strs)
-		}
-	}
-
-	// if there is a select, use the base value as the conditions default value
-	if len(ret) > 0 {
-		if _, ok := ret[bazel.ConditionsDefaultSelectKey]; !ok {
-			ret[bazel.ConditionsDefaultSelectKey] = value
-			value = reflect.Zero(value.Type())
-		}
-	}
-
-	return value, []selects{ret}
-}
-
-func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects, bool) {
-	value := reflect.ValueOf(list.Value)
-	prepend := list.Prepend
-	if !list.HasConfigurableValues() {
-		return value, []selects{}, prepend
-	}
-
-	var ret []selects
-	for _, axis := range list.SortedConfigurationAxes() {
-		configToLists := list.ConfigurableValues[axis]
-		archSelects := map[string]reflect.Value{}
-		for config, labels := range configToLists {
-			selectKey := axis.SelectKey(config)
-			archSelects[selectKey] = reflect.ValueOf(labels)
-		}
-		if len(archSelects) > 0 {
-			ret = append(ret, archSelects)
-		}
-	}
-
-	return value, ret, prepend
-}
-
-func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
-	value := reflect.ValueOf(label.Value)
-	if !label.HasConfigurableValues() {
-		return value, []selects{}
-	}
-
-	ret := selects{}
-	for _, axis := range label.SortedConfigurationAxes() {
-		configToLabels := label.ConfigurableValues[axis]
-		for config, labels := range configToLabels {
-			selectKey := axis.SelectKey(config)
-			ret[selectKey] = reflect.ValueOf(labels)
-		}
-	}
-
-	// if there is a select, use the base value as the conditions default value
-	if len(ret) > 0 {
-		ret[bazel.ConditionsDefaultSelectKey] = value
-		value = reflect.Zero(value.Type())
-	}
-
-	return value, []selects{ret}
-}
-
-func getBoolValue(boolAttr bazel.BoolAttribute) (reflect.Value, []selects) {
-	value := reflect.ValueOf(boolAttr.Value)
-	if !boolAttr.HasConfigurableValues() {
-		return value, []selects{}
-	}
-
-	ret := selects{}
-	for _, axis := range boolAttr.SortedConfigurationAxes() {
-		configToBools := boolAttr.ConfigurableValues[axis]
-		for config, bools := range configToBools {
-			selectKey := axis.SelectKey(config)
-			ret[selectKey] = reflect.ValueOf(bools)
-		}
-	}
-	// if there is a select, use the base value as the conditions default value
-	if len(ret) > 0 {
-		ret[bazel.ConditionsDefaultSelectKey] = value
-		value = reflect.Zero(value.Type())
-	}
-
-	return value, []selects{ret}
-}
-func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects, bool) {
-	value := reflect.ValueOf(list.Value.Includes)
-	prepend := list.Prepend
-	var ret []selects
-	for _, axis := range list.SortedConfigurationAxes() {
-		configToLabels := list.ConfigurableValues[axis]
-		if !configToLabels.HasConfigurableValues() {
-			continue
-		}
-		archSelects := map[string]reflect.Value{}
-		defaultVal := configToLabels[bazel.ConditionsDefaultConfigKey]
-		// Skip empty list values unless ether EmitEmptyList is true, or these values differ from the default.
-		emitEmptyList := list.EmitEmptyList || len(defaultVal.Includes) > 0
-		for config, labels := range configToLabels {
-			// Omit any entries in the map which match the default value, for brevity.
-			if config != bazel.ConditionsDefaultConfigKey && labels.Equals(defaultVal) {
-				continue
-			}
-			selectKey := axis.SelectKey(config)
-			if use, value := labelListSelectValue(selectKey, labels, emitEmptyList); use {
-				archSelects[selectKey] = value
-			}
-		}
-		if len(archSelects) > 0 {
-			ret = append(ret, archSelects)
-		}
-	}
-
-	return value, ret, prepend
-}
-
-func labelListSelectValue(selectKey string, list bazel.LabelList, emitEmptyList bool) (bool, reflect.Value) {
-	if selectKey == bazel.ConditionsDefaultSelectKey || emitEmptyList || len(list.Includes) > 0 {
-		return true, reflect.ValueOf(list.Includes)
-	} else if len(list.Excludes) > 0 {
-		// if there is still an excludes -- we need to have an empty list for this select & use the
-		// value in conditions default Includes
-		return true, reflect.ValueOf([]string{})
-	}
-	return false, reflect.Zero(reflect.TypeOf([]string{}))
-}
-
-var (
-	emptyBazelList = "[]"
-	bazelNone      = "None"
-)
-
-// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
-// select statements.
-func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
-	var value reflect.Value
-	// configurableAttrs is the list of individual select statements to be
-	// concatenated together. These select statements should be along different
-	// axes. For example, one element may be
-	// `select({"//color:red": "one", "//color:green": "two"})`, and the second
-	// element may be `select({"//animal:cat": "three", "//animal:dog": "four"}).
-	// These selects should be sorted by axis identifier.
-	var configurableAttrs []selects
-	var prepend bool
-	var defaultSelectValue *string
-	var emitZeroValues bool
-	// If true, print the default attribute value, even if the attribute is zero.
-	shouldPrintDefault := false
-	switch list := v.(type) {
-	case bazel.StringAttribute:
-		if err := list.Collapse(); err != nil {
-			return "", err
-		}
-		value, configurableAttrs = getStringValue(list)
-		defaultSelectValue = &bazelNone
-	case bazel.StringListAttribute:
-		value, configurableAttrs, prepend = getStringListValues(list)
-		defaultSelectValue = &emptyBazelList
-	case bazel.LabelListAttribute:
-		value, configurableAttrs, prepend = getLabelListValues(list)
-		emitZeroValues = list.EmitEmptyList
-		defaultSelectValue = &emptyBazelList
-		if list.ForceSpecifyEmptyList && (!value.IsNil() || list.HasConfigurableValues()) {
-			shouldPrintDefault = true
-		}
-	case bazel.LabelAttribute:
-		if err := list.Collapse(); err != nil {
-			return "", err
-		}
-		value, configurableAttrs = getLabelValue(list)
-		defaultSelectValue = &bazelNone
-	case bazel.BoolAttribute:
-		if err := list.Collapse(); err != nil {
-			return "", err
-		}
-		value, configurableAttrs = getBoolValue(list)
-		defaultSelectValue = &bazelNone
-	default:
-		return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v)
-	}
-
-	var err error
-	ret := ""
-	if value.Kind() != reflect.Invalid {
-		s, err := prettyPrint(value, indent, false) // never emit zero values for the base value
-		if err != nil {
-			return ret, err
-		}
-
-		ret += s
-	}
-	// Convenience function to prepend/append selects components to an attribute value.
-	concatenateSelects := func(selectsData selects, defaultValue *string, s string, prepend bool) (string, error) {
-		selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent, emitZeroValues)
-		if err != nil {
-			return "", err
-		}
-		var left, right string
-		if prepend {
-			left, right = selectMap, s
-		} else {
-			left, right = s, selectMap
-		}
-		if left != "" && right != "" {
-			left += " + "
-		}
-		left += right
-
-		return left, nil
-	}
-
-	for _, configurableAttr := range configurableAttrs {
-		ret, err = concatenateSelects(configurableAttr, defaultSelectValue, ret, prepend)
-		if err != nil {
-			return "", err
-		}
-	}
-
-	if ret == "" && shouldPrintDefault {
-		return *defaultSelectValue, nil
-	}
-	return ret, nil
-}
-
-// prettyPrintSelectMap converts a map of select keys to reflected Values as a generic way
-// to construct a select map for any kind of attribute type.
-func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue *string, indent int, emitZeroValues bool) (string, error) {
-	if selectMap == nil {
-		return "", nil
-	}
-
-	var selects string
-	for _, selectKey := range android.SortedKeys(selectMap) {
-		if selectKey == bazel.ConditionsDefaultSelectKey {
-			// Handle default condition later.
-			continue
-		}
-		value := selectMap[selectKey]
-		if isZero(value) && !emitZeroValues && isZero(selectMap[bazel.ConditionsDefaultSelectKey]) {
-			// Ignore zero values to not generate empty lists. However, always note zero values if
-			// the default value is non-zero.
-			continue
-		}
-		s, err := prettyPrintSelectEntry(value, selectKey, indent, true)
-		if err != nil {
-			return "", err
-		}
-		// s could still be an empty string, e.g. unset slices of structs with
-		// length of 0.
-		if s != "" {
-			selects += s + ",\n"
-		}
-	}
-
-	if len(selects) == 0 {
-		// If there is a default value, and there are no selects for this axis, print that without any selects.
-		if val, exists := selectMap[bazel.ConditionsDefaultSelectKey]; exists {
-			return prettyPrint(val, indent, emitZeroValues)
-		}
-		// No conditions (or all values are empty lists), so no need for a map.
-		return "", nil
-	}
-
-	// Create the map.
-	ret := "select({\n"
-	ret += selects
-
-	// Handle the default condition
-	s, err := prettyPrintSelectEntry(selectMap[bazel.ConditionsDefaultSelectKey], bazel.ConditionsDefaultSelectKey, indent, emitZeroValues)
-	if err != nil {
-		return "", err
-	}
-	if s != "" {
-		// Print the custom default value.
-		ret += s
-		ret += ",\n"
-	} else if defaultValue != nil {
-		// Print an explicit empty list (the default value) even if the value is
-		// empty, to avoid errors about not finding a configuration that matches.
-		ret += fmt.Sprintf("%s\"%s\": %s,\n", starlark_fmt.Indention(indent+1), bazel.ConditionsDefaultSelectKey, *defaultValue)
-	}
-
-	ret += starlark_fmt.Indention(indent)
-	ret += "})"
-
-	return ret, nil
-}
-
-// prettyPrintSelectEntry converts a reflect.Value into an entry in a select map
-// with a provided key.
-func prettyPrintSelectEntry(value reflect.Value, key string, indent int, emitZeroValues bool) (string, error) {
-	s := starlark_fmt.Indention(indent + 1)
-	v, err := prettyPrint(value, indent+1, emitZeroValues)
-	if err != nil {
-		return "", err
-	}
-	if v == "" {
-		return "", nil
-	}
-	s += fmt.Sprintf("\"%s\": %s", key, v)
-	return s, nil
-}
diff --git a/bp2build/constants.go b/bp2build/constants.go
index 4870dff..76ba106 100644
--- a/bp2build/constants.go
+++ b/bp2build/constants.go
@@ -20,9 +20,4 @@
 
 	// The file name used for automatically generated files.
 	GeneratedBuildFileName = "BUILD.bazel"
-
-	// The file name used for hand-crafted build targets.
-	// NOTE: It is okay that this matches GeneratedBuildFileName, since we generate BUILD files in a different directory to source files
-	// FIXME: Because there are hundreds of existing BUILD.bazel files in the AOSP tree, we should pick another name here, like BUILD.android
-	HandcraftedBuildFileName = "BUILD.bazel"
 )
