diff --git a/src/test/java/BUILD b/src/test/java/BUILD
index ef8e053..30f2bcc 100644
--- a/src/test/java/BUILD
+++ b/src/test/java/BUILD
@@ -53,6 +53,10 @@
         "com/google/devtools/build/lib/vfs/util/*.java",
         "com/google/devtools/build/lib/events/util/*.java",
     ]),
+    data = [
+        "//src/main/native:libunix.dylib",
+        "//src/main/native:libunix.so",
+    ],
     deps = [
         ":testutil",
         "//src/main/java:bazel-core",
@@ -102,10 +106,7 @@
         ],
     ),
     args = ["com.google.devtools.build.lib.AllTests"],
-    data = glob([test_prefix + "/vfs/*.zip"]) + [
-        "//src/main/native:libunix.dylib",
-        "//src/main/native:libunix.so",
-    ],
+    data = glob([test_prefix + "/vfs/*.zip"]),
     deps = [
         ":foundations_testutil",
         ":test_runner",
@@ -131,10 +132,6 @@
     args = [
         "com.google.devtools.build.lib.AllTests",
     ],
-    data = [
-        "//src/main/native:libunix.dylib",
-        "//src/main/native:libunix.so",
-    ],
     jvm_flags = ["-Dblaze.os=Windows"],
     deps = [
         ":foundations_testutil",
@@ -174,10 +171,6 @@
         "com/google/devtools/build/lib/actions/*.java",
     ]),
     args = ["com.google.devtools.build.lib.AllTests"],
-    data = [
-        "//src/main/native:libunix.dylib",
-        "//src/main/native:libunix.so",
-    ],
     deps = [
         ":actions_testutil",
         ":foundations_testutil",
@@ -200,20 +193,15 @@
         "com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java",
         "com/google/devtools/build/lib/analysis/util/*.java",
         "com/google/devtools/build/lib/exec/util/*.java",
-        "com/google/devtools/build/lib/packages/util/*.java",
         "com/google/devtools/build/lib/skyframe/util/*.java",
     ]),
-    data = [
-        "//src/main/native:libunix.dylib",
-        "//src/main/native:libunix.so",
-    ],
     resources = [
         "MOCK_CROSSTOOL",
     ],
     deps = [
         ":actions_testutil",
         ":foundations_testutil",
-        ":test_runner",
+        ":packages_testutil",
         ":testutil",
         "//src/main/java:bazel-core",
         "//src/main/java:concurrent",
@@ -302,6 +290,7 @@
         ":actions_testutil",
         ":analysis_testutil",
         ":foundations_testutil",
+        ":packages_testutil",
         ":test_runner",
         ":testutil",
         "//src/main/java:bazel-core",
@@ -332,6 +321,46 @@
     ],
 )
 
+java_library(
+    name = "packages_testutil",
+    srcs = glob([
+        "com/google/devtools/build/lib/packages/util/*.java",
+    ]),
+    deps = [
+        ":foundations_testutil",
+        ":testutil",
+        "//src/main/java:bazel-core",
+        "//src/main/protobuf:proto_extra_actions_base",
+        "//third_party:guava",
+        "//third_party:guava-testlib",
+        "//third_party:jsr305",
+        "//third_party:junit4",
+        "//third_party:mockito",
+        "//third_party:truth",
+    ],
+)
+
+java_test(
+    name = "packages_test",
+    srcs = glob([
+        "com/google/devtools/build/lib/packages/*.java",
+    ]),
+    args = ["com.google.devtools.build.lib.AllTests"],
+    deps = [
+        ":actions_testutil",
+        ":foundations_testutil",
+        ":packages_testutil",
+        ":test_runner",
+        ":testutil",
+        "//src/main/java:bazel-core",
+        "//third_party:guava",
+        "//third_party:guava-testlib",
+        "//third_party:jsr305",
+        "//third_party:junit4",
+        "//third_party:truth",
+    ],
+)
+
 cc_binary(
     name = "com/google/devtools/build/lib/shell/killmyself",
     srcs = ["com/google/devtools/build/lib/shell/killmyself.cc"],
@@ -345,8 +374,6 @@
     args = ["com.google.devtools.build.lib.AllTests"],
     data = [
         ":com/google/devtools/build/lib/shell/killmyself",
-        "//src/main/native:libunix.dylib",
-        "//src/main/native:libunix.so",
     ],
     deps = [
         ":foundations_testutil",
@@ -369,10 +396,6 @@
         "com/google/devtools/build/lib/syntax/*.java",
     ]),
     args = ["com.google.devtools.build.lib.AllTests"],
-    data = [
-        "//src/main/native:libunix.dylib",
-        "//src/main/native:libunix.so",
-    ],
     deps = [
         ":foundations_testutil",
         ":test_runner",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 0bc8e87..a2cfe08 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -1264,7 +1264,7 @@
         + depRuleType + " rule '" + depRuleName + "' is misplaced here";
   }
 
-  public static String getErrorMsgNonEmptyList(String attrName, String ruleType, String ruleName) {
+  protected String getErrorMsgNonEmptyList(String attrName, String ruleType, String ruleName) {
     return "non empty attribute '" + attrName + "' in '" + ruleType
         + "' rule '" + ruleName + "' has to have at least one value";
   }
diff --git a/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java b/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java
new file mode 100644
index 0000000..c15e9ac
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/AttributeTest.java
@@ -0,0 +1,248 @@
+// Copyright 2006-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.Type.INTEGER;
+import static com.google.devtools.build.lib.packages.Type.LABEL;
+import static com.google.devtools.build.lib.packages.Type.LABEL_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Predicates;
+import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.util.FileType;
+import com.google.devtools.build.lib.util.FileTypeSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests of Attribute code.
+ */
+@RunWith(JUnit4.class)
+public class AttributeTest {
+
+  private void assertDefaultValue(Object expected, Attribute attr) {
+    assertEquals(expected, attr.getDefaultValue(null));
+  }
+
+  private void assertType(Type<?> expectedType, Attribute attr) {
+    assertEquals(expectedType, attr.getType());
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    Attribute attr = attr("foo", Type.INTEGER).mandatory().value(3).build();
+    assertEquals("foo", attr.getName());
+    assertEquals(3, attr.getDefaultValue(null));
+    assertEquals(Type.INTEGER, attr.getType());
+    assertTrue(attr.isMandatory());
+    assertTrue(attr.isDocumented());
+    attr = attr("$foo", Type.INTEGER).build();
+    assertFalse(attr.isDocumented());
+  }
+
+  @Test
+  public void testNonEmptyReqiresListType() throws Exception {
+    try {
+      attr("foo", Type.INTEGER).nonEmpty().value(3).build();
+      fail();
+    } catch (NullPointerException e) {
+      assertThat(e).hasMessage("attribute 'foo' must be a list");
+    }
+  }
+
+  @Test
+  public void testNonEmpty() throws Exception {
+    Attribute attr = attr("foo", Type.LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build();
+    assertEquals("foo", attr.getName());
+    assertEquals(Type.LABEL_LIST, attr.getType());
+    assertTrue(attr.isNonEmpty());
+  }
+
+  @Test
+  public void testSingleArtifactReqiresLabelType() throws Exception {
+    try {
+      attr("foo", Type.INTEGER).singleArtifact().value(3).build();
+      fail();
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("attribute 'foo' must be a label-valued type");
+    }
+  }
+
+  @Test
+  public void testDoublePropertySet() {
+    Attribute.Builder<String> builder = attr("x", STRING).mandatory().cfg(HOST).undocumented("")
+        .value("y");
+    try {
+      builder.mandatory();
+      fail();
+    } catch (IllegalStateException expected) {
+      // expected
+    }
+    try {
+      builder.cfg(HOST);
+      fail();
+    } catch (IllegalStateException expected) {
+      // expected
+    }
+    try {
+      builder.undocumented("");
+      fail();
+    } catch (IllegalStateException expected) {
+      // expected
+    }
+    try {
+      builder.value("z");
+      fail();
+    } catch (IllegalStateException expected) {
+      // expected
+    }
+
+    builder = attr("$x", STRING);
+    try {
+      builder.undocumented("");
+      fail();
+    } catch (IllegalStateException expected) {
+      // expected
+    }
+  }
+
+  /**
+   *  Tests the "convenience factories" (string, label, etc) for default
+   *  values.
+   */
+  @Test
+  public void testConvenienceFactoriesDefaultValues() throws Exception {
+    assertDefaultValue(0,
+                       attr("x", INTEGER).build());
+    assertDefaultValue(42,
+                       attr("x", INTEGER).value(42).build());
+
+    assertDefaultValue("",
+                       attr("x", STRING).build());
+    assertDefaultValue("foo",
+                       attr("x", STRING).value("foo").build());
+
+    Label label = Label.parseAbsolute("//foo:bar");
+    assertDefaultValue(null,
+                       attr("x", LABEL).legacyAllowAnyFileType().build());
+    assertDefaultValue(label,
+                       attr("x", LABEL).legacyAllowAnyFileType().value(label).build());
+
+    List<String> slist = Arrays.asList("foo", "bar");
+    assertDefaultValue(Collections.emptyList(),
+                       attr("x", STRING_LIST).build());
+    assertDefaultValue(slist,
+                       attr("x", STRING_LIST).value(slist).build());
+
+    List<Label> llist = Arrays.asList(Label.parseAbsolute("//foo:bar"),
+                                      Label.parseAbsolute("//foo:wiz"));
+    assertDefaultValue(Collections.emptyList(),
+                       attr("x", LABEL_LIST).legacyAllowAnyFileType().build());
+    assertDefaultValue(llist,
+                       attr("x", LABEL_LIST).legacyAllowAnyFileType().value(llist).build());
+  }
+
+  /**
+   *  Tests the "convenience factories" (string, label, etc) for types.
+   */
+  @Test
+  public void testConvenienceFactoriesTypes() throws Exception {
+    assertType(INTEGER,
+               attr("x", INTEGER).build());
+    assertType(INTEGER,
+               attr("x", INTEGER).value(42).build());
+
+    assertType(STRING,
+               attr("x", STRING).build());
+    assertType(STRING,
+               attr("x", STRING).value("foo").build());
+
+    Label label = Label.parseAbsolute("//foo:bar");
+    assertType(LABEL,
+                       attr("x", LABEL).legacyAllowAnyFileType().build());
+    assertType(LABEL,
+               attr("x", LABEL).legacyAllowAnyFileType().value(label).build());
+
+    List<String> slist = Arrays.asList("foo", "bar");
+    assertType(STRING_LIST,
+               attr("x", STRING_LIST).build());
+    assertType(STRING_LIST,
+               attr("x", STRING_LIST).value(slist).build());
+
+    List<Label> llist = Arrays.asList(Label.parseAbsolute("//foo:bar"),
+                                      Label.parseAbsolute("//foo:wiz"));
+    assertType(LABEL_LIST,
+               attr("x", LABEL_LIST).legacyAllowAnyFileType().build());
+    assertType(LABEL_LIST,
+               attr("x", LABEL_LIST).legacyAllowAnyFileType().value(llist).build());
+  }
+
+  @Test
+  public void testCloneBuilder() {
+    FileTypeSet txtFiles = FileTypeSet.of(FileType.of("txt"));
+    RuleClass.Builder.RuleClassNamePredicate ruleClasses = 
+        new RuleClass.Builder.RuleClassNamePredicate("mock_rule");
+    
+    Attribute parentAttr = attr("x", LABEL_LIST)
+        .allowedFileTypes(txtFiles)
+        .mandatory()
+        .build();
+    
+    Attribute childAttr1 = parentAttr.cloneBuilder().build();
+    assertEquals("x", childAttr1.getName());
+    assertEquals(txtFiles, childAttr1.getAllowedFileTypesPredicate());
+    assertEquals(Predicates.alwaysTrue(), childAttr1.getAllowedRuleClassesPredicate());
+    assertTrue(childAttr1.isMandatory());
+    assertFalse(childAttr1.isNonEmpty());
+
+    Attribute childAttr2 = parentAttr.cloneBuilder()
+        .nonEmpty()
+        .allowedRuleClasses(ruleClasses)
+        .build();
+    assertEquals("x", childAttr2.getName());
+    assertEquals(txtFiles, childAttr2.getAllowedFileTypesPredicate());
+    assertEquals(ruleClasses, childAttr2.getAllowedRuleClassesPredicate());
+    assertTrue(childAttr2.isMandatory());
+    assertTrue(childAttr2.isNonEmpty());
+
+    //Check if the parent attribute is unchanged
+    assertFalse(parentAttr.isNonEmpty());
+    assertEquals(Predicates.alwaysTrue(), parentAttr.getAllowedRuleClassesPredicate());
+  }
+
+  /**
+   * Tests that configurability settings are properly received.
+   */
+  @Test
+  public void testConfigurability() {
+    assertTrue(attr("foo_configurable", Type.LABEL_LIST).legacyAllowAnyFileType().build()
+        .isConfigurable());
+    assertFalse(attr("foo_nonconfigurable", Type.LABEL_LIST).legacyAllowAnyFileType()
+        .nonconfigurable("test").build().isConfigurable());
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/ExportsFilesTest.java b/src/test/java/com/google/devtools/build/lib/packages/ExportsFilesTest.java
new file mode 100644
index 0000000..c5f5c79
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/ExportsFilesTest.java
@@ -0,0 +1,103 @@
+// Copyright 2006-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Joiner;
+import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
+import com.google.devtools.build.lib.packages.util.PackageFactoryApparatus;
+import com.google.devtools.build.lib.testutil.Scratch;
+import com.google.devtools.build.lib.vfs.Path;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A test for the {@code exports_files} function defined in
+ * {@link PackageFactory}.
+ */
+@RunWith(JUnit4.class)
+public class ExportsFilesTest {
+
+  private Scratch scratch = new Scratch("/workspace");
+  private EventCollectionApparatus events = new EventCollectionApparatus();
+  private PackageFactoryApparatus packages = new PackageFactoryApparatus(events, scratch);
+
+  private Package pkg() throws Exception {
+    Path buildFile = scratch.file("pkg/BUILD",
+                                  "exports_files(['foo.txt', 'bar.txt'])");
+    return packages.createPackage("pkg", buildFile);
+  }
+
+  @Test
+  public void testExportsFilesRegistersFilesWithPackage() throws Exception {
+    List<String> names = getFileNamesOf(pkg());
+    String expected = "//pkg:BUILD //pkg:bar.txt //pkg:foo.txt";
+    assertEquals(expected, Joiner.on(' ').join(names));
+  }
+
+  /**
+   * Returns the names of the input files that are known to pkg.
+   */
+  private static List<String> getFileNamesOf(Package pkg) {
+    List<String> names = new ArrayList<>();
+    for (FileTarget target : pkg.getTargets(FileTarget.class)) {
+      names.add(target.getLabel().toString());
+    }
+    Collections.sort(names);
+    return names;
+  }
+
+  @Test
+  public void testFileThatsNotRegisteredYieldsUnknownTargetException() throws Exception {
+    try {
+      pkg().getTarget("baz.txt");
+      fail();
+    } catch (NoSuchTargetException e) {
+      assertThat(e).hasMessage("no such target '//pkg:baz.txt':"
+          + " target 'baz.txt' not declared in package 'pkg' defined by /workspace/pkg/BUILD");
+    }
+  }
+
+  @Test
+  public void testRegisteredFilesAreRetrievable() throws Exception {
+    Package pkg = pkg();
+    assertEquals("foo.txt", pkg.getTarget("foo.txt").getName());
+    assertEquals("bar.txt", pkg.getTarget("bar.txt").getName());
+  }
+
+  @Test
+  public void testExportsFilesAndRuleNameConflict() throws Exception {
+    events.setFailFast(false);
+
+    Path buildFile = scratch.file("pkg2/BUILD",
+        "exports_files(['foo'])",
+        "genrule(name = 'foo', srcs = ['bar'], outs = [],",
+        "        cmd = '/bin/true')");
+    Package pkg = packages.createPackage("pkg2", buildFile);
+    events.assertContainsEvent("rule 'foo' in package 'pkg2' conflicts with "
+                               + "existing source file");
+    assertTrue(pkg.getTarget("foo") instanceof InputFile);
+  }
+
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java b/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java
new file mode 100644
index 0000000..bd8d536
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java
@@ -0,0 +1,254 @@
+// Copyright 2008-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.devtools.build.lib.packages.GlobCache.BadGlobException;
+import com.google.devtools.build.lib.testutil.Scratch;
+import com.google.devtools.build.lib.testutil.TestUtils;
+import com.google.devtools.build.lib.util.Pair;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import com.google.devtools.build.lib.vfs.Path;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests for {@link GlobCache}
+ */
+@RunWith(JUnit4.class)
+public class GlobCacheTest {
+
+  private static final List<String> NONE = Collections.emptyList();
+
+  private Scratch scratch = new Scratch("/workspace");
+
+  private Path packageDirectory;
+  private Path buildFile;
+  private GlobCache cache;
+
+  @Before
+  public void setUp() throws Exception {
+    buildFile = scratch.file("isolated/BUILD",
+        "# contents don't matter in this test");
+    scratch.file("isolated/sub/BUILD",
+        "# contents don't matter in this test");
+
+    packageDirectory = buildFile.getParentDirectory();
+
+    scratch.file("isolated/first.txt",
+        "# this is first.txt");
+
+    scratch.file("isolated/second.txt",
+        "# this is second.txt");
+
+    scratch.file("isolated/first.js",
+        "# this is first.js");
+
+    scratch.file("isolated/second.js",
+        "# this is second.js");
+
+    // Files in subdirectories
+
+    scratch.file("isolated/foo/first.js",
+        "# this is foo/first.js");
+
+    scratch.file("isolated/foo/second.js",
+        "# this is foo/second.js");
+
+    scratch.file("isolated/bar/first.js",
+        "# this is bar/first.js");
+
+    scratch.file("isolated/bar/second.js",
+        "# this is bar/second.js");
+
+    scratch.file("isolated/sub/sub.js",
+        "# this is sub/sub.js");
+
+    cache = new GlobCache(packageDirectory, PackageIdentifier.createInDefaultRepo("isolated"),
+        new CachingPackageLocator() {
+      @Override
+      public Path getBuildFileForPackage(String packageName) {
+        if (packageName.equals("isolated")) {
+          return scratch.resolve("isolated/BUILD");
+        } else if (packageName.equals("isolated/sub")) {
+          return scratch.resolve("isolated/sub/BUILD");
+        } else {
+          return null;
+        }
+      }
+    }, null, TestUtils.getPool());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    FileSystemUtils.deleteTreesBelow(scratch.getFileSystem().getRootDirectory());
+  }
+
+  @Test
+  public void testSafeGlob() throws Exception {
+    List<Path> paths = cache.safeGlob("*.js", false).get();
+    assertPathsAre(paths,
+        "/workspace/isolated/first.js", "/workspace/isolated/second.js");
+  }
+
+  @Test
+  public void testSafeGlobInvalidPatterns() throws Exception {
+    for (String pattern : new String[] {
+        "Foo?.txt", "List{Test}.py", "List(Test).py" }) {
+      try {
+        cache.safeGlob(pattern, false);
+        fail("Expected pattern " + pattern + " to fail");
+      } catch (BadGlobException expected) {
+      }
+    }
+  }
+
+  @Test
+  public void testGetGlob() throws Exception {
+    List<String> glob = cache.getGlob("*.js");
+    assertThat(glob).containsExactly("first.js", "second.js");
+  }
+
+  @Test
+  public void testGetGlob_subdirectory() throws Exception {
+    List<String> glob = cache.getGlob("foo/*.js");
+    assertThat(glob).containsExactly("foo/first.js", "foo/second.js");
+  }
+
+  @Test
+  public void testGetKeySet() throws Exception {
+    assertThat(cache.getKeySet()).isEmpty();
+
+    cache.getGlob("*.java");
+    assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false));
+
+    cache.getGlob("*.java");
+    assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false));
+
+    cache.getGlob("*.js");
+    assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false));
+
+    cache.getGlob("*.java", true);
+    assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false),
+        Pair.of("*.java", true));
+
+    try {
+      cache.getGlob("invalid?");
+      fail("Expected an invalid regex exception");
+    } catch (BadGlobException expected) {
+    }
+    assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false),
+        Pair.of("*.java", true));
+
+    cache.getGlob("foo/first.*");
+    assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.java", true),
+        Pair.of("*.js", false), Pair.of("foo/first.*", false));
+  }
+
+  @Test
+  public void testGlob() throws Exception {
+    assertEmpty(cache.glob(list("*.java"), NONE, false));
+
+    assertThat(cache.glob(list("*.*"), NONE, false)).containsExactly("first.js", "first.txt",
+        "second.js", "second.txt").inOrder();
+
+    assertThat(cache.glob(list("*.*"), list("first.js"), false)).containsExactly("first.txt",
+        "second.js", "second.txt").inOrder();
+
+    assertThat(cache.glob(list("*.txt", "first.*"), NONE, false)).containsExactly("first.txt",
+        "second.txt", "first.js").inOrder();
+  }
+
+  @Test
+  public void testSetGlobPaths() throws Exception {
+    // This pattern matches no files.
+    String pattern = "fake*.java";
+    assertThat(cache.getKeySet()).doesNotContain(pattern);
+
+    List<String> results = cache.getGlob(pattern, false);
+
+    assertThat(cache.getKeySet()).contains(Pair.of(pattern, false));
+    assertThat(results).isEmpty();
+
+    cache.setGlobPaths(pattern, false, Futures.<List<Path>>immediateFuture(Lists.newArrayList(
+        scratch.resolve("isolated/fake.txt"),
+        scratch.resolve("isolated/fake.py"))));
+
+    assertThat(cache.getGlob(pattern, false)).containsExactly("fake.py", "fake.txt");
+  }
+
+  @Test
+  public void testGlobsUpToDate() throws Exception {
+    assertTrue(cache.globsUpToDate());
+
+    // Initialize the cache
+    cache.getGlob("*.txt");
+    assertTrue(cache.globsUpToDate());
+
+    cache.getGlob("*.js");
+    assertTrue(cache.globsUpToDate());
+
+    // Change the filesystem
+    scratch.file("isolated/third.txt",
+        "# this is third.txt");
+    assertFalse(cache.globsUpToDate());
+
+    // Fool the cache to observe the method's behavior.
+    cache.setGlobPaths("*.txt", false, Futures.<List<Path>>immediateFuture(Lists.newArrayList(
+        scratch.resolve("isolated/first.txt"),
+        scratch.resolve("isolated/second.txt"),
+        scratch.resolve("isolated/third.txt"))));
+    assertTrue(cache.globsUpToDate());
+  }
+
+  @Test
+  public void testRecursiveGlobDoesNotMatchSubpackage() throws Exception {
+    List<String> glob = cache.getGlob("**/*.js");
+    assertThat(glob).containsExactly("first.js", "second.js", "foo/first.js", "bar/first.js",
+        "foo/second.js", "bar/second.js");
+  }
+
+  private void assertEmpty(Collection<?> glob) {
+    assertThat(glob).isEmpty();
+  }
+
+  private void assertPathsAre(List<Path> paths, String... strings) {
+    List<String> pathStrings = new ArrayList<>();
+    for (Path path : paths) {
+      pathStrings.add(path.getPathString());
+    }
+    assertThat(pathStrings).containsExactlyElementsIn(Arrays.asList(strings));
+  }
+
+  /* syntactic shorthand for Lists.newArrayList(strings) */
+  private List<String> list(String... strings) {
+    return Lists.newArrayList(strings);
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
new file mode 100644
index 0000000..7eb0ed4
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
@@ -0,0 +1,830 @@
+// Copyright 2006-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.substitutePlaceholderIntoTemplate;
+import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
+import static com.google.devtools.build.lib.packages.Type.INTEGER;
+import static com.google.devtools.build.lib.packages.Type.LABEL;
+import static com.google.devtools.build.lib.packages.Type.LABEL_LIST;
+import static com.google.devtools.build.lib.packages.Type.OUTPUT_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventCollector;
+import com.google.devtools.build.lib.events.EventKind;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.events.Location.LineAndColumn;
+import com.google.devtools.build.lib.packages.Attribute.ValidityPredicate;
+import com.google.devtools.build.lib.packages.Package.Builder;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
+import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase;
+import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.syntax.Label.SyntaxException;
+import com.google.devtools.build.lib.vfs.Path;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for {@link RuleClass}.
+ */
+public class RuleClassTest extends PackageLoadingTestCase {
+  private static final RuleClass.ConfiguredTargetFactory<Object, Object>
+      DUMMY_CONFIGURED_TARGET_FACTORY = new RuleClass.ConfiguredTargetFactory<Object, Object>() {
+        @Override
+        public Object create(Object ruleContext) throws InterruptedException {
+          throw new IllegalStateException();
+        }
+  };
+
+  private static final class DummyFragment extends BuildConfiguration.Fragment {
+    @Override
+    public String getName() {
+      return "dummy-for-testing";
+    }
+
+    @Override
+    public String cacheKey() {
+      return "some cache key";
+    }
+  }
+
+  private static final Predicate<String> PREFERRED_DEPENDENCY_PREDICATE = Predicates.alwaysFalse();
+
+  private static RuleClass createRuleClassA() throws Label.SyntaxException {
+    return new RuleClass("ruleA", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE,
+        DUMMY_CONFIGURED_TARGET_FACTORY, PredicatesWithMessage.<Rule>alwaysTrue(),
+        PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), null, null,
+        ImmutableSet.<Class<?>>of(), false, true,
+        attr("my-string-attr", STRING).mandatory().build(),
+        attr("my-label-attr", LABEL).mandatory().legacyAllowAnyFileType()
+            .value(Label.parseAbsolute("//default:label")).build(),
+        attr("my-labellist-attr", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
+        attr("my-integer-attr", INTEGER).value(42).build(),
+        attr("my-string-attr2", STRING).mandatory().value((String) null).build(),
+        attr("my-stringlist-attr", STRING_LIST).build(),
+        attr("my-sorted-stringlist-attr", STRING_LIST).orderIndependent().build());
+  }
+
+  private static RuleClass createRuleClassB(RuleClass ruleClassA) {
+    // emulates attribute inheritance
+    List<Attribute> attributes = new ArrayList<>(ruleClassA.getAttributes());
+    attributes.add(attr("another-string-attr", STRING).mandatory().build());
+    return new RuleClass("ruleB", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attributes.toArray(new Attribute[0]));
+  }
+
+  public void testRuleClassBasics() throws Exception {
+    RuleClass ruleClassA = createRuleClassA();
+
+    assertEquals("ruleA", ruleClassA.getName());
+    assertEquals(7, ruleClassA.getAttributeCount());
+
+    assertEquals(0, (int) ruleClassA.getAttributeIndex("my-string-attr"));
+    assertEquals(1, (int) ruleClassA.getAttributeIndex("my-label-attr"));
+    assertEquals(2, (int) ruleClassA.getAttributeIndex("my-labellist-attr"));
+    assertEquals(3, (int) ruleClassA.getAttributeIndex("my-integer-attr"));
+    assertEquals(4, (int) ruleClassA.getAttributeIndex("my-string-attr2"));
+    assertEquals(5, (int) ruleClassA.getAttributeIndex("my-stringlist-attr"));
+    assertEquals(6, (int) ruleClassA.getAttributeIndex("my-sorted-stringlist-attr"));
+
+    assertEquals(ruleClassA.getAttribute(0),
+                 ruleClassA.getAttributeByName("my-string-attr"));
+    assertEquals(ruleClassA.getAttribute(1),
+                 ruleClassA.getAttributeByName("my-label-attr"));
+    assertEquals(ruleClassA.getAttribute(2),
+                 ruleClassA.getAttributeByName("my-labellist-attr"));
+    assertEquals(ruleClassA.getAttribute(3),
+                 ruleClassA.getAttributeByName("my-integer-attr"));
+    assertEquals(ruleClassA.getAttribute(4),
+                 ruleClassA.getAttributeByName("my-string-attr2"));
+    assertEquals(ruleClassA.getAttribute(5),
+                 ruleClassA.getAttributeByName("my-stringlist-attr"));
+    assertEquals(ruleClassA.getAttribute(6),
+                 ruleClassA.getAttributeByName("my-sorted-stringlist-attr"));
+
+    assertEquals("", // default based on type
+                 ruleClassA.getAttribute(0).getDefaultValue(null));
+    assertEquals(Label.parseAbsolute("//default:label"),
+                 ruleClassA.getAttribute(1).getDefaultValue(null));
+    assertEquals(Collections.emptyList(),
+                 ruleClassA.getAttribute(2).getDefaultValue(null));
+    assertEquals(42,
+                 ruleClassA.getAttribute(3).getDefaultValue(null));
+    assertEquals(null, // default explicitly specified
+                 ruleClassA.getAttribute(4).getDefaultValue(null));
+    assertEquals(Collections.emptyList(),
+                 ruleClassA.getAttribute(5).getDefaultValue(null));
+    assertEquals(Collections.emptyList(),
+                 ruleClassA.getAttribute(6).getDefaultValue(null));
+  }
+
+  public void testRuleClassInheritance() throws Exception {
+    RuleClass ruleClassA = createRuleClassA();
+    RuleClass ruleClassB = createRuleClassB(ruleClassA);
+
+    assertEquals("ruleB", ruleClassB.getName());
+    assertEquals(8, ruleClassB.getAttributeCount());
+
+    assertEquals(0, (int) ruleClassB.getAttributeIndex("my-string-attr"));
+    assertEquals(1, (int) ruleClassB.getAttributeIndex("my-label-attr"));
+    assertEquals(2, (int) ruleClassB.getAttributeIndex("my-labellist-attr"));
+    assertEquals(3, (int) ruleClassB.getAttributeIndex("my-integer-attr"));
+    assertEquals(4, (int) ruleClassB.getAttributeIndex("my-string-attr2"));
+    assertEquals(5, (int) ruleClassB.getAttributeIndex("my-stringlist-attr"));
+    assertEquals(6, (int) ruleClassB.getAttributeIndex("my-sorted-stringlist-attr"));
+    assertEquals(7, (int) ruleClassB.getAttributeIndex("another-string-attr"));
+
+    assertEquals(ruleClassB.getAttribute(0),
+                 ruleClassB.getAttributeByName("my-string-attr"));
+    assertEquals(ruleClassB.getAttribute(1),
+                 ruleClassB.getAttributeByName("my-label-attr"));
+    assertEquals(ruleClassB.getAttribute(2),
+                 ruleClassB.getAttributeByName("my-labellist-attr"));
+    assertEquals(ruleClassB.getAttribute(3),
+                 ruleClassB.getAttributeByName("my-integer-attr"));
+    assertEquals(ruleClassB.getAttribute(4),
+                 ruleClassB.getAttributeByName("my-string-attr2"));
+    assertEquals(ruleClassB.getAttribute(5),
+                 ruleClassB.getAttributeByName("my-stringlist-attr"));
+    assertEquals(ruleClassB.getAttribute(6),
+                 ruleClassB.getAttributeByName("my-sorted-stringlist-attr"));
+    assertEquals(ruleClassB.getAttribute(7),
+                 ruleClassB.getAttributeByName("another-string-attr"));
+  }
+
+  private static final String TEST_PACKAGE_NAME = "testpackage";
+
+  private static final String TEST_RULE_NAME = "my-rule-A";
+
+  private static final int TEST_RULE_DEFINED_AT_LINE = 42;
+
+  private static final String TEST_RULE_LABEL = "//" + TEST_PACKAGE_NAME + ":" + TEST_RULE_NAME;
+
+  private Path testBuildfilePath;
+  private Location testRuleLocation;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    testBuildfilePath = scratch.resolve("/home/user/workspace/testpackage/BUILD");
+    testRuleLocation = Location.fromPathAndStartColumn(
+        testBuildfilePath, 0, 0, new LineAndColumn(TEST_RULE_DEFINED_AT_LINE, 0));
+  }
+
+  private Package.Builder createDummyPackageBuilder() {
+    return new Builder(PackageIdentifier.createInDefaultRepo(TEST_PACKAGE_NAME))
+        .setFilename(testBuildfilePath)
+        .setMakeEnv(new MakeEnvironment.Builder());
+  }
+
+  public void testDuplicatedDeps() throws Exception {
+    RuleClass depsRuleClass = new RuleClass("ruleDeps", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attr("list1", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
+        attr("list2", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
+        attr("list3", LABEL_LIST).mandatory().legacyAllowAnyFileType().build());
+
+    // LinkedHashMap -> predictable iteration order for testing
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    attributeValues.put("list1", Lists.newArrayList("//testpackage:dup1", ":dup1", ":nodup"));
+    attributeValues.put("list2", Lists.newArrayList(":nodup1", ":nodup2"));
+    attributeValues.put("list3", Lists.newArrayList(":dup1", ":dup1", ":dup2", ":dup2"));
+
+    reporter.removeHandler(failFastHandler);
+    createRule(depsRuleClass, "depsRule", attributeValues, testRuleLocation);
+
+    assertSame(3, eventCollector.count());
+    assertDupError("//testpackage:dup1", "list1", "depsRule");
+    assertDupError("//testpackage:dup1", "list3", "depsRule");
+    assertDupError("//testpackage:dup2", "list3", "depsRule");
+  }
+
+  private void assertDupError(String label, String attrName, String ruleName) {
+    assertContainsEvent(String.format("Label '%s' is duplicated in the '%s' attribute of rule '%s'",
+        label, attrName, ruleName));
+  }
+
+  public void testCreateRuleWithLegacyPublicVisibility() throws Exception {
+    RuleClass ruleClass = new RuleClass("ruleVis", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attr("visibility", LABEL_LIST).legacyAllowAnyFileType().build());
+    Map<String, Object> attributeValues = new HashMap<>();
+    attributeValues.put("visibility", Arrays.asList("//visibility:legacy_public"));
+
+    reporter.removeHandler(failFastHandler);
+    EventCollector collector = new EventCollector(EventKind.ERRORS);
+    reporter.addHandler(collector);
+
+    createRule(ruleClass, TEST_RULE_NAME, attributeValues, testRuleLocation);
+
+    assertContainsEvent("//visibility:legacy_public only allowed in package declaration");
+  }
+
+  public void testCreateRule() throws Exception {
+    RuleClass ruleClassA = createRuleClassA();
+
+    // LinkedHashMap -> predictable iteration order for testing
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    attributeValues.put("my-labellist-attr", "foobar"); // wrong type
+    attributeValues.put("bogus-attr", "foobar"); // no such attr
+    attributeValues.put("my-stringlist-attr", Arrays.asList("foo", "bar"));
+
+    reporter.removeHandler(failFastHandler);
+    EventCollector collector = new EventCollector(EventKind.ERRORS);
+    reporter.addHandler(collector);
+
+    Rule rule = createRule(ruleClassA, TEST_RULE_NAME, attributeValues, testRuleLocation);
+
+    // TODO(blaze-team): (2009) refactor to use assertContainsEvent
+    Iterator<String> expectedMessages = Arrays.asList(
+        "expected value of type 'list(label)' for attribute 'my-labellist-attr' "
+        + "in 'ruleA' rule, but got 'foobar' (string)",
+        "no such attribute 'bogus-attr' in 'ruleA' rule",
+        "missing value for mandatory "
+        + "attribute 'my-string-attr' in 'ruleA' rule",
+        "missing value for mandatory attribute 'my-label-attr' in 'ruleA' rule",
+        "missing value for mandatory "
+        + "attribute 'my-labellist-attr' in 'ruleA' rule",
+        "missing value for mandatory "
+        + "attribute 'my-string-attr2' in 'ruleA' rule"
+    ).iterator();
+
+    for (Event event : collector) {
+      assertEquals(TEST_RULE_DEFINED_AT_LINE,
+          event.getLocation().getStartLineAndColumn().getLine());
+      assertEquals(testBuildfilePath.asFragment(), event.getLocation().getPath());
+      assertEquals(TEST_RULE_LABEL + ": " + expectedMessages.next(), event.getMessage());
+    }
+
+    // Test basic rule properties:
+    assertEquals("ruleA",
+                 rule.getRuleClass());
+    assertEquals(TEST_RULE_NAME,
+                 rule.getName());
+    assertEquals(TEST_RULE_LABEL,
+                 rule.getLabel().toString());
+
+    // Test attribute access:
+    AttributeMap attributes = RawAttributeMapper.of(rule);
+    assertEquals("//default:label",
+                 attributes.get("my-label-attr", Type.LABEL).toString());
+    assertEquals(42,
+                 attributes.get("my-integer-attr", Type.INTEGER).intValue());
+    assertEquals("",  // missing attribute -> default chosen based on type
+                 attributes.get("my-string-attr", Type.STRING));
+    assertThat(attributes.get("my-labellist-attr", Type.LABEL_LIST)).isEmpty();
+    assertEquals(Arrays.asList("foo", "bar"),
+                 attributes.get("my-stringlist-attr", Type.STRING_LIST));
+    try {
+      attributes.get("my-labellist-attr", Type.STRING); // wrong type
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Attribute my-labellist-attr is not of type string "
+          + "in rule //testpackage:my-rule-A");
+    }
+  }
+
+  public void testImplicitOutputs() throws Exception {
+    RuleClass ruleClassC = new RuleClass("ruleC", false, false, false, false, false, false,
+        ImplicitOutputsFunction.fromTemplates("foo-%{name}.bar",
+                                              "lib%{name}-wazoo-%{name}.mumble",
+                                              "stuff-%{outs}-bar"),
+        RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attr("outs", OUTPUT_LIST).build());
+
+    Map<String, Object> attributeValues = new HashMap<>();
+    attributeValues.put("outs", Collections.singletonList("explicit_out"));
+
+    Rule rule = createRule(ruleClassC, "myrule", attributeValues, testRuleLocation);
+
+    Set<String> set = new HashSet<>();
+    for (OutputFile outputFile : rule.getOutputFiles()) {
+      set.add(outputFile.getName());
+      assertSame(rule, outputFile.getGeneratingRule());
+    }
+    assertThat(set).containsExactly("foo-myrule.bar", "libmyrule-wazoo-myrule.mumble",
+        "stuff-explicit_out-bar", "explicit_out");
+  }
+
+  public void testImplicitOutsWithBasenameDirname() throws Exception {
+    RuleClass ruleClass = new RuleClass("ruleClass", false, false, false, false, false, false,
+        ImplicitOutputsFunction.fromTemplates("%{dirname}lib%{basename}.bar"), RuleClass.NO_CHANGE,
+        DUMMY_CONFIGURED_TARGET_FACTORY, PredicatesWithMessage.<Rule>alwaysTrue(),
+        PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), null, null,
+        ImmutableSet.<Class<?>>of(), false, true);
+
+    Rule rule = createRule(ruleClass, "myRule", Collections.<String, Object>emptyMap(),
+        testRuleLocation);
+    assertEquals("libmyRule.bar", Iterables.getOnlyElement(rule.getOutputFiles()).getName());
+
+    Rule ruleWithSlash = createRule(ruleClass, "myRule/with/slash",
+        Collections.<String, Object>emptyMap(), testRuleLocation);
+    assertEquals("myRule/with/libslash.bar",
+                 Iterables.getOnlyElement(ruleWithSlash.getOutputFiles()).getName());
+  }
+
+  /**
+   * Helper routine that instantiates a rule class with the given computed default and supporting
+   * attributes for the default to reference.
+   */
+  private static RuleClass getRuleClassWithComputedDefault(Attribute computedDefault) {
+    return new RuleClass("ruleClass", false, false, false, false, false, false,
+        ImplicitOutputsFunction.fromTemplates("empty"), RuleClass.NO_CHANGE,
+        DUMMY_CONFIGURED_TARGET_FACTORY, PredicatesWithMessage.<Rule>alwaysTrue(),
+        PREFERRED_DEPENDENCY_PREDICATE, ImmutableSet.<Class<?>>of(), null, null,
+        ImmutableSet.<Class<?>>of(), false, true,
+        attr("condition", BOOLEAN).value(false).build(),
+        attr("declared1", BOOLEAN).value(false).build(),
+        attr("declared2", BOOLEAN).value(false).build(),
+        attr("nonconfigurable", BOOLEAN).nonconfigurable("test").value(false).build(),
+        computedDefault);
+  }
+
+  /**
+   * Helper routine that checks that a computed default is valid and bound to the expected value.
+   */
+  private void checkValidComputedDefault(Object expectedValue, Attribute computedDefault,
+      ImmutableMap<String, Object> attrValueMap) throws Exception {
+    assertTrue(computedDefault.getDefaultValueForTesting() instanceof Attribute.ComputedDefault);
+    Rule rule = createRule(getRuleClassWithComputedDefault(computedDefault), "myRule",
+        attrValueMap, testRuleLocation);
+    AttributeMap attributes = RawAttributeMapper.of(rule);
+    assertEquals(
+        expectedValue,
+        attributes.get(computedDefault.getName(), computedDefault.getType()));
+  }
+
+  /**
+   * Helper routine that checks that a computed default is invalid due to declared dependency
+   * issues and fails with the expected message.
+   */
+  private void checkInvalidComputedDefault(Attribute computedDefault, String expectedMessage)
+      throws Exception {
+    try {
+      createRule(getRuleClassWithComputedDefault(computedDefault), "myRule",
+              ImmutableMap.<String, Object>of(), testRuleLocation);
+      fail("Expected computed default \"" + computedDefault.getName() + "\" to fail with "
+          + "declaration errors");
+    } catch (IllegalArgumentException e) {
+      // Expected outcome.
+      assertThat(e).hasMessage(expectedMessage);
+    }
+  }
+
+  /**
+   * Tests computed default values are computed as expected.
+   */
+  public void testComputedDefault() throws Exception {
+    Attribute computedDefault =
+        attr("$result", BOOLEAN).value(new Attribute.ComputedDefault("condition") {
+          @Override
+          public Object getDefault(AttributeMap rule) {
+            return rule.get("condition", Type.BOOLEAN);
+          }
+        }).build();
+
+    checkValidComputedDefault(Boolean.FALSE, computedDefault,
+        ImmutableMap.<String, Object>of("condition", Boolean.FALSE));
+    checkValidComputedDefault(Boolean.TRUE, computedDefault,
+        ImmutableMap.<String, Object>of("condition", Boolean.TRUE));
+  }
+
+  /**
+   * Tests that computed defaults can only read attribute values for configurable attributes that
+   * have been explicitly declared.
+   */
+  public void testComputedDefaultDeclarations() throws Exception {
+    checkValidComputedDefault(
+        Boolean.FALSE,
+        attr("$good_default_no_declares", BOOLEAN).value(
+            new Attribute.ComputedDefault() {
+              @Override public Object getDefault(AttributeMap rule) {
+                // OK: not a value check:
+                return rule.isAttributeValueExplicitlySpecified("undeclared");
+              }
+        }).build(),
+        ImmutableMap.<String, Object>of());
+
+    checkValidComputedDefault(
+        Boolean.FALSE,
+        attr("$good_default_one_declare", BOOLEAN).value(
+            new Attribute.ComputedDefault("declared1") {
+              @Override public Object getDefault(AttributeMap rule) {
+                return rule.get("declared1", Type.BOOLEAN);
+              }
+        }).build(),
+        ImmutableMap.<String, Object>of());
+
+    checkValidComputedDefault(
+        Boolean.FALSE,
+        attr("$good_default_two_declares", BOOLEAN).value(
+            new Attribute.ComputedDefault("declared1", "declared2") {
+              @Override public Object getDefault(AttributeMap rule) {
+                return rule.get("declared1", Type.BOOLEAN) && rule.get("declared2", Type.BOOLEAN);
+              }
+        }).build(),
+        ImmutableMap.<String, Object>of());
+
+    checkInvalidComputedDefault(
+        attr("$bad_default_no_declares", BOOLEAN).value(
+            new Attribute.ComputedDefault() {
+              @Override public Object getDefault(AttributeMap rule) {
+                return rule.get("declared1", Type.BOOLEAN);
+              }
+        }).build(),
+        "attribute \"declared1\" isn't available in this computed default context");
+
+    checkInvalidComputedDefault(
+        attr("$bad_default_one_declare", BOOLEAN).value(
+            new Attribute.ComputedDefault("declared1") {
+              @Override public Object getDefault(AttributeMap rule) {
+                return rule.get("declared1", Type.BOOLEAN) || rule.get("declared2", Type.BOOLEAN);
+              }
+        }).build(),
+        "attribute \"declared2\" isn't available in this computed default context");
+
+    checkInvalidComputedDefault(
+        attr("$bad_default_two_declares", BOOLEAN).value(
+            new Attribute.ComputedDefault("declared1", "declared2") {
+              @Override public Object getDefault(AttributeMap rule) {
+                return rule.get("condition", Type.BOOLEAN);
+              }
+        }).build(),
+        "attribute \"condition\" isn't available in this computed default context");
+  }
+
+  /**
+   * Tests that computed defaults *can* read attribute values for non-configurable attributes
+   * without needing to explicitly declare them.
+   */
+  public void testComputedDefaultWithNonConfigurableAttributes() throws Exception {
+    checkValidComputedDefault(
+        Boolean.FALSE,
+        attr("$good_default_reading_undeclared_nonconfigurable_attribute", BOOLEAN).value(
+            new Attribute.ComputedDefault() {
+              @Override public Object getDefault(AttributeMap rule) {
+                return rule.get("nonconfigurable", Type.BOOLEAN);
+              }
+        }).build(),
+        ImmutableMap.<String, Object>of());
+  }
+
+  public void testOutputsAreOrdered() throws Exception {
+    RuleClass ruleClassC = new RuleClass("ruleC", false, false, false, false, false, false,
+        ImplicitOutputsFunction.fromTemplates("first-%{name}", "second-%{name}", "out-%{outs}"),
+        RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attr("outs", OUTPUT_LIST).build());
+
+    Map<String, Object> attributeValues = new HashMap<>();
+    attributeValues.put("outs", ImmutableList.of("third", "fourth"));
+
+    Rule rule = createRule(ruleClassC, "myrule", attributeValues, testRuleLocation);
+
+    List<String> actual = new ArrayList<>();
+    for (OutputFile outputFile : rule.getOutputFiles()) {
+      actual.add(outputFile.getName());
+      assertSame(rule, outputFile.getGeneratingRule());
+    }
+    assertWithMessage("unexpected output set").that(actual).containsExactly("first-myrule",
+        "second-myrule", "out-third", "out-fourth", "third", "fourth");
+    assertWithMessage("invalid output ordering").that(actual).containsExactly("first-myrule",
+        "second-myrule", "out-third", "out-fourth", "third", "fourth").inOrder();
+  }
+
+  public void testSubstitutePlaceholderIntoTemplate() throws Exception {
+    RuleClass ruleClass = new RuleClass("ruleA", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attr("a", STRING_LIST).mandatory().build(),
+        attr("b", STRING_LIST).mandatory().build(),
+        attr("c", STRING_LIST).mandatory().build(),
+        attr("baz", STRING_LIST).mandatory().build(),
+        attr("empty", STRING_LIST).build());
+
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    attributeValues.put("a", ImmutableList.of("a", "A"));
+    attributeValues.put("b", ImmutableList.of("b", "B"));
+    attributeValues.put("c", ImmutableList.of("c", "C"));
+    attributeValues.put("baz", ImmutableList.of("baz", "BAZ"));
+    attributeValues.put("empty", ImmutableList.<String>of());
+
+    AttributeMap rule = RawAttributeMapper.of(
+        createRule(ruleClass, "testrule", attributeValues, testRuleLocation));
+
+    assertThat(substitutePlaceholderIntoTemplate("foo", rule)).containsExactly("foo");
+    assertThat(substitutePlaceholderIntoTemplate("foo-%{baz}-bar", rule)).containsExactly(
+        "foo-baz-bar", "foo-BAZ-bar").inOrder();
+    assertThat(substitutePlaceholderIntoTemplate("%{a}-%{b}-%{c}", rule)).containsExactly("a-b-c",
+        "a-b-C", "a-B-c", "a-B-C", "A-b-c", "A-b-C", "A-B-c", "A-B-C").inOrder();
+    assertThat(substitutePlaceholderIntoTemplate("%{a", rule)).containsExactly("%{a");
+    assertThat(substitutePlaceholderIntoTemplate("%{a}}", rule)).containsExactly("a}", "A}")
+        .inOrder();
+    assertThat(substitutePlaceholderIntoTemplate("x%{a}y%{empty}", rule)).isEmpty();
+  }
+
+  public void testOrderIndependentAttribute() throws Exception {
+    RuleClass ruleClassA = createRuleClassA();
+
+    List<String> list = Arrays.asList("foo", "bar", "baz");
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    // mandatory values
+    attributeValues.put("my-string-attr", "");
+    attributeValues.put("my-label-attr", "//project");
+    attributeValues.put("my-string-attr2", "");
+    attributeValues.put("my-labellist-attr", Collections.emptyList());
+    // to compare the effect of .orderIndependent()
+    attributeValues.put("my-stringlist-attr", list);
+    attributeValues.put("my-sorted-stringlist-attr", list);
+
+    Rule rule = createRule(ruleClassA, "testrule", attributeValues, testRuleLocation);
+    AttributeMap attributes = RawAttributeMapper.of(rule);
+
+    assertEquals(list,
+                 attributes.get("my-stringlist-attr", Type.STRING_LIST));
+    assertEquals(Arrays.asList("bar", "baz", "foo"),
+                 attributes.get("my-sorted-stringlist-attr", Type.STRING_LIST));
+  }
+
+  public void testNonEmptyGood() throws Exception {
+    RuleClass mneRuleClass = setupNonEmpty(
+        attr("list1", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
+        attr("list2", LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build(),
+        attr("list3", STRING_LIST).nonEmpty().build());
+
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    attributeValues.put("list1", Lists.newArrayList());
+    attributeValues.put("list2", Lists.newArrayList(":nodup1", ":nodup2"));
+    attributeValues.put("list3", Lists.newArrayList("val1", "val2"));
+
+    createRule(mneRuleClass, "ruleTestMNE", attributeValues, testRuleLocation);
+  }
+
+  public void testNonEmptyFail() throws Exception {
+    RuleClass mandNonEmptyRuleClass = setupNonEmpty(
+        attr("list", LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build());
+
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    attributeValues.put("list", Lists.newArrayList());
+
+    reporter.removeHandler(failFastHandler);
+    createRule(mandNonEmptyRuleClass, "ruleTestMNE", attributeValues, testRuleLocation);
+
+    assertSame(1, eventCollector.count());
+    assertContainsEvent(getErrorMsgNonEmptyList(
+        "list", "ruleMNE", "//testpackage:ruleTestMNE"));
+  }
+
+  private RuleClass setupNonEmpty(Attribute... attributes) {
+    RuleClass mandNonEmptyRuleClass = new RuleClass(
+        "ruleMNE", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attributes);
+    return mandNonEmptyRuleClass;
+  }
+
+  public void testNonEmptyWrongDefVal() throws Exception {
+    List<Label> emptyList = ImmutableList.of();
+    RuleClass mandNonEmptyRuleClass = new RuleClass(
+        "ruleMNE", false, false, false, false, false, false,
+        ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(), false, true,
+        attr("list", LABEL_LIST).nonEmpty().legacyAllowAnyFileType().value(emptyList).build());
+
+    Map<String, Object> attributeValues = new LinkedHashMap<>();
+    reporter.removeHandler(failFastHandler);
+    createRule(mandNonEmptyRuleClass, "ruleTestMNE", attributeValues, testRuleLocation);
+
+    assertSame(1, eventCollector.count());
+
+    assertContainsEvent(getErrorMsgNonEmptyList(
+        "list", "ruleMNE", "//testpackage:ruleTestMNE"));
+  }
+
+  private Rule createRule(RuleClass ruleClass, String name, Map<String, Object> attributeValues,
+      Location location) throws SyntaxException {
+    Package.Builder pkgBuilder = createDummyPackageBuilder();
+    Label ruleLabel;
+    try {
+      ruleLabel = pkgBuilder.createLabel(name);
+    } catch (Label.SyntaxException e) {
+      throw new IllegalArgumentException("Rule has illegal label");
+    }
+    return ruleClass.createRuleWithLabel(pkgBuilder, ruleLabel, attributeValues,
+         reporter, null, location);
+  }
+
+  public void testOverrideWithWrongType() {
+    try {
+      RuleClass parentRuleClass = createParentRuleClass();
+
+      RuleClass.Builder childRuleClassBuilder = new RuleClass.Builder(
+          "child_rule", RuleClassType.NORMAL, false, parentRuleClass);
+      childRuleClassBuilder.override(attr("attr", INTEGER));
+      fail();
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("The type of the new attribute 'int' is different from "
+          + "the original one 'string'.");
+    }
+  }
+
+  public void testOverrideWithRightType() {
+    RuleClass parentRuleClass = createParentRuleClass();
+
+    RuleClass.Builder childRuleClassBuilder = new RuleClass.Builder(
+      "child_rule", RuleClassType.NORMAL, false, parentRuleClass);
+      childRuleClassBuilder.override(attr("attr", STRING));
+  }
+
+  public void testCopyAndOverrideAttribute() throws Exception {
+    RuleClass parentRuleClass = createParentRuleClass();
+    RuleClass childRuleClass = createChildRuleClass(parentRuleClass);
+
+    Map<String, Object> parentValues = new LinkedHashMap<>();
+    Map<String, Object> childValues = new LinkedHashMap<>();
+    childValues.put("attr", "somevalue");
+    createRule(parentRuleClass, "parent_rule", parentValues, testRuleLocation);
+    createRule(childRuleClass, "child_rule", childValues, testRuleLocation);
+  }
+
+  public void testCopyAndOverrideAttributeMandatoryMissing() throws Exception {
+    RuleClass parentRuleClass = createParentRuleClass();
+    RuleClass childRuleClass = createChildRuleClass(parentRuleClass);
+
+    Map<String, Object> childValues = new LinkedHashMap<>();
+    reporter.removeHandler(failFastHandler);
+    createRule(childRuleClass, "child_rule", childValues, testRuleLocation);
+
+    assertSame(1, eventCollector.count());
+    assertContainsEvent("//testpackage:child_rule: missing value for mandatory "
+        + "attribute 'attr' in 'child_rule' rule");
+  }
+
+  public void testRequiredFragmentInheritance() throws Exception {
+    RuleClass parentRuleClass = createParentRuleClass();
+    RuleClass childRuleClass = createChildRuleClass(parentRuleClass);
+    assertThat(parentRuleClass.getRequiredConfigurationFragments())
+        .containsExactly(DummyFragment.class);
+    assertThat(childRuleClass.getRequiredConfigurationFragments())
+        .containsExactly(DummyFragment.class);
+  }
+
+  private RuleClass createParentRuleClass() {
+    RuleClass parentRuleClass = new RuleClass("parent_rule", false, false, false, false, false,
+        false, ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
+        PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
+        ImmutableSet.<Class<?>>of(), null, null, ImmutableSet.<Class<?>>of(DummyFragment.class),
+        false, true, attr("attr", STRING).build());
+    return parentRuleClass;
+  }
+
+  private RuleClass createChildRuleClass(RuleClass parentRuleClass) {
+    RuleClass.Builder childRuleClassBuilder = new RuleClass.Builder(
+        "child_rule", RuleClassType.NORMAL, false, parentRuleClass);
+    return childRuleClassBuilder.override(
+        childRuleClassBuilder
+          .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
+          .copy("attr").mandatory())
+          .add(attr("tags", STRING_LIST))
+          .build();
+  }
+
+  public void testValidityChecker() throws Exception {
+    RuleClass depClass = new RuleClass.Builder("dep", RuleClassType.NORMAL, false)
+        .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
+        .add(attr("tags", STRING_LIST))
+        .build();
+    final Rule dep1 = createRule(depClass, "dep1", Collections.<String, Object>emptyMap(),
+        testRuleLocation);
+    final Rule dep2 = createRule(depClass, "dep2", Collections.<String, Object>emptyMap(),
+        testRuleLocation);
+
+    ValidityPredicate checker = new ValidityPredicate() {
+      @Override
+      public String checkValid(Rule from, Rule to) {
+        assertEquals("top", from.getName());
+        if (to.getName().equals("dep1")) {
+          return "pear";
+        } else if (to.getName().equals("dep2")) {
+          return null;
+        } else {
+          fail("invalid dependency");
+          return null;
+        }
+      }
+    };
+
+    RuleClass topClass = new RuleClass.Builder("top", RuleClassType.NORMAL, false)
+        .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
+        .add(attr("tags", STRING_LIST))
+        .add(attr("deps", LABEL_LIST).legacyAllowAnyFileType()
+              .validityPredicate(checker))
+        .build();
+
+    Rule topRule = createRule(topClass, "top", Collections.<String, Object>emptyMap(),
+        testRuleLocation);
+
+    assertEquals("pear", topClass.getAttributeByName("deps").getValidityPredicate().checkValid(
+        topRule, dep1));
+    assertEquals(null, topClass.getAttributeByName("deps").getValidityPredicate().checkValid(
+        topRule, dep2));
+  }
+
+  /**
+   * Tests structure for making certain rules "preferential choices" for certain files
+   * under --compile_one_dependency.
+   */
+  public void testPreferredDependencyChecker() throws Exception {
+    final String cppFile = "file.cc";
+    final String textFile = "file.txt";
+
+    // Default: not preferred for anything.
+    RuleClass defaultClass = new RuleClass.Builder("defaultClass", RuleClassType.NORMAL, false)
+        .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
+        .add(attr("tags", STRING_LIST))
+        .build();
+    final Rule defaultRule = createRule(defaultClass, "defaultRule",
+        Collections.<String, Object>emptyMap(), testRuleLocation);
+    assertFalse(defaultRule.getRuleClassObject().isPreferredDependency(cppFile));
+    assertFalse(defaultRule.getRuleClassObject().isPreferredDependency(textFile));
+
+    // Make a rule that's preferred for C++ sources.
+    RuleClass cppClass = new RuleClass.Builder("cppClass", RuleClassType.NORMAL, false)
+        .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
+        .add(attr("tags", STRING_LIST))
+        .setPreferredDependencyPredicate(new Predicate<String>() {
+          @Override
+          public boolean apply(String filename) {
+            return filename.endsWith(".cc");
+          }
+        })
+        .build();
+    final Rule cppRule = createRule(cppClass, "cppRule",
+        Collections.<String, Object>emptyMap(), testRuleLocation);
+    assertTrue(cppRule.getRuleClassObject().isPreferredDependency(cppFile));
+    assertFalse(cppRule.getRuleClassObject().isPreferredDependency(textFile));
+  }
+
+  public void testBadRuleClassNames() {
+    expectError(RuleClassType.NORMAL, "8abc");
+    expectError(RuleClassType.NORMAL, "_abc");
+    expectError(RuleClassType.NORMAL, "a b");
+  }
+
+  private void expectError(RuleClassType type, String name) {
+    try {
+      type.checkName(name);
+      fail();
+    } catch (IllegalArgumentException expected) {
+      // expected
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/TestSizeTest.java b/src/test/java/com/google/devtools/build/lib/packages/TestSizeTest.java
new file mode 100644
index 0000000..af3d458
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/TestSizeTest.java
@@ -0,0 +1,70 @@
+// Copyright 2012-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests the various methods of {@link TestSize}
+ */
+@RunWith(JUnit4.class)
+public class TestSizeTest {
+
+  @Test
+  public void testBasicConversion() {
+    assertEquals(TestSize.valueOf("SMALL"), TestSize.SMALL);
+    assertEquals(TestSize.valueOf("MEDIUM"), TestSize.MEDIUM);
+    assertEquals(TestSize.valueOf("LARGE"), TestSize.LARGE);
+    assertEquals(TestSize.valueOf("ENORMOUS"), TestSize.ENORMOUS);
+  }
+
+  @Test
+  public void testGetDefaultTimeout() {
+    assertEquals(TestTimeout.SHORT, TestSize.SMALL.getDefaultTimeout());
+    assertEquals(TestTimeout.MODERATE, TestSize.MEDIUM.getDefaultTimeout());
+    assertEquals(TestTimeout.LONG, TestSize.LARGE.getDefaultTimeout());
+    assertEquals(TestTimeout.ETERNAL, TestSize.ENORMOUS.getDefaultTimeout());
+  }
+
+  @Test
+  public void testGetDefaultShards() {
+    assertEquals(2, TestSize.SMALL.getDefaultShards());
+    assertEquals(10, TestSize.MEDIUM.getDefaultShards());
+    assertEquals(20, TestSize.LARGE.getDefaultShards());
+    assertEquals(30, TestSize.ENORMOUS.getDefaultShards());
+  }
+
+  @Test
+  public void testGetTestSizeFromString() {
+    assertNull(TestSize.getTestSize("Small"));
+    assertNull(TestSize.getTestSize("Koala"));
+    assertEquals(TestSize.SMALL, TestSize.getTestSize("small"));
+    assertEquals(TestSize.MEDIUM, TestSize.getTestSize("medium"));
+    assertEquals(TestSize.LARGE, TestSize.getTestSize("large"));
+    assertEquals(TestSize.ENORMOUS, TestSize.getTestSize("enormous"));
+  }
+
+  @Test
+  public void testGetTestSizeFromDefaultTimeout() {
+    assertEquals(TestSize.SMALL, TestSize.getTestSize(TestTimeout.SHORT));
+    assertEquals(TestSize.MEDIUM, TestSize.getTestSize(TestTimeout.MODERATE));
+    assertEquals(TestSize.LARGE, TestSize.getTestSize(TestTimeout.LONG));
+    assertEquals(TestSize.ENORMOUS, TestSize.getTestSize(TestTimeout.ETERNAL));
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/TestTimeoutTest.java b/src/test/java/com/google/devtools/build/lib/packages/TestTimeoutTest.java
new file mode 100644
index 0000000..d83c1e5
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/TestTimeoutTest.java
@@ -0,0 +1,93 @@
+// Copyright 2009-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static com.google.devtools.build.lib.packages.TestTimeout.ETERNAL;
+import static com.google.devtools.build.lib.packages.TestTimeout.LONG;
+import static com.google.devtools.build.lib.packages.TestTimeout.MODERATE;
+import static com.google.devtools.build.lib.packages.TestTimeout.SHORT;
+import static com.google.devtools.build.lib.packages.TestTimeout.getSuggestedTestTimeout;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests the various methods of {@link TestTimeout}
+ */
+@RunWith(JUnit4.class)
+public class TestTimeoutTest {
+
+  @Test
+  public void testBasicConversion() throws Exception {
+    assertSame(SHORT, TestTimeout.valueOf("SHORT"));
+    assertSame(MODERATE, TestTimeout.valueOf("MODERATE"));
+    assertSame(LONG, TestTimeout.valueOf("LONG"));
+    assertSame(ETERNAL, TestTimeout.valueOf("ETERNAL"));
+  }
+
+  @Test
+  public void testSuggestedTestSize() throws Exception {
+    assertEquals(SHORT, getSuggestedTestTimeout(0));
+    assertEquals(SHORT, getSuggestedTestTimeout(2));
+    assertEquals(SHORT, getSuggestedTestTimeout(6));
+    assertEquals(SHORT, getSuggestedTestTimeout(59));
+    assertEquals(MODERATE, getSuggestedTestTimeout(60));
+    assertEquals(MODERATE, getSuggestedTestTimeout(299));
+    assertEquals(LONG, getSuggestedTestTimeout(300));
+    assertEquals(LONG, getSuggestedTestTimeout(899));
+    assertEquals(ETERNAL, getSuggestedTestTimeout(900));
+    assertEquals(ETERNAL, getSuggestedTestTimeout(1234567890));
+  }
+
+  @Test
+  public void testIsInRangeExact() throws Exception {
+    assertTrue(SHORT.isInRangeExact(0));
+    assertTrue(SHORT.isInRangeExact(1));
+    assertFalse(SHORT.isInRangeExact(60));
+    assertTrue(MODERATE.isInRangeExact(60));
+    assertTrue(MODERATE.isInRangeExact(299));
+    assertFalse(MODERATE.isInRangeExact(300));
+    assertTrue(LONG.isInRangeExact(300));
+    assertTrue(LONG.isInRangeExact(899));
+    assertFalse(LONG.isInRangeExact(900));
+    assertTrue(ETERNAL.isInRangeExact(900));
+    assertFalse(ETERNAL.isInRangeExact(1234567890));
+  }
+
+  @Test
+  public void testIsInRangeFuzzy() throws Exception {
+    assertFuzzyRange(SHORT, 0, 105);
+    assertFuzzyRange(MODERATE, 8, 525);
+    assertFuzzyRange(LONG, 75, 1575);
+    assertFuzzyRange(ETERNAL, 225, Integer.MAX_VALUE);
+  }
+
+  private void assertFuzzyRange(TestTimeout timeout, int min, int max) {
+    if (min > 0) {
+      assertFalse(timeout.isInRangeFuzzy(min - 1));
+    }
+    assertTrue(timeout.isInRangeFuzzy(min));
+    assertTrue(timeout.isInRangeFuzzy(min + 1));
+    assertTrue(timeout.isInRangeFuzzy(max - 1));
+    assertTrue(timeout.isInRangeFuzzy(max));
+    if (max < Integer.MAX_VALUE) {
+      assertFalse(timeout.isInRangeFuzzy(max + 1));
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java b/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java
new file mode 100644
index 0000000..39c5dbe
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java
@@ -0,0 +1,744 @@
+// Copyright 2006-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.testutil.MoreAsserts.assertSameContents;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.packages.Type.ConversionException;
+import com.google.devtools.build.lib.syntax.FilesetEntry;
+import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.syntax.SelectorList;
+import com.google.devtools.build.lib.syntax.SelectorValue;
+import com.google.devtools.build.lib.testutil.MoreAsserts;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Test of type-conversions using Type.
+ */
+@RunWith(JUnit4.class)
+public class TypeTest {
+
+  private Label currentRule;
+
+  @Before
+  public void setUp() throws Exception {
+    this.currentRule = Label.parseAbsolute("//quux:baz");
+  }
+
+  @Test
+  public void testInteger() throws Exception {
+    Object x = 3;
+    assertEquals(x, Type.INTEGER.convert(x, null));
+    assertThat(Type.INTEGER.getLabels(x)).isEmpty();
+  }
+
+  @Test
+  public void testNonInteger() throws Exception {
+    try {
+      Type.INTEGER.convert("foo", null);
+      fail();
+    } catch (Type.ConversionException e) {
+      // This does not use assertMessageContainsWordsWithQuotes because at least
+      // one test should test exact wording (but they all shouldn't to make
+      // changing/improving the messages easy).
+      assertThat(e).hasMessage("expected value of type 'int', but got 'foo' (string)");
+    }
+  }
+
+  // Ensure that types are reported correctly.
+  @Test
+  public void testTypeErrorMessage() throws Exception {
+    try {
+      Type.STRING_LIST.convert("[(1,2), 3, 4]", "myexpr", null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'list(string)' for myexpr, "
+          + "but got '[(1,2), 3, 4]' (string)");
+    }
+  }
+
+  @Test
+  public void testString() throws Exception {
+    Object s = "foo";
+    assertEquals(s, Type.STRING.convert(s, null));
+    assertThat(Type.STRING.getLabels(s)).isEmpty();
+  }
+
+  @Test
+  public void testNonString() throws Exception {
+    try {
+      Type.STRING.convert(3, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "3", "string");
+    }
+  }
+
+  @Test
+  public void testBoolean() throws Exception {
+    Object myTrue = true;
+    Object myFalse = false;
+    assertEquals(Boolean.TRUE, Type.BOOLEAN.convert(1, null));
+    assertEquals(Boolean.FALSE, Type.BOOLEAN.convert(0, null));
+    assertTrue(Type.BOOLEAN.convert(true, null));
+    assertTrue(Type.BOOLEAN.convert(myTrue, null));
+    assertFalse(Type.BOOLEAN.convert(false, null));
+    assertFalse(Type.BOOLEAN.convert(myFalse, null));
+    assertThat(Type.BOOLEAN.getLabels(myTrue)).isEmpty();
+  }
+
+  @Test
+  public void testNonBoolean() throws Exception {
+    try {
+      Type.BOOLEAN.convert("unexpected", null);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "unexpected");
+    }
+    // Integers other than [0, 1] should fail.
+    try {
+      Type.BOOLEAN.convert(2, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertEquals(e.getMessage(), "boolean is not one of [0, 1]");
+    }
+    try {
+      Type.BOOLEAN.convert(-1, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertEquals(e.getMessage(), "boolean is not one of [0, 1]");
+    }
+  }
+
+  @Test
+  public void testTriState() throws Exception {
+    assertEquals(TriState.YES, Type.TRISTATE.convert(1, null));
+    assertEquals(TriState.NO, Type.TRISTATE.convert(0, null));
+    assertEquals(TriState.AUTO, Type.TRISTATE.convert(-1, null));
+    assertEquals(TriState.YES, Type.TRISTATE.convert(true, null));
+    assertEquals(TriState.NO, Type.TRISTATE.convert(false, null));
+    assertEquals(TriState.YES, Type.TRISTATE.convert(TriState.YES, null));
+    assertEquals(TriState.NO, Type.TRISTATE.convert(TriState.NO, null));
+    assertEquals(TriState.AUTO, Type.TRISTATE.convert(TriState.AUTO, null));
+    assertThat(Type.TRISTATE.getLabels(TriState.YES)).isEmpty();
+  }
+
+  @Test
+  public void testTriStateDoesNotAcceptArbitraryIntegers() throws Exception {
+    List<Integer> listOfCases = Lists.newArrayList(2, 3, -5, -2, 20);
+    for (Object entry : listOfCases) {
+      try {
+        Type.TRISTATE.convert(entry, null);
+        fail();
+      } catch (Type.ConversionException e) {
+        // Expected.
+      }
+    }
+  }
+
+  @Test
+  public void testTriStateDoesNotAcceptStrings() throws Exception {
+    List<String> listOfCases = Lists.newArrayList("bad", "true", "auto", "false");
+    for (Object entry : listOfCases) {
+      try {
+        Type.TRISTATE.convert(entry, null);
+        fail();
+      } catch (Type.ConversionException e) {
+        // Expected.
+      }
+    }
+  }
+
+  @Test
+  public void testTagConversion() throws Exception {
+    assertSameContents(Sets.newHashSet("attribute"),
+        Type.BOOLEAN.toTagSet(true, "attribute"));
+    assertSameContents(Sets.newHashSet("noattribute"),
+        Type.BOOLEAN.toTagSet(false, "attribute"));
+
+    assertSameContents(Sets.newHashSet("whiskey"),
+        Type.STRING.toTagSet("whiskey", "preferred_cocktail"));
+
+    assertSameContents(Sets.newHashSet("cheddar", "ementaler", "gruyere"),
+        Type.STRING_LIST.toTagSet(
+            Lists.newArrayList("cheddar", "ementaler", "gruyere"), "cheeses"));
+  }
+
+  @Test
+  public void testIllegalTagConversionByType() throws Exception {
+    try {
+      Type.TRISTATE.toTagSet(TriState.AUTO, "some_tristate");
+      fail("Expect UnsuportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // Success.
+    }
+    try {
+      Type.LICENSE.toTagSet(License.NO_LICENSE, "output_license");
+      fail("Expect UnsuportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // Success.
+    }
+  }
+
+  @Test
+  public void testIllegalTagConversIonFromNullOnSupportedType() throws Exception {
+    try {
+      Type.BOOLEAN.toTagSet(null, "a_boolean");
+      fail("Expect UnsuportedOperationException");
+    } catch (IllegalStateException e) {
+      // Success.
+    }
+  }
+
+  @Test
+  public void testLabel() throws Exception {
+    Label label = Label.parseAbsolute("//foo:bar");
+    assertEquals(label, Type.LABEL.convert("//foo:bar", null, currentRule));
+    assertThat(Type.LABEL.getLabels(label)).containsExactly(label);
+  }
+
+  @Test
+  public void testNodepLabel() throws Exception {
+    Label label = Label.parseAbsolute("//foo:bar");
+    assertEquals(label, Type.NODEP_LABEL.convert("//foo:bar", null, currentRule));
+    assertThat(Type.NODEP_LABEL.getLabels(label)).containsExactly(label);
+  }
+
+  @Test
+  public void testRelativeLabel() throws Exception {
+    assertEquals(Label.parseAbsolute("//quux:wiz"),
+        Type.LABEL.convert(":wiz", null, currentRule));
+    assertEquals(Label.parseAbsolute("//quux:wiz"),
+        Type.LABEL.convert("wiz", null, currentRule));
+    try {
+      Type.LABEL.convert("wiz", null);
+      fail();
+    } catch (NullPointerException e) {
+      /* ok */
+    }
+  }
+
+  @Test
+  public void testInvalidLabel() throws Exception {
+    try {
+      Type.LABEL.convert("not a label", null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "not a label");
+    }
+  }
+
+  @Test
+  public void testNonLabel() throws Exception {
+    try {
+      Type.LABEL.convert(3, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "3", "string");
+    }
+  }
+
+  @Test
+  public void testStringList() throws Exception {
+    Object input = Arrays.asList("foo", "bar", "wiz");
+    List<String> converted =
+        Type.STRING_LIST.convert(input, null);
+    assertEquals(input, converted);
+    assertNotSame(input, converted);
+    assertThat(Type.STRING_LIST.getLabels(input)).isEmpty();
+  }
+
+  @Test
+  public void testStringDict() throws Exception {
+    Object input = ImmutableMap.of("foo", "bar",
+                                   "wiz", "bang");
+    Map<String, String> converted = Type.STRING_DICT.convert(input, null);
+    assertEquals(input, converted);
+    assertNotSame(input, converted);
+    assertThat(Type.STRING_DICT.getLabels(converted)).isEmpty();
+  }
+
+  @Test
+  public void testStringDictBadElements() throws Exception {
+    Object input = ImmutableMap.of("foo", Arrays.asList("bar", "baz"),
+        "wiz", "bang");
+    try {
+      Type.STRING_DICT.convert(input, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'string' for dict value element, but got "
+          + "'[\"bar\", \"baz\"]' (List)");
+    }
+  }
+
+  @Test
+  public void testNonStringList() throws Exception {
+    try {
+      Type.STRING_LIST.convert(3, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "3", "list(string)");
+    }
+  }
+
+  @Test
+  public void testStringListBadElements() throws Exception {
+    Object input = Arrays.<Object>asList("foo", "bar", 1);
+    try {
+      Type.STRING_LIST.convert(input, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "1", "string");
+    }
+  }
+
+  @Test
+  public void testLabelList() throws Exception {
+    Object input = Arrays.asList("//foo:bar", ":wiz");
+    List<Label> converted =
+      Type.LABEL_LIST.convert(input , null, currentRule);
+    List<Label> expected =
+      Arrays.asList(Label.parseAbsolute("//foo:bar"),
+                    Label.parseAbsolute("//quux:wiz"));
+    assertEquals(expected, converted);
+    assertNotSame(expected, converted);
+    assertThat(Type.LABEL_LIST.getLabels(converted)).containsExactlyElementsIn(expected);
+  }
+
+  @Test
+  public void testNonLabelList() throws Exception {
+    try {
+      Type.LABEL_LIST.convert(3, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "3", "list(label)");
+    }
+  }
+
+  @Test
+  public void testLabelListBadElements() throws Exception {
+    Object list = Arrays.<Object>asList("//foo:bar", 2, "foo");
+    try {
+      Type.LABEL_LIST.convert(list, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "2", "string");
+    }
+  }
+
+  @Test
+  public void testLabelListSyntaxError() throws Exception {
+    Object list = Arrays.<Object>asList("//foo:bar/..", "foo");
+    try {
+      Type.LABEL_LIST.convert(list, "myexpr", currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("invalid label '//foo:bar/..' in element 0 of myexpr: "
+          + "invalid target name 'bar/..': "
+          + "target names may not contain up-level references '..'");
+    }
+  }
+
+  @Test
+  public void testLabelListDict() throws Exception {
+    Object input = ImmutableMap.of("foo", Arrays.asList("//foo:bar"),
+        "wiz", Arrays.asList(":bang"));
+    Map<String, List<Label>> converted = Type.LABEL_LIST_DICT.convert(input, null, currentRule);
+    Label fooLabel = Label.parseAbsolute("//foo:bar");
+    Label bangLabel = Label.parseAbsolute("//quux:bang");
+    Map<?, ?> expected = ImmutableMap.<String, List<Label>>of(
+            "foo", Arrays.<Label>asList(fooLabel),
+            "wiz", Arrays.<Label>asList(bangLabel));
+    assertEquals(expected, converted);
+    assertNotSame(expected, converted);
+    assertThat(Type.LABEL_LIST_DICT.getLabels(converted)).containsExactly(fooLabel, bangLabel);
+  }
+
+  @Test
+  public void testLabelListDictBadFirstElement() throws Exception {
+    Object input = ImmutableMap.of(2, Arrays.asList("//foo:bar"),
+        "wiz", Arrays.asList(":bang"));
+    try {
+      Type.LABEL_LIST_DICT.convert(input, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'string' for dict key element,"
+          + " but got '2' (int)");
+    }
+  }
+
+  @Test
+  public void testLabelListDictBadSecondElement() throws Exception {
+    Object input = ImmutableMap.of("foo", "//foo:bar",
+                                   "wiz", Arrays.asList(":bang"));
+    try {
+      Type.LABEL_LIST_DICT.convert(input, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "//foo:bar", "list(label)");
+    }
+  }
+
+  @Test
+  public void testLabelListDictBadElements1() throws Exception {
+    Object input = ImmutableMap.of("foo", "bar",
+                                   "bar", Arrays.asList("//foo:bar"),
+                                   "wiz", Arrays.asList(":bang"));
+    try {
+      Type.LABEL_LIST_DICT.convert(input, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'list(label)' for dict value element, "
+          + "but got 'bar' (string)");
+    }
+  }
+
+  @Test
+  public void testLabelListDictSyntaxError() throws Exception {
+    Object input = ImmutableMap.of("foo", Arrays.asList("//foo:.."),
+                                   "wiz", Arrays.asList(":bang"));
+    try {
+      Type.LABEL_LIST_DICT.convert(input, "baz", currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("invalid label '//foo:..' in element 0 of dict value element: "
+          + "invalid target name '..': "
+          + "target names may not contain up-level references '..'");
+    }
+  }
+
+  @Test
+  public void testStringListDict() throws Exception {
+    Object input = ImmutableMap.of("foo", Arrays.asList("foo", "bar"),
+                                   "wiz", Arrays.asList("bang"));
+    Map<String, List<String>> converted =
+        Type.STRING_LIST_DICT.convert(input, null, currentRule);
+    Map<?, ?> expected = ImmutableMap.<String, List<String>>of(
+            "foo", Arrays.asList("foo", "bar"),
+            "wiz", Arrays.asList("bang"));
+    assertEquals(expected, converted);
+    assertNotSame(expected, converted);
+    assertThat(Type.STRING_LIST_DICT.getLabels(converted)).isEmpty();
+  }
+
+  @Test
+  public void testStringListDictBadFirstElement() throws Exception {
+    Object input = ImmutableMap.of(2, Arrays.asList("foo", "bar"),
+                                   "wiz", Arrays.asList("bang"));
+    try {
+      Type.STRING_LIST_DICT.convert(input, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage(
+          "expected value of type 'string' for dict key element, but got '2' (int)");
+    }
+  }
+
+  @Test
+  public void testStringListDictBadSecondElement() throws Exception {
+    Object input = ImmutableMap.of("foo", "bar",
+                                   "wiz", Arrays.asList("bang"));
+    try {
+      Type.STRING_LIST_DICT.convert(input, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "bar", "list(string)");
+    }
+  }
+
+  @Test
+  public void testStringListDictBadElements1() throws Exception {
+    Object input = ImmutableMap.of(Arrays.asList("foo"), Arrays.asList("bang"),
+                                   "wiz", Arrays.asList("bang"));
+    try {
+      Type.STRING_LIST_DICT.convert(input, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'string' for dict key element, but got "
+          + "'[\"foo\"]' (List)");
+    }
+  }
+
+  @Test
+  public void testStringDictUnary() throws Exception {
+    Object input = ImmutableMap.of("foo", "bar",
+                                   "wiz", "bang");
+    Map<?, ?> converted =
+        Type.STRING_DICT_UNARY.convert(input, null, currentRule);
+    Map<?, ?> expected = ImmutableMap.<String, String>of(
+            "foo", "bar",
+            "wiz", "bang");
+    assertEquals(expected, converted);
+    assertNotSame(expected, converted);
+    assertThat(Type.STRING_DICT_UNARY.getLabels(converted)).isEmpty();
+  }
+
+  @Test
+  public void testStringDictUnaryBadFirstElement() throws Exception {
+    Object input = ImmutableMap.of(2, Arrays.asList("foo", "bar"),
+                                   "wiz", Arrays.asList("bang"));
+    try {
+      Type.STRING_DICT_UNARY.convert(input, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'string' for dict key element, but got "
+          + "'2' (int)");
+    }
+  }
+
+  @Test
+  public void testStringDictUnaryBadSecondElement() throws Exception {
+    Object input = ImmutableMap.of("foo", "bar",
+                                   "wiz", Arrays.asList("bang"));
+    try {
+      Type.STRING_DICT_UNARY.convert(input, null, currentRule);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'string' for dict value element, but got "
+          + "'[\"bang\"]' (List)");
+    }
+  }
+
+  @Test
+  public void testStringDictUnaryBadElements1() throws Exception {
+    Object input = ImmutableMap.of("foo", "bar",
+                                   Arrays.asList("foo", "bar"),
+                                   Arrays.<Object>asList("wiz", "bang"));
+    try {
+      Type.STRING_DICT_UNARY.convert(input, null);
+      fail();
+    } catch (Type.ConversionException e) {
+      assertThat(e).hasMessage("expected value of type 'string' for dict key element, but got "
+          + "'[\"foo\", \"bar\"]' (List)");
+    }
+  }
+
+  @Test
+  public void testStringDictThrowsConversionException() throws Exception {
+    try {
+      Type.STRING_DICT.convert("some string", null);
+      fail();
+    } catch (ConversionException e) {
+      assertThat(e).hasMessage("Expected a map for dictionary but got a java.lang.String");
+    }
+  }
+
+  @Test
+  public void testFilesetEntry() throws Exception {
+    Label srcDir = Label.create("foo", "src");
+    Label entryLabel = Label.create("foo", "entry");
+    FilesetEntry input =
+        new FilesetEntry(srcDir, ImmutableList.of(entryLabel), null, null, null, null);
+    assertEquals(input, Type.FILESET_ENTRY.convert(input, null, currentRule));
+    assertThat(Type.FILESET_ENTRY.getLabels(input)).containsExactly(entryLabel);
+  }
+
+  @Test
+  public void testFilesetEntryList() throws Exception {
+    Label srcDir = Label.create("foo", "src");
+    Label entry1Label = Label.create("foo", "entry1");
+    Label entry2Label = Label.create("foo", "entry");
+    List<FilesetEntry> input = ImmutableList.of(
+        new FilesetEntry(srcDir, ImmutableList.of(entry1Label), null, null, null, null),
+        new FilesetEntry(srcDir, ImmutableList.of(entry2Label), null, null, null, null));
+    assertEquals(input, Type.FILESET_ENTRY_LIST.convert(input, null, currentRule));
+    assertThat(Type.FILESET_ENTRY_LIST.getLabels(input)).containsExactly(entry1Label, entry2Label);
+  }
+
+  /**
+   * Tests basic {@link Type.Selector} functionality.
+   */
+  @Test
+  public void testSelector() throws Exception {
+    Object input = ImmutableMap.of(
+        "//conditions:a", "//a:a",
+        "//conditions:b", "//b:b",
+        Type.Selector.DEFAULT_CONDITION_KEY, "//d:d");
+    Type.Selector<Label> selector = new Type.Selector<>(input, null, currentRule, Type.LABEL);
+    assertEquals(Type.LABEL, selector.getOriginalType());
+
+    Map<Label, Label> expectedMap = ImmutableMap.of(
+        Label.parseAbsolute("//conditions:a"), Label.create("a", "a"),
+        Label.parseAbsolute("//conditions:b"), Label.create("b", "b"),
+        Label.parseAbsolute(Type.Selector.DEFAULT_CONDITION_KEY), Label.create("d", "d"));
+    assertSameContents(expectedMap.entrySet(), selector.getEntries().entrySet());
+  }
+
+  /**
+   * Tests that creating a {@link Type.Selector} over a mismatching native type triggers an
+   * exception.
+   */
+  @Test
+  public void testSelectorWrongType() throws Exception {
+    Object input = ImmutableMap.of(
+        "//conditions:a", "not a label",
+        "//conditions:b", "also not a label",
+        Type.Selector.DEFAULT_CONDITION_KEY, "whatever");
+    try {
+      new Type.Selector<Label>(input, null, currentRule, Type.LABEL);
+      fail("Expected Selector instantiation to fail since the input isn't a selection of labels");
+    } catch (ConversionException e) {
+      assertThat(e.getMessage()).contains("invalid label 'not a label'");
+    }
+  }
+
+  /**
+   * Tests that non-label selector keys trigger an exception.
+   */
+  @Test
+  public void testSelectorKeyIsNotALabel() throws Exception {
+    Object input = ImmutableMap.of(
+        "not a label", "//a:a",
+        Type.Selector.DEFAULT_CONDITION_KEY, "whatever");
+    try {
+      new Type.Selector<Label>(input, null, currentRule, Type.LABEL);
+      fail("Expected Selector instantiation to fail since the key isn't a label");
+    } catch (ConversionException e) {
+      assertThat(e.getMessage()).contains("invalid label 'not a label'");
+    }
+  }
+
+  /**
+   * Tests that {@link Type.Selector} correctly references its default value.
+   */
+  @Test
+  public void testSelectorDefault() throws Exception {
+    Object input = ImmutableMap.of(
+        "//conditions:a", "//a:a",
+        "//conditions:b", "//b:b",
+        Type.Selector.DEFAULT_CONDITION_KEY, "//d:d");
+    assertEquals(
+        Label.create("d", "d"),
+        new Type.Selector<Label>(input, null, currentRule, Type.LABEL).getDefault());
+  }
+
+  @Test
+  public void testSelectorList() throws Exception {
+    Object selector1 = new SelectorValue(ImmutableMap.of("//conditions:a",
+        ImmutableList.of("//a:a"), "//conditions:b", ImmutableList.of("//b:b")));
+    Object selector2 = new SelectorValue(ImmutableMap.of("//conditions:c",
+        ImmutableList.of("//c:c"), "//conditions:d", ImmutableList.of("//d:d")));
+    Type.SelectorList<List<Label>> selectorList = new Type.SelectorList<>(
+        ImmutableList.of(selector1, selector2), null, currentRule, Type.LABEL_LIST);
+
+    assertEquals(Type.LABEL_LIST, selectorList.getOriginalType());
+    assertSameContents(
+        ImmutableSet.of(
+            Label.parseAbsolute("//conditions:a"), Label.parseAbsolute("//conditions:b"),
+            Label.parseAbsolute("//conditions:c"), Label.parseAbsolute("//conditions:d")),
+        selectorList.getKeyLabels());
+
+    List<Type.Selector<List<Label>>> selectors = selectorList.getSelectors();
+    assertSameContents(
+        ImmutableMap.of(
+                Label.parseAbsolute("//conditions:a"), ImmutableList.of(Label.create("a", "a")),
+                Label.parseAbsolute("//conditions:b"), ImmutableList.of(Label.create("b", "b")))
+            .entrySet(),
+        selectors.get(0).getEntries().entrySet());
+    assertSameContents(
+        ImmutableMap.of(
+                Label.parseAbsolute("//conditions:c"), ImmutableList.of(Label.create("c", "c")),
+                Label.parseAbsolute("//conditions:d"), ImmutableList.of(Label.create("d", "d")))
+            .entrySet(),
+        selectors.get(1).getEntries().entrySet());
+  }
+
+  @Test
+  public void testSelectorListMixedTypes() throws Exception {
+    Object selector1 =
+        new SelectorValue(ImmutableMap.of("//conditions:a", ImmutableList.of("//a:a")));
+    Object selector2 =
+        new SelectorValue(ImmutableMap.of("//conditions:b", "//b:b"));
+    try {
+      new Type.SelectorList<>(ImmutableList.of(selector1, selector2), null, currentRule,
+          Type.LABEL_LIST);
+      fail("Expected SelectorList initialization to fail on mixed element types");
+    } catch (ConversionException e) {
+      assertThat(e.getMessage()).contains("expected value of type 'list(label)'");
+    }
+  }
+
+  /**
+   * Tests that {@link Type#selectableConvert} returns either the native type or a selector
+   * on that type, in accordance with the provided input.
+   */
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testSelectableConvert() throws Exception {
+    Object nativeInput = Arrays.asList("//a:a1", "//a:a2");
+    Object selectableInput =
+        SelectorList.of(new SelectorValue(ImmutableMap.of(
+            "//conditions:a", nativeInput,
+            Type.Selector.DEFAULT_CONDITION_KEY, nativeInput)));
+    List<Label> expectedLabels = ImmutableList.of(Label.create("a", "a1"), Label.create("a", "a2"));
+
+    // Conversion to direct type:
+    Object converted = Type.LABEL_LIST.selectableConvert(nativeInput, null, currentRule);
+    assertTrue(converted instanceof List<?>);
+    assertSameContents(expectedLabels, (List<Label>) converted);
+
+    // Conversion to selectable type:
+    converted = Type.LABEL_LIST.selectableConvert(selectableInput, null, currentRule);
+    Type.SelectorList<?> selectorList = (Type.SelectorList<?>) converted;
+    assertSameContents(
+        ImmutableMap.of(
+            Label.parseAbsolute("//conditions:a"), expectedLabels,
+            Label.parseAbsolute(Type.Selector.DEFAULT_CONDITION_KEY), expectedLabels).entrySet(),
+        ((Type.Selector<Label>) selectorList.getSelectors().get(0)).getEntries().entrySet());
+  }
+
+  /**
+   * Tests that {@link Type#convert} fails on selector inputs.
+   */
+  @Test
+  public void testConvertDoesNotAcceptSelectables() throws Exception {
+    Object selectableInput = SelectorList.of(
+        new SelectorValue(ImmutableMap.of("//conditions:a", Arrays.asList("//a:a1", "//a:a2"))));
+    try {
+      Type.LABEL_LIST.convert(selectableInput, null, currentRule);
+      fail("Expected conversion to fail on a selectable input");
+    } catch (ConversionException e) {
+      assertThat(e.getMessage()).contains("expected value of type 'list(label)'");
+    }
+  }
+
+  /**
+   * Tests for "reserved" key labels (i.e. not intended to map to actual targets).
+   */
+  @Test
+  public void testReservedKeyLabels() throws Exception {
+    assertFalse(Type.Selector.isReservedLabel(Label.parseAbsolute("//condition:a")));
+    assertTrue(Type.Selector.isReservedLabel(
+        Label.parseAbsolute(Type.Selector.DEFAULT_CONDITION_KEY)));
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
new file mode 100644
index 0000000..8d7ee5b
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
@@ -0,0 +1,244 @@
+// Copyright 2006-2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.packages.util;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.packages.ConstantRuleVisibility;
+import com.google.devtools.build.lib.packages.NoSuchPackageException;
+import com.google.devtools.build.lib.packages.NoSuchTargetException;
+import com.google.devtools.build.lib.packages.NoSuchThingException;
+import com.google.devtools.build.lib.packages.PackageFactory;
+import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension;
+import com.google.devtools.build.lib.packages.Preprocessor;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
+import com.google.devtools.build.lib.pkgcache.PackageManager;
+import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
+import com.google.devtools.build.lib.skyframe.DiffAwareness;
+import com.google.devtools.build.lib.skyframe.PrecomputedValue;
+import com.google.devtools.build.lib.skyframe.SequencedSkyframeExecutor;
+import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
+import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.syntax.Label.SyntaxException;
+import com.google.devtools.build.lib.testutil.FoundationTestCase;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import com.google.devtools.build.lib.util.BlazeClock;
+import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
+import com.google.devtools.build.lib.vfs.ModifiedFileSet;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyFunctionName;
+import com.google.devtools.common.options.OptionsParser;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * This is a specialization of {@link FoundationTestCase} that's useful for
+ * implementing tests of the "packages" library.
+ */
+public abstract class PackageLoadingTestCase extends FoundationTestCase {
+
+  protected ConfiguredRuleClassProvider ruleClassProvider;
+  private SkyframeExecutor skyframeExecutor;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    ruleClassProvider = TestRuleClassProvider.getRuleClassProvider();
+    skyframeExecutor = SequencedSkyframeExecutor.create(reporter,
+        new PackageFactory(ruleClassProvider, getEnvironmentExtensions()),
+        new TimestampGranularityMonitor(BlazeClock.instance()),
+        new BlazeDirectories(outputBase, outputBase, rootDirectory),
+        null, /* workspaceStatusActionFactory */
+        ruleClassProvider.getBuildInfoFactories(),
+        ImmutableSet.<Path>of(),
+        ImmutableList.<DiffAwareness.Factory>of(),
+        Predicates.<PathFragment>alwaysFalse(),
+        Preprocessor.Factory.Supplier.NullSupplier.INSTANCE,
+        ImmutableMap.<SkyFunctionName, SkyFunction>of(),
+        ImmutableList.<PrecomputedValue.Injected>of()
+    );
+    skyframeExecutor.preparePackageLoading(
+        new PathPackageLocator(rootDirectory), ConstantRuleVisibility.PUBLIC, true, "",
+        UUID.randomUUID());
+    setUpSkyframe(parsePackageCacheOptions());
+  }
+
+  protected Iterable<EnvironmentExtension> getEnvironmentExtensions() {
+    return ImmutableList.<EnvironmentExtension>of();
+  }
+
+  private void setUpSkyframe(PackageCacheOptions packageCacheOptions) {
+    PathPackageLocator pkgLocator = PathPackageLocator.create(
+        packageCacheOptions.packagePath, reporter, rootDirectory, rootDirectory);
+    skyframeExecutor.preparePackageLoading(pkgLocator,
+        packageCacheOptions.defaultVisibility, true,
+        ruleClassProvider.getDefaultsPackageContent(),
+        UUID.randomUUID());
+    skyframeExecutor.setDeletedPackages(ImmutableSet.copyOf(packageCacheOptions.deletedPackages));
+  }
+
+  private PackageCacheOptions parsePackageCacheOptions(String... options) throws Exception {
+    OptionsParser parser = OptionsParser.newOptionsParser(PackageCacheOptions.class);
+    parser.parse(new String[] { "--default_visibility=public" });
+    parser.parse(options);
+    return parser.getOptions(PackageCacheOptions.class);
+  }
+
+  protected void setPackageCacheOptions(String... options) throws Exception {
+    setUpSkyframe(parsePackageCacheOptions(options));
+  }
+
+  protected Target getTarget(String label)
+      throws NoSuchPackageException, NoSuchTargetException,
+             Label.SyntaxException, InterruptedException {
+    return getTarget(Label.parseAbsolute(label));
+  }
+
+  protected Target getTarget(Label label)
+      throws NoSuchPackageException, NoSuchTargetException, InterruptedException {
+    return getPackageManager().getTarget(reporter, label);
+  }
+
+  /**
+   * Create and return a scratch rule.
+   *
+   * @param packageName the package name of the rule.
+   * @param ruleName the name of the rule.
+   * @param lines the text of the rule.
+   * @return the rule instance for the created rule.
+   * @throws IOException
+   * @throws Exception
+   */
+  protected Rule scratchRule(String packageName, String ruleName, String... lines)
+      throws Exception {
+    scratch.file(packageName + "/BUILD", lines);
+    return (Rule) getTarget("//" + packageName + ":" + ruleName);
+  }
+
+  /**
+   * A Utility method that generates build file rules for tests.
+   * @param rule the name of the rule class.
+   * @param name the name of the rule instance.
+   * @param body an array of strings containing the contents of the rule.
+   * @return a string containing the build file rule.
+   */
+  protected String genRule(String rule, String name, String... body) {
+    StringBuilder buf = new StringBuilder();
+    buf.append(rule);
+    buf.append("(name='");
+    buf.append(name);
+    buf.append("',\n");
+    for (String line : body) {
+      buf.append(line);
+    }
+    buf.append(")\n");
+    return buf.toString();
+  }
+
+  /**
+   * A utility function which generates the "deps" clause for a build file
+   * rule from a list of targets.
+   * @param depTargets the list of targets.
+   * @return a string containing the deps clause
+   */
+  protected static String deps(String... depTargets) {
+    StringBuilder buf = new StringBuilder();
+    buf.append("    deps=[");
+    String sep = "'";
+    for (String dep : depTargets) {
+      buf.append(sep);
+      buf.append(dep);
+      buf.append("'");
+      sep = ", '";
+    }
+    buf.append("]");
+    return buf.toString();
+  }
+
+  /**
+   * Utility method for tests. Converts an array of strings into a set of labels.
+   *
+   * @param strings the set of strings to be converted to labels.
+   * @throws SyntaxException if there are any syntax errors in the strings.
+   */
+  public static Set<Label> asLabelSet(String... strings) throws SyntaxException {
+    return asLabelSet(ImmutableList.copyOf(strings));
+  }
+
+  /**
+   * Utility method for tests. Converts an array of strings into a set of labels.
+   *
+   * @param strings the set of strings to be converted to labels.
+   * @throws SyntaxException if there are any syntax errors in the strings.
+   */
+  public static Set<Label> asLabelSet(Iterable<String> strings) throws SyntaxException {
+    Set<Label> result = Sets.newTreeSet();
+    for (String s : strings) {
+      result.add(Label.parseAbsolute(s));
+    }
+    return result;
+  }
+
+  protected final Set<Target> asTargetSet(String... strLabels)
+      throws SyntaxException, NoSuchThingException, InterruptedException {
+    return asTargetSet(Arrays.asList(strLabels));
+  }
+
+  protected Set<Target> asTargetSet(Iterable<String> strLabels)
+      throws SyntaxException, NoSuchThingException, InterruptedException {
+    Set<Target> targets = new HashSet<>();
+    for (String strLabel : strLabels) {
+      targets.add(getTarget(strLabel));
+    }
+    return targets;
+  }
+
+  protected PackageManager getPackageManager() {
+    return skyframeExecutor.getPackageManager();
+  }
+
+  protected SkyframeExecutor getSkyframeExecutor() {
+    return skyframeExecutor;
+  }
+
+  /**
+   * Invalidates all existing packages below the usual rootDirectory. Must be called _after_ the
+   * files are modified.
+   *
+   * @throws InterruptedException
+   */
+  protected void invalidatePackages() throws InterruptedException {
+    skyframeExecutor.invalidateFilesUnderPathForTesting(ModifiedFileSet.EVERYTHING_MODIFIED,
+        rootDirectory);
+  }
+
+  protected String getErrorMsgNonEmptyList(String attrName, String ruleType, String ruleName) {
+    return "non empty attribute '" + attrName + "' in '" + ruleType
+        + "' rule '" + ruleName + "' has to have at least one value";
+  }
+}
