diff --git a/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalStateTracker.java b/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalStateTracker.java
index 2b2670c..60f63dd 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalStateTracker.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalStateTracker.java
@@ -13,12 +13,16 @@
 // limitations under the License.
 package com.google.devtools.build.lib.runtime;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import com.google.devtools.build.lib.actions.Action;
 import com.google.devtools.build.lib.actions.ActionCompletionEvent;
+import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
 import com.google.devtools.build.lib.actions.ActionStartedEvent;
 import com.google.devtools.build.lib.actions.AnalyzingActionEvent;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -26,7 +30,6 @@
 import com.google.devtools.build.lib.actions.SchedulingActionEvent;
 import com.google.devtools.build.lib.analysis.AnalysisPhaseCompleteEvent;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.bugreport.BugReport;
 import com.google.devtools.build.lib.buildeventstream.AnnounceBuildEventTransportsEvent;
 import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
 import com.google.devtools.build.lib.buildeventstream.BuildEventTransportClosedEvent;
@@ -49,7 +52,6 @@
 import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus;
 import java.io.IOException;
 import java.util.ArrayDeque;
-import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Deque;
 import java.util.HashSet;
@@ -59,6 +61,7 @@
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
+import javax.annotation.concurrent.ThreadSafe;
 
 /**
  * An experimental state tracker for the new experimental UI.
@@ -86,22 +89,195 @@
   // Non-positive values indicate not to aim for a particular width.
   private final int targetWidth;
 
-  private static class ActionState {
-    public final Action action;
-    public final long nanoStartTime;
-    public final boolean executing;
-    public final String status;
+  /**
+   * Tracker of strategy names to unique IDs and viceversa.
+   *
+   * <p>The IDs generated by this class can be used to index bitmaps.
+   *
+   * <p>TODO(jmmv): Would be nice if the strategies themselves contained their IDs (initialized at
+   * construction time) and we passed around those IDs instead of strings.
+   */
+  @ThreadSafe
+  @VisibleForTesting
+  static class StrategyIds {
+    /** Fallback name in case we exhaust our space for IDs. */
+    public static final String FALLBACK_NAME = "unknown";
 
-    private ActionState(Action action, long nanoStartTime, boolean executing, String status) {
+    /** Counter of unique strategies seen so far. */
+    private AtomicInteger counter = new AtomicInteger(0);
+
+    /** Mapping of strategy names to their unique IDs. */
+    private Map<String, Integer> strategyIds = new ConcurrentHashMap<>();
+
+    /** Mapping of strategy unique IDs to their names. */
+    private Map<Integer, String> strategyNames = new ConcurrentHashMap<>();
+
+    public final Integer fallbackId;
+
+    /** Constructs a new collection of strategy IDs. */
+    public StrategyIds() {
+      fallbackId = getId(FALLBACK_NAME);
+    }
+
+    /** Computes the ID of a strategy given its name. */
+    public Integer getId(String strategy) {
+      Integer id =
+          strategyIds.computeIfAbsent(
+              strategy,
+              (key) -> {
+                int value = counter.getAndIncrement();
+                if (value >= Integer.SIZE) {
+                  return fallbackId;
+                } else {
+                  return 1 << value;
+                }
+              });
+      strategyNames.putIfAbsent(id, strategy);
+      return id;
+    }
+
+    /** Flattens a bitmap of strategy IDs into a human-friendly string. */
+    public String formatNames(int bitmap) {
+      StringBuilder builder = new StringBuilder();
+      int mask = 0x1;
+      while (bitmap != 0) {
+        int id = bitmap & mask;
+        if (id != 0) {
+          String name = checkNotNull(strategyNames.get(id), "Unknown strategy with id " + id);
+          builder.append(name);
+          bitmap &= ~mask;
+          if (bitmap != 0) {
+            builder.append(", ");
+          }
+        }
+        mask <<= 1;
+      }
+      return builder.toString();
+    }
+  }
+
+  private static final StrategyIds strategyIds = new StrategyIds();
+
+  /**
+   * Tracks all details for an action that we have heard about.
+   *
+   * <p>We cannot make assumptions on the order in which action state events come in, so this class
+   * takes care of always "advancing" the state of an action.
+   */
+  private static class ActionState {
+    /**
+     * The action this state belongs to.
+     *
+     * <p>We assume that all events related to the same action refer to the same {@link
+     * ActionExecutionMetadata} object.
+     */
+    final ActionExecutionMetadata action;
+
+    /** Timestamp of the last state change. */
+    long nanoStartTime;
+
+    /**
+     * Whether this action is in the analyzing state or not.
+     *
+     * <p>If true, implies that {@link #schedulingStrategiesBitmap} and {@link
+     * #runningStrategiesBitmap} are both zero. The opposite is not necessarily true: if false, the
+     * bitmaps can be zero as well to represent that the action is still in the preparation stage.
+     */
+    boolean analyzing;
+
+    /**
+     * Bitmap of strategies that are scheduling this action.
+     *
+     * <p>If non-zero, implies that {@link #analyzing} is false.
+     */
+    int schedulingStrategiesBitmap = 0;
+
+    /**
+     * Bitmap of strategies that are running this action.
+     *
+     * <p>If non-zero, implies that {@link #analyzing} is false.
+     */
+    int runningStrategiesBitmap = 0;
+
+    /** Starts tracking the state of an action. */
+    ActionState(ActionExecutionMetadata action, long nanoStartTime) {
       this.action = action;
       this.nanoStartTime = nanoStartTime;
-      this.executing = executing;
-      this.status = status;
+    }
+
+    /** Creates a deep copy of this action state. */
+    synchronized ActionState deepCopy() {
+      ActionState other = new ActionState(action, nanoStartTime);
+      other.analyzing = analyzing;
+      other.schedulingStrategiesBitmap = schedulingStrategiesBitmap;
+      other.runningStrategiesBitmap = runningStrategiesBitmap;
+      return other;
+    }
+
+    /** Computes the weight of this action for the global active actions counter. */
+    synchronized int countActions() {
+      int activeStrategies =
+          Integer.bitCount(schedulingStrategiesBitmap) + Integer.bitCount(runningStrategiesBitmap);
+      return activeStrategies > 0 ? activeStrategies : 1;
+    }
+
+    /**
+     * Marks the action as analyzing.
+     *
+     * <p>Because we may receive events out of order, this does nothing if the action is already
+     * scheduled or running.
+     */
+    void setAnalyzing(long nanoChangeTime) {
+      if (schedulingStrategiesBitmap == 0 && runningStrategiesBitmap == 0) {
+        analyzing = true;
+        nanoStartTime = nanoChangeTime;
+      }
+    }
+
+    /**
+     * Marks the action as scheduling with the given strategy.
+     *
+     * <p>Because we may receive events out of order, this does nothing if the action is already
+     * running with this strategy.
+     */
+    void setScheduling(String strategy, long nanoChangeTime) {
+      int id = strategyIds.getId(strategy);
+      if ((runningStrategiesBitmap & id) == 0) {
+        analyzing = false;
+        schedulingStrategiesBitmap |= id;
+        nanoStartTime = nanoChangeTime;
+      }
+    }
+
+    /**
+     * Marks the action as running with the given strategy.
+     *
+     * <p>Because "running" is a terminal state, this forcibly updates the state to running
+     * regardless of any other events (which may come out of order).
+     */
+    void setRunning(String strategy, long nanoChangeTime) {
+      analyzing = false;
+      int id = strategyIds.getId(strategy);
+      schedulingStrategiesBitmap &= ~id;
+      runningStrategiesBitmap |= id;
+      nanoStartTime = nanoChangeTime;
+    }
+
+    /** Generates a human-readable description of this action's state. */
+    synchronized String describe() {
+      if (runningStrategiesBitmap != 0) {
+        return "Running";
+      } else if (schedulingStrategiesBitmap != 0) {
+        return "Scheduling";
+      } else if (analyzing) {
+        return "Analyzing";
+      } else {
+        return "Preparing";
+      }
     }
   }
 
   private final Map<Artifact, ActionState> activeActions;
-  private final Map<Artifact, String> notStartedActionStatus;
 
   // running downloads are identified by the original URL they were trying to access.
   private final Deque<String> runningDownloads;
@@ -136,7 +312,6 @@
 
   ExperimentalStateTracker(Clock clock, int targetWidth) {
     this.activeActions = new ConcurrentHashMap<>();
-    this.notStartedActionStatus = new ConcurrentHashMap<>();
 
     this.actionsCompleted = new AtomicInteger();
     this.testActions = new ConcurrentHashMap<>();
@@ -262,16 +437,21 @@
     }
   }
 
+  private ActionState getActionState(
+      ActionExecutionMetadata action, Artifact actionId, long nanoTimeNow) {
+    ActionState state =
+        activeActions.computeIfAbsent(actionId, (key) -> new ActionState(action, nanoTimeNow));
+    checkState(
+        state.action == action,
+        "Inconsistent ActionExecutionMetadata objects across events for the same action");
+    return state;
+  }
+
   void actionStarted(ActionStartedEvent event) {
     Action action = event.getAction();
     Artifact actionId = action.getPrimaryOutput();
-    long nanoStartTime = event.getNanoTimeStart();
 
-    String status = notStartedActionStatus.remove(actionId);
-    boolean nowExecuting = status != null;
-    activeActions.put(
-        actionId,
-        new ActionState(action, nanoStartTime, nowExecuting, nowExecuting ? status : null));
+    getActionState(action, actionId, event.getNanoTimeStart());
 
     if (action.getOwner() != null) {
       Label owner = action.getOwner().getLabel();
@@ -285,53 +465,33 @@
   }
 
   void analyzingAction(AnalyzingActionEvent event) {
+    ActionExecutionMetadata action = event.getActionMetadata();
     Artifact actionId = event.getActionMetadata().getPrimaryOutput();
-    ActionState state = activeActions.remove(actionId);
-    if (state != null) {
-      activeActions.put(
-          actionId,
-          new ActionState(state.action, clock.nanoTime(), /*executing=*/ false, "Analyzing"));
-    }
-    notStartedActionStatus.remove(actionId);
+    long now = clock.nanoTime();
+    getActionState(action, actionId, now).setAnalyzing(now);
   }
 
   void schedulingAction(SchedulingActionEvent event) {
+    ActionExecutionMetadata action = event.getActionMetadata();
     Artifact actionId = event.getActionMetadata().getPrimaryOutput();
-    ActionState state = activeActions.remove(actionId);
-    if (state != null) {
-      activeActions.put(
-          actionId,
-          new ActionState(state.action, clock.nanoTime(), /*executing=*/ false, "Scheduling"));
-    }
-    notStartedActionStatus.remove(actionId);
+    long now = clock.nanoTime();
+    getActionState(action, actionId, now).setScheduling(event.getStrategy(), now);
   }
 
   void runningAction(RunningActionEvent event) {
+    ActionExecutionMetadata action = event.getActionMetadata();
     Artifact actionId = event.getActionMetadata().getPrimaryOutput();
-    String strategy = event.getStrategy();
-
-    ActionState state = activeActions.remove(actionId);
-    if (state != null) {
-      activeActions.put(
-          actionId, new ActionState(state.action, clock.nanoTime(), /*executing=*/ true, strategy));
-    } else {
-      notStartedActionStatus.put(actionId, strategy);
-    }
+    long now = clock.nanoTime();
+    getActionState(action, actionId, now).setRunning(event.getStrategy(), now);
   }
 
   void actionCompletion(ActionCompletionEvent event) {
     actionsCompleted.incrementAndGet();
     Action action = event.getAction();
     Artifact actionId = action.getPrimaryOutput();
+
+    checkState(activeActions.containsKey(actionId));
     activeActions.remove(actionId);
-    boolean removed = notStartedActionStatus.containsKey(actionId);
-    if (removed && !action.discoversInputs()) {
-      BugReport.sendBugReport(
-          new IllegalStateException(
-              "Should not complete an action before starting it, and action did not discover "
-                  + "inputs, so should not have published a status before execution: "
-                  + action));
-    }
 
     if (action.getOwner() != null) {
       Label owner = action.getOwner().getLabel();
@@ -431,7 +591,9 @@
       long nanoRuntime = nanoTime - actionState.nanoStartTime;
       long runtimeSeconds = nanoRuntime / NANOS_PER_SECOND;
       String text =
-          actionState.executing ? sep + runtimeSeconds + "s" : sep + "[" + runtimeSeconds + "s]";
+          actionState.runningStrategiesBitmap == 0
+              ? sep + "[" + runtimeSeconds + "s]"
+              : sep + runtimeSeconds + "s";
       if (remainingWidth < text.length()) {
         allReported = false;
         break;
@@ -448,7 +610,7 @@
   // actions.
   private String describeAction(
       ActionState actionState, long nanoTime, int desiredWidth, Set<Artifact> toSkip) {
-    Action action = actionState.action;
+    ActionExecutionMetadata action = actionState.action;
     if (action.getOwner() != null) {
       Label owner = action.getOwner().getLabel();
       if (owner != null) {
@@ -467,10 +629,10 @@
     long nanoRuntime = nanoTime - actionState.nanoStartTime;
     long runtimeSeconds = nanoRuntime / NANOS_PER_SECOND;
     String strategy = null;
-    if (actionState.executing) {
-      strategy = actionState.status;
+    if (actionState.runningStrategiesBitmap != 0) {
+      strategy = strategyIds.formatNames(actionState.runningStrategiesBitmap);
     } else {
-      String status = actionState.status;
+      String status = actionState.describe();
       if (status == null) {
         status = NO_STATUS;
       }
@@ -562,10 +724,8 @@
     int actionsCount = 0;
     int executingActionsCount = 0;
     for (ActionState actionState : activeActions.values()) {
-      actionsCount++;
-      if (actionState.executing) {
-        executingActionsCount++;
-      }
+      actionsCount += actionState.countActions();
+      executingActionsCount += Integer.bitCount(actionState.runningStrategiesBitmap);
     }
 
     if (actionsCount == 1) {
@@ -583,14 +743,19 @@
     long nanoTime = clock.nanoTime();
     int actionCount = activeActions.size();
     Set<Artifact> toSkip = new TreeSet<>();
-    ArrayList<Map.Entry<Artifact, ActionState>> copy = new ArrayList<>(activeActions.entrySet());
-    copy.sort(
-        Comparator.comparing(
-                (Map.Entry<Artifact, ActionState> entry) -> !entry.getValue().executing)
-            .thenComparing(entry -> entry.getValue().nanoStartTime));
-    for (Map.Entry<Artifact, ActionState> entry : copy) {
+
+    Map<ActionState, Artifact> copy =
+        new TreeMap<>(
+            Comparator.comparing((ActionState entry) -> entry.runningStrategiesBitmap == 0)
+                .thenComparing(entry -> entry.nanoStartTime)
+                .thenComparing(ActionState::hashCode));
+    for (Map.Entry<Artifact, ActionState> action : activeActions.entrySet()) {
+      copy.put(action.getValue().deepCopy(), action.getKey());
+    }
+
+    for (Map.Entry<ActionState, Artifact> entry : copy.entrySet()) {
       totalCount++;
-      if (toSkip.contains(entry.getKey())) {
+      if (toSkip.contains(entry.getValue())) {
         continue;
       }
       count++;
@@ -602,7 +767,7 @@
           targetWidth - 4 - ((count >= sampleSize && count < actionCount) ? AND_MORE.length() : 0);
       terminalWriter
           .newline()
-          .append("    " + describeAction(entry.getValue(), nanoTime, width, toSkip));
+          .append("    " + describeAction(entry.getKey(), nanoTime, width, toSkip));
     }
     if (totalCount < actionCount) {
       terminalWriter.append(AND_MORE);
diff --git a/src/main/java/com/google/devtools/build/lib/util/io/LoggingTerminalWriter.java b/src/main/java/com/google/devtools/build/lib/util/io/LoggingTerminalWriter.java
index 290ba37..1264a02 100644
--- a/src/main/java/com/google/devtools/build/lib/util/io/LoggingTerminalWriter.java
+++ b/src/main/java/com/google/devtools/build/lib/util/io/LoggingTerminalWriter.java
@@ -16,8 +16,7 @@
 import java.io.IOException;
 
 /**
- * An {@link AnsiTerminalWriter} that keeps just generates a transcript
- * of the events it was exposed of.
+ * An {@link AnsiTerminalWriter} that just generates a transcript of the events it was exposed of.
  */
 public class LoggingTerminalWriter implements AnsiTerminalWriter {
   // Strings for recording the non-append calls
@@ -38,6 +37,11 @@
     this(false);
   }
 
+  /** Clears the stored transcript; mostly useful for testing purposes. */
+  public void reset() {
+    transcript = "";
+  }
+
   @Override
   public AnsiTerminalWriter append(String text) throws IOException {
     transcript += text;
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
index 3366488..b768dd5 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
@@ -26,7 +26,6 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Action;
 import com.google.devtools.build.lib.actions.ActionCompletionEvent;
-import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
 import com.google.devtools.build.lib.actions.ActionLookupData;
 import com.google.devtools.build.lib.actions.ActionOwner;
 import com.google.devtools.build.lib.actions.ActionStartedEvent;
@@ -46,6 +45,7 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.ExtendedEventHandler.FetchProgress;
 import com.google.devtools.build.lib.packages.AspectDescriptor;
+import com.google.devtools.build.lib.runtime.ExperimentalStateTracker.StrategyIds;
 import com.google.devtools.build.lib.skyframe.LoadingPhaseStartedEvent;
 import com.google.devtools.build.lib.skyframe.PackageProgressReceiver;
 import com.google.devtools.build.lib.testutil.FoundationTestCase;
@@ -59,6 +59,8 @@
 import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus;
 import java.io.IOException;
 import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -71,6 +73,80 @@
 @RunWith(JUnit4.class)
 public class ExperimentalStateTrackerTest extends FoundationTestCase {
 
+  @Test
+  public void testStrategyIds_getId_idsAreBitmasks() {
+    StrategyIds strategyIds = new StrategyIds();
+    Integer id1 = strategyIds.getId("foo");
+    Integer id2 = strategyIds.getId("bar");
+    Integer id3 = strategyIds.getId("baz");
+
+    assertThat(id1).isGreaterThan(0);
+    assertThat(id2).isGreaterThan(0);
+    assertThat(id3).isGreaterThan(0);
+
+    assertThat(id1 & id2).isEqualTo(0);
+    assertThat(id1 & id3).isEqualTo(0);
+    assertThat(id2 & id3).isEqualTo(0);
+  }
+
+  @Test
+  public void testStrategyIds_getId_idsAreReusedIfAlreadyExist() {
+    StrategyIds strategyIds = new StrategyIds();
+    Integer id1 = strategyIds.getId("foo");
+    Integer id2 = strategyIds.getId("bar");
+    Integer id3 = strategyIds.getId("foo");
+
+    assertThat(id1).isNotEqualTo(id2);
+    assertThat(id1).isEqualTo(id3);
+  }
+
+  @Test
+  public void testStrategyIds_getId_exhaustIds() {
+    StrategyIds strategyIds = new StrategyIds();
+    Set<Integer> ids = new HashSet<>();
+    StringBuilder name = new StringBuilder();
+    for (; ; ) {
+      name.append('a');
+      Integer id = strategyIds.getId(name.toString());
+      if (id.equals(strategyIds.fallbackId)) {
+        break;
+      }
+      ids.add(id);
+    }
+    assertThat(ids).hasSize(Integer.SIZE - 1); // Minus 1 for FALLBACK_NAME.
+
+    assertThat(strategyIds.getId("some")).isEqualTo(strategyIds.fallbackId);
+    assertThat(strategyIds.getId("more")).isEqualTo(strategyIds.fallbackId);
+  }
+
+  @Test
+  public void testStrategyIds_formatNames_fallbackExistsByDefault() {
+    StrategyIds strategyIds = new StrategyIds();
+    assertThat(strategyIds.formatNames(strategyIds.fallbackId))
+        .isEqualTo(StrategyIds.FALLBACK_NAME);
+  }
+
+  @Test
+  public void testStrategyIds_formatNames_oneHasNoComma() {
+    StrategyIds strategyIds = new StrategyIds();
+    Integer id1 = strategyIds.getId("abc");
+    assertThat(strategyIds.formatNames(id1)).isEqualTo("abc");
+  }
+
+  @Test
+  public void testStrategyIds_formatNames() {
+    StrategyIds strategyIds = new StrategyIds();
+    Integer id1 = strategyIds.getId("abc");
+    Integer id2 = strategyIds.getId("xyz");
+    Integer id3 = strategyIds.getId("def");
+
+    // Names are not sorted alphabetically but their order is stable based on prior getId calls.
+    assertThat(strategyIds.formatNames(id1 | id2)).isEqualTo("abc, xyz");
+    assertThat(strategyIds.formatNames(id1 | id3)).isEqualTo("abc, def");
+    assertThat(strategyIds.formatNames(id2 | id3)).isEqualTo("xyz, def");
+    assertThat(strategyIds.formatNames(id1 | id2 | id3)).isEqualTo("abc, xyz, def");
+  }
+
   private Action mockAction(String progressMessage, String primaryOutput) {
     Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
     Artifact artifact = new Artifact(path, ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)));
@@ -480,14 +556,13 @@
     ManualClock clock = new ManualClock();
     Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
     Artifact artifact = new Artifact(path, ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)));
-    ActionExecutionMetadata actionMetadata = Mockito.mock(ActionExecutionMetadata.class);
-    when(actionMetadata.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
-    when(actionMetadata.getPrimaryOutput()).thenReturn(artifact);
+    Action action = mockAction("Some random action", primaryOutput);
+    when(action.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
+    when(action.getPrimaryOutput()).thenReturn(artifact);
 
     ExperimentalStateTracker stateTracker = new ExperimentalStateTracker(clock);
-    stateTracker.actionStarted(
-        new ActionStartedEvent(mockAction("Some random action", primaryOutput), clock.nanoTime()));
-    stateTracker.runningAction(new RunningActionEvent(actionMetadata, strategy));
+    stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
+    stateTracker.runningAction(new RunningActionEvent(action, strategy));
 
     LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
     stateTracker.writeProgressBar(terminalWriter);
@@ -498,6 +573,84 @@
         .isTrue();
   }
 
+  @Test
+  public void testMultipleActionStrategiesVisibleForDynamicScheduling() throws Exception {
+    String strategy1 = "strategy1";
+    String strategy2 = "stratagy2";
+    String primaryOutput = "some/path/to/a/file";
+
+    ManualClock clock = new ManualClock();
+    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
+    Artifact artifact = new Artifact(path, ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)));
+    Action action = mockAction("Some random action", primaryOutput);
+    when(action.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
+    when(action.getPrimaryOutput()).thenReturn(artifact);
+
+    ExperimentalStateTracker stateTracker = new ExperimentalStateTracker(clock);
+    stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
+    stateTracker.runningAction(new RunningActionEvent(action, strategy1));
+    stateTracker.runningAction(new RunningActionEvent(action, strategy2));
+
+    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
+    stateTracker.writeProgressBar(terminalWriter);
+    String output = terminalWriter.getTranscript();
+
+    assertWithMessage(
+            "Output should mention strategies '"
+                + strategy1
+                + "' and '"
+                + strategy2
+                + "', but was: "
+                + output)
+        .that(output.contains(strategy1 + ", " + strategy2))
+        .isTrue();
+  }
+
+  @Test
+  public void testActionCountsWithDynamicScheduling() throws Exception {
+    String primaryOutput1 = "some/path/to/a/file";
+    String primaryOutput2 = "some/path/to/b/file";
+
+    ManualClock clock = new ManualClock();
+    ExperimentalStateTracker stateTracker = new ExperimentalStateTracker(clock);
+    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
+
+    Path path1 = outputBase.getRelative(PathFragment.create(primaryOutput1));
+    Artifact artifact1 = new Artifact(path1, ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)));
+    Action action1 = mockAction("First random action", primaryOutput1);
+    when(action1.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
+    when(action1.getPrimaryOutput()).thenReturn(artifact1);
+    stateTracker.actionStarted(new ActionStartedEvent(action1, clock.nanoTime()));
+
+    Path path2 = outputBase.getRelative(PathFragment.create(primaryOutput2));
+    Artifact artifact2 = new Artifact(path2, ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)));
+    Action action2 = mockAction("First random action", primaryOutput1);
+    when(action2.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
+    when(action2.getPrimaryOutput()).thenReturn(artifact2);
+    stateTracker.actionStarted(new ActionStartedEvent(action2, clock.nanoTime()));
+
+    stateTracker.runningAction(new RunningActionEvent(action1, "strategy1"));
+    stateTracker.schedulingAction(new SchedulingActionEvent(action2, "strategy1"));
+    terminalWriter.reset();
+    stateTracker.writeProgressBar(terminalWriter);
+    assertThat(terminalWriter.getTranscript()).contains("2 actions, 1 running");
+
+    stateTracker.runningAction(new RunningActionEvent(action1, "strategy2"));
+    terminalWriter.reset();
+    stateTracker.writeProgressBar(terminalWriter);
+    assertThat(terminalWriter.getTranscript()).contains("3 actions, 2 running");
+
+    stateTracker.runningAction(new RunningActionEvent(action2, "strategy1"));
+    terminalWriter.reset();
+    stateTracker.writeProgressBar(terminalWriter);
+    assertThat(terminalWriter.getTranscript()).contains("3 actions running");
+
+    stateTracker.runningAction(new RunningActionEvent(action2, "strategy2"));
+    terminalWriter.reset();
+    stateTracker.writeProgressBar(terminalWriter);
+    assertThat(terminalWriter.getTranscript()).contains("4 actions running");
+  }
+
   private void doTestOutputLength(boolean withTest, int actions) throws Exception {
     // If we target 70 characters, then there should be enough space to both,
     // keep the line limit, and show the local part of the running actions and
