diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java b/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java
index 4b5485d..1877b72 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java
@@ -45,7 +45,7 @@
   private static final ResourceSet RESOURCES =
       ResourceSet.createWithRamCpuIo(/*memoryMb=*/1.0, /*cpu=*/0.1, /*io=*/0.0);
 
-  private final Callable<Void> effect;
+  protected final Callable<Void> effect;
 
   /** Use this constructor if the effect can't throw exceptions. */
   public TestAction(Runnable effect,
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
new file mode 100644
index 0000000..18d54e9
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
@@ -0,0 +1,773 @@
+// Copyright 2016 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.skyframe;
+
+import static com.google.common.base.Throwables.getRootCause;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.actions.ActionInputHelper.artifactFile;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.hash.Hashing;
+import com.google.common.util.concurrent.Runnables;
+import com.google.devtools.build.lib.actions.ActionExecutionContext;
+import com.google.devtools.build.lib.actions.ActionExecutionException;
+import com.google.devtools.build.lib.actions.ActionInput;
+import com.google.devtools.build.lib.actions.ActionInputHelper;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
+import com.google.devtools.build.lib.actions.ArtifactFile;
+import com.google.devtools.build.lib.actions.BuildFailedException;
+import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.actions.TestExecException;
+import com.google.devtools.build.lib.actions.cache.InjectedStat;
+import com.google.devtools.build.lib.actions.cache.MetadataHandler;
+import com.google.devtools.build.lib.actions.util.TestAction;
+import com.google.devtools.build.lib.testutil.TestUtils;
+import com.google.devtools.build.lib.util.AbruptExitException;
+import com.google.devtools.build.lib.vfs.FileStatus;
+import com.google.devtools.build.lib.vfs.FileSystem;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.Symlinks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/** Timestamp builder tests for TreeArtifacts. */
+@RunWith(JUnit4.class)
+public class TreeArtifactBuildTest extends TimestampBuilderTestCase {
+  // Common Artifacts, ArtifactFiles, and Buttons. These aren't all used in all tests, but they're
+  // used often enough that we can save ourselves a lot of copy-pasted code by creating them
+  // in setUp().
+
+  Artifact in;
+
+  Artifact outOne;
+  ArtifactFile outOneFileOne;
+  ArtifactFile outOneFileTwo;
+  Button buttonOne = new Button();
+
+  Artifact outTwo;
+  ArtifactFile outTwoFileOne;
+  ArtifactFile outTwoFileTwo;
+  Button buttonTwo = new Button();
+
+  @Before
+  public void setUp() throws Exception {
+    in = createSourceArtifact("input");
+    writeFile(in, "input_content");
+
+    outOne = createTreeArtifact("outputOne");
+    outOneFileOne = artifactFile(outOne, "out_one_file_one");
+    outOneFileTwo = artifactFile(outOne, "out_one_file_two");
+
+    outTwo = createTreeArtifact("outputTwo");
+    outTwoFileOne = artifactFile(outTwo, "out_one_file_one");
+    outTwoFileTwo = artifactFile(outTwo, "out_one_file_two");
+  }
+
+  /** Simple smoke test. If this isn't passing, something is very wrong... */
+  @Test
+  public void testTreeArtifactSimpleCase() throws Exception {
+    TouchingTestAction action = new TouchingTestAction(outOneFileOne, outOneFileTwo);
+    registerAction(action);
+    buildArtifact(action.getSoleOutput());
+
+    assertTrue(outOneFileOne.getPath().exists());
+    assertTrue(outOneFileTwo.getPath().exists());
+  }
+
+  /** Simple test for the case with dependencies. */
+  @Test
+  public void testDependentTreeArtifacts() throws Exception {
+    TouchingTestAction actionOne = new TouchingTestAction(outOneFileOne, outOneFileTwo);
+    registerAction(actionOne);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        ImmutableList.of(outOneFileOne, outOneFileTwo),
+        ImmutableList.of(outTwoFileOne, outTwoFileTwo));
+    registerAction(actionTwo);
+
+    buildArtifact(outTwo);
+
+    assertTrue(outOneFileOne.getPath().exists());
+    assertTrue(outOneFileTwo.getPath().exists());
+    assertTrue(outTwoFileOne.getPath().exists());
+    assertTrue(outTwoFileTwo.getPath().exists());
+  }
+
+  /** Unchanged TreeArtifact outputs should not cause reexecution. */
+  @Test
+  public void testCacheCheckingForTreeArtifactsDoesNotCauseReexecution() throws Exception {
+    Artifact outOne = createTreeArtifact("outputOne");
+    Button buttonOne = new Button();
+
+    Artifact outTwo = createTreeArtifact("outputTwo");
+    Button buttonTwo = new Button();
+
+    TouchingTestAction actionOne = new TouchingTestAction(
+        buttonOne, outOne, "file_one", "file_two");
+    registerAction(actionOne);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        buttonTwo, outOne, outTwo, "file_one", "file_two");
+    registerAction(actionTwo);
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    buildArtifact(outTwo);
+    assertTrue(buttonOne.pressed); // built
+    assertTrue(buttonTwo.pressed); // built
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    buildArtifact(outTwo);
+    assertFalse(buttonOne.pressed); // not built
+    assertFalse(buttonTwo.pressed); // not built
+  }
+
+  /**
+   * Test rebuilding TreeArtifacts for inputs, outputs, and dependents.
+   * Also a test for caching.
+   */
+  @Test
+  public void testTransitiveReexecutionForTreeArtifacts() throws Exception {
+    WriteInputToFilesAction actionOne = new WriteInputToFilesAction(
+        buttonOne,
+        in,
+        outOneFileOne, outOneFileTwo);
+    registerAction(actionOne);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        buttonTwo,
+        ImmutableList.of(outOneFileOne, outOneFileTwo),
+        ImmutableList.of(outTwoFileOne, outTwoFileTwo));
+    registerAction(actionTwo);
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    buildArtifact(outTwo);
+    assertTrue(buttonOne.pressed); // built
+    assertTrue(buttonTwo.pressed); // built
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    writeFile(in, "modified_input");
+    buildArtifact(outTwo);
+    assertTrue(buttonOne.pressed); // built
+    assertTrue(buttonTwo.pressed); // not built
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    writeFile(outOneFileOne, "modified_output");
+    buildArtifact(outTwo);
+    assertTrue(buttonOne.pressed); // built
+    assertFalse(buttonTwo.pressed); // should have been cached
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    writeFile(outTwoFileOne, "more_modified_output");
+    buildArtifact(outTwo);
+    assertFalse(buttonOne.pressed); // not built
+    assertTrue(buttonTwo.pressed); // built
+  }
+
+  /** Tests that changing a TreeArtifact directory should cause reexeuction. */
+  @Test
+  public void testDirectoryContentsCachingForTreeArtifacts() throws Exception {
+    WriteInputToFilesAction actionOne = new WriteInputToFilesAction(
+        buttonOne,
+        in,
+        outOneFileOne, outOneFileTwo);
+    registerAction(actionOne);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        buttonTwo,
+        ImmutableList.of(outOneFileOne, outOneFileTwo),
+        ImmutableList.of(outTwoFileOne, outTwoFileTwo));
+    registerAction(actionTwo);
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    buildArtifact(outTwo);
+    // just a smoke test--if these aren't built we have bigger problems!
+    assertTrue(buttonOne.pressed);
+    assertTrue(buttonTwo.pressed);
+
+    // Adding a file to a directory should cause reexecution.
+    buttonOne.pressed = buttonTwo.pressed = false;
+    Path spuriousOutputOne = outOne.getPath().getRelative("spuriousOutput");
+    touchFile(spuriousOutputOne);
+    buildArtifact(outTwo);
+    // Should re-execute, and delete spurious output
+    assertFalse(spuriousOutputOne.exists());
+    assertTrue(buttonOne.pressed);
+    assertFalse(buttonTwo.pressed); // should have been cached
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    Path spuriousOutputTwo = outTwo.getPath().getRelative("anotherSpuriousOutput");
+    touchFile(spuriousOutputTwo);
+    buildArtifact(outTwo);
+    assertFalse(spuriousOutputTwo.exists());
+    assertFalse(buttonOne.pressed);
+    assertTrue(buttonTwo.pressed);
+
+    // Deleting should cause reexecution.
+    buttonOne.pressed = buttonTwo.pressed = false;
+    deleteFile(outOneFileOne);
+    buildArtifact(outTwo);
+    assertTrue(outOneFileOne.getPath().exists());
+    assertTrue(buttonOne.pressed);
+    assertFalse(buttonTwo.pressed); // should have been cached
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    deleteFile(outTwoFileOne);
+    buildArtifact(outTwo);
+    assertTrue(outTwoFileOne.getPath().exists());
+    assertFalse(buttonOne.pressed);
+    assertTrue(buttonTwo.pressed);
+  }
+
+  /**
+   * TreeArtifacts don't care about mtime, even when the file is empty.
+   * However, actions taking input non-Tree artifacts still care about mtime
+   * (although this behavior should go away).
+   */
+  @Test
+  public void testMTimeForTreeArtifactsDoesNotMatter() throws Exception {
+    // For this test, we only touch the input file.
+    Artifact in = createSourceArtifact("touchable_input");
+    touchFile(in);
+
+    WriteInputToFilesAction actionOne = new WriteInputToFilesAction(
+        buttonOne,
+        in,
+        outOneFileOne, outOneFileTwo);
+    registerAction(actionOne);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        buttonTwo,
+        ImmutableList.of(outOneFileOne, outOneFileTwo),
+        ImmutableList.of(outTwoFileOne, outTwoFileTwo));
+    registerAction(actionTwo);
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    buildArtifact(outTwo);
+    assertTrue(buttonOne.pressed); // built
+    assertTrue(buttonTwo.pressed); // built
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    touchFile(in);
+    buildArtifact(outTwo);
+    // Per existing behavior, mtime matters for empty file Artifacts.
+    assertTrue(buttonOne.pressed);
+    // But this should be cached.
+    assertFalse(buttonTwo.pressed);
+
+    // None of the below following should result in anything being built.
+    buttonOne.pressed = buttonTwo.pressed = false;
+    touchFile(outOneFileOne);
+    buildArtifact(outTwo);
+    // Nothing should be built.
+    assertFalse(buttonOne.pressed);
+    assertFalse(buttonTwo.pressed);
+
+    buttonOne.pressed = buttonTwo.pressed = false;
+    touchFile(outOneFileTwo);
+    buildArtifact(outTwo);
+    // Nothing should be built.
+    assertFalse(buttonOne.pressed);
+    assertFalse(buttonTwo.pressed);
+  }
+
+  /** Tests that the declared order of TreeArtifact contents does not matter. */
+  @Test
+  public void testOrderIndependenceOfTreeArtifactContents() throws Exception {
+    WriteInputToFilesAction actionOne = new WriteInputToFilesAction(
+        in,
+        // The design of WritingTestAction is s.t.
+        // these files will be registered in the given order.
+        outOneFileTwo, outOneFileOne);
+    registerAction(actionOne);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        ImmutableList.of(outOneFileOne, outOneFileTwo),
+        ImmutableList.of(outTwoFileOne, outTwoFileTwo));
+    registerAction(actionTwo);
+
+    buildArtifact(outTwo);
+  }
+
+  @Test
+  public void testActionExpansion() throws Exception {
+    WriteInputToFilesAction action = new WriteInputToFilesAction(in, outOneFileOne, outOneFileTwo);
+
+    CopyTreeAction actionTwo = new CopyTreeAction(
+        ImmutableList.of(outOneFileOne, outOneFileTwo),
+        ImmutableList.of(outTwoFileOne, outTwoFileTwo)) {
+      @Override
+      public void executeTestBehavior(ActionExecutionContext actionExecutionContext)
+          throws ActionExecutionException {
+        super.executeTestBehavior(actionExecutionContext);
+
+        Collection<ActionInput> expanded =
+            ActionInputHelper.expandArtifacts(ImmutableList.of(outOne),
+                actionExecutionContext.getArtifactExpander());
+        // Only files registered should show up here.
+        assertThat(expanded).containsExactly(outOneFileOne, outOneFileTwo);
+      }
+    };
+
+    registerAction(action);
+    registerAction(actionTwo);
+
+    buildArtifact(outTwo); // should not fail
+  }
+
+  @Test
+  public void testInvalidOutputRegistrations() throws Exception {
+    TreeArtifactTestAction failureOne = new TreeArtifactTestAction(
+        Runnables.doNothing(), outOneFileOne, outOneFileTwo) {
+      @Override
+      public void executeTestBehavior(ActionExecutionContext actionExecutionContext)
+          throws ActionExecutionException {
+        try {
+          writeFile(outOneFileOne, "one");
+          writeFile(outOneFileTwo, "two");
+          // In this test case, we only register one output. This will fail.
+          registerOutput(actionExecutionContext, "one");
+        } catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+    };
+
+    registerAction(failureOne);
+    try {
+      buildArtifact(outOne);
+      fail(); // Should have thrown
+    } catch (Exception e) {
+      assertThat(getRootCause(e).getMessage()).contains("not present on disk");
+    }
+
+    TreeArtifactTestAction failureTwo = new TreeArtifactTestAction(
+        Runnables.doNothing(), outTwoFileOne, outTwoFileTwo) {
+      @Override
+      public void executeTestBehavior(ActionExecutionContext actionExecutionContext)
+          throws ActionExecutionException {
+        try {
+          writeFile(outTwoFileOne, "one");
+          writeFile(outTwoFileTwo, "two");
+          // In this test case, register too many outputs. This will fail.
+          registerOutput(actionExecutionContext, "one");
+          registerOutput(actionExecutionContext, "two");
+          registerOutput(actionExecutionContext, "three");
+        } catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+    };
+
+    registerAction(failureTwo);
+    try {
+      buildArtifact(outTwo);
+      fail(); // Should have thrown
+    } catch (Exception e) {
+      assertThat(getRootCause(e).getMessage()).contains("not present on disk");
+    }
+  }
+
+  private static void checkDirectoryPermissions(Path path) throws IOException {
+    assertTrue(path.isDirectory());
+    assertTrue(path.isExecutable());
+    assertTrue(path.isReadable());
+    assertFalse(path.isWritable());
+  }
+
+  private static void checkFilePermissions(Path path) throws IOException {
+    assertFalse(path.isDirectory());
+    assertTrue(path.isExecutable());
+    assertTrue(path.isReadable());
+    assertFalse(path.isWritable());
+  }
+
+  @Test
+  public void testOutputsAreReadOnlyAndExecutable() throws Exception {
+    final Artifact out = createTreeArtifact("output");
+
+    TreeArtifactTestAction action = new TreeArtifactTestAction(out) {
+      @Override
+      public void execute(ActionExecutionContext actionExecutionContext)
+          throws ActionExecutionException {
+        try {
+          writeFile(out.getPath().getChild("one"), "one");
+          writeFile(out.getPath().getChild("two"), "two");
+          writeFile(out.getPath().getChild("three").getChild("four"), "three/four");
+          registerOutput(actionExecutionContext, "one");
+          registerOutput(actionExecutionContext, "two");
+          registerOutput(actionExecutionContext, "three/four");
+        } catch (Exception e) {
+          throw new RuntimeException(e);
+        }
+      }
+    };
+
+    registerAction(action);
+
+    buildArtifact(action.getSoleOutput());
+
+    checkDirectoryPermissions(out.getPath());
+    checkFilePermissions(out.getPath().getChild("one"));
+    checkFilePermissions(out.getPath().getChild("two"));
+    checkDirectoryPermissions(out.getPath().getChild("three"));
+    checkFilePermissions(out.getPath().getChild("three").getChild("four"));
+  }
+
+  // This is more a smoke test than anything, because it turns out that:
+  // 1) there is no easy way to turn fast digests on/off for these test cases, and
+  // 2) injectDigest() doesn't really complain if you inject bad digests or digests
+  // for nonexistent files. Instead some weird error shows up down the line.
+  // In fact, there are no tests for injectDigest anywhere in the codebase.
+  // So all we're really testing here is that injectDigest() doesn't throw a weird exception.
+  // TODO(bazel-team): write real tests for injectDigest, here and elsewhere.
+  @Test
+  public void testDigestInjection() throws Exception {
+    TreeArtifactTestAction action = new TreeArtifactTestAction(outOne) {
+      @Override
+      public void execute(ActionExecutionContext actionExecutionContext)
+          throws ActionExecutionException {
+        try {
+          writeFile(outOneFileOne, "one");
+          writeFile(outOneFileTwo, "two");
+
+          MetadataHandler md = actionExecutionContext.getMetadataHandler();
+          FileStatus stat = outOneFileOne.getPath().stat(Symlinks.NOFOLLOW);
+          md.injectDigest(outOneFileOne,
+              new InjectedStat(stat.getLastModifiedTime(), stat.getSize(), stat.getNodeId()),
+              Hashing.md5().hashString("one", Charset.forName("UTF-8")).asBytes());
+
+          stat = outOneFileTwo.getPath().stat(Symlinks.NOFOLLOW);
+          md.injectDigest(outOneFileTwo,
+              new InjectedStat(stat.getLastModifiedTime(), stat.getSize(), stat.getNodeId()),
+              Hashing.md5().hashString("two", Charset.forName("UTF-8")).asBytes());
+        } catch (Exception e) {
+          throw new RuntimeException(e);
+        }
+      }
+    };
+
+    registerAction(action);
+    buildArtifact(action.getSoleOutput());
+  }
+
+  /**
+   * A generic test action that takes at most one input TreeArtifact,
+   * exactly one output TreeArtifact, and some path fragment inputs/outputs.
+   */
+  private abstract static class TreeArtifactTestAction extends TestAction {
+    final Iterable<ArtifactFile> inputFiles;
+    final Iterable<ArtifactFile> outputFiles;
+
+    TreeArtifactTestAction(final Artifact output, final String... subOutputs) {
+      this(Runnables.doNothing(),
+          null,
+          ImmutableList.<ArtifactFile>of(),
+          output,
+          Collections2.transform(
+              Arrays.asList(subOutputs),
+              new Function<String, ArtifactFile>() {
+                @Nullable
+                @Override
+                public ArtifactFile apply(String s) {
+                  return ActionInputHelper.artifactFile(output, s);
+                }
+              }));
+    }
+
+    TreeArtifactTestAction(Runnable effect, ArtifactFile... outputFiles) {
+      this(effect, Arrays.asList(outputFiles));
+    }
+
+    TreeArtifactTestAction(Runnable effect, Collection<ArtifactFile> outputFiles) {
+      this(effect, null, ImmutableList.<ArtifactFile>of(),
+          outputFiles.iterator().next().getParent(), outputFiles);
+    }
+
+    TreeArtifactTestAction(Runnable effect, Artifact inputFile,
+        Collection<ArtifactFile> outputFiles) {
+      this(effect, inputFile, ImmutableList.<ArtifactFile>of(),
+          outputFiles.iterator().next().getParent(), outputFiles);
+    }
+
+    TreeArtifactTestAction(Runnable effect, Collection<ArtifactFile> inputFiles,
+        Collection<ArtifactFile> outputFiles) {
+      this(effect, inputFiles.iterator().next().getParent(), inputFiles,
+          outputFiles.iterator().next().getParent(), outputFiles);
+    }
+
+    TreeArtifactTestAction(
+        Runnable effect,
+        @Nullable Artifact input,
+        Collection<ArtifactFile> inputFiles,
+        Artifact output,
+        Collection<ArtifactFile> outputFiles) {
+      super(effect,
+          input == null ? ImmutableList.<Artifact>of() : ImmutableList.of(input),
+          ImmutableList.of(output));
+      Preconditions.checkArgument(
+          inputFiles.isEmpty() || (input != null && input.isTreeArtifact()));
+      Preconditions.checkArgument(output == null || output.isTreeArtifact());
+      this.inputFiles = ImmutableList.copyOf(inputFiles);
+      this.outputFiles = ImmutableList.copyOf(outputFiles);
+      for (ArtifactFile inputFile : inputFiles) {
+        Preconditions.checkState(inputFile.getParent().equals(input));
+      }
+      for (ArtifactFile outputFile : outputFiles) {
+        Preconditions.checkState(outputFile.getParent().equals(output));
+      }
+    }
+
+    @Override
+    public void execute(ActionExecutionContext actionExecutionContext)
+        throws ActionExecutionException {
+      if (getInputs().iterator().hasNext()) {
+        // Sanity check--verify all inputs exist.
+        Artifact input = getSoleInput();
+        if (!input.getPath().exists()) {
+          throw new IllegalStateException("action's input Artifact does not exist: "
+              + input.getPath());
+        }
+        for (ArtifactFile inputFile : inputFiles) {
+          if (!inputFile.getPath().exists()) {
+            throw new IllegalStateException("action's input does not exist: " + inputFile);
+          }
+        }
+      }
+
+      Artifact output = getSoleOutput();
+      assertTrue(output.getPath().exists());
+      try {
+        effect.call();
+        executeTestBehavior(actionExecutionContext);
+        for (ArtifactFile outputFile : outputFiles) {
+          actionExecutionContext.getMetadataHandler().addExpandedTreeOutput(outputFile);
+        }
+      } catch (RuntimeException e) {
+        throw new RuntimeException(e);
+      } catch (Exception e) {
+        throw new ActionExecutionException("TestAction failed due to exception",
+            e, this, false);
+      }
+    }
+
+    void executeTestBehavior(ActionExecutionContext c) throws ActionExecutionException {
+      // Default: do nothing
+    }
+
+    /** Checks there's exactly one input, and returns it. */
+    // This prevents us from making testing mistakes, like
+    // assuming there's only one input when this isn't actually true.
+    Artifact getSoleInput() {
+      Iterator<Artifact> it = getInputs().iterator();
+      Artifact r = it.next();
+      Preconditions.checkNotNull(r);
+      Preconditions.checkState(!it.hasNext());
+      return r;
+    }
+
+    /** Checks there's exactly one output, and returns it. */
+    Artifact getSoleOutput() {
+      Iterator<Artifact> it = getOutputs().iterator();
+      Artifact r = it.next();
+      Preconditions.checkNotNull(r);
+      Preconditions.checkState(!it.hasNext());
+      Preconditions.checkState(r.equals(getPrimaryOutput()));
+      return r;
+    }
+
+    void registerOutput(ActionExecutionContext context, String outputName) throws IOException {
+      context.getMetadataHandler().addExpandedTreeOutput(
+          artifactFile(getSoleOutput(), new PathFragment(outputName)));
+    }
+
+    static List<ArtifactFile> asArtifactFiles(final Artifact parent, String... files) {
+      return Lists.transform(
+          Arrays.asList(files),
+          new Function<String, ArtifactFile>() {
+            @Nullable
+            @Override
+            public ArtifactFile apply(String s) {
+              return ActionInputHelper.artifactFile(parent, s);
+            }
+          });
+    }
+  }
+
+  /** An action that touches some output ArtifactFiles. Takes no inputs. */
+  private static class TouchingTestAction extends TreeArtifactTestAction {
+    TouchingTestAction(ArtifactFile... outputPaths) {
+      super(Runnables.doNothing(), outputPaths);
+    }
+
+    TouchingTestAction(Runnable effect, Artifact output, String... outputPaths) {
+      super(effect, asArtifactFiles(output, outputPaths));
+    }
+
+    @Override
+    public void executeTestBehavior(ActionExecutionContext actionExecutionContext)
+        throws ActionExecutionException {
+      try {
+        for (ArtifactFile file : outputFiles) {
+          touchFile(file);
+        }
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  /** Takes an input file and populates several copies inside a TreeArtifact. */
+  private static class WriteInputToFilesAction extends TreeArtifactTestAction {
+    WriteInputToFilesAction(Artifact input, ArtifactFile... outputs) {
+      this(Runnables.doNothing(), input, outputs);
+    }
+
+    WriteInputToFilesAction(
+        Runnable effect,
+        Artifact input,
+        ArtifactFile... outputs) {
+      super(effect, input, Arrays.asList(outputs));
+      Preconditions.checkArgument(!input.isTreeArtifact());
+    }
+
+    @Override
+    public void executeTestBehavior(ActionExecutionContext actionExecutionContext)
+        throws ActionExecutionException {
+      try {
+        for (ArtifactFile file : outputFiles) {
+          FileSystemUtils.createDirectoryAndParents(file.getPath().getParentDirectory());
+          FileSystemUtils.copyFile(getSoleInput().getPath(), file.getPath());
+        }
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  /** Copies the given ArtifactFile inputs to the given outputs, in respective order. */
+  private static class CopyTreeAction extends TreeArtifactTestAction {
+
+    CopyTreeAction(Runnable effect, Artifact input, Artifact output, String... sourcesAndDests) {
+      super(effect, input, asArtifactFiles(input, sourcesAndDests), output,
+          asArtifactFiles(output, sourcesAndDests));
+    }
+
+    CopyTreeAction(
+        Collection<ArtifactFile> inputPaths,
+        Collection<ArtifactFile> outputPaths) {
+      super(Runnables.doNothing(), inputPaths, outputPaths);
+    }
+
+    CopyTreeAction(
+        Runnable effect,
+        Collection<ArtifactFile> inputPaths,
+        Collection<ArtifactFile> outputPaths) {
+      super(effect, inputPaths, outputPaths);
+    }
+
+    @Override
+    public void executeTestBehavior(ActionExecutionContext actionExecutionContext)
+        throws ActionExecutionException {
+      Iterator<ArtifactFile> inputIterator = inputFiles.iterator();
+      Iterator<ArtifactFile> outputIterator = outputFiles.iterator();
+
+      try {
+        while (inputIterator.hasNext() || outputIterator.hasNext()) {
+          ArtifactFile input = inputIterator.next();
+          ArtifactFile output = outputIterator.next();
+          FileSystemUtils.createDirectoryAndParents(output.getPath().getParentDirectory());
+          FileSystemUtils.copyFile(input.getPath(), output.getPath());
+        }
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+
+      // both iterators must be of the same size
+      assertFalse(inputIterator.hasNext());
+      assertFalse(inputIterator.hasNext());
+    }
+  }
+
+  private Artifact createTreeArtifact(String name) {
+    FileSystem fs = scratch.getFileSystem();
+    Path execRoot = fs.getPath(TestUtils.tmpDir());
+    PathFragment execPath = new PathFragment("out").getRelative(name);
+    Path path = execRoot.getRelative(execPath);
+    return new SpecialArtifact(
+        path, Root.asDerivedRoot(execRoot, execRoot.getRelative("out")), execPath, ALL_OWNER,
+        SpecialArtifactType.TREE);
+  }
+
+  private void buildArtifact(Artifact artifact)
+      throws InterruptedException, BuildFailedException, TestExecException, AbruptExitException {
+    buildArtifacts(cachingBuilder(), artifact);
+  }
+
+  private static void writeFile(Path path, String contents) throws IOException {
+    FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
+    // sometimes we write read-only files
+    if (path.exists()) {
+      path.setWritable(true);
+    }
+    FileSystemUtils.writeContentAsLatin1(path, contents);
+  }
+
+  private static void writeFile(ArtifactFile file, String contents) throws IOException {
+    writeFile(file.getPath(), contents);
+  }
+
+  private static void touchFile(Path path) throws IOException {
+    FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
+    path.getParentDirectory().setWritable(true);
+    FileSystemUtils.touchFile(path);
+  }
+
+  private static void touchFile(ArtifactFile file) throws IOException {
+    touchFile(file.getPath());
+  }
+
+  private static void deleteFile(ArtifactFile file) throws IOException {
+    Path path = file.getPath();
+    // sometimes we write read-only files
+    if (path.exists()) {
+      path.setWritable(true);
+      // work around the sticky bit (this might depend on the behavior of the OS?)
+      path.getParentDirectory().setWritable(true);
+      path.delete();
+    }
+  }
+}
