diff --git a/src/main/java/com/google/devtools/build/lib/exec/BUILD b/src/main/java/com/google/devtools/build/lib/exec/BUILD
index c90923a..491df37 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/exec/BUILD
@@ -107,9 +107,7 @@
     srcs = ["ExecutorBuilder.java"],
     deps = [
         ":executor_lifecycle_listener",
-        ":spawn_action_context_maps",
         "//src/main/java/com/google/devtools/build/lib/actions",
-        "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
         "//third_party:guava",
     ],
 )
@@ -201,27 +199,6 @@
 )
 
 java_library(
-    name = "spawn_action_context_maps",
-    srcs = [
-        "ProxySpawnActionContext.java",
-        "SpawnActionContextMaps.java",
-    ],
-    deps = [
-        ":abstract_spawn_strategy",
-        ":remote_local_fallback_registry",
-        "//src/main/java/com/google/devtools/build/lib/actions",
-        "//src/main/java/com/google/devtools/build/lib/events",
-        "//src/main/java/com/google/devtools/build/lib/util",
-        "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
-        "//src/main/java/com/google/devtools/build/lib/util:detailed_exit_code",
-        "//src/main/protobuf:failure_details_java_proto",
-        "//third_party:auto_value",
-        "//third_party:guava",
-        "//third_party:jsr305",
-    ],
-)
-
-java_library(
     name = "spawn_cache",
     srcs = ["SpawnCache.java"],
     deps = [
diff --git a/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java b/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java
index 3c40288..78da325 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java
@@ -16,7 +16,6 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
-import com.google.devtools.build.lib.util.AbruptExitException;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -25,15 +24,9 @@
  * class is part of the module API, which allows modules to affect how the executor is initialized.
  */
 public class ExecutorBuilder {
-  private final SpawnActionContextMaps.Builder spawnActionContextMapsBuilder =
-      new SpawnActionContextMaps.Builder();
   private final Set<ExecutorLifecycleListener> executorLifecycleListeners = new LinkedHashSet<>();
   private ActionInputPrefetcher prefetcher;
 
-  public SpawnActionContextMaps getSpawnActionContextMaps() throws AbruptExitException {
-    return spawnActionContextMapsBuilder.build();
-  }
-
   /** Returns all executor lifecycle listeners registered with this builder so far. */
   public ImmutableSet<ExecutorLifecycleListener> getExecutorLifecycleListeners() {
     return ImmutableSet.copyOf(executorLifecycleListeners);
diff --git a/src/main/java/com/google/devtools/build/lib/exec/ProxySpawnActionContext.java b/src/main/java/com/google/devtools/build/lib/exec/ProxySpawnActionContext.java
deleted file mode 100644
index ae0960a..0000000
--- a/src/main/java/com/google/devtools/build/lib/exec/ProxySpawnActionContext.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018 The Bazel Authors. 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 com.google.devtools.build.lib.exec;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.ActionContext;
-import com.google.devtools.build.lib.actions.ActionExecutionContext;
-import com.google.devtools.build.lib.actions.ExecException;
-import com.google.devtools.build.lib.actions.Spawn;
-import com.google.devtools.build.lib.actions.SpawnContinuation;
-import com.google.devtools.build.lib.actions.SpawnResult;
-import com.google.devtools.build.lib.actions.SpawnStrategy;
-import com.google.devtools.build.lib.actions.UserExecException;
-import com.google.devtools.build.lib.events.NullEventHandler;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/** Proxy that looks up the right SpawnActionContext for a spawn during {@link #exec}. */
-public final class ProxySpawnActionContext implements SpawnStrategy {
-
-  private final SpawnActionContextMaps spawnActionContextMaps;
-
-  /**
-   * Creates a new {@link ProxySpawnActionContext}.
-   *
-   * @param spawnActionContextMaps The {@link SpawnActionContextMaps} to use to decide which {@link
-   *     SpawnStrategy} should execute a given {@link Spawn} during {@link #exec}.
-   */
-  public ProxySpawnActionContext(SpawnActionContextMaps spawnActionContextMaps) {
-    this.spawnActionContextMaps = spawnActionContextMaps;
-  }
-
-  @Override
-  public ImmutableList<SpawnResult> exec(Spawn spawn, ActionExecutionContext actionExecutionContext)
-      throws ExecException, InterruptedException {
-    return resolveOne(spawn, actionExecutionContext).exec(spawn, actionExecutionContext);
-  }
-
-  @Override
-  public SpawnContinuation beginExecution(
-      Spawn spawn, ActionExecutionContext actionExecutionContext) throws InterruptedException {
-    SpawnStrategy resolvedStrategy;
-    try {
-      resolvedStrategy = resolveOne(spawn, actionExecutionContext);
-    } catch (ExecException e) {
-      return SpawnContinuation.failedWithExecException(e);
-    }
-    return resolvedStrategy.beginExecution(spawn, actionExecutionContext);
-  }
-
-  private SpawnStrategy resolveOne(Spawn spawn, ActionExecutionContext actionExecutionContext)
-      throws UserExecException {
-    List<SpawnStrategy> strategies = resolve(spawn, actionExecutionContext);
-
-    // Because the strategies are ordered by preference, we can execute the spawn with the best
-    // possible one by simply filtering out the ones that can't execute it and then picking the
-    // first one from the remaining strategies in the list.
-    return strategies.get(0);
-  }
-
-  /**
-   * Returns the list of {@link SpawnStrategy}s that should be used to execute the given spawn.
-   *
-   * @param spawn The spawn for which the correct {@link SpawnStrategy} should be determined.
-   * @param eventHandler An event handler that can be used to print messages while resolving the
-   *     correct {@link SpawnStrategy} for the given spawn.
-   */
-  @VisibleForTesting
-  public List<SpawnStrategy> resolve(Spawn spawn, ActionExecutionContext actionExecutionContext)
-      throws UserExecException {
-    List<SpawnStrategy> strategies =
-        spawnActionContextMaps.getSpawnActionContexts(
-            spawn, actionExecutionContext.getEventHandler());
-
-    strategies =
-        strategies.stream()
-            .filter(spawnActionContext -> spawnActionContext.canExec(spawn, actionExecutionContext))
-            .collect(Collectors.toList());
-
-    if (strategies.isEmpty()) {
-      throw new UserExecException(
-          String.format(
-              "No usable spawn strategy found for spawn with mnemonic %s.  Your"
-                  + " --spawn_strategy, --genrule_strategy or --strategy flags are probably too"
-                  + " strict. Visit https://github.com/bazelbuild/bazel/issues/7480 for"
-                  + " migration advice",
-              spawn.getMnemonic()));
-    }
-
-    return strategies;
-  }
-
-  @Override
-  public boolean canExec(Spawn spawn, ActionContext.ActionContextRegistry actionContextRegistry) {
-    return spawnActionContextMaps.getSpawnActionContexts(spawn, NullEventHandler.INSTANCE).stream()
-        .anyMatch(spawnActionContext -> spawnActionContext.canExec(spawn, actionContextRegistry));
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SpawnActionContextMaps.java b/src/main/java/com/google/devtools/build/lib/exec/SpawnActionContextMaps.java
deleted file mode 100644
index b8aae55..0000000
--- a/src/main/java/com/google/devtools/build/lib/exec/SpawnActionContextMaps.java
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright 2018 The Bazel Authors. 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 com.google.devtools.build.lib.exec;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Table;
-import com.google.devtools.build.lib.actions.ActionContext;
-import com.google.devtools.build.lib.actions.ActionContextMarker;
-import com.google.devtools.build.lib.actions.DynamicStrategyRegistry;
-import com.google.devtools.build.lib.actions.SandboxedSpawnStrategy;
-import com.google.devtools.build.lib.actions.Spawn;
-import com.google.devtools.build.lib.actions.SpawnStrategy;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.events.EventHandler;
-import com.google.devtools.build.lib.events.Reporter;
-import com.google.devtools.build.lib.server.FailureDetails;
-import com.google.devtools.build.lib.server.FailureDetails.ExecutionOptions.Code;
-import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
-import com.google.devtools.build.lib.util.AbruptExitException;
-import com.google.devtools.build.lib.util.DetailedExitCode;
-import com.google.devtools.build.lib.util.RegexFilter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
-
-/**
- * Container for looking up the {@link ActionContext} to use for a given action.
- *
- * <p>Holds {@link ActionContext} mappings populated by modules. These include mappings from
- * mnemonics and from description patterns.
- *
- * <p>At startup time, the application provides {@link Builder} to each module to register its
- * contexts and mappings. At runtime, the {@link BlazeExecutor} uses the constructed object to find
- * the context for each action.
- */
-public final class SpawnActionContextMaps
-    implements DynamicStrategyRegistry,
-        RemoteLocalFallbackRegistry,
-        ActionContext.ActionContextRegistry {
-
-  /** A stored entry for a {@link RegexFilter} to {@link SpawnStrategy} mapping. */
-  @AutoValue
-  public abstract static class RegexFilterSpawnStrategy {
-    public abstract RegexFilter regexFilter();
-
-    public abstract ImmutableList<SpawnStrategy> strategies();
-  }
-
-  private final ImmutableSortedMap<String, List<SpawnStrategy>> mnemonicToSpawnStrategiesMap;
-  private final ImmutableClassToInstanceMap<ActionContext> strategies;
-  private final ImmutableList<RegexFilterSpawnStrategy> spawnStrategyRegexList;
-  private final ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToRemoteDynamicStrategies;
-  private final ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToLocalDynamicStrategies;
-  private final ImmutableMap<Class<? extends ActionContext>, ActionContext> contextMap;
-  @Nullable private final AbstractSpawnStrategy remoteLocalFallbackStrategy;
-
-  private SpawnActionContextMaps(
-      ImmutableSortedMap<String, List<SpawnStrategy>> mnemonicToSpawnStrategiesMap,
-      ImmutableClassToInstanceMap<ActionContext> strategies,
-      ImmutableList<RegexFilterSpawnStrategy> spawnStrategyRegexList,
-      ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToRemoteDynamicStrategies,
-      ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToLocalDynamicStrategies,
-      AbstractSpawnStrategy remoteLocalFallbackStrategy) {
-    this.mnemonicToSpawnStrategiesMap = mnemonicToSpawnStrategiesMap;
-    this.strategies = strategies;
-    this.spawnStrategyRegexList = spawnStrategyRegexList;
-    this.mnemonicToRemoteDynamicStrategies = mnemonicToRemoteDynamicStrategies;
-    this.mnemonicToLocalDynamicStrategies = mnemonicToLocalDynamicStrategies;
-    this.remoteLocalFallbackStrategy = remoteLocalFallbackStrategy;
-    contextMap = createContextMap();
-  }
-
-  /**
-   * Returns a list of appropriate {@link ActionContext}s to execute the given {@link Spawn} with.
-   *
-   * <p>If the reason for selecting the context is worth mentioning to the user, logs a message
-   * using the given {@link Reporter}.
-   */
-  List<SpawnStrategy> getSpawnActionContexts(Spawn spawn, EventHandler reporter) {
-    Preconditions.checkNotNull(spawn);
-    if (!spawnStrategyRegexList.isEmpty() && spawn.getResourceOwner() != null
-            // Don't override test strategies by --strategy_regexp for backwards compatibility.
-            && !"TestRunner".equals(spawn.getMnemonic())) {
-      String description = spawn.getResourceOwner().getProgressMessage();
-      if (description != null) {
-        for (RegexFilterSpawnStrategy entry : spawnStrategyRegexList) {
-          if (entry.regexFilter().isIncluded(description) && entry.strategies() != null) {
-            reporter.handle(
-                Event.progress(description + " with context " + entry.strategies().toString()));
-            return entry.strategies();
-          }
-        }
-      }
-    }
-    List<SpawnStrategy> strategies = mnemonicToSpawnStrategiesMap.get(spawn.getMnemonic());
-    if (strategies != null) {
-      return strategies;
-    }
-    return Preconditions.checkNotNull(mnemonicToSpawnStrategiesMap.get(""));
-  }
-
-  @Override
-  public List<SandboxedSpawnStrategy> getDynamicSpawnActionContexts(
-      Spawn spawn, DynamicMode dynamicMode) {
-    ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToDynamicStrategies =
-        dynamicMode == DynamicStrategyRegistry.DynamicMode.REMOTE
-            ? mnemonicToRemoteDynamicStrategies
-            : mnemonicToLocalDynamicStrategies;
-    return ImmutableList.<SandboxedSpawnStrategy>builder()
-        .addAll(mnemonicToDynamicStrategies.get(spawn.getMnemonic()))
-        .addAll(mnemonicToDynamicStrategies.get(""))
-        .build();
-  }
-
-  @Nullable
-  @Override
-  public AbstractSpawnStrategy getRemoteLocalFallbackStrategy() {
-    return remoteLocalFallbackStrategy;
-  }
-
-  private ImmutableMap<Class<? extends ActionContext>, ActionContext> createContextMap() {
-    Map<Class<? extends ActionContext>, ActionContext> contextMap = new HashMap<>();
-    for (Map.Entry<Class<? extends ActionContext>, ActionContext> typeToStrategy :
-        strategies.entrySet()) {
-      ActionContext strategy = typeToStrategy.getValue();
-      contextMap.put(typeToStrategy.getKey(), strategy);
-      contextMap.put(strategy.getClass(), strategy);
-    }
-    contextMap.put(SpawnStrategy.class, new ProxySpawnActionContext(this));
-    contextMap.put(DynamicStrategyRegistry.class, this);
-    contextMap.put(RemoteLocalFallbackRegistry.class, this);
-    return ImmutableMap.copyOf(contextMap);
-  }
-
-  @Nullable
-  @Override
-  public <T extends ActionContext> T getContext(Class<T> identifyingType) {
-    return identifyingType.cast(contextMap.get(identifyingType));
-  }
-
-  /** Returns a list of all referenced {@link ActionContext} instances. */
-  @VisibleForTesting
-  public ImmutableList<ActionContext> allContexts() {
-    // We need to keep only the last occurrences of the entries in contextImplementations
-    // (so we respect insertion order but also instantiate them only once).
-    LinkedHashSet<ActionContext> allContexts = new LinkedHashSet<>(strategies.values());
-    mnemonicToSpawnStrategiesMap.values().forEach(allContexts::addAll);
-    spawnStrategyRegexList.forEach(x -> allContexts.addAll(x.strategies()));
-    return ImmutableList.copyOf(allContexts);
-  }
-
-  /**
-   * Notifies all (non-dynamic) contexts stored in this context map that they are {@link
-   * ActionContext#usedContext used}.
-   */
-  public void notifyUsed() {
-    for (ActionContext context : allContexts()) {
-      context.usedContext(this);
-    }
-  }
-
-  @Override
-  public void notifyUsedDynamic(ActionContext.ActionContextRegistry actionContextRegistry) {
-    for (SandboxedSpawnStrategy context : mnemonicToRemoteDynamicStrategies.values()) {
-      context.usedContext(actionContextRegistry);
-    }
-
-    for (SandboxedSpawnStrategy context : mnemonicToLocalDynamicStrategies.values()) {
-      context.usedContext(actionContextRegistry);
-    }
-  }
-
-  /**
-   * Print a sorted list of our (Spawn)ActionContext maps.
-   *
-   * <p>Prints out debug information about the mappings.
-   */
-  void debugPrintSpawnActionContextMaps(Reporter reporter) {
-    for (Entry<String, List<SpawnStrategy>> entry : mnemonicToSpawnStrategiesMap.entrySet()) {
-      List<String> strategyNames =
-          entry.getValue().stream()
-              .map(spawnActionContext -> spawnActionContext.getClass().getSimpleName())
-              .collect(Collectors.toList());
-      reporter.handle(
-          Event.info(
-              String.format(
-                  "SpawnActionContextMap: \"%s\" = [%s]",
-                  entry.getKey(), Joiner.on(", ").join(strategyNames))));
-    }
-
-    ImmutableMap<Class<? extends ActionContext>, ActionContext> contextMap = createContextMap();
-    TreeMap<String, String> sortedContextMapWithSimpleNames = new TreeMap<>();
-    for (Map.Entry<Class<? extends ActionContext>, ActionContext> entry : contextMap.entrySet()) {
-      sortedContextMapWithSimpleNames.put(
-          entry.getKey().getSimpleName(), entry.getValue().getClass().getSimpleName());
-    }
-    for (Map.Entry<String, String> entry : sortedContextMapWithSimpleNames.entrySet()) {
-      // Skip uninteresting identity mappings of contexts.
-      if (!entry.getKey().equals(entry.getValue())) {
-        reporter.handle(
-            Event.info(String.format("ContextMap: %s = %s", entry.getKey(), entry.getValue())));
-      }
-    }
-
-    for (RegexFilterSpawnStrategy entry : spawnStrategyRegexList) {
-      reporter.handle(
-          Event.info(
-              String.format(
-                  "SpawnActionContextMap: \"%s\" = %s",
-                  entry.regexFilter().toString(), entry.strategies().getClass().getSimpleName())));
-    }
-  }
-
-  @VisibleForTesting
-  public static SpawnActionContextMaps createStub(
-      Map<Class<? extends ActionContext>, ActionContext> strategies,
-      Map<String, List<SpawnStrategy>> spawnStrategyMnemonicMap) {
-    return new SpawnActionContextMaps(
-        ImmutableSortedMap.copyOf(spawnStrategyMnemonicMap, String.CASE_INSENSITIVE_ORDER),
-        ImmutableClassToInstanceMap.copyOf(strategies),
-        ImmutableList.of(),
-        ImmutableMultimap.of(),
-        ImmutableMultimap.of(),
-        /* remoteLocalFallbackStrategy=*/ null);
-  }
-
-  /** A stored entry for a {@link RegexFilter} to {@code strategy} mapping. */
-  @AutoValue
-  public abstract static class RegexFilterStrategy {
-    public abstract RegexFilter regexFilter();
-
-    public abstract ImmutableList<String> strategy();
-  }
-
-  /** Builder for {@code SpawnActionContextMaps}. */
-  public static final class Builder {
-    private final LinkedHashMultimap<String, String> strategyByMnemonicMap =
-        LinkedHashMultimap.create();
-    private ImmutableListMultimap.Builder<Class<? extends ActionContext>, String>
-        strategyByContextMapBuilder = ImmutableListMultimap.builder();
-    private final ImmutableList.Builder<RegexFilterStrategy> strategyByRegexpBuilder =
-        ImmutableList.builder();
-    private final LinkedHashMultimap<String, String> remoteDynamicStrategyByMnemonicMap =
-        LinkedHashMultimap.create();
-    private final LinkedHashMultimap<String, String> localDynamicStrategyByMnemonicMap =
-        LinkedHashMultimap.create();
-    private final List<ActionContextInformation<?>> actionContexts = new ArrayList<>();
-    @Nullable private String remoteLocalFallbackStrategyName;
-
-    /**
-     * Returns a builder modules can use to add mappings from mnemonics to strategy names.
-     *
-     * <p>If a spawn action is executed whose mnemonic maps to the empty string or is not present in
-     * the map at all, the choice of the implementation is left to Blaze.
-     *
-     * <p>Matching on mnemonics is done case-insensitively so it is recommended that any module
-     * makes sure that no two strategies refer to the same mnemonic. If they do, Blaze will pick the
-     * last one added.
-     */
-    public LinkedHashMultimap<String, String> strategyByMnemonicMap() {
-      return strategyByMnemonicMap;
-    }
-
-    /**
-     * Returns a builder modules can use to add mappings from mnemonics to strategy names for use in
-     * the remote branch of dynamic execution.
-     *
-     * <p>If a spawn action is executed whose mnemonic maps to the empty string or is not present in
-     * the map at all, the choice of the implementation is left to Blaze.
-     *
-     * <p>Matching on mnemonics is done case-insensitively so it is recommended that any module
-     * makes sure that no two strategies refer to the same mnemonic. If they do, Blaze will pick the
-     * last one added.
-     */
-    public LinkedHashMultimap<String, String> remoteDynamicStrategyByMnemonicMap() {
-      return remoteDynamicStrategyByMnemonicMap;
-    }
-
-    /**
-     * Returns a builder modules can use to add mappings from mnemonics to strategy names for use in
-     * the local branch of dynamic execution.
-     *
-     * <p>If a spawn action is executed whose mnemonic maps to the empty string or is not present in
-     * the map at all, the choice of the implementation is left to Blaze.
-     *
-     * <p>Matching on mnemonics is done case-insensitively so it is recommended that any module
-     * makes sure that no two strategies refer to the same mnemonic. If they do, Blaze will pick the
-     * last one added.
-     */
-    public LinkedHashMultimap<String, String> localDynamicStrategyByMnemonicMap() {
-      return localDynamicStrategyByMnemonicMap;
-    }
-
-    /**
-     * Sets the command-line identifier of the strategy to be used when falling back from remote to
-     * local execution.
-     *
-     * <p>Note that this is an optional setting, if not provided {@link
-     * SpawnActionContextMaps#getRemoteLocalFallbackStrategy()} will return {@code null}. If the
-     * value <b>is</b> provided it must match the commandline identifier of a registered strategy
-     * (at {@linkplain #build build} time).
-     */
-    public void setRemoteFallbackStrategy(String remoteLocalFallbackStrategy) {
-      this.remoteLocalFallbackStrategyName = remoteLocalFallbackStrategy;
-    }
-
-    /**
-     * Returns a builder modules can use to associate {@link ActionContext} classes with strategy
-     * names.
-     */
-    public ImmutableMultimap.Builder<Class<? extends ActionContext>, String>
-        strategyByContextMap() {
-      return strategyByContextMapBuilder;
-    }
-
-    /** Adds a mapping from the given {@link RegexFilter} to a {@code strategy}. */
-    public void addStrategyByRegexp(RegexFilter regexFilter, List<String> strategy) {
-      strategyByRegexpBuilder.add(
-          new AutoValue_SpawnActionContextMaps_RegexFilterStrategy(
-              regexFilter, ImmutableList.copyOf(strategy)));
-    }
-
-    /**
-     * Adds a context implementation to this map with the given identifying type and command-line
-     * identifiers.
-     *
-     * <p>If two contexts are added for the same identifying type and they are not distinguished by
-     * a restriction to a different command-line identifier then the last registered implementation
-     * is used.
-     */
-    public <T extends ActionContext> Builder addContext(
-        Class<T> identifyingType, T context, String... commandLineIdentifiers) {
-      actionContexts.add(
-          new AutoValue_SpawnActionContextMaps_ActionContextInformation<>(
-              context, identifyingType, ImmutableList.copyOf(commandLineIdentifiers)));
-      return this;
-    }
-
-    /** Builds a {@link SpawnActionContextMaps} instance. */
-    public SpawnActionContextMaps build() throws AbruptExitException {
-      StrategyConverter strategyConverter = new StrategyConverter(actionContexts);
-
-      ImmutableSortedMap.Builder<String, List<SpawnStrategy>> spawnStrategyMap =
-          ImmutableSortedMap.orderedBy(String.CASE_INSENSITIVE_ORDER);
-      HashMap<Class<? extends ActionContext>, ActionContext> strategies = new HashMap<>();
-      ImmutableList.Builder<RegexFilterSpawnStrategy> spawnStrategyRegexList =
-          ImmutableList.builder();
-
-      for (String mnemonic : strategyByMnemonicMap.keySet()) {
-        ImmutableList.Builder<SpawnStrategy> spawnStrategies = ImmutableList.builder();
-        Set<String> strategiesForMnemonic = strategyByMnemonicMap.get(mnemonic);
-        for (String strategy : strategiesForMnemonic) {
-          SpawnStrategy spawnStrategy =
-              strategyConverter.getStrategy(SpawnStrategy.class, strategy);
-          if (spawnStrategy == null) {
-            String strategyOrNull = Strings.emptyToNull(strategy);
-            throw makeExceptionForInvalidStrategyValue(
-                strategy,
-                Joiner.on(' ').skipNulls().join(strategyOrNull, "spawn"),
-                strategyConverter.getValidValues(SpawnStrategy.class));
-          }
-          spawnStrategies.add(spawnStrategy);
-        }
-        spawnStrategyMap.put(mnemonic, spawnStrategies.build());
-      }
-
-      Set<ActionContext> seenContext = new HashSet<>();
-      for (Map.Entry<Class<? extends ActionContext>, String> entry :
-          strategyByContextMapBuilder.orderValuesBy(Collections.reverseOrder()).build().entries()) {
-        ActionContext context = strategyConverter.getStrategy(entry.getKey(), entry.getValue());
-        if (context == null) {
-          throw makeExceptionForInvalidStrategyValue(
-              entry.getValue(),
-              strategyConverter.getUserFriendlyName(entry.getKey()),
-              strategyConverter.getValidValues(entry.getKey()));
-        }
-        if (seenContext.contains(context)) {
-          continue;
-        }
-        seenContext.add(context);
-        strategies.put(entry.getKey(), context);
-      }
-
-      for (RegexFilterStrategy entry : strategyByRegexpBuilder.build()) {
-        ImmutableList.Builder<SpawnStrategy> spawnStrategies = ImmutableList.builder();
-        List<String> strategiesForRegex = entry.strategy();
-        for (String strategy : strategiesForRegex) {
-          SpawnStrategy spawnStrategy =
-              strategyConverter.getStrategy(SpawnStrategy.class, strategy);
-          if (spawnStrategy == null) {
-            strategy = Strings.emptyToNull(strategy);
-            throw makeExceptionForInvalidStrategyValue(
-                entry.regexFilter().toString(),
-                Joiner.on(' ').skipNulls().join(strategy, "spawn"),
-                strategyConverter.getValidValues(SpawnStrategy.class));
-          }
-          spawnStrategies.add(spawnStrategy);
-        }
-        spawnStrategyRegexList.add(
-            new AutoValue_SpawnActionContextMaps_RegexFilterSpawnStrategy(
-                entry.regexFilter(), spawnStrategies.build()));
-      }
-
-      AbstractSpawnStrategy remoteLocalFallbackStrategy = null;
-      if (remoteLocalFallbackStrategyName != null) {
-        SpawnStrategy strategy =
-            strategyConverter.getStrategy(SpawnStrategy.class, remoteLocalFallbackStrategyName);
-        if (!(strategy instanceof AbstractSpawnStrategy)) {
-          throw makeExceptionForInvalidStrategyValue(
-              remoteLocalFallbackStrategyName,
-              "remote local fallback",
-              strategyConverter.getValidValues(SpawnStrategy.class, "remote"));
-        }
-        remoteLocalFallbackStrategy = (AbstractSpawnStrategy) strategy;
-      }
-
-      return new SpawnActionContextMaps(
-          spawnStrategyMap.build(),
-          ImmutableClassToInstanceMap.copyOf(strategies),
-          spawnStrategyRegexList.build(),
-          toActionContexts(strategyConverter, remoteDynamicStrategyByMnemonicMap),
-          toActionContexts(strategyConverter, localDynamicStrategyByMnemonicMap),
-          remoteLocalFallbackStrategy);
-    }
-
-    private ImmutableMultimap<String, SandboxedSpawnStrategy> toActionContexts(
-        StrategyConverter strategyConverter,
-        LinkedHashMultimap<String, String> dynamicStrategyByMnemonicMap)
-        throws AbruptExitException {
-      ImmutableMultimap.Builder<String, SandboxedSpawnStrategy> mnemonicToStrategies =
-          ImmutableMultimap.builder();
-      for (Entry<String, Collection<String>> mnemonicToIdentifiers :
-          dynamicStrategyByMnemonicMap.asMap().entrySet()) {
-        for (String identifier : mnemonicToIdentifiers.getValue()) {
-          if (identifier.isEmpty()) {
-            continue;
-          }
-          SpawnStrategy strategy = strategyConverter.getStrategy(SpawnStrategy.class, identifier);
-          if (strategy == null) {
-            throw makeExceptionForInvalidStrategyValue(
-                identifier,
-                Joiner.on(' ').skipNulls().join(Strings.emptyToNull(identifier), "spawn"),
-                strategyConverter.getValidValues(SpawnStrategy.class));
-          }
-          if (!(strategy instanceof SandboxedSpawnStrategy)) {
-            throw createExitException(
-                "Requested strategy " + identifier + " exists but does not support sandboxing",
-                Code.REQUESTED_STRATEGY_INCOMPATIBLE_WITH_SANDBOXING);
-          }
-          mnemonicToStrategies.put(
-              mnemonicToIdentifiers.getKey(), (SandboxedSpawnStrategy) strategy);
-        }
-      }
-      return mnemonicToStrategies.build();
-    }
-  }
-
-  private static AbruptExitException makeExceptionForInvalidStrategyValue(
-      String value, String strategy, String validValues) {
-    return createExitException(
-        String.format(
-            "'%s' is an invalid value for %s strategy. Valid values are: %s",
-            value, strategy, validValues),
-        Code.INVALID_STRATEGY);
-  }
-
-  private static AbruptExitException createExitException(String message, Code detailedCode) {
-    return new AbruptExitException(
-        DetailedExitCode.of(
-            FailureDetail.newBuilder()
-                .setMessage(message)
-                .setExecutionOptions(
-                    FailureDetails.ExecutionOptions.newBuilder().setCode(detailedCode))
-                .build()));
-  }
-
-  private static class StrategyConverter {
-    private Table<Class<? extends ActionContext>, String, ActionContext> classMap =
-        HashBasedTable.create();
-    private Map<Class<? extends ActionContext>, ActionContext> defaultClassMap = new HashMap<>();
-
-    /** Aggregates all {@link ActionContext}s that are in {@code contextProviders}. */
-    private StrategyConverter(List<ActionContextInformation<?>> actionContexts) {
-      for (ActionContextInformation<?> contextInformation : actionContexts) {
-        defaultClassMap.put(contextInformation.identifyingType(), contextInformation.context());
-
-        for (String name : contextInformation.commandLineIdentifiers()) {
-          classMap.put(contextInformation.identifyingType(), name, contextInformation.context());
-        }
-      }
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T extends ActionContext> T getStrategy(Class<T> clazz, String name) {
-      return (T) (name.isEmpty() ? defaultClassMap.get(clazz) : classMap.get(clazz, name));
-    }
-
-    private String getValidValues(Class<? extends ActionContext> context, String... excludes) {
-      ImmutableSet<String> excludedNames = ImmutableSet.copyOf(excludes);
-      return classMap.row(context).keySet().stream()
-          .filter(s -> !excludedNames.contains(s))
-          .sorted()
-          .collect(Collectors.joining(", "));
-    }
-
-    private String getUserFriendlyName(Class<? extends ActionContext> context) {
-      ActionContextMarker marker = context.getAnnotation(ActionContextMarker.class);
-      return marker != null ? marker.name() : context.getSimpleName();
-    }
-  }
-
-  @AutoValue
-  abstract static class ActionContextInformation<T extends ActionContext> {
-    abstract T context();
-
-    abstract Class<T> identifyingType();
-
-    abstract ImmutableList<String> commandLineIdentifiers();
-  }
-}
diff --git a/src/test/java/com/google/devtools/build/lib/dynamic/BUILD b/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
index 6fcae49..3338aa1 100644
--- a/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
@@ -22,9 +22,7 @@
         "//src/main/java/com/google/devtools/build/lib/dynamic",
         "//src/main/java/com/google/devtools/build/lib/exec:blaze_executor",
         "//src/main/java/com/google/devtools/build/lib/exec:execution_options",
-        "//src/main/java/com/google/devtools/build/lib/exec:executor_builder",
         "//src/main/java/com/google/devtools/build/lib/exec:module_action_context_registry",
-        "//src/main/java/com/google/devtools/build/lib/exec:spawn_action_context_maps",
         "//src/main/java/com/google/devtools/build/lib/exec:spawn_strategy_registry",
         "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
         "//src/main/java/com/google/devtools/build/lib/util/io",
diff --git a/src/test/java/com/google/devtools/build/lib/exec/BUILD b/src/test/java/com/google/devtools/build/lib/exec/BUILD
index 89cef69..7817e8d 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/exec/BUILD
@@ -38,7 +38,6 @@
         "//src/main/java/com/google/devtools/build/lib/exec:execution_options",
         "//src/main/java/com/google/devtools/build/lib/exec:module_action_context_registry",
         "//src/main/java/com/google/devtools/build/lib/exec:single_build_file_cache",
-        "//src/main/java/com/google/devtools/build/lib/exec:spawn_action_context_maps",
         "//src/main/java/com/google/devtools/build/lib/exec:spawn_cache",
         "//src/main/java/com/google/devtools/build/lib/exec:spawn_exec_exception",
         "//src/main/java/com/google/devtools/build/lib/exec:spawn_input_expander",
diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
deleted file mode 100644
index 67856b1..0000000
--- a/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2018 The Bazel Authors. 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 com.google.devtools.build.lib.exec;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
-import com.google.devtools.build.lib.actions.ActionContext;
-import com.google.devtools.build.lib.actions.ActionExecutionContext;
-import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
-import com.google.devtools.build.lib.actions.ExecException;
-import com.google.devtools.build.lib.actions.Spawn;
-import com.google.devtools.build.lib.actions.SpawnResult;
-import com.google.devtools.build.lib.actions.SpawnStrategy;
-import com.google.devtools.build.lib.events.Reporter;
-import com.google.devtools.build.lib.testutil.Suite;
-import com.google.devtools.build.lib.testutil.TestSpec;
-import com.google.devtools.build.lib.util.RegexFilter.RegexFilterConverter;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mockito;
-
-/** Tests of {@link SpawnActionContextMaps}. */
-@RunWith(JUnit4.class)
-@TestSpec(size = Suite.SMALL_TESTS)
-public class SpawnActionContextMapsTest {
-
-  private SpawnActionContextMaps.Builder builder;
-  private final RegexFilterConverter converter = new RegexFilterConverter();
-  private final EventBus bus = new EventBus();
-  private final Reporter reporter = new Reporter(bus);
-
-  private static final AC1 ac1 = new AC1();
-  private static final AC2 ac2 = new AC2();
-
-  @Before
-  public void setUp() {
-    builder =
-        new SpawnActionContextMaps.Builder()
-            .addContext(SpawnStrategy.class, ac1, "ac1")
-            .addContext(SpawnStrategy.class, ac2, "ac2");
-  }
-
-  @Test
-  public void duplicateMnemonics_bothGetStored() throws Exception {
-    builder.strategyByMnemonicMap().put("Spawn1", "ac1");
-    builder.strategyByMnemonicMap().put("Spawn1", "ac2");
-    SpawnActionContextMaps maps = builder.build();
-    List<SpawnStrategy> result = maps.getSpawnActionContexts(mockSpawn("Spawn1", null), reporter);
-    assertThat(result).containsExactly(ac1, ac2);
-  }
-
-  @Test
-  public void emptyStrategyFallsBackToEmptyMnemonicNotToDefault() throws Exception {
-    builder.strategyByMnemonicMap().put("Spawn1", "");
-    builder.strategyByMnemonicMap().put("", "ac2");
-    SpawnActionContextMaps maps = builder.build();
-    List<SpawnStrategy> result = maps.getSpawnActionContexts(mockSpawn("Spawn1", null), reporter);
-    assertThat(result).containsExactly(ac2);
-  }
-
-  @Test
-  public void multipleRegexps_firstMatchWins() throws Exception {
-    builder.addStrategyByRegexp(converter.convert("foo"), ImmutableList.of("ac1"));
-    builder.addStrategyByRegexp(converter.convert("foo/bar"), ImmutableList.of("ac2"));
-    SpawnActionContextMaps maps = builder.build();
-
-    List<SpawnStrategy> result =
-        maps.getSpawnActionContexts(mockSpawn(null, "Doing something with foo/bar/baz"), reporter);
-
-    assertThat(result).containsExactly(ac1);
-  }
-
-  @Test
-  public void regexpAndMnemonic_regexpWins() throws Exception {
-    builder.strategyByMnemonicMap().put("Spawn1", "ac1");
-    builder.addStrategyByRegexp(converter.convert("foo/bar"), ImmutableList.of("ac2"));
-    SpawnActionContextMaps maps = builder.build();
-
-    List<SpawnStrategy> result =
-        maps.getSpawnActionContexts(
-            mockSpawn("Spawn1", "Doing something with foo/bar/baz"), reporter);
-
-    assertThat(result).containsExactly(ac2);
-  }
-
-  @Test
-  public void duplicateContext_noException() throws Exception {
-    builder.strategyByContextMap().put(AC1.class, "one");
-    builder.strategyByContextMap().put(AC1.class, "two");
-    builder.strategyByContextMap().put(AC1.class, "");
-  }
-
-  private Spawn mockSpawn(String mnemonic, String message) {
-    Spawn mockSpawn = Mockito.mock(Spawn.class);
-    ActionExecutionMetadata mockOwner = Mockito.mock(ActionExecutionMetadata.class);
-    when(mockOwner.getProgressMessage()).thenReturn(message);
-    when(mockSpawn.getResourceOwner()).thenReturn(mockOwner);
-    when(mockSpawn.getMnemonic()).thenReturn(mnemonic);
-    return mockSpawn;
-  }
-
-  private static class AC1 implements SpawnStrategy {
-    @Override
-    public ImmutableList<SpawnResult> exec(
-        Spawn spawn, ActionExecutionContext actionExecutionContext)
-        throws ExecException, InterruptedException {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean canExec(Spawn spawn, ActionContext.ActionContextRegistry actionContextRegistry) {
-      return true;
-    }
-  }
-
-  private static class AC2 implements SpawnStrategy {
-    @Override
-    public ImmutableList<SpawnResult> exec(
-        Spawn spawn, ActionExecutionContext actionExecutionContext)
-        throws ExecException, InterruptedException {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean canExec(Spawn spawn, ActionContext.ActionContextRegistry actionContextRegistry) {
-      return true;
-    }
-  }
-}
