diff --git a/dexpreopt/Android.bp b/dexpreopt/Android.bp
index b8f7ea6..94c0361 100644
--- a/dexpreopt/Android.bp
+++ b/dexpreopt/Android.bp
@@ -2,6 +2,7 @@
     name: "soong-dexpreopt",
     pkgPath: "android/soong/dexpreopt",
     srcs: [
+        "class_loader_context.go",
         "config.go",
         "dexpreopt.go",
         "testing.go",
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
new file mode 100644
index 0000000..48269e6
--- /dev/null
+++ b/dexpreopt/class_loader_context.go
@@ -0,0 +1,377 @@
+// 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 dexpreopt
+
+import (
+	"fmt"
+	"path/filepath"
+	"strings"
+
+	"android/soong/android"
+)
+
+// These libs are added as <uses-library> dependencies for apps if the targetSdkVersion in the
+// app manifest is less than the specified version. This is needed because these libraries haven't
+// existed prior to certain SDK version, but classes in them were in bootclasspath jars, etc.
+// Some of the compatibility libraries are optional (their <uses-library> tag has "required=false"),
+// so that if this library is missing this in not a build or run-time error.
+var OrgApacheHttpLegacy = "org.apache.http.legacy"
+var AndroidTestBase = "android.test.base"
+var AndroidTestMock = "android.test.mock"
+var AndroidHidlBase = "android.hidl.base-V1.0-java"
+var AndroidHidlManager = "android.hidl.manager-V1.0-java"
+
+var OptionalCompatUsesLibs28 = []string{
+	OrgApacheHttpLegacy,
+}
+var OptionalCompatUsesLibs30 = []string{
+	AndroidTestBase,
+	AndroidTestMock,
+}
+var CompatUsesLibs29 = []string{
+	AndroidHidlBase,
+	AndroidHidlManager,
+}
+var OptionalCompatUsesLibs = append(android.CopyOf(OptionalCompatUsesLibs28), OptionalCompatUsesLibs30...)
+var CompatUsesLibs = android.CopyOf(CompatUsesLibs29)
+
+const UnknownInstallLibraryPath = "error"
+
+const AnySdkVersion int = 9999 // should go last in class loader context
+
+// LibraryPath contains paths to the library DEX jar on host and on device.
+type LibraryPath struct {
+	Host   android.Path
+	Device string
+}
+
+// LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar.
+type LibraryPaths map[string]*LibraryPath
+
+type classLoaderContext struct {
+	// Library names
+	Names []string
+
+	// The class loader context using paths in the build.
+	Host android.Paths
+
+	// The class loader context using paths as they will be on the device.
+	Target []string
+}
+
+// A map of class loader contexts for each SDK version.
+// A map entry for "any" version contains libraries that are unconditionally added to class loader
+// context. Map entries for existing versions contains libraries that were in the default classpath
+// until that API version, and should be added to class loader context if and only if the
+// targetSdkVersion in the manifest or APK is less than that API version.
+type classLoaderContextMap map[int]*classLoaderContext
+
+// Add a new library path to the map, unless a path for this library already exists.
+// If necessary, check that the build and install paths exist.
+func (libPaths LibraryPaths) addLibraryPath(ctx android.ModuleContext, lib string,
+	hostPath, installPath android.Path, strict bool) {
+
+	// If missing dependencies are allowed, the build shouldn't fail when a <uses-library> is
+	// not found. However, this is likely to result is disabling dexpreopt, as it won't be
+	// possible to construct class loader context without on-host and on-device library paths.
+	strict = strict && !ctx.Config().AllowMissingDependencies()
+
+	if hostPath == nil && strict {
+		android.ReportPathErrorf(ctx, "unknown build path to <uses-library> '%s'", lib)
+	}
+
+	if installPath == nil {
+		if android.InList(lib, CompatUsesLibs) || android.InList(lib, OptionalCompatUsesLibs) {
+			// Assume that compatibility libraries are installed in /system/framework.
+			installPath = android.PathForModuleInstall(ctx, "framework", lib+".jar")
+		} else if strict {
+			android.ReportPathErrorf(ctx, "unknown install path to <uses-library> '%s'", lib)
+		}
+	}
+
+	// Add a library only if the build and install path to it is known.
+	if _, present := libPaths[lib]; !present {
+		var devicePath string
+		if installPath != nil {
+			devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath))
+		} else {
+			// For some stub libraries the only known thing is the name of their implementation
+			// library, but the library itself is unavailable (missing or part of a prebuilt). In
+			// such cases we still need to add the library to <uses-library> tags in the manifest,
+			// but we cannot use if for dexpreopt.
+			devicePath = UnknownInstallLibraryPath
+		}
+		libPaths[lib] = &LibraryPath{hostPath, devicePath}
+	}
+}
+
+// Add a new library path to the map. Enforce checks that the library paths exist.
+func (libPaths LibraryPaths) AddLibraryPath(ctx android.ModuleContext, lib string, hostPath, installPath android.Path) {
+	libPaths.addLibraryPath(ctx, lib, hostPath, installPath, true)
+}
+
+// Add a new library path to the map, if the library exists (name is not nil).
+// Don't enforce checks that the library paths exist. Some libraries may be missing from the build,
+// but their names still need to be added to <uses-library> tags in the manifest.
+func (libPaths LibraryPaths) MaybeAddLibraryPath(ctx android.ModuleContext, lib *string, hostPath, installPath android.Path) {
+	if lib != nil {
+		libPaths.addLibraryPath(ctx, *lib, hostPath, installPath, false)
+	}
+}
+
+// Add library paths from the second map to the first map (do not override existing entries).
+func (libPaths LibraryPaths) AddLibraryPaths(otherPaths LibraryPaths) {
+	for lib, path := range otherPaths {
+		if _, present := libPaths[lib]; !present {
+			libPaths[lib] = path
+		}
+	}
+}
+
+func (m classLoaderContextMap) getValue(sdkVer int) *classLoaderContext {
+	if _, ok := m[sdkVer]; !ok {
+		m[sdkVer] = &classLoaderContext{}
+	}
+	return m[sdkVer]
+}
+
+func (clc *classLoaderContext) addLib(lib string, hostPath android.Path, targetPath string) {
+	clc.Names = append(clc.Names, lib)
+	clc.Host = append(clc.Host, hostPath)
+	clc.Target = append(clc.Target, targetPath)
+}
+
+func (m classLoaderContextMap) addLibs(ctx android.PathContext, sdkVer int, module *ModuleConfig, libs ...string) bool {
+	clc := m.getValue(sdkVer)
+	for _, lib := range libs {
+		if p, ok := module.LibraryPaths[lib]; ok && p.Host != nil && p.Device != UnknownInstallLibraryPath {
+			clc.addLib(lib, p.Host, p.Device)
+		} else {
+			if sdkVer == AnySdkVersion {
+				// Fail the build if dexpreopt doesn't know paths to one of the <uses-library>
+				// dependencies. In the future we may need to relax this and just disable dexpreopt.
+				android.ReportPathErrorf(ctx, "dexpreopt cannot find path for <uses-library> '%s'", lib)
+			} else {
+				// No error for compatibility libraries, as Soong doesn't know if they are needed
+				// (this depends on the targetSdkVersion in the manifest).
+			}
+			return false
+		}
+	}
+	return true
+}
+
+func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathContext, module *ModuleConfig, libs ...string) {
+	clc := m.getValue(sdkVer)
+	for _, lib := range libs {
+		clc.addLib(lib, SystemServerDexJarHostPath(ctx, lib), filepath.Join("/system/framework", lib+".jar"))
+	}
+}
+
+func (m classLoaderContextMap) usesLibs() []string {
+	if clc, ok := m[AnySdkVersion]; ok {
+		return clc.Names
+	}
+	return nil
+}
+
+// genClassLoaderContext generates host and target class loader context to be passed to the dex2oat
+// command for the dexpreopted module. There are three possible cases:
+//
+// 1. System server jars. They have a special class loader context that includes other system
+//    server jars.
+//
+// 2. Library jars or APKs which have precise list of their <uses-library> libs. Their class loader
+//    context includes build and on-device paths to these libs. In some cases it may happen that
+//    the path to a <uses-library> is unknown (e.g. the dexpreopted module may depend on stubs
+//    library, whose implementation library is missing from the build altogether). In such case
+//    dexpreopting with the <uses-library> is impossible, and dexpreopting without it is pointless,
+//    as the runtime classpath won't match and the dexpreopted code will be discarded. Therefore in
+//    such cases the function returns nil, which disables dexpreopt.
+//
+// 3. All other library jars or APKs for which the exact <uses-library> list is unknown. They use
+//    the unsafe &-classpath workaround that means empty class loader context and absence of runtime
+//    check that the class loader context provided by the PackageManager agrees with the stored
+//    class loader context recorded in the .odex file.
+//
+func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) *classLoaderContextMap {
+	classLoaderContexts := make(classLoaderContextMap)
+	systemServerJars := NonUpdatableSystemServerJars(ctx, global)
+
+	if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
+		// System server jars should be dexpreopted together: class loader context of each jar
+		// should include all preceding jars on the system server classpath.
+		classLoaderContexts.addSystemServerLibs(AnySdkVersion, ctx, module, systemServerJars[:jarIndex]...)
+
+	} else if module.EnforceUsesLibraries {
+		// Unconditional class loader context.
+		usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...)
+		if !classLoaderContexts.addLibs(ctx, AnySdkVersion, module, usesLibs...) {
+			return nil
+		}
+
+		// Conditional class loader context for API version < 28.
+		const httpLegacy = "org.apache.http.legacy"
+		if !classLoaderContexts.addLibs(ctx, 28, module, httpLegacy) {
+			return nil
+		}
+
+		// Conditional class loader context for API version < 29.
+		usesLibs29 := []string{
+			"android.hidl.base-V1.0-java",
+			"android.hidl.manager-V1.0-java",
+		}
+		if !classLoaderContexts.addLibs(ctx, 29, module, usesLibs29...) {
+			return nil
+		}
+
+		// Conditional class loader context for API version < 30.
+		if !classLoaderContexts.addLibs(ctx, 30, module, OptionalCompatUsesLibs30...) {
+			return nil
+		}
+
+	} else {
+		// Pass special class loader context to skip the classpath and collision check.
+		// This will get removed once LOCAL_USES_LIBRARIES is enforced.
+		// Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default
+		// to the &.
+	}
+
+	fixConditionalClassLoaderContext(classLoaderContexts)
+
+	return &classLoaderContexts
+}
+
+// Find build and install paths to "android.hidl.base". The library must be present in conditional
+// class loader context for SDK version 29, because it's one of the compatibility libraries.
+func findHidlBasePaths(ctx android.PathContext, clcMap classLoaderContextMap) (android.Path, string) {
+	var hostPath android.Path
+	targetPath := UnknownInstallLibraryPath
+
+	if clc, ok := clcMap[29]; ok {
+		for i, lib := range clc.Names {
+			if lib == AndroidHidlBase {
+				hostPath = clc.Host[i]
+				targetPath = clc.Target[i]
+				break
+			}
+		}
+	}
+
+	// Fail if the library paths were not found. This may happen if the function is called at the
+	// wrong time (either before the compatibility libraries were added to context, or after they
+	// have been removed for some reason).
+	if hostPath == nil {
+		android.ReportPathErrorf(ctx, "dexpreopt cannot find build path to '%s'", AndroidHidlBase)
+	} else if targetPath == UnknownInstallLibraryPath {
+		android.ReportPathErrorf(ctx, "dexpreopt cannot find install path to '%s'", AndroidHidlBase)
+	}
+
+	return hostPath, targetPath
+}
+
+// Now that the full unconditional context is known, reconstruct conditional context.
+// Apply filters for individual libraries, mirroring what the PackageManager does when it
+// constructs class loader context on device.
+//
+// TODO(b/132357300):
+//   - move handling of android.hidl.manager -> android.hidl.base dependency here
+//   - remove android.hidl.manager and android.hidl.base unless the app is a system app.
+//
+func fixConditionalClassLoaderContext(clcMap classLoaderContextMap) {
+	usesLibs := clcMap.usesLibs()
+
+	for sdkVer, clc := range clcMap {
+		if sdkVer == AnySdkVersion {
+			continue
+		}
+		clcMap[sdkVer] = &classLoaderContext{}
+		for i, lib := range clc.Names {
+			if android.InList(lib, usesLibs) {
+				// skip compatibility libraries that are already included in unconditional context
+			} else if lib == AndroidTestMock && !android.InList("android.test.runner", usesLibs) {
+				// android.test.mock is only needed as a compatibility library (in conditional class
+				// loader context) if android.test.runner is used, otherwise skip it
+			} else {
+				clcMap[sdkVer].addLib(lib, clc.Host[i], clc.Target[i])
+			}
+		}
+	}
+}
+
+// Return the class loader context as a string and a slice of build paths for all dependencies.
+func computeClassLoaderContext(ctx android.PathContext, clcMap classLoaderContextMap) (clcStr string, paths android.Paths) {
+	hidlBaseHostPath, hidlBaseTargetPath := findHidlBasePaths(ctx, clcMap)
+
+	for _, ver := range android.SortedIntKeys(clcMap) {
+		clc := clcMap.getValue(ver)
+
+		clcLen := len(clc.Names)
+		if clcLen != len(clc.Host) || clcLen != len(clc.Target) {
+			android.ReportPathErrorf(ctx, "ill-formed class loader context")
+		}
+
+		var hostClc, targetClc []string
+		var hostPaths android.Paths
+
+		for i := 0; i < clcLen; i++ {
+			hostStr := "PCL[" + clc.Host[i].String() + "]"
+			targetStr := "PCL[" + clc.Target[i] + "]"
+
+			// Add dependency of android.hidl.manager on android.hidl.base (it is not tracked as
+			// a regular dependency by the build system, so it needs special handling).
+			if clc.Names[i] == AndroidHidlManager {
+				hostStr += "{PCL[" + hidlBaseHostPath.String() + "]}"
+				targetStr += "{PCL[" + hidlBaseTargetPath + "]}"
+				hostPaths = append(hostPaths, hidlBaseHostPath)
+			}
+
+			hostClc = append(hostClc, hostStr)
+			targetClc = append(targetClc, targetStr)
+			hostPaths = append(hostPaths, clc.Host[i])
+		}
+
+		if hostPaths != nil {
+			sdkVerStr := fmt.Sprintf("%d", ver)
+			if ver == AnySdkVersion {
+				sdkVerStr = "any" // a special keyword that means any SDK version
+			}
+			clcStr += fmt.Sprintf(" --host-context-for-sdk %s %s", sdkVerStr, strings.Join(hostClc, "#"))
+			clcStr += fmt.Sprintf(" --target-context-for-sdk %s %s", sdkVerStr, strings.Join(targetClc, "#"))
+			paths = append(paths, hostPaths...)
+		}
+	}
+
+	return clcStr, paths
+}
+
+type jsonLibraryPath struct {
+	Host   string
+	Device string
+}
+
+type jsonLibraryPaths map[string]jsonLibraryPath
+
+// convert JSON map of library paths to LibraryPaths
+func constructLibraryPaths(ctx android.PathContext, paths jsonLibraryPaths) LibraryPaths {
+	m := LibraryPaths{}
+	for lib, path := range paths {
+		m[lib] = &LibraryPath{
+			constructPath(ctx, path.Host),
+			path.Device,
+		}
+	}
+	return m
+}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 2052847..03accc8 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -100,104 +100,6 @@
 	ConstructContext android.Path
 }
 
-// These libs are added as <uses-library> dependencies for apps if the targetSdkVersion in the
-// app manifest is less than the specified version. This is needed because these libraries haven't
-// existed prior to certain SDK version, but classes in them were in bootclasspath jars, etc.
-// Some of the compatibility libraries are optional (their <uses-library> tag has "required=false"),
-// so that if this library is missing this in not a build or run-time error.
-var OrgApacheHttpLegacy = "org.apache.http.legacy"
-var AndroidTestBase = "android.test.base"
-var AndroidTestMock = "android.test.mock"
-var AndroidHidlBase = "android.hidl.base-V1.0-java"
-var AndroidHidlManager = "android.hidl.manager-V1.0-java"
-
-var OptionalCompatUsesLibs28 = []string{
-	OrgApacheHttpLegacy,
-}
-var OptionalCompatUsesLibs30 = []string{
-	AndroidTestBase,
-	AndroidTestMock,
-}
-var CompatUsesLibs29 = []string{
-	AndroidHidlBase,
-	AndroidHidlManager,
-}
-var OptionalCompatUsesLibs = append(android.CopyOf(OptionalCompatUsesLibs28), OptionalCompatUsesLibs30...)
-var CompatUsesLibs = android.CopyOf(CompatUsesLibs29)
-
-const UnknownInstallLibraryPath = "error"
-
-// LibraryPath contains paths to the library DEX jar on host and on device.
-type LibraryPath struct {
-	Host   android.Path
-	Device string
-}
-
-// LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar.
-type LibraryPaths map[string]*LibraryPath
-
-// Add a new library path to the map, unless a path for this library already exists.
-// If necessary, check that the build and install paths exist.
-func (libPaths LibraryPaths) addLibraryPath(ctx android.ModuleContext, lib string,
-	hostPath, installPath android.Path, strict bool) {
-
-	// If missing dependencies are allowed, the build shouldn't fail when a <uses-library> is
-	// not found. However, this is likely to result is disabling dexpreopt, as it won't be
-	// possible to construct class loader context without on-host and on-device library paths.
-	strict = strict && !ctx.Config().AllowMissingDependencies()
-
-	if hostPath == nil && strict {
-		android.ReportPathErrorf(ctx, "unknown build path to <uses-library> '%s'", lib)
-	}
-
-	if installPath == nil {
-		if android.InList(lib, CompatUsesLibs) || android.InList(lib, OptionalCompatUsesLibs) {
-			// Assume that compatibility libraries are installed in /system/framework.
-			installPath = android.PathForModuleInstall(ctx, "framework", lib+".jar")
-		} else if strict {
-			android.ReportPathErrorf(ctx, "unknown install path to <uses-library> '%s'", lib)
-		}
-	}
-
-	// Add a library only if the build and install path to it is known.
-	if _, present := libPaths[lib]; !present {
-		var devicePath string
-		if installPath != nil {
-			devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath))
-		} else {
-			// For some stub libraries the only known thing is the name of their implementation
-			// library, but the library itself is unavailable (missing or part of a prebuilt). In
-			// such cases we still need to add the library to <uses-library> tags in the manifest,
-			// but we cannot use if for dexpreopt.
-			devicePath = UnknownInstallLibraryPath
-		}
-		libPaths[lib] = &LibraryPath{hostPath, devicePath}
-	}
-}
-
-// Add a new library path to the map. Enforce checks that the library paths exist.
-func (libPaths LibraryPaths) AddLibraryPath(ctx android.ModuleContext, lib string, hostPath, installPath android.Path) {
-	libPaths.addLibraryPath(ctx, lib, hostPath, installPath, true)
-}
-
-// Add a new library path to the map, if the library exists (name is not nil).
-// Don't enforce checks that the library paths exist. Some libraries may be missing from the build,
-// but their names still need to be added to <uses-library> tags in the manifest.
-func (libPaths LibraryPaths) MaybeAddLibraryPath(ctx android.ModuleContext, lib *string, hostPath, installPath android.Path) {
-	if lib != nil {
-		libPaths.addLibraryPath(ctx, *lib, hostPath, installPath, false)
-	}
-}
-
-// Add library paths from the second map to the first map (do not override existing entries).
-func (libPaths LibraryPaths) AddLibraryPaths(otherPaths LibraryPaths) {
-	for lib, path := range otherPaths {
-		if _, present := libPaths[lib]; !present {
-			libPaths[lib] = path
-		}
-	}
-}
-
 type ModuleConfig struct {
 	Name            string
 	DexLocation     string // dex location on device
@@ -354,13 +256,6 @@
 // from Make to read the module dexpreopt.config written in the Make config
 // stage.
 func ParseModuleConfig(ctx android.PathContext, data []byte) (*ModuleConfig, error) {
-	type jsonLibraryPath struct {
-		Host   string
-		Device string
-	}
-
-	type jsonLibraryPaths map[string]jsonLibraryPath
-
 	type ModuleJSONConfig struct {
 		*ModuleConfig
 
@@ -376,18 +271,6 @@
 		PreoptBootClassPathDexFiles []string
 	}
 
-	// convert JSON map of library paths to LibraryPaths
-	constructLibraryPaths := func(ctx android.PathContext, paths jsonLibraryPaths) LibraryPaths {
-		m := LibraryPaths{}
-		for lib, path := range paths {
-			m[lib] = &LibraryPath{
-				constructPath(ctx, path.Host),
-				path.Device,
-			}
-		}
-		return m
-	}
-
 	config := ModuleJSONConfig{}
 
 	err := json.Unmarshal(data, &config)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 66e765f..51d1157 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -194,243 +194,6 @@
 	return profilePath
 }
 
-type classLoaderContext struct {
-	// Library names
-	Names []string
-
-	// The class loader context using paths in the build.
-	Host android.Paths
-
-	// The class loader context using paths as they will be on the device.
-	Target []string
-}
-
-// A map of class loader contexts for each SDK version.
-// A map entry for "any" version contains libraries that are unconditionally added to class loader
-// context. Map entries for existing versions contains libraries that were in the default classpath
-// until that API version, and should be added to class loader context if and only if the
-// targetSdkVersion in the manifest or APK is less than that API version.
-type classLoaderContextMap map[int]*classLoaderContext
-
-const AnySdkVersion int = 9999 // should go last in class loader context
-
-func (m classLoaderContextMap) getValue(sdkVer int) *classLoaderContext {
-	if _, ok := m[sdkVer]; !ok {
-		m[sdkVer] = &classLoaderContext{}
-	}
-	return m[sdkVer]
-}
-
-func (clc *classLoaderContext) addLib(lib string, hostPath android.Path, targetPath string) {
-	clc.Names = append(clc.Names, lib)
-	clc.Host = append(clc.Host, hostPath)
-	clc.Target = append(clc.Target, targetPath)
-}
-
-func (m classLoaderContextMap) addLibs(ctx android.PathContext, sdkVer int, module *ModuleConfig, libs ...string) bool {
-	clc := m.getValue(sdkVer)
-	for _, lib := range libs {
-		if p, ok := module.LibraryPaths[lib]; ok && p.Host != nil && p.Device != UnknownInstallLibraryPath {
-			clc.addLib(lib, p.Host, p.Device)
-		} else {
-			if sdkVer == AnySdkVersion {
-				// Fail the build if dexpreopt doesn't know paths to one of the <uses-library>
-				// dependencies. In the future we may need to relax this and just disable dexpreopt.
-				android.ReportPathErrorf(ctx, "dexpreopt cannot find path for <uses-library> '%s'", lib)
-			} else {
-				// No error for compatibility libraries, as Soong doesn't know if they are needed
-				// (this depends on the targetSdkVersion in the manifest).
-			}
-			return false
-		}
-	}
-	return true
-}
-
-func (m classLoaderContextMap) usesLibs() []string {
-	if clc, ok := m[AnySdkVersion]; ok {
-		return clc.Names
-	}
-	return nil
-}
-
-func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathContext, module *ModuleConfig, libs ...string) {
-	clc := m.getValue(sdkVer)
-	for _, lib := range libs {
-		clc.addLib(lib, SystemServerDexJarHostPath(ctx, lib), filepath.Join("/system/framework", lib+".jar"))
-	}
-}
-
-// genClassLoaderContext generates host and target class loader context to be passed to the dex2oat
-// command for the dexpreopted module. There are three possible cases:
-//
-// 1. System server jars. They have a special class loader context that includes other system
-//    server jars.
-//
-// 2. Library jars or APKs which have precise list of their <uses-library> libs. Their class loader
-//    context includes build and on-device paths to these libs. In some cases it may happen that
-//    the path to a <uses-library> is unknown (e.g. the dexpreopted module may depend on stubs
-//    library, whose implementation library is missing from the build altogether). In such case
-//    dexpreopting with the <uses-library> is impossible, and dexpreopting without it is pointless,
-//    as the runtime classpath won't match and the dexpreopted code will be discarded. Therefore in
-//    such cases the function returns nil, which disables dexpreopt.
-//
-// 3. All other library jars or APKs for which the exact <uses-library> list is unknown. They use
-//    the unsafe &-classpath workaround that means empty class loader context and absence of runtime
-//    check that the class loader context provided by the PackageManager agrees with the stored
-//    class loader context recorded in the .odex file.
-//
-func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) *classLoaderContextMap {
-	classLoaderContexts := make(classLoaderContextMap)
-	systemServerJars := NonUpdatableSystemServerJars(ctx, global)
-
-	if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
-		// System server jars should be dexpreopted together: class loader context of each jar
-		// should include all preceding jars on the system server classpath.
-		classLoaderContexts.addSystemServerLibs(AnySdkVersion, ctx, module, systemServerJars[:jarIndex]...)
-
-	} else if module.EnforceUsesLibraries {
-		// Unconditional class loader context.
-		usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...)
-		if !classLoaderContexts.addLibs(ctx, AnySdkVersion, module, usesLibs...) {
-			return nil
-		}
-
-		// Conditional class loader context for API version < 28.
-		const httpLegacy = "org.apache.http.legacy"
-		if !classLoaderContexts.addLibs(ctx, 28, module, httpLegacy) {
-			return nil
-		}
-
-		// Conditional class loader context for API version < 29.
-		usesLibs29 := []string{
-			"android.hidl.base-V1.0-java",
-			"android.hidl.manager-V1.0-java",
-		}
-		if !classLoaderContexts.addLibs(ctx, 29, module, usesLibs29...) {
-			return nil
-		}
-
-		// Conditional class loader context for API version < 30.
-		if !classLoaderContexts.addLibs(ctx, 30, module, OptionalCompatUsesLibs30...) {
-			return nil
-		}
-
-	} else {
-		// Pass special class loader context to skip the classpath and collision check.
-		// This will get removed once LOCAL_USES_LIBRARIES is enforced.
-		// Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default
-		// to the &.
-	}
-
-	fixConditionalClassLoaderContext(classLoaderContexts)
-
-	return &classLoaderContexts
-}
-
-// Find build and install paths to "android.hidl.base". The library must be present in conditional
-// class loader context for SDK version 29, because it's one of the compatibility libraries.
-func findHidlBasePaths(ctx android.PathContext, clcMap classLoaderContextMap) (android.Path, string) {
-	var hostPath android.Path
-	targetPath := UnknownInstallLibraryPath
-
-	if clc, ok := clcMap[29]; ok {
-		for i, lib := range clc.Names {
-			if lib == AndroidHidlBase {
-				hostPath = clc.Host[i]
-				targetPath = clc.Target[i]
-				break
-			}
-		}
-	}
-
-	// Fail if the library paths were not found. This may happen if the function is called at the
-	// wrong time (either before the compatibility libraries were added to context, or after they
-	// have been removed for some reason).
-	if hostPath == nil {
-		android.ReportPathErrorf(ctx, "dexpreopt cannot find build path to '%s'", AndroidHidlBase)
-	} else if targetPath == UnknownInstallLibraryPath {
-		android.ReportPathErrorf(ctx, "dexpreopt cannot find install path to '%s'", AndroidHidlBase)
-	}
-
-	return hostPath, targetPath
-}
-
-// Now that the full unconditional context is known, reconstruct conditional context.
-// Apply filters for individual libraries, mirroring what the PackageManager does when it
-// constructs class loader context on device.
-//
-// TODO(b/132357300):
-//   - move handling of android.hidl.manager -> android.hidl.base dependency here
-//   - remove android.hidl.manager and android.hidl.base unless the app is a system app.
-//
-func fixConditionalClassLoaderContext(clcMap classLoaderContextMap) {
-	usesLibs := clcMap.usesLibs()
-
-	for sdkVer, clc := range clcMap {
-		if sdkVer == AnySdkVersion {
-			continue
-		}
-		clcMap[sdkVer] = &classLoaderContext{}
-		for i, lib := range clc.Names {
-			if android.InList(lib, usesLibs) {
-				// skip compatibility libraries that are already included in unconditional context
-			} else if lib == AndroidTestMock && !android.InList("android.test.runner", usesLibs) {
-				// android.test.mock is only needed as a compatibility library (in conditional class
-				// loader context) if android.test.runner is used, otherwise skip it
-			} else {
-				clcMap[sdkVer].addLib(lib, clc.Host[i], clc.Target[i])
-			}
-		}
-	}
-}
-
-// Return the class loader context as a string and a slice of build paths for all dependencies.
-func computeClassLoaderContext(ctx android.PathContext, clcMap classLoaderContextMap) (clcStr string, paths android.Paths) {
-	hidlBaseHostPath, hidlBaseTargetPath := findHidlBasePaths(ctx, clcMap)
-
-	for _, ver := range android.SortedIntKeys(clcMap) {
-		clc := clcMap.getValue(ver)
-
-		clcLen := len(clc.Names)
-		if clcLen != len(clc.Host) || clcLen != len(clc.Target) {
-			android.ReportPathErrorf(ctx, "ill-formed class loader context")
-		}
-
-		var hostClc, targetClc []string
-		var hostPaths android.Paths
-
-		for i := 0; i < clcLen; i++ {
-			hostStr := "PCL[" + clc.Host[i].String() + "]"
-			targetStr := "PCL[" + clc.Target[i] + "]"
-
-			// Add dependency of android.hidl.manager on android.hidl.base (it is not tracked as
-			// a regular dependency by the build system, so it needs special handling).
-			if clc.Names[i] == AndroidHidlManager {
-				hostStr += "{PCL[" + hidlBaseHostPath.String() + "]}"
-				targetStr += "{PCL[" + hidlBaseTargetPath + "]}"
-				hostPaths = append(hostPaths, hidlBaseHostPath)
-			}
-
-			hostClc = append(hostClc, hostStr)
-			targetClc = append(targetClc, targetStr)
-			hostPaths = append(hostPaths, clc.Host[i])
-		}
-
-		if hostPaths != nil {
-			sdkVerStr := fmt.Sprintf("%d", ver)
-			if ver == AnySdkVersion {
-				sdkVerStr = "any" // a special keyword that means any SDK version
-			}
-			clcStr += fmt.Sprintf(" --host-context-for-sdk %s %s", sdkVerStr, strings.Join(hostClc, "#"))
-			clcStr += fmt.Sprintf(" --target-context-for-sdk %s %s", sdkVerStr, strings.Join(targetClc, "#"))
-			paths = append(paths, hostPaths...)
-		}
-	}
-
-	return clcStr, paths
-}
-
 func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
 	module *ModuleConfig, rule *android.RuleBuilder, archIdx int, classLoaderContexts classLoaderContextMap,
 	profile android.WritablePath, appImage bool, generateDM bool) {
