diff --git a/src/test/java/BUILD b/src/test/java/BUILD
index c249559..7fde4f2 100644
--- a/src/test/java/BUILD
+++ b/src/test/java/BUILD
@@ -49,7 +49,8 @@
 java_library(
     name = "foundations_testutil",
     srcs = glob([
-        "%s/vfs/util/*.java" % test_prefix,
+        "com/google/devtools/build/lib/vfs/util/*.java",
+        "com/google/devtools/build/lib/events/util/*.java",
     ]),
     deps = [
         ":testutil",
@@ -226,3 +227,26 @@
         "//third_party:truth",
     ],
 )
+
+java_test(
+    name = "syntax_test",
+    srcs = glob([
+        "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",
+        ":testutil",
+        "//src/main/java:bazel-core",
+        "//third_party:guava",
+        "//third_party:guava-testlib",
+        "//third_party:jsr305",
+        "//third_party:junit4",
+        "//third_party:truth",
+    ],
+)
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ASTNodeTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ASTNodeTest.java
new file mode 100644
index 0000000..c607d90
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ASTNodeTest.java
@@ -0,0 +1,64 @@
+// Copyright 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.syntax;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests {@link ASTNode}.
+ */
+@RunWith(JUnit4.class)
+public class ASTNodeTest {
+
+  private ASTNode node;
+
+  @Before
+  public void setUp() throws Exception {
+    node = new ASTNode() {
+      @Override
+      public String toString() {
+        return null;
+      }
+      @Override
+      public void accept(SyntaxTreeVisitor visitor) {
+      }
+    };
+  }
+
+  @Test
+  public void testHashCodeNotSupported() {
+    try {
+      node.hashCode();
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // yes!
+    }
+  }
+
+  @Test
+  public void testEqualsNotSupported() {
+    try {
+      node.equals(this);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // yes!
+    }
+  }
+
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/AbstractEvaluationTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/AbstractEvaluationTestCase.java
new file mode 100644
index 0000000..7937786
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/AbstractEvaluationTestCase.java
@@ -0,0 +1,52 @@
+// Copyright 2006 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.syntax;
+
+import java.util.List;
+
+/**
+ * Base class for test cases that use eval services.
+ */
+public abstract class AbstractEvaluationTestCase extends AbstractParserTestCase {
+
+  public Object eval(String input) throws Exception {
+    return eval(parseExpr(input));
+  }
+
+  public Object eval(String input, Environment env) throws Exception {
+    return eval(parseExpr(input), env);
+  }
+
+  public static Object eval(Expression e) throws Exception {
+    return eval(e, new Environment());
+  }
+
+  public static Object eval(Expression e, Environment env) throws Exception {
+    return e.eval(env);
+  }
+
+  public void exec(String input, Environment env) throws Exception {
+    exec(parseStmt(input), env);
+  }
+
+  public void exec(Statement s, Environment env) throws Exception {
+    s.exec(env);
+  }
+
+  public static void exec(List<Statement> li, Environment env) throws Exception {
+    for (Statement stmt : li) {
+      stmt.exec(env);
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java
new file mode 100644
index 0000000..ba59864
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java
@@ -0,0 +1,100 @@
+// Copyright 2006 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.syntax;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
+import com.google.devtools.build.lib.packages.CachingPackageLocator;
+import com.google.devtools.build.lib.rules.SkylarkModules;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * Base class for test cases that use parsing services.
+ */
+public abstract class AbstractParserTestCase extends TestCase {
+  public static final class EmptyPackageLocator implements CachingPackageLocator {
+    @Override
+    public Path getBuildFileForPackage(String packageName) {
+      return null;
+    }
+  }
+
+  protected EventCollectionApparatus syntaxEvents = new EventCollectionApparatus();
+  private FsApparatus scratch = FsApparatus.newInMemory();
+  private CachingPackageLocator locator = new EmptyPackageLocator();
+
+  private static Lexer createLexer(String input,
+      EventCollectionApparatus syntaxEvents, FsApparatus scratch) {
+    Path someFile = scratch.path("/some/file.txt");
+    ParserInputSource inputSource = ParserInputSource.create(input, someFile);
+    return new Lexer(inputSource, syntaxEvents.reporter());
+  }
+
+  protected Lexer createLexer(String input) {
+    return createLexer(input, syntaxEvents, scratch);
+  }
+
+  protected List<Statement> parseFile(String input) {
+    return Parser.parseFile(createLexer(input), syntaxEvents.reporter(), locator, false)
+        .statements;
+  }
+
+  protected List<Statement> parseFile(String input, boolean parsePython) {
+    return Parser.parseFile(createLexer(input), syntaxEvents.reporter(), locator, parsePython)
+        .statements;
+  }
+
+  protected List<Statement> parseFileForSkylark(String input) {
+    return Parser.parseFileForSkylark(createLexer(input), syntaxEvents.reporter(), locator,
+        SkylarkModules.getValidationEnvironment()).statements;
+  }
+
+  protected List<Statement> parseFileForSkylark(
+      String input, ImmutableMap<String, SkylarkType> extraObject) {
+    return Parser.parseFileForSkylark(createLexer(input), syntaxEvents.reporter(), locator,
+        SkylarkModules.getValidationEnvironment(extraObject)).statements;
+  }
+
+  protected Parser.ParseResult parseFileWithComments(String input) {
+    return Parser.parseFile(createLexer(input), syntaxEvents.reporter(), locator, false);
+  }
+
+  protected Statement parseStmt(String input) {
+    return Parser.parseStatement(createLexer(input), syntaxEvents.reporter());
+  }
+
+  protected Expression parseExpr(String input) {
+    return Parser.parseExpression(createLexer(input), syntaxEvents.reporter());
+  }
+
+  public static List<Statement> parseFileForSkylark(
+      EventCollectionApparatus syntaxEvents, FsApparatus scratch, String input) {
+    return Parser.parseFileForSkylark(createLexer(input, syntaxEvents, scratch),
+        syntaxEvents.reporter(), null,
+        SkylarkModules.getValidationEnvironment()).statements;
+  }
+
+  public static List<Statement> parseFileForSkylark(
+      EventCollectionApparatus syntaxEvents, FsApparatus scratch, String input,
+      ImmutableMap<String, SkylarkType> extraObject) {
+    return Parser.parseFileForSkylark(createLexer(input, syntaxEvents, scratch),
+        syntaxEvents.reporter(), null,
+        SkylarkModules.getValidationEnvironment(extraObject)).statements;
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
new file mode 100644
index 0000000..eff5c92
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java
@@ -0,0 +1,300 @@
+// Copyright 2006 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.syntax;
+
+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.Reporter;
+import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
+import com.google.devtools.build.lib.packages.CachingPackageLocator;
+import com.google.devtools.build.lib.testutil.JunitTestUtils;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+public class BuildFileASTTest extends TestCase {
+
+  private FsApparatus scratch = FsApparatus.newInMemory();
+
+  private EventCollectionApparatus events = new EventCollectionApparatus(EventKind.ALL_EVENTS);
+
+  private class ScratchPathPackageLocator implements CachingPackageLocator {
+    @Override
+    public Path getBuildFileForPackage(String packageName) {
+      return scratch.path(packageName).getRelative("BUILD");
+    }
+  }
+
+  private CachingPackageLocator locator = new ScratchPathPackageLocator();
+
+  /**
+   * Parses the contents of the specified string (using DUMMY_PATH as the fake
+   * filename) and returns the AST. Resets the error handler beforehand.
+   */
+  private BuildFileAST parseBuildFile(String... lines) throws IOException {
+    Path file = scratch.file("/a/build/file/BUILD", lines);
+    return BuildFileAST.parseBuildFile(file, events.reporter(), locator, false);
+  }
+
+  public void testParseBuildFileOK() throws Exception {
+    Path buildFile = scratch.file("/BUILD",
+        "# a file in the build language",
+        "",
+        "x = [1,2,'foo',4] + [1,2, \"%s%d\" % ('foo', 1)]");
+
+    Environment env = new Environment();
+    Reporter reporter = new Reporter();
+    BuildFileAST buildfile = BuildFileAST.parseBuildFile(buildFile, reporter, null, false);
+
+    assertTrue(buildfile.exec(env, reporter));
+
+    // Test final environment is correctly modified:
+    //
+    // input1.BUILD contains:
+    // x = [1,2,'foo',4] + [1,2, "%s%d" % ('foo', 1)]
+    assertEquals(Arrays.<Object>asList(1, 2, "foo", 4, 1, 2, "foo1"),
+                 env.lookup("x"));
+  }
+
+  public void testEvalException() throws Exception {
+    Path buildFile = scratch.file("/input1.BUILD",
+        "x = 1",
+        "y = [2,3]",
+        "",
+        "z = x + y");
+
+    Environment env = new Environment();
+    Reporter reporter = new Reporter();
+    EventCollector collector = new EventCollector(EventKind.ALL_EVENTS);
+    reporter.addHandler(collector);
+    BuildFileAST buildfile = BuildFileAST.parseBuildFile(buildFile, reporter, null, false);
+
+    assertFalse(buildfile.exec(env, reporter));
+    Event e = JunitTestUtils.assertContainsEvent(collector,
+        "unsupported operand type(s) for +: 'int' and 'list'");
+    assertEquals(4, e.getLocation().getStartLineAndColumn().getLine());
+  }
+
+  public void testParsesFineWithNewlines() throws Exception {
+    BuildFileAST buildFileAST = parseBuildFile("foo()\n"
+                                               + "bar()\n"
+                                               + "something = baz()\n"
+                                               + "bar()");
+    assertEquals(4, buildFileAST.getStatements().size());
+  }
+
+  public void testFailsIfNewlinesAreMissing() throws Exception {
+    events.setFailFast(false);
+
+    BuildFileAST buildFileAST =
+      parseBuildFile("foo() bar() something = baz() bar()");
+
+    Event event = events.collector().iterator().next();
+    assertEquals("syntax error at \'bar\'", event.getMessage());
+    assertEquals("/a/build/file/BUILD",
+                 event.getLocation().getPath().toString());
+    assertEquals(1, event.getLocation().getStartLineAndColumn().getLine());
+    assertTrue(buildFileAST.containsErrors());
+  }
+
+  public void testImplicitStringConcatenationFails() throws Exception {
+    events.setFailFast(false);
+    BuildFileAST buildFileAST = parseBuildFile("a = 'foo' 'bar'");
+    Event event = events.collector().iterator().next();
+    assertEquals("Implicit string concatenation is forbidden, use the + operator",
+        event.getMessage());
+    assertEquals("/a/build/file/BUILD",
+                 event.getLocation().getPath().toString());
+    assertEquals(1, event.getLocation().getStartLineAndColumn().getLine());
+    assertEquals(10, event.getLocation().getStartLineAndColumn().getColumn());
+    assertTrue(buildFileAST.containsErrors());
+  }
+
+  public void testImplicitStringConcatenationAcrossLinesIsIllegal() throws Exception {
+    events.setFailFast(false);
+    BuildFileAST buildFileAST = parseBuildFile("a = 'foo'\n  'bar'");
+
+    Event event = events.collector().iterator().next();
+    assertEquals("indentation error", event.getMessage());
+    assertEquals("/a/build/file/BUILD",
+                 event.getLocation().getPath().toString());
+    assertEquals(2, event.getLocation().getStartLineAndColumn().getLine());
+    assertEquals(2, event.getLocation().getStartLineAndColumn().getColumn());
+    assertTrue(buildFileAST.containsErrors());
+  }
+
+  /**
+   * If the specified EventCollector does contain an event which has
+   * 'expectedEvent' as a substring, the matching event is
+   * returned. Otherwise this will return null.
+   */
+  public static Event findEvent(EventCollector eventCollector,
+                                String expectedEvent) {
+    for (Event event : eventCollector) {
+      if (event.getMessage().contains(expectedEvent)) {
+        return event;
+      }
+    }
+    return null;
+  }
+
+  public void testWithSyntaxErrorsDoesNotPrintDollarError() throws Exception {
+    events.setFailFast(false);
+    BuildFileAST buildFile = parseBuildFile(
+        "abi = cxx_abi + '-glibc-' + glibc_version + '-' + "
+        + "generic_cpu + '-' + sysname",
+        "libs = [abi + opt_level + '/lib/libcc.a']",
+        "shlibs = [abi + opt_level + '/lib/libcc.so']",
+        "+* shlibs", // syntax error at '+'
+        "cc_library(name = 'cc',",
+        "           srcs = libs,",
+        "           includes = [ abi + opt_level + '/include' ])");
+    assertTrue(buildFile.containsErrors());
+    Event event = events.collector().iterator().next();
+    assertEquals("syntax error at '+'", event.getMessage());
+    Environment env = new Environment();
+    assertFalse(buildFile.exec(env, events.reporter()));
+    assertNull(findEvent(events.collector(), "$error$"));
+    // This message should not be printed anymore.
+    Event event2 = findEvent(events.collector(), "contains syntax error(s)");
+    assertNull(event2);
+  }
+
+  public void testInclude() throws Exception {
+    scratch.file("/foo/bar/BUILD",
+        "c = 4\n"
+        + "d = 5\n");
+    Path buildFile = scratch.file("/BUILD",
+        "a = 2\n"
+        + "include(\"//foo/bar:BUILD\")\n"
+        + "b = 4\n");
+
+    BuildFileAST buildFileAST = BuildFileAST.parseBuildFile(buildFile, events.reporter(),
+                                                            locator, false);
+
+    assertFalse(buildFileAST.containsErrors());
+    assertEquals(5, buildFileAST.getStatements().size());
+  }
+
+  public void testInclude2() throws Exception {
+    scratch.file("/foo/bar/defs",
+        "a = 1\n");
+    Path buildFile = scratch.file("/BUILD",
+        "include(\"//foo/bar:defs\")\n"
+        + "b = a + 1\n");
+
+    BuildFileAST buildFileAST = BuildFileAST.parseBuildFile(buildFile, events.reporter(),
+                                                            locator, false);
+
+    assertFalse(buildFileAST.containsErrors());
+    assertEquals(3, buildFileAST.getStatements().size());
+
+    Environment env = new Environment();
+    Reporter reporter = new Reporter();
+    assertFalse(buildFileAST.exec(env, reporter));
+    assertEquals(2, env.lookup("b"));
+  }
+
+  public void testMultipleIncludes() throws Exception {
+    String fileA =
+        "include(\"//foo:fileB\")\n"
+        + "include(\"//foo:fileC\")\n";
+    scratch.file("/foo/fileB",
+        "b = 3\n"
+        + "include(\"//foo:fileD\")\n");
+    scratch.file("/foo/fileC",
+        "include(\"//foo:fileD\")\n"
+        + "c = b + 2\n");
+    scratch.file("/foo/fileD",
+        "b = b + 1\n"); // this code is included twice
+
+    BuildFileAST buildFileAST = parseBuildFile(fileA);
+    assertFalse(buildFileAST.containsErrors());
+    assertEquals(8, buildFileAST.getStatements().size());
+
+    Environment env = new Environment();
+    Reporter reporter = new Reporter();
+    assertFalse(buildFileAST.exec(env, reporter));
+    assertEquals(5, env.lookup("b"));
+    assertEquals(7, env.lookup("c"));
+  }
+
+  public void testFailInclude() throws Exception {
+    events.setFailFast(false);
+    BuildFileAST buildFileAST = parseBuildFile("include(\"//nonexistent\")");
+    assertEquals(1, buildFileAST.getStatements().size());
+    events.assertContainsEvent("Include of '//nonexistent' failed");
+  }
+
+
+  private class EmptyPackageLocator implements CachingPackageLocator {
+    @Override
+    public Path getBuildFileForPackage(String packageName) {
+      return null;
+    }
+  }
+
+  private CachingPackageLocator emptyLocator = new EmptyPackageLocator();
+
+  public void testFailInclude2() throws Exception {
+    events.setFailFast(false);
+    Path buildFile = scratch.file("/foo/bar/BUILD",
+        "include(\"//nonexistent:foo\")\n");
+    BuildFileAST buildFileAST = BuildFileAST.parseBuildFile(buildFile, events.reporter(),
+                                                            emptyLocator, false);
+    assertEquals(1, buildFileAST.getStatements().size());
+    events.assertContainsEvent("Package 'nonexistent' not found");
+  }
+
+  public void testInvalidInclude() throws Exception {
+    events.setFailFast(false);
+    BuildFileAST buildFileAST = parseBuildFile("include(2)");
+    assertEquals(0, buildFileAST.getStatements().size());
+    events.assertContainsEvent("syntax error at '2'");
+  }
+
+  public void testRecursiveInclude() throws Exception {
+    events.setFailFast(false);
+    Path buildFile = scratch.file("/foo/bar/BUILD",
+        "include(\"//foo/bar:BUILD\")\n");
+
+    BuildFileAST.parseBuildFile(buildFile, events.reporter(), locator, false);
+    events.assertContainsEvent("Recursive inclusion");
+  }
+
+  public void testParseErrorInclude() throws Exception {
+    events.setFailFast(false);
+
+    scratch.file("/foo/bar/file",
+        "a = 2 + % 3\n"); // parse error
+
+    parseBuildFile("include(\"//foo/bar:file\")");
+
+    // Check the location is properly reported
+    Event event = events.collector().iterator().next();
+    assertEquals("/foo/bar/file:1:9", event.getLocation().print());
+    assertEquals("syntax error at '%'", event.getMessage());
+  }
+
+  public void testNonExistentIncludeReported() throws Exception {
+    events.setFailFast(false);
+    BuildFileAST buildFileAST = parseBuildFile("include('//foo:bar')");
+    assertEquals(1, buildFileAST.getStatements().size());
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
new file mode 100644
index 0000000..0452913
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
@@ -0,0 +1,133 @@
+// Copyright 2006 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.syntax;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Tests of Environment.
+ */
+public class EnvironmentTest extends AbstractEvaluationTestCase {
+
+  // Test the API directly
+  public void testLookupAndUpdate() throws Exception {
+    Environment env = new Environment();
+
+    try {
+      env.lookup("foo");
+      fail();
+    } catch (Environment.NoSuchVariableException e) {
+       assertEquals("no such variable: foo", e.getMessage());
+    }
+
+    env.update("foo", "bar");
+
+    assertEquals("bar", env.lookup("foo"));
+  }
+
+  public void testLookupWithDefault() throws Exception {
+    Environment env = new Environment();
+    assertEquals(21, env.lookup("VERSION", 21));
+    env.update("VERSION", 42);
+    assertEquals(42, env.lookup("VERSION", 21));
+  }
+
+  public void testDoubleUpdateSucceeds() throws Exception {
+    Environment env = new Environment();
+    env.update("VERSION", 42);
+    assertEquals(42, env.lookup("VERSION"));
+    env.update("VERSION", 43);
+    assertEquals(43, env.lookup("VERSION"));
+  }
+
+  // Test assign through interpreter, lookup through API:
+  public void testAssign() throws Exception {
+    Environment env = new Environment();
+
+    try {
+      env.lookup("foo");
+      fail();
+    } catch (Environment.NoSuchVariableException e) {
+      assertEquals("no such variable: foo", e.getMessage());
+    }
+
+    exec(parseStmt("foo = 'bar'"), env);
+
+    assertEquals("bar", env.lookup("foo"));
+  }
+
+  // Test update through API, reference through interpreter:
+  public void testReference() throws Exception {
+    Environment env = new Environment();
+
+    try {
+      eval(parseExpr("foo"), env);
+      fail();
+    } catch (EvalException e) {
+      assertEquals("name 'foo' is not defined", e.getMessage());
+    }
+
+    env.update("foo", "bar");
+
+    assertEquals("bar", eval(parseExpr("foo"), env));
+  }
+
+  // Test assign and reference through interpreter:
+  public void testAssignAndReference() throws Exception {
+    Environment env = new Environment();
+
+    try {
+      eval(parseExpr("foo"), env);
+      fail();
+    } catch (EvalException e) {
+      assertEquals("name 'foo' is not defined", e.getMessage());
+    }
+
+    exec(parseStmt("foo = 'bar'"), env);
+
+    assertEquals("bar", eval(parseExpr("foo"), env));
+  }
+
+  public void testGetVariableNames() throws Exception {
+    Environment env = new Environment();
+    env.update("foo", "bar");
+    env.update("wiz", 3);
+
+    Environment nestedEnv = new Environment(env);
+    nestedEnv.update("foo", "bat");
+    nestedEnv.update("quux", 42);
+
+    assertEquals(Sets.newHashSet("True", "False", "None", "foo", "wiz"), env.getVariableNames());
+    assertEquals(Sets.newHashSet("True", "False", "None", "foo", "wiz", "quux"),
+        nestedEnv.getVariableNames());
+  }
+
+  public void testToString() throws Exception {
+    Environment env = new Environment();
+    env.update("subject", new StringLiteral("Hello, 'world'.", '\''));
+    env.update("from", new StringLiteral("Java", '"'));
+    assertEquals("Environment{False -> false, None -> None, True -> true, from -> \"Java\", "
+        + "subject -> 'Hello, \\'world\\'.', }", env.toString());
+  }
+
+  public void testBindToNullThrowsException() throws Exception {
+    try {
+      new Environment().update("some_name", null);
+      fail();
+    } catch (NullPointerException e) {
+      assertEquals("update(value == null)", e.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
new file mode 100644
index 0000000..595055b
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
@@ -0,0 +1,221 @@
+// Copyright 2006 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.syntax;
+
+import com.google.common.collect.Lists;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.IllegalFormatException;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *  Test properties of the evaluator's datatypes and utility functions
+ *  without actually creating any parse trees.
+ */
+public class EvalUtilsTest extends TestCase {
+
+  private static List<?> makeList(Object ...args) {
+    return EvalUtils.makeSequence(Arrays.<Object>asList(args), false);
+  }
+  private static List<?> makeTuple(Object ...args) {
+    return EvalUtils.makeSequence(Arrays.<Object>asList(args), true);
+  }
+  private static Map<Object, Object> makeDict() {
+    return new LinkedHashMap<>();
+  }
+  private static FilesetEntry makeFilesetEntry() {
+    try {
+      return new FilesetEntry(Label.parseAbsolute("//foo:bar"),
+                              Lists.<Label>newArrayList(), Lists.newArrayList("xyz"), "",
+                              FilesetEntry.SymlinkBehavior.COPY, ".");
+    } catch (Label.SyntaxException e) {
+      throw new RuntimeException("Bad label: ", e);
+    }
+  }
+
+  public void testDataTypeNames() throws Exception {
+    assertEquals("string", EvalUtils.getDataTypeName("foo"));
+    assertEquals("int", EvalUtils.getDataTypeName(3));
+    assertEquals("tuple", EvalUtils.getDataTypeName(makeTuple(1, 2, 3)));
+    assertEquals("list",  EvalUtils.getDataTypeName(makeList(1, 2, 3)));
+    assertEquals("dict",  EvalUtils.getDataTypeName(makeDict()));
+    assertEquals("FilesetEntry",  EvalUtils.getDataTypeName(makeFilesetEntry()));
+    assertEquals("None", EvalUtils.getDataTypeName(Environment.NONE));
+  }
+
+  public void testDatatypeMutability() throws Exception {
+    assertTrue(EvalUtils.isImmutable("foo"));
+    assertTrue(EvalUtils.isImmutable(3));
+    assertTrue(EvalUtils.isImmutable(makeTuple(1, 2, 3)));
+    assertFalse(EvalUtils.isImmutable(makeList(1, 2, 3)));
+    assertFalse(EvalUtils.isImmutable(makeDict()));
+    assertFalse(EvalUtils.isImmutable(makeFilesetEntry()));
+  }
+
+  public void testPrintValue() throws Exception {
+    // Note that prettyPrintValue and printValue only differ on behaviour of
+    // labels and strings at toplevel.
+    assertEquals("foo\nbar", EvalUtils.printValue("foo\nbar"));
+    assertEquals("\"foo\\nbar\"", EvalUtils.prettyPrintValue("foo\nbar"));
+    assertEquals("'", EvalUtils.printValue("'"));
+    assertEquals("\"'\"", EvalUtils.prettyPrintValue("'"));
+    assertEquals("\"", EvalUtils.printValue("\""));
+    assertEquals("\"\\\"\"", EvalUtils.prettyPrintValue("\""));
+    assertEquals("3", EvalUtils.printValue(3));
+    assertEquals("3", EvalUtils.prettyPrintValue(3));
+    assertEquals("None", EvalUtils.prettyPrintValue(Environment.NONE));
+
+    assertEquals("//x:x", EvalUtils.printValue(Label.parseAbsolute("//x")));
+    assertEquals("\"//x:x\"", EvalUtils.prettyPrintValue(Label.parseAbsolute("//x")));
+
+    List<?> list = makeList("foo", "bar");
+    List<?> tuple = makeTuple("foo", "bar");
+
+    assertEquals("(1, [\"foo\", \"bar\"], 3)",
+                 EvalUtils.printValue(makeTuple(1, list, 3)));
+    assertEquals("(1, [\"foo\", \"bar\"], 3)",
+                 EvalUtils.prettyPrintValue(makeTuple(1, list, 3)));
+    assertEquals("[1, (\"foo\", \"bar\"), 3]",
+                 EvalUtils.printValue(makeList(1, tuple, 3)));
+    assertEquals("[1, (\"foo\", \"bar\"), 3]",
+                 EvalUtils.prettyPrintValue(makeList(1, tuple, 3)));
+
+    Map<Object, Object> dict = makeDict();
+    dict.put(1, tuple);
+    dict.put(2, list);
+    dict.put("foo", makeList());
+    assertEquals("{1: (\"foo\", \"bar\"), 2: [\"foo\", \"bar\"], \"foo\": []}",
+                EvalUtils.printValue(dict));
+    assertEquals("{1: (\"foo\", \"bar\"), 2: [\"foo\", \"bar\"], \"foo\": []}",
+                EvalUtils.prettyPrintValue(dict));
+    assertEquals("FilesetEntry(srcdir = \"//foo:bar\", files = [], "
+               + "excludes = [\"xyz\"], destdir = \"\", "
+               + "strip_prefix = \".\", symlinks = \"copy\")",
+                 EvalUtils.prettyPrintValue(makeFilesetEntry()));
+  }
+
+  private void checkFormatPositionalFails(String format, List<?> tuple,
+                                          String errorMessage) {
+    try {
+      EvalUtils.formatString(format, tuple);
+      fail();
+    } catch (IllegalFormatException e) {
+      assertEquals(errorMessage, e.getMessage());
+    }
+  }
+
+  public void testFormatPositional() throws Exception {
+    assertEquals("foo 3", EvalUtils.formatString("%s %d", makeTuple("foo", 3)));
+
+    // Note: formatString doesn't perform scalar x -> (x) conversion;
+    // The %-operator is responsible for that.
+    assertEquals("", EvalUtils.formatString("", makeTuple()));
+    assertEquals("foo", EvalUtils.formatString("%s", makeTuple("foo")));
+    assertEquals("3.14159", EvalUtils.formatString("%s", makeTuple(3.14159)));
+    checkFormatPositionalFails("%s", makeTuple(1, 2, 3),
+        "not all arguments converted during string formatting");
+    assertEquals("%foo", EvalUtils.formatString("%%%s", makeTuple("foo")));
+    checkFormatPositionalFails("%%s", makeTuple("foo"),
+        "not all arguments converted during string formatting");
+    checkFormatPositionalFails("% %s", makeTuple("foo"),
+        "invalid arguments for format string");
+    assertEquals("[1, 2, 3]", EvalUtils.formatString("%s", makeTuple(makeList(1, 2, 3))));
+    assertEquals("(1, 2, 3)", EvalUtils.formatString("%s", makeTuple(makeTuple(1, 2, 3))));
+    assertEquals("[]", EvalUtils.formatString("%s", makeTuple(makeList())));
+    assertEquals("()", EvalUtils.formatString("%s", makeTuple(makeTuple())));
+
+    checkFormatPositionalFails("%.3g", makeTuple(), "invalid arguments for format string");
+    checkFormatPositionalFails("%.3g", makeTuple(1, 2), "invalid arguments for format string");
+    checkFormatPositionalFails("%.s", makeTuple(), "invalid arguments for format string");
+  }
+
+  private String createExpectedFilesetEntryString(FilesetEntry.SymlinkBehavior symlinkBehavior) {
+    return "FilesetEntry(srcdir = \"//x:x\","
+           + " files = [\"//x:x\"],"
+           + " excludes = [],"
+           + " destdir = \"\","
+           + " strip_prefix = \".\","
+           + " symlinks = \"" + symlinkBehavior.toString().toLowerCase() + "\")";
+  }
+
+  private FilesetEntry createTestFilesetEntry(FilesetEntry.SymlinkBehavior symlinkBehavior)
+    throws Exception {
+    Label label = Label.parseAbsolute("//x");
+    return new FilesetEntry(label,
+                            Arrays.asList(label),
+                            Arrays.<String>asList(),
+                            "",
+                            symlinkBehavior,
+                            ".");
+  }
+
+  public void testFilesetEntrySymlinkAttr() throws Exception {
+    FilesetEntry entryDereference =
+      createTestFilesetEntry(FilesetEntry.SymlinkBehavior.DEREFERENCE);
+
+    assertEquals(createExpectedFilesetEntryString(FilesetEntry.SymlinkBehavior.DEREFERENCE),
+                 EvalUtils.prettyPrintValue(entryDereference));
+  }
+
+  private FilesetEntry createStripPrefixFilesetEntry(String stripPrefix)  throws Exception {
+    Label label = Label.parseAbsolute("//x");
+    return new FilesetEntry(
+        label,
+        Arrays.asList(label),
+        Arrays.<String>asList(),
+        "",
+        FilesetEntry.SymlinkBehavior.DEREFERENCE,
+        stripPrefix);
+  }
+
+  public void testFilesetEntryStripPrefixAttr() throws Exception {
+    FilesetEntry withoutStripPrefix = createStripPrefixFilesetEntry(".");
+    FilesetEntry withStripPrefix = createStripPrefixFilesetEntry("orange");
+
+    String prettyWithout = EvalUtils.prettyPrintValue(withoutStripPrefix);
+    String prettyWith = EvalUtils.prettyPrintValue(withStripPrefix);
+
+    assertTrue(prettyWithout.contains("strip_prefix = \".\""));
+    assertTrue(prettyWith.contains("strip_prefix = \"orange\""));
+  }
+
+  public void testRegressionCrashInPrettyPrintValue() throws Exception {
+    // Would cause crash in code such as this:
+    //  Fileset(name='x', entries=[], out=[FilesetEntry(files=['a'])])
+    // While formatting the "expected x, got y" message for the 'out'
+    // attribute, prettyPrintValue(FilesetEntry) would be recursively called
+    // with a List<Label> even though this isn't a valid datatype in the
+    // interpreter.
+    // Fileset isn't part of bazel, even though FilesetEntry is.
+    Label label = Label.parseAbsolute("//x");
+    assertEquals("FilesetEntry(srcdir = \"//x:x\","
+                 + " files = [\"//x:x\"],"
+                 + " excludes = [],"
+                 + " destdir = \"\","
+                 + " strip_prefix = \".\","
+                 + " symlinks = \"copy\")",
+                 EvalUtils.prettyPrintValue(
+                     new FilesetEntry(label,
+                                      Arrays.asList(label),
+                                      Arrays.<String>asList(),
+                                      "",
+                                      FilesetEntry.SymlinkBehavior.COPY,
+                                      ".")));
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
new file mode 100644
index 0000000..f7ed359
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
@@ -0,0 +1,492 @@
+// Copyright 2014 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.syntax;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.devtools.build.lib.packages.PackageFactory;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Test of evaluation behavior.  (Implicitly uses lexer + parser.)
+ */
+public class EvaluationTest extends AbstractEvaluationTestCase {
+
+  protected Environment env;
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    PackageFactory factory = new PackageFactory(TestRuleClassProvider.getRuleClassProvider());
+    env = factory.getEnvironment();
+  }
+
+  public Environment singletonEnv(String id, Object value) {
+    Environment env = new Environment();
+    env.update(id, value);
+    return env;
+  }
+
+  @Override
+  public Object eval(String input) throws Exception {
+    return eval(parseExpr(input), env);
+  }
+
+  public void testExprs() throws Exception {
+    assertEquals("fooxbar",
+                 eval("'%sx' % 'foo' + 'bar'"));
+    assertEquals("fooxbar",
+                 eval("('%sx' % 'foo') + 'bar'"));
+    assertEquals("foobarx",
+                 eval("'%sx' % ('foo' + 'bar')"));
+    assertEquals(579,
+                 eval("123 + 456"));
+    assertEquals(333,
+                 eval("456 - 123"));
+    assertEquals(2,
+                 eval("8 % 3"));
+
+    checkEvalError("3 % 'foo'", "unsupported operand type(s) for %: 'int' and 'string'");
+  }
+
+  public void testListExprs() throws Exception {
+    assertEquals(Arrays.asList(1, 2, 3),
+        eval("[1, 2, 3]"));
+    assertEquals(Arrays.asList(1, 2, 3),
+        eval("(1, 2, 3)"));
+  }
+
+  public void testStringFormatMultipleArgs() throws Exception {
+    assertEquals("XYZ", eval("'%sY%s' % ('X', 'Z')"));
+  }
+
+  public void testAndOr() throws Exception {
+    assertEquals(8, eval("8 or 9"));
+    assertEquals(8, eval("8 or foo")); // check that 'foo' is not evaluated
+    assertEquals(9, eval("0 or 9"));
+    assertEquals(9, eval("8 and 9"));
+    assertEquals(0, eval("0 and 9"));
+    assertEquals(0, eval("0 and foo")); // check that 'foo' is not evaluated
+
+    assertEquals(2, eval("1 and 2 or 3"));
+    assertEquals(3, eval("0 and 2 or 3"));
+    assertEquals(3, eval("1 and 0 or 3"));
+
+    assertEquals(1, eval("1 or 2 and 3"));
+    assertEquals(3, eval("0 or 2 and 3"));
+    assertEquals(0, eval("0 or 0 and 3"));
+    assertEquals(1, eval("1 or 0 and 3"));
+    assertEquals(1, eval("1 or 0 and 3"));
+
+    assertEquals(9, eval("\"\" or 9"));
+    assertEquals("abc", eval("\"abc\" or 9"));
+    assertEquals(Environment.NONE, eval("None and 1"));
+  }
+
+  public void testNot() throws Exception {
+    assertEquals(false, eval("not 1"));
+    assertEquals(true, eval("not ''"));
+  }
+
+  public void testNotWithLogicOperators() throws Exception {
+    assertEquals(0, eval("0 and not 0"));
+    assertEquals(0, eval("not 0 and 0"));
+
+    assertEquals(true, eval("1 and not 0"));
+    assertEquals(true, eval("not 0 or 0"));
+
+    assertEquals(0, eval("not 1 or 0"));
+    assertEquals(1, eval("not 1 or 1"));
+
+    assertEquals(true, eval("not (0 and 0)"));
+    assertEquals(false, eval("not (1 or 0)"));
+  }
+
+  public void testNotWithArithmeticOperators() throws Exception {
+    assertEquals(true, eval("not 0 + 0"));
+    assertEquals(false, eval("not 2 - 1"));
+  }
+
+  public void testNotWithCollections() throws Exception {
+    assertEquals(true, eval("not []"));
+    assertEquals(false, eval("not {'a' : 1}"));
+  }
+
+  public void testEquality() throws Exception {
+    assertEquals(true, eval("1 == 1"));
+    assertEquals(false, eval("1 == 2"));
+    assertEquals(true, eval("'hello' == 'hel' + 'lo'"));
+    assertEquals(false, eval("'hello' == 'bye'"));
+    assertEquals(true, eval("[1, 2] == [1, 2]"));
+    assertEquals(false, eval("[1, 2] == [2, 1]"));
+    assertEquals(true, eval("None == None"));
+  }
+
+  public void testInequality() throws Exception {
+    assertEquals(false, eval("1 != 1"));
+    assertEquals(true, eval("1 != 2"));
+    assertEquals(false, eval("'hello' != 'hel' + 'lo'"));
+    assertEquals(true, eval("'hello' != 'bye'"));
+    assertEquals(false, eval("[1, 2] != [1, 2]"));
+    assertEquals(true, eval("[1, 2] != [2, 1]"));
+  }
+
+  public void testEqualityPrecedence() throws Exception {
+    assertEquals(true, eval("1 + 3 == 2 + 2"));
+    assertEquals(true, eval("not 1 == 2"));
+    assertEquals(false, eval("not 1 != 2"));
+    assertEquals(true, eval("2 and 3 == 3 or 1"));
+    assertEquals(2, eval("2 or 3 == 3 and 1"));
+  }
+
+  public void testLessThan() throws Exception {
+    assertEquals(true, eval("1 <= 1"));
+    assertEquals(false, eval("1 < 1"));
+    assertEquals(true, eval("'a' <= 'b'"));
+    assertEquals(false, eval("'c' < 'a'"));
+  }
+
+  public void testGreaterThan() throws Exception {
+    assertEquals(true, eval("1 >= 1"));
+    assertEquals(false, eval("1 > 1"));
+    assertEquals(false, eval("'a' >= 'b'"));
+    assertEquals(true, eval("'c' > 'a'"));
+  }
+
+  public void testCompareStringInt() throws Exception {
+    checkEvalError("'a' >= 1", "Cannot compare string with int");
+  }
+
+  public void testNotComparable() throws Exception {
+    checkEvalError("[1, 2] < [1, 3]", "[1, 2] is not comparable");
+  }
+
+  public void testSumFunction() throws Exception {
+    Function sum = new AbstractFunction("sum") {
+        @Override
+        public Object call(List<Object> args, Map<String, Object> kwargs,
+            FuncallExpression ast, Environment env) {
+          int sum = 0;
+          for (Object arg : args) {
+            sum += (Integer) arg;
+          }
+          return sum;
+        }
+      };
+
+    Environment env = singletonEnv(sum.getName(), sum);
+
+    String callExpr = "sum(1, 2, 3, 4, 5, 6)";
+    assertEquals(21, eval(callExpr, env));
+
+    assertEquals(sum, eval("sum", env));
+
+    assertEquals(0, eval("sum(a=1, b=2)", env));
+
+    // rebind 'sum' in a new environment:
+    env = new Environment();
+    exec(parseStmt("sum = 123456"), env);
+
+    assertEquals(123456, env.lookup("sum"));
+
+    // now we can't call it any more:
+    checkEvalError(callExpr, env, "'int' object is not callable");
+
+    assertEquals(123456, eval("sum", env));
+  }
+
+  public void testKeywordArgs() throws Exception {
+
+    // This function returns the list of keyword-argument keys or values,
+    // depending on whether its first (integer) parameter is zero.
+    Function keyval = new AbstractFunction("keyval") {
+        @Override
+        public Object call(List<Object> args,
+                           final Map<String, Object> kwargs,
+                           FuncallExpression ast,
+                           Environment env) {
+          ArrayList<String> keys = new ArrayList<>(kwargs.keySet());
+          Collections.sort(keys);
+          if ((Integer) args.get(0) == 0) {
+            return keys;
+          } else {
+            return Lists.transform(keys, new com.google.common.base.Function<String, Object> () {
+                  @Override public Object apply (String s) {
+                    return kwargs.get(s);
+                  }});
+          }
+        }
+      };
+
+    Environment env = singletonEnv(keyval.getName(), keyval);
+
+    assertEquals(eval("['bar', 'foo', 'wiz']"),
+                 eval("keyval(0, foo=1, bar='bar', wiz=[1,2,3])", env));
+
+    assertEquals(eval("['bar', 1, [1,2,3]]"),
+                 eval("keyval(1, foo=1, bar='bar', wiz=[1,2,3])", env));
+  }
+
+  public void testMult() throws Exception {
+    assertEquals(42, eval("6 * 7"));
+
+    assertEquals("ababab", eval("3 * 'ab'"));
+    assertEquals("", eval("0 * 'ab'"));
+    assertEquals("100000", eval("'1' + '0' * 5"));
+  }
+
+  public void testConcatStrings() throws Exception {
+    assertEquals("foobar", eval("'foo' + 'bar'"));
+  }
+
+  public void testConcatLists() throws Exception {
+    // list
+    Object x = eval("[1,2] + [3,4]");
+    assertEquals(Arrays.asList(1, 2, 3, 4), x);
+    assertFalse(EvalUtils.isImmutable(x));
+
+    // tuple
+    x = eval("(1,2) + (3,4)");
+    assertEquals(Arrays.asList(1, 2, 3, 4), x);
+    assertTrue(EvalUtils.isImmutable(x));
+
+    checkEvalError("(1,2) + [3,4]", // list + tuple
+        "can only concatenate list (not \"tuple\") to list");
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testListComprehensions() throws Exception {
+    Iterable<Object> eval = (Iterable<Object>) eval(
+        "['foo/%s.java' % x for x in []]");
+    assertThat(eval).isEmpty();
+
+    eval = (Iterable<Object>) eval(
+        "['foo/%s.java' % x for x in ['bar', 'wiz', 'quux']]");
+    assertThat(eval).containsExactly("foo/bar.java", "foo/wiz.java", "foo/quux.java").inOrder();
+
+    eval = (Iterable<Object>) eval(
+        "['%s/%s.java' % (x, y) "
+        + "for x in ['foo', 'bar'] "
+        + "for y in ['baz', 'wiz', 'quux']]");
+    assertThat(eval).containsExactly("foo/baz.java", "foo/wiz.java", "foo/quux.java",
+        "bar/baz.java", "bar/wiz.java", "bar/quux.java").inOrder();
+
+    eval = (Iterable<Object>) eval(
+        "['%s/%s.java' % (x, x) "
+        + "for x in ['foo', 'bar'] "
+        + "for x in ['baz', 'wiz', 'quux']]");
+    assertThat(eval).containsExactly("baz/baz.java", "wiz/wiz.java", "quux/quux.java",
+        "baz/baz.java", "wiz/wiz.java", "quux/quux.java").inOrder();
+
+    eval = (Iterable<Object>) eval(
+        "['%s/%s.%s' % (x, y, z) "
+        + "for x in ['foo', 'bar'] "
+        + "for y in ['baz', 'wiz', 'quux'] "
+        + "for z in ['java', 'cc']]");
+    assertThat(eval).containsExactly("foo/baz.java", "foo/baz.cc", "foo/wiz.java", "foo/wiz.cc",
+        "foo/quux.java", "foo/quux.cc", "bar/baz.java", "bar/baz.cc", "bar/wiz.java", "bar/wiz.cc",
+        "bar/quux.java", "bar/quux.cc").inOrder();
+  }
+
+  // TODO(bazel-team): should this test work in Skylark?
+  @SuppressWarnings("unchecked")
+  public void testListComprehensionModifiesGlobalEnv() throws Exception {
+    Environment env = singletonEnv("x", 42);
+    assertThat((Iterable<Object>) eval(parseExpr("[x + 1 for x in [1,2,3]]"), env))
+        .containsExactly(2, 3, 4).inOrder();
+    assertEquals(3, env.lookup("x")); // (x is global)
+  }
+
+  public void testDictComprehensions() throws Exception {
+    assertEquals(Collections.emptyMap(), eval("{x : x for x in []}"));
+    assertEquals(ImmutableMap.of(1, 1, 2, 2), eval("{x : x for x in [1, 2]}"));
+    assertEquals(ImmutableMap.of("a", "v_a", "b", "v_b"),
+        eval("{x : 'v_' + x for x in ['a', 'b']}"));
+    assertEquals(ImmutableMap.of("k_a", "a", "k_b", "b"),
+        eval("{'k_' + x : x for x in ['a', 'b']}"));
+    assertEquals(ImmutableMap.of("k_a", "v_a", "k_b", "v_b"),
+        eval("{'k_' + x : 'v_' + x for x in ['a', 'b']}"));
+  }
+
+  public void testDictComprehensions_MultipleKey() throws Exception {
+    assertEquals(ImmutableMap.of(1, 1, 2, 2), eval("{x : x for x in [1, 2, 1]}"));
+    assertEquals(ImmutableMap.of("ab", "ab", "c", "c"),
+        eval("{x : x for x in ['ab', 'c', 'a' + 'b']}"));
+  }
+
+  public void testDictComprehensions_ToString() throws Exception {
+    assertEquals("{x: x for x in [1, 2]}", parseExpr("{x : x for x in [1, 2]}").toString());
+    assertEquals("{x + 'a': x for x in [1, 2]}",
+        parseExpr("{x + 'a' : x for x in [1, 2]}").toString());
+  }
+
+  public void testListConcatenation() throws Exception {
+    assertEquals(Arrays.asList(1, 2, 3, 4), eval("[1, 2] + [3, 4]", env));
+    assertEquals(ImmutableList.of(1, 2, 3, 4), eval("(1, 2) + (3, 4)", env));
+    checkEvalError("[1, 2] + (3, 4)", "can only concatenate tuple (not \"list\") to tuple");
+    checkEvalError("(1, 2) + [3, 4]", "can only concatenate list (not \"tuple\") to list");
+  }
+
+  public void testListComprehensionFailsOnNonSequence() throws Exception {
+    checkEvalError("[x + 1 for x in 123]", "type 'int' is not an iterable");
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testListComprehensionOnString() throws Exception {
+    assertThat((Iterable<Object>) eval("[x for x in 'abc']")).containsExactly("a", "b", "c")
+        .inOrder();
+  }
+
+  public void testInvalidAssignment() throws Exception {
+    Environment env = singletonEnv("x", 1);
+    checkEvalError(parseStmt("x + 1 = 2"), env, "can only assign to variables, not to 'x + 1'");
+  }
+
+  public void testListComprehensionOnDictionary() throws Exception {
+    List<Statement> input = parseFile("val = ['var_' + n for n in {'a':1,'b':2}]");
+    exec(input, env);
+    Iterable<?> result = (Iterable<?>) env.lookup("val");
+    assertThat(result).hasSize(2);
+    assertEquals("var_a", Iterables.get(result, 0));
+    assertEquals("var_b", Iterables.get(result, 1));
+  }
+
+  public void testListComprehensionOnDictionaryCompositeExpression() throws Exception {
+    exec(parseFile("d = {1:'a',2:'b'}\n"
+                  + "l = [d[x] for x in d]"), env);
+    assertEquals("[a, b]", env.lookup("l").toString());
+  }
+
+  public void testInOnListContains() throws Exception {
+    assertEquals(Boolean.TRUE, eval("'b' in ['a', 'b']"));
+  }
+
+  public void testInOnListDoesNotContain() throws Exception {
+    assertEquals(Boolean.FALSE, eval("'c' in ['a', 'b']"));
+  }
+
+  public void testInOnTupleContains() throws Exception {
+    assertEquals(Boolean.TRUE, eval("'b' in ('a', 'b')"));
+  }
+
+  public void testInOnTupleDoesNotContain() throws Exception {
+    assertEquals(Boolean.FALSE, eval("'c' in ('a', 'b')"));
+  }
+
+  public void testInOnDictContains() throws Exception {
+    assertEquals(Boolean.TRUE, eval("'b' in {'a' : 1, 'b' : 2}"));
+  }
+
+  public void testInOnDictDoesNotContainKey() throws Exception {
+    assertEquals(Boolean.FALSE, eval("'c' in {'a' : 1, 'b' : 2}"));
+  }
+
+  public void testInOnDictDoesNotContainVal() throws Exception {
+    assertEquals(Boolean.FALSE, eval("1 in {'a' : 1, 'b' : 2}"));
+  }
+
+  public void testInOnStringContains() throws Exception {
+    assertEquals(Boolean.TRUE, eval("'b' in 'abc'"));
+  }
+
+  public void testInOnStringDoesNotContain() throws Exception {
+    assertEquals(Boolean.FALSE, eval("'d' in 'abc'"));
+  }
+
+  public void testInOnStringLeftNotString() throws Exception {
+    checkEvalError("1 in '123'",
+        "in operator only works on strings if the left operand is also a string");
+  }
+
+  public void testInFailsOnNonIterable() throws Exception {
+    checkEvalError("'a' in 1",
+        "in operator only works on lists, tuples, dictionaries and strings");
+  }
+
+  public void testInCompositeForPrecedence() throws Exception {
+    assertEquals(0, eval("not 'a' in ['a'] or 0"));
+  }
+
+  private Object createObjWithStr() {
+    return new Object() {
+      @Override
+      public String toString() {
+        return "str marker";
+      }
+    };
+  }
+
+  public void testPercOnObject() throws Exception {
+    env.update("obj", createObjWithStr());
+    assertEquals("str marker", eval("'%s' % obj", env));
+  }
+
+  public void testPercOnObjectList() throws Exception {
+    env.update("obj", createObjWithStr());
+    assertEquals("str marker str marker", eval("'%s %s' % (obj, obj)", env));
+  }
+
+  public void testPercOnObjectInvalidFormat() throws Exception {
+    env.update("obj", createObjWithStr());
+    checkEvalError("'%d' % obj", env, "invalid arguments for format string");
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testDictKeys() throws Exception {
+    exec("v = {'a': 1}.keys() + ['b', 'c']", env);
+    assertThat((Iterable<Object>) env.lookup("v")).containsExactly("a", "b", "c").inOrder();
+  }
+
+  public void testDictKeysTooManyArgs() throws Exception {
+    checkEvalError("{'a': 1}.keys('abc')", env, "Invalid number of arguments (expected 0)");
+    checkEvalError("{'a': 1}.keys(arg='abc')", env, "Invalid number of arguments (expected 0)");
+  }
+
+  protected void checkEvalError(String input, String msg) throws Exception {
+    checkEvalError(input, env, msg);
+  }
+
+  protected void checkEvalError(String input, Environment env, String msg) throws Exception {
+    try {
+      eval(input, env);
+      fail();
+    } catch (EvalException e) {
+      assertEquals(msg, e.getMessage());
+    }
+  }
+
+  protected void checkEvalError(Statement input, Environment env, String msg) throws Exception {
+    checkEvalError(ImmutableList.of(input), env, msg);
+  }
+
+  protected void checkEvalError(List<Statement> input, Environment env, String msg)
+      throws Exception {
+    try {
+      exec(input, env);
+      fail();
+    } catch (EvalException e) {
+      assertEquals(msg, e.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java b/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
new file mode 100644
index 0000000..fc14922
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
@@ -0,0 +1,424 @@
+// Copyright 2014 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.syntax;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.packages.MethodLibrary;
+import com.google.devtools.build.lib.syntax.SkylarkType.SkylarkFunctionType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A test class for functions and scoping.
+ */
+public class FunctionTest extends AbstractEvaluationTestCase {
+
+  private Environment env;
+
+  private static final ImmutableMap<String, SkylarkType> OUTER_FUNC_TYPES =
+      ImmutableMap.<String, SkylarkType>of(
+          "outer_func", SkylarkFunctionType.of("outer_func", SkylarkType.NONE));
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    env = new SkylarkEnvironment(syntaxEvents.collector());
+  }
+
+  public void testFunctionDef() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def func(a,b,c):\n"
+        + "  a = 1\n"
+        + "  b = a\n");
+
+    exec(input, env);
+    UserDefinedFunction stmt = (UserDefinedFunction) env.lookup("func");
+    assertNotNull(stmt);
+    assertEquals("func", stmt.getName());
+    assertEquals(3, stmt.getFunctionSignature().getSignature().getShape().getMandatoryPositionals());
+    assertThat(stmt.getStatements()).hasSize(2);
+  }
+
+  public void testFunctionDefDuplicateArguments() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark(
+        "def func(a,b,a):\n"
+        + "  a = 1\n");
+    syntaxEvents.assertContainsEvent("duplicate parameter name in function definition");
+  }
+
+  public void testFunctionDefCallOuterFunc() throws Exception {
+    final List<Object> params = new ArrayList<>();
+    List<Statement> input = parseFileForSkylark(
+        "def func(a):\n"
+        + "  outer_func(a)\n"
+        + "func(1)\n"
+        + "func(2)",
+        OUTER_FUNC_TYPES);
+    createOuterFunction(env, params);
+    exec(input, env);
+    assertThat(params).containsExactly(1, 2).inOrder();
+  }
+
+  private void createOuterFunction(Environment env, final List<Object> params) {
+    Function outerFunc = new AbstractFunction("outer_func") {
+
+      @Override
+      public Object call(List<Object> args, Map<String, Object> kwargs, FuncallExpression ast,
+          Environment env) throws EvalException, InterruptedException {
+        params.addAll(args);
+        return Environment.NONE;
+      }
+    };
+    env.update("outer_func", outerFunc);
+  }
+
+  public void testFunctionDefNoEffectOutsideScope() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def func():\n"
+        + "  a = 2\n"
+        + "func()\n");
+    env.update("a", 1);
+    exec(input, env);
+    assertEquals(1, env.lookup("a"));
+  }
+
+  public void testFunctionDefGlobalVaribleReadInFunction() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = 1\n"
+        + "def func():\n"
+        + "  b = a\n"
+        + "  return b\n"
+        + "c = func()\n");
+    exec(input, env);
+    assertEquals(1, env.lookup("c"));
+  }
+
+  public void testFunctionDefLocalGlobalScope() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = 1\n"
+        + "def func():\n"
+        + "  a = 2\n"
+        + "  b = a\n"
+        + "  return b\n"
+        + "c = func()\n");
+    exec(input, env);
+    assertEquals(2, env.lookup("c"));
+  }
+
+  public void testFunctionDefLocalVariableReferencedBeforeAssignment() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = 1\n"
+        + "def func():\n"
+        + "  b = a\n"
+        + "  a = 2\n"
+        + "  return b\n"
+        + "c = func()\n");
+    try {
+      exec(input, env);
+      fail();
+    } catch (EvalException e) {
+      assertThat(e.getMessage()).contains("Variable 'a' is referenced before assignment.");
+    }
+  }
+
+  public void testFunctionDefLocalVariableReferencedAfterAssignment() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = 1\n"
+        + "def func():\n"
+        + "  a = 2\n"
+        + "  b = a\n"
+        + "  a = 3\n"
+        + "  return b\n"
+        + "c = func()\n");
+    exec(input, env);
+    assertEquals(2, env.lookup("c"));
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testSkylarkGlobalComprehensionIsAllowed() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = [i for i in [1, 2, 3]]\n");
+    exec(input, env);
+    assertThat((Iterable<Object>) env.lookup("a")).containsExactly(1, 2, 3).inOrder();
+  }
+
+  public void testFunctionReturn() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def func():\n"
+        + "  return 2\n"
+        + "b = func()\n");
+    exec(input, env);
+    assertEquals(2, env.lookup("b"));
+  }
+
+  public void testFunctionReturnFromALoop() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def func():\n"
+        + "  for i in [1, 2, 3, 4, 5]:\n"
+        + "    return i\n"
+        + "b = func()\n");
+    exec(input, env);
+    assertEquals(1, env.lookup("b"));
+  }
+
+  public void testFunctionExecutesProperly() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def func(a):\n"
+        + "  b = 1\n"
+        + "  if a:\n"
+        + "    b = 2\n"
+        + "  return b\n"
+        + "c = func(0)\n"
+        + "d = func(1)\n");
+    exec(input, env);
+    assertEquals(1, env.lookup("c"));
+    assertEquals(2, env.lookup("d"));
+  }
+
+  public void testFunctionCallFromFunction() throws Exception {
+    final List<Object> params = new ArrayList<>();
+    List<Statement> input = parseFileForSkylark(
+        "def func2(a):\n"
+        + "  outer_func(a)\n"
+        + "def func1(b):\n"
+        + "  func2(b)\n"
+        + "func1(1)\n"
+        + "func1(2)\n",
+        OUTER_FUNC_TYPES);
+    createOuterFunction(env, params);
+    exec(input, env);
+    assertThat(params).containsExactly(1, 2).inOrder();
+  }
+
+  public void testFunctionCallFromFunctionReadGlobalVar() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = 1\n"
+        + "def func2():\n"
+        + "  return a\n"
+        + "def func1():\n"
+        + "  return func2()\n"
+        + "b = func1()\n");
+    exec(input, env);
+    assertEquals(1, env.lookup("b"));
+  }
+
+  public void testSingleLineFunction() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def func(): return 'a'\n"
+        + "s = func()\n");
+    exec(input, env);
+    assertEquals("a", env.lookup("s"));
+  }
+
+  public void testFunctionReturnsDictionary() throws Exception {
+    MethodLibrary.setupMethodEnvironment(env);
+    List<Statement> input = parseFileForSkylark(
+        "def func(): return {'a' : 1}\n"
+        + "d = func()\n"
+        + "a = d['a']\n");
+    exec(input, env);
+    assertEquals(1, env.lookup("a"));
+  }
+
+  public void testFunctionReturnsList() throws Exception {
+    MethodLibrary.setupMethodEnvironment(env);
+    List<Statement> input = parseFileForSkylark(
+        "def func(): return [1, 2, 3]\n"
+        + "d = func()\n"
+        + "a = d[1]\n");
+    exec(input, env);
+    assertEquals(2, env.lookup("a"));
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testFunctionListArgumentsAreImmutable() throws Exception {
+    MethodLibrary.setupMethodEnvironment(env);
+    List<Statement> input = parseFileForSkylark(
+          "l = [1]\n"
+        + "def func(l):\n"
+        + "  l += [2]\n"
+        + "func(l)");
+    exec(input, env);
+    assertThat((Iterable<Object>) env.lookup("l")).containsExactly(1);
+  }
+
+  public void testFunctionDictArgumentsAreImmutable() throws Exception {
+    MethodLibrary.setupMethodEnvironment(env);
+    List<Statement> input = parseFileForSkylark(
+          "d = {'a' : 1}\n"
+        + "def func(d):\n"
+        + "  d += {'a' : 2}\n"
+        + "func(d)");
+    exec(input, env);
+    assertEquals(ImmutableMap.of("a", 1), env.lookup("d"));
+  }
+
+  public void testFunctionNameAliasing() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+          "def func(a):\n"
+        + "  return a + 1\n"
+        + "alias = func\n"
+        + "r = alias(1)");
+    exec(input, env);
+    assertEquals(2, env.lookup("r"));
+  }
+
+  public void testCallingFunctionsWithMixedModeArgs() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+          "def func(a, b, c):\n"
+        + "  return a + b + c\n"
+        + "v = func(1, c = 2, b = 3)");
+    exec(input, env);
+    assertEquals(6, env.lookup("v"));
+  }
+
+  private String functionWithOptionalArgs() {
+    return "def func(a, b = None, c = None):\n"
+         + "  r = a + 'a'\n"
+         + "  if b:\n"
+         + "    r += 'b'\n"
+         + "  if c:\n"
+         + "    r += 'c'\n"
+         + "  return r\n";
+  }
+
+  public void testWhichOptionalArgsAreDefinedForFunctions() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        functionWithOptionalArgs()
+        + "v1 = func('1', 1, 1)\n"
+        + "v2 = func(b = 2, a = '2', c = 2)\n"
+        + "v3 = func('3')\n"
+        + "v4 = func('4', c = 1)\n");
+    exec(input, env);
+    assertEquals("1abc", env.lookup("v1"));
+    assertEquals("2abc", env.lookup("v2"));
+    assertEquals("3a", env.lookup("v3"));
+    assertEquals("4ac", env.lookup("v4"));
+  }
+
+  public void testDefaultArguments() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+          "def func(a, b = 'b', c = 'c'):\n"
+        + "  return a + b + c\n"
+        + "v1 = func('a', 'x', 'y')\n"
+        + "v2 = func(b = 'x', a = 'a', c = 'y')\n"
+        + "v3 = func('a')\n"
+        + "v4 = func('a', c = 'y')\n");
+    exec(input, env);
+    assertEquals("axy", env.lookup("v1"));
+    assertEquals("axy", env.lookup("v2"));
+    assertEquals("abc", env.lookup("v3"));
+    assertEquals("aby", env.lookup("v4"));
+  }
+
+  public void testDefaultArgumentsInsufficientArgNum() throws Exception {
+    checkError("func(a, b = null, c = null) received insufficient arguments",
+        "def func(a, b = 'b', c = 'c'):",
+        "  return a + b + c",
+        "func()");
+  }
+
+  public void testKwargs() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo(a, b = 'b', c = 'c'):\n"
+      + "  return a + b + c\n"
+      + "args = {'a': 'x', 'c': 'z'}\n"
+      + "v1 = foo(**args)\n"
+      + "v2 = foo('x', **{'b': 'y'})\n"
+      + "v3 = foo(c = 'z', a = 'x', **{'b': 'y'})");
+    exec(input, env);
+    assertEquals("xbz", env.lookup("v1"));
+    assertEquals("xyc", env.lookup("v2"));
+    assertEquals("xyz", env.lookup("v3"));
+  }
+
+  public void testKwargsBadKey() throws Exception {
+    checkError("Keywords must be strings, not int",
+        "def func(a, b):",
+        "  return a + b",
+        "func('a', **{3: 1})");
+  }
+
+  public void testKwargsIsNotDict() throws Exception {
+    checkError("Argument after ** must be a dictionary, not int",
+        "def func(a, b):",
+        "  return a + b",
+        "func('a', **42)");
+  }
+
+  public void testKwargsCollision() throws Exception {
+    checkError("func(a, b) got multiple values for keyword argument 'b'",
+        "def func(a, b):",
+        "  return a + b",
+        "func('a', 'b', **{'b': 'foo'})");
+  }
+
+  public void testKwargsCollisionWithNamed() throws Exception {
+    checkError("duplicate keyword 'b' in call to func",
+        "def func(a, b):",
+        "  return a + b",
+        "func('a', b = 'b', **{'b': 'foo'})");
+  }
+
+  public void testDefaultArguments2() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "a = 2\n"
+        + "def foo(x=a): return x\n"
+        + "def bar():\n"
+        + "  a = 3\n"
+        + "  return foo()\n"
+        + "v = bar()\n");
+    exec(input, env);
+    assertEquals(2, env.lookup("v"));
+  }
+
+  public void testMixingPositionalOptional() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+                "def f(name, value = '', optional = ''): return value\n"
+                + "v = f('name', 'value')\n");
+    exec(input, env);
+    assertEquals("value", env.lookup("v"));
+  }
+
+  public void testStarArg() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+                "def f(name, value = '1', optional = '2'): return name + value + optional\n"
+                        + "v1 = f(*['name', 'value'])\n"
+                        + "v2 = f('0', *['name', 'value'])\n"
+                        + "v3 = f('0', *['b'], optional = '3')\n"
+                + "v4 = f(*[],name='a')\n");
+    exec(input, env);
+    assertEquals("namevalue2", env.lookup("v1"));
+    assertEquals("0namevalue", env.lookup("v2"));
+    assertEquals("0b3", env.lookup("v3"));
+    assertEquals("a12", env.lookup("v4"));
+  }
+
+  private void checkError(String msg, String... lines)
+      throws Exception {
+    try {
+      List<Statement> input = parseFileForSkylark(Joiner.on("\n").join(lines));
+      exec(input, env);
+      fail();
+    } catch (EvalException e) {
+      assertEquals(msg, e.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/GlobCriteriaTest.java b/src/test/java/com/google/devtools/build/lib/syntax/GlobCriteriaTest.java
new file mode 100644
index 0000000..75fed7d
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/GlobCriteriaTest.java
@@ -0,0 +1,169 @@
+// Copyright 2009 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.syntax;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.testutil.Suite;
+import com.google.devtools.build.lib.testutil.TestSpec;
+
+import junit.framework.TestCase;
+
+/**
+ * Links for {@link GlobCriteria}
+ */
+@TestSpec(size = Suite.SMALL_TESTS)
+public class GlobCriteriaTest extends TestCase {
+
+  public void testParse_EmptyList() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("[]");
+    assertFalse(gc.isGlob());
+    assertTrue(gc.getIncludePatterns().isEmpty());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_SingleList() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("['abc']");
+    assertFalse(gc.isGlob());
+    assertEquals(ImmutableList.of("abc"), gc.getIncludePatterns());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_MultipleList() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("['abc', 'def', 'ghi']");
+    assertFalse(gc.isGlob());
+    assertEquals(ImmutableList.of("abc", "def", "ghi"), gc.getIncludePatterns());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_EmptyGlob() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob([])");
+    assertTrue(gc.isGlob());
+    assertTrue(gc.getIncludePatterns().isEmpty());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_SingleGlob() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob(['abc'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("abc"), gc.getIncludePatterns());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_MultipleGlob() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob(['abc', 'def', 'ghi'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("abc", "def", "ghi"), gc.getIncludePatterns());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_EmptyGlobWithExclude() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob([], exclude=['xyz'])");
+    assertTrue(gc.isGlob());
+    assertTrue(gc.getIncludePatterns().isEmpty());
+    assertEquals(ImmutableList.of("xyz"), gc.getExcludePatterns());
+  }
+
+  public void testParse_SingleGlobWithExclude() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob(['abc'], exclude=['xyz'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("abc"), gc.getIncludePatterns());
+    assertEquals(ImmutableList.of("xyz"), gc.getExcludePatterns());
+  }
+
+  public void testParse_MultipleGlobWithExclude() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob(['abc', 'def', 'ghi'], exclude=['xyz'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("abc", "def", "ghi"), gc.getIncludePatterns());
+    assertEquals(ImmutableList.of("xyz"), gc.getExcludePatterns());
+  }
+
+  public void testParse_MultipleGlobWithMultipleExclude() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse(
+        "glob(['abc', 'def', 'ghi'], exclude=['rst', 'uvw', 'xyz'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("abc", "def", "ghi"), gc.getIncludePatterns());
+    assertEquals(ImmutableList.of("rst", "uvw", "xyz"), gc.getExcludePatterns());
+  }
+
+  public void testParse_GlobWithSlashesAndWildcards() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob(['java/src/net/jsunit/*.java'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("java/src/net/jsunit/*.java"), gc.getIncludePatterns());
+    assertTrue(gc.getExcludePatterns().isEmpty());
+  }
+
+  public void testParse_ExcludeWithInvalidLabel() throws Exception {
+    GlobCriteria gc = GlobCriteria.parse("glob(['abc', 'def', 'ghi'], exclude=['xyz~'])");
+    assertTrue(gc.isGlob());
+    assertEquals(ImmutableList.of("abc", "def", "ghi"), gc.getIncludePatterns());
+    assertEquals(ImmutableList.of("xyz~"), gc.getExcludePatterns());
+  }
+
+  public void testParse_InvalidFormat_TooManySpacesList() throws Exception {
+    try {
+      GlobCriteria.parse("glob(['abc,  'def', 'ghi'], exclude=['xyz~'])");
+      fail();
+    } catch (IllegalArgumentException e) {
+      // expected
+    }
+  }
+
+  public void testParse_InvalidFormat_MissingQuote() throws Exception {
+    try {
+      GlobCriteria.parse("glob(['abc, 'def', 'ghi'], exclude=['xyz~'])");
+      fail();
+    } catch (IllegalArgumentException e) {
+      // expected
+    }
+  }
+
+  public void testParse_InvalidFormat_TooManySpacesExclude() throws Exception {
+    try {
+      GlobCriteria.parse("glob(['abc', 'def', 'ghi'],  exclude=['xyz~'])");
+      fail();
+    } catch (IllegalArgumentException e) {
+      // expected
+    }
+  }
+
+  public void testParse_InvalidFormat_MissingQuoteExclude() throws Exception {
+    try {
+      GlobCriteria.parse("glob(['abc, 'def', 'ghi'], exclude=['xyz~])");
+      fail();
+    } catch (IllegalArgumentException e) {
+      // expected
+    }
+  }
+
+  public void testParse_InvalidFormat_ExcludeWithList() throws Exception {
+    try {
+      GlobCriteria.parse("['abc, 'def', 'ghi'], exclude=['xyz~']");
+      fail();
+    } catch (IllegalArgumentException e) {
+      // expected
+    }
+  }
+
+  public void testParse_veryLongString() throws Exception {
+    StringBuilder builder = new StringBuilder();
+    builder.append("['File0.java'");
+    for (int i = 1; i < 5000; ++i) {
+      builder.append(", 'File").append(i).append(".java'");
+    }
+    builder.append("]");
+    String s = builder.toString();
+    GlobCriteria gc = GlobCriteria.parse(s);
+    assertEquals(s, gc.toString());
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/GlobListTest.java b/src/test/java/com/google/devtools/build/lib/syntax/GlobListTest.java
new file mode 100644
index 0000000..94e0667
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/GlobListTest.java
@@ -0,0 +1,103 @@
+// Copyright 2009 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.syntax;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.testutil.Suite;
+import com.google.devtools.build.lib.testutil.TestSpec;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.List;
+
+/**
+ * Tests for {@link GlobList}
+ */
+@TestSpec(size = Suite.SMALL_TESTS)
+@RunWith(JUnit4.class)
+public class GlobListTest {
+
+  @Test
+  public void testParse_glob() throws Exception {
+    String expression = "glob(['abc'])";
+    assertEquals(expression, GlobList.parse(expression).toExpression());
+  }
+
+  @Test
+  public void testParse_multipleGlobs() throws Exception {
+    String expression = "glob(['abc']) + glob(['def']) + glob(['ghi'])";
+    assertEquals(expression, GlobList.parse(expression).toExpression());
+  }
+
+  @Test
+  public void testParse_multipleLists() throws Exception {
+    String expression = "['abc'] + ['def'] + ['ghi']";
+    assertEquals(expression, GlobList.parse(expression).toExpression());
+  }
+
+  @Test
+  public void testParse_complexExpression() throws Exception {
+    String expression = "glob(['abc', 'def', 'ghi'], "
+      + "exclude=['rst', 'uvw', 'xyz']) "
+      + "+ glob(['abc', 'def', 'ghi'], exclude=['rst', 'uvw', 'xyz'])";
+    assertEquals(expression, GlobList.parse(expression).toExpression());
+  }
+
+  @Test
+  public void testConcat_GlobToGlob() throws Exception {
+    GlobList<String> glob1 = GlobList.parse(
+        "glob(['abc'], exclude=['def']) + glob(['xyz'])");
+    GlobList<String> glob2 = GlobList.parse(
+        "glob(['xyzzy']) + glob(['foo'], exclude=['bar'])");
+    GlobList<String> cat = GlobList.concat(glob1, glob2);
+    assertEquals(glob1.toExpression() + " + " + glob2.toExpression(), cat.toExpression());
+  }
+
+  @Test
+  public void testConcat_GlobToList() throws Exception {
+    GlobList<String> glob = GlobList.parse(
+        "glob(['abc'], exclude=['def']) + glob(['xyz'])");
+    List<String> list = ImmutableList.of("xyzzy", "foo", "bar");
+    GlobList<String> cat = GlobList.concat(list, glob);
+    assertEquals("['xyzzy', 'foo', 'bar'] + glob(['abc'], exclude=['def']) + glob(['xyz'])",
+        cat.toExpression());
+  }
+
+  @Test
+  public void testConcat_ListToGlob() throws Exception {
+    GlobList<String> glob = GlobList.parse(
+        "glob(['abc'], exclude=['def']) + glob(['xyz'])");
+    List<String> list = ImmutableList.of("xyzzy", "foo", "bar");
+    GlobList<String> cat = GlobList.concat(glob, list);
+    assertEquals("glob(['abc'], exclude=['def']) + glob(['xyz']) + ['xyzzy', 'foo', 'bar']",
+        cat.toExpression());
+  }
+
+  @Test
+  public void testGetCriteria() throws Exception {
+    List<String> include = ImmutableList.of("abc", "def", "ghi");
+    List<String> exclude = ImmutableList.of("rst", "uvw", "xyz");
+    List<String> matches = ImmutableList.of("xyzzy", "foo", "bar");
+    GlobList<String> glob = GlobList.captureResults(include, exclude, matches);
+    assertEquals(matches, glob);
+    ImmutableList<GlobCriteria> criteria = glob.getCriteria();
+    assertEquals(1, criteria.size());
+    assertEquals(include, criteria.get(0).getIncludePatterns());
+    assertEquals(exclude, criteria.get(0).getExcludePatterns());
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LabelTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LabelTest.java
new file mode 100644
index 0000000..a0daf20
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LabelTest.java
@@ -0,0 +1,364 @@
+// Copyright 2005 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.syntax;
+
+import static com.google.devtools.build.lib.testutil.MoreAsserts.assertContainsRegex;
+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.devtools.build.lib.syntax.Label.SyntaxException;
+import com.google.devtools.build.lib.testutil.TestUtils;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.regex.Pattern;
+
+/**
+ * Tests for {@link Label}.
+ */
+@RunWith(JUnit4.class)
+public class LabelTest {
+
+  private static final String BAD_PACKAGE_CHARS =
+      "package names may contain only A-Z, a-z, 0-9, '/', '-' and '_'";
+
+  private static final String TARGET_UPLEVEL =
+      "target names may not contain up-level references '..'";
+
+  @Test
+  public void testAbsolute() throws Exception {
+    {
+      Label l = Label.parseAbsolute("//foo/bar:baz");
+      assertEquals("foo/bar", l.getPackageName());
+      assertEquals("baz", l.getName());
+    }
+    {
+      Label l = Label.parseAbsolute("//foo/bar");
+      assertEquals("foo/bar", l.getPackageName());
+      assertEquals("bar", l.getName());
+    }
+  }
+
+  private static String parseCommandLine(String label, String prefix) throws SyntaxException {
+    return Label.parseCommandLineLabel(label, new PathFragment(prefix)).toString();
+  }
+
+  @Test
+  public void testLabelResolution() throws Exception {
+    assertEquals("//absolute:label", parseCommandLine("//absolute:label", ""));
+    assertEquals("//absolute:label", parseCommandLine("//absolute:label", "absolute"));
+    assertEquals("//absolute:label", parseCommandLine(":label", "absolute"));
+    assertEquals("//absolute:label", parseCommandLine("label", "absolute"));
+    assertEquals("//absolute:label", parseCommandLine("absolute:label", ""));
+    assertEquals("//absolute/path:label", parseCommandLine("path:label", "absolute"));
+    assertEquals("//absolute/path:label/path", parseCommandLine("path:label/path", "absolute"));
+    assertEquals("//absolute:label/path", parseCommandLine("label/path", "absolute"));
+  }
+
+  @Test
+  public void testLabelResolutionAbsolutePath() throws Exception {
+    try {
+      parseCommandLine("//absolute:label", "/absolute");
+      fail();
+    } catch (IllegalArgumentException e) {
+      // Expected exception
+    }
+  }
+
+  @Test
+  public void testLabelResolutionBadSyntax() throws Exception {
+    try {
+      parseCommandLine("//absolute:A+bad%syntax", "");
+      fail();
+    } catch (SyntaxException e) {
+      // Expected exception
+    }
+  }
+
+  @Test
+  public void testGetRelative() throws Exception {
+    Label base = Label.parseAbsolute("//foo/bar:baz");
+    {
+      Label l = base.getRelative("//p1/p2:target");
+      assertEquals("p1/p2", l.getPackageName());
+      assertEquals("target", l.getName());
+    }
+    {
+      Label l = base.getRelative(":quux");
+      assertEquals("foo/bar", l.getPackageName());
+      assertEquals("quux", l.getName());
+    }
+    try {
+      base.getRelative("/p1/p2:target");
+      fail();
+    } catch (Label.SyntaxException e) {
+      /* ok */
+    }
+    try {
+      base.getRelative("quux:");
+      fail();
+    } catch (Label.SyntaxException e) {
+      /* ok */
+    }
+    try {
+      base.getRelative(":");
+      fail();
+    } catch (Label.SyntaxException e) {
+      /* ok */
+    }
+    try {
+      base.getRelative("::");
+      fail();
+    } catch (Label.SyntaxException e) {
+      /* ok */
+    }
+  }
+
+  @Test
+  public void testFactory() throws Exception {
+    Label l = Label.create("foo/bar", "quux");
+    assertEquals("foo/bar", l.getPackageName());
+    assertEquals("quux", l.getName());
+  }
+
+  @Test
+  public void testIdentities() throws Exception {
+
+    Label l1 = Label.parseAbsolute("//foo/bar:baz");
+    Label l2 = Label.parseAbsolute("//foo/bar:baz");
+    Label l3 = Label.parseAbsolute("//foo/bar:quux");
+
+    assertTrue(l1.equals(l1));
+    assertTrue(l2.equals(l1));
+    assertTrue(l1.equals(l2));
+    assertTrue(l2.equals(l1));
+
+    assertFalse(l3.equals(l1));
+    assertFalse(l1.equals(l3));
+
+    assertEquals(l1.hashCode(), l2.hashCode());
+  }
+
+  @Test
+  public void testToString() throws Exception {
+    {
+      String s = "//foo/bar:baz";
+      Label l = Label.parseAbsolute(s);
+      assertEquals(s, l.toString());
+    }
+    {
+      Label l = Label.parseAbsolute("//foo/bar");
+      assertEquals("//foo/bar:bar", l.toString());
+    }
+  }
+
+  @Test
+  public void testDotDot() throws Exception {
+    Label.parseAbsolute("//foo/bar:baz..gif");
+  }
+
+  /**
+   * Asserts that creating a label throws a SyntaxException.
+   * @param label the label to create.
+   */
+  private static void assertSyntaxError(String expectedError, String label) {
+    try {
+      Label.parseAbsolute(label);
+      fail("Label '" + label + "' did not contain a syntax error");
+    } catch (SyntaxException e) {
+      assertContainsRegex(Pattern.quote(expectedError), e.getMessage());
+    }
+  }
+
+  @Test
+  public void testBadCharacters() throws Exception {
+    assertSyntaxError("package names may contain only",
+                      "//foo/bar baz");
+    assertSyntaxError("target names may not contain ':'",
+                      "//foo:bar:baz");
+    assertSyntaxError("target names may not contain ':'",
+                      "//foo:bar:");
+    assertSyntaxError("target names may not contain ':'",
+                      "//foo/bar::");
+    assertSyntaxError("target names may not contain '&'",
+                      "//foo:bar&");
+    assertSyntaxError("target names may not contain '$'",
+                      "//foo/bar:baz$a");
+    assertSyntaxError("target names may not contain '('",
+                      "//foo/bar:baz(foo)");
+    assertSyntaxError("target names may not contain ')'",
+                      "//foo/bar:bazfoo)");
+  }
+
+  @Test
+  public void testUplevelReferences() throws Exception {
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//foo/bar/..:baz");
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//foo/../baz:baz");
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//../bar/baz:baz");
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//..:foo");
+    assertSyntaxError(TARGET_UPLEVEL,
+                      "//foo:bar/../baz");
+    assertSyntaxError(TARGET_UPLEVEL,
+                      "//foo:../bar/baz");
+    assertSyntaxError(TARGET_UPLEVEL,
+                      "//foo:bar/baz/..");
+    assertSyntaxError(TARGET_UPLEVEL,
+                      "//foo:..");
+  }
+
+  @Test
+  public void testDotAsAPathSegment() throws Exception {
+    assertSyntaxError("package names may contain only A-Z, a-z, 0-9, '/', '-' and '_'",
+                      "//foo/bar/.:baz");
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//foo/./baz:baz");
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//./bar/baz:baz");
+    assertSyntaxError(BAD_PACKAGE_CHARS,
+                      "//.:foo");
+    assertSyntaxError("target names may not contain '.' as a path segment",
+                      "//foo:bar/./baz");
+    assertSyntaxError("target names may not contain '.' as a path segment",
+                      "//foo:./bar/baz");
+    // TODO(bazel-team): enable when we have removed the "Workaround" in Label
+    // that rewrites broken Labels by removing the trailing '.'
+    //assertSyntaxError(TARGET_UPLEVEL,
+    //                  "//foo:bar/baz/.");
+    //assertSyntaxError(TARGET_UPLEVEL,
+    //                  "//foo:.");
+  }
+
+  @Test
+  public void testTrailingDotSegment() throws Exception {
+    assertEquals(Label.parseAbsolute("//foo:dir/."), Label.parseAbsolute("//foo:dir"));
+  }
+
+  @Test
+  public void testSomeOtherBadLabels() throws Exception {
+    assertSyntaxError("package names may not end with '/'",
+                      "//foo/:bar");
+    assertSyntaxError("empty package name", "//:foo");
+    assertSyntaxError("package names may not start with '/'", "///p:foo");
+    assertSyntaxError("package names may not contain '//' path separators",
+                      "//a//b:foo");
+  }
+
+  @Test
+  public void testSomeGoodLabels() throws Exception {
+    Label.parseAbsolute("//foo:..bar");
+    Label.parseAbsolute("//Foo:..bar");
+    Label.parseAbsolute("//-Foo:..bar");
+    Label.parseAbsolute("//00:..bar");
+    Label.parseAbsolute("//package:foo+bar");
+    Label.parseAbsolute("//package:foo_bar");
+    Label.parseAbsolute("//package:foo=bar");
+    Label.parseAbsolute("//package:foo-bar");
+    Label.parseAbsolute("//package:foo.bar");
+    Label.parseAbsolute("//package:foo@bar");
+    Label.parseAbsolute("//package:foo~bar");
+  }
+
+  /**
+   * Regression test: we previously expanded the set of characters which are considered label chars
+   * to include "@" (see test above). An unexpected side-effect is that "@D" in genrule(cmd) was
+   * considered to be a valid relative label! The fix is to forbid "@x" in package names.
+   */
+  @Test
+  public void testAtVersionIsIllegal() throws Exception {
+    assertSyntaxError(BAD_PACKAGE_CHARS, "//foo/bar@123:baz");
+  }
+
+  @Test
+  public void testDoubleSlashPathSeparator() throws Exception {
+    assertSyntaxError("package names may not contain '//' path separators",
+                      "//foo//bar:baz");
+    assertSyntaxError("target names may not contain '//' path separator",
+                      "//foo:bar//baz");
+  }
+
+  @Test
+  public void testNonPrintableCharacters() throws Exception {
+    assertSyntaxError(
+      "target names may not contain non-printable characters: '\\x02'",
+      "//foo:..\002bar");
+  }
+
+  /** Make sure that control characters - such as CR - are escaped on output. */
+  @Test
+  public void testInvalidLineEndings() throws Exception {
+    assertSyntaxError("invalid target name '..bar\\r': "
+        + "target names may not end with carriage returns", "//foo:..bar\r");
+  }
+
+  @Test
+  public void testEmptyName() throws Exception {
+    assertSyntaxError("invalid target name '': empty target name", "//foo/bar:");
+  }
+
+  @Test
+  public void testSerializationSimple() throws Exception {
+    checkSerialization("//a", 91);
+  }
+
+  @Test
+  public void testSerializationNested() throws Exception {
+    checkSerialization("//foo/bar:baz", 99);
+  }
+
+  @Test
+  public void testSerializationWithoutTargetName() throws Exception {
+    checkSerialization("//foo/bar", 99);
+  }
+
+  private void checkSerialization(String labelString, int expectedSize) throws Exception {
+    Label a = Label.parseAbsolute(labelString);
+    byte[] sa = TestUtils.serializeObject(a);
+    assertEquals(expectedSize, sa.length);
+
+    Label a2 = (Label) TestUtils.deserializeObject(sa);
+    assertEquals(a, a2);
+  }
+
+  @Test
+  public void testRepoLabel() throws Exception {
+    Label label = Label.parseRepositoryLabel("@foo//bar/baz:bat/boo");
+    assertEquals("@foo//bar/baz:bat/boo", label.toString());
+  }
+
+  @Test
+  public void testNoRepo() throws Exception {
+    Label label = Label.parseRepositoryLabel("//bar/baz:bat/boo");
+    assertEquals("//bar/baz:bat/boo", label.toString());
+  }
+
+  @Test
+  public void testInvalidRepo() throws Exception {
+    try {
+      Label.parseRepositoryLabel("foo//bar/baz:bat/boo");
+      fail();
+    } catch (SyntaxException e) {
+      assertEquals("invalid repository name 'foo': workspace name must start with '@'",
+          e.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
new file mode 100644
index 0000000..fd5385c
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LexerTest.java
@@ -0,0 +1,399 @@
+// Copyright 2006 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.syntax;
+
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.events.EventKind;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.events.Reporter;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests of tokenization behavior of the {@link Lexer}.
+ */
+public class LexerTest extends TestCase implements EventHandler {
+
+  private FsApparatus scratch = FsApparatus.newInMemory();
+
+  /**
+   * Create a lexer which takes input from the specified string. Resets the
+   * error handler beforehand.
+   */
+  private Lexer createLexer(String input) {
+    Path somePath = scratch.path("/some/path.txt");
+    ParserInputSource inputSource = ParserInputSource.create(input, somePath);
+    Reporter reporter = new Reporter();
+    reporter.addHandler(this);
+    return new Lexer(inputSource, reporter);
+  }
+
+  public Token[] tokens(String input) {
+    return createLexer(input).getTokens().toArray(new Token[0]);
+  }
+
+  /**
+   * Lexes the specified input string, and returns a string containing just the
+   * linenumbers of each token.
+   */
+  private String linenums(String input) {
+    Lexer lexer = createLexer(input);
+    StringBuilder buf = new StringBuilder();
+    for (Token tok : lexer.getTokens()) {
+      if (buf.length() > 0) {
+        buf.append(' ');
+      }
+      int line =
+        lexer.createLocation(tok.left, tok.left).getStartLineAndColumn().getLine();
+      buf.append(line);
+    }
+    return buf.toString();
+  }
+
+  private String lastError;
+
+  private Location lastErrorLocation;
+
+  @Override
+  public void handle(Event event) {
+    if (EventKind.ERRORS.contains(event.getKind())) {
+      lastErrorLocation = event.getLocation();
+      lastError = lastErrorLocation.getPath() + ":"
+          + event.getLocation().getStartLineAndColumn().getLine() + ": "
+          + event.getMessage();
+    }
+  }
+
+  /**
+   * Returns a string containing the names of the tokens and their associated
+   * values. (String-literals are printed without escaping.)
+   */
+  private static String values(Token[] tokens) {
+    StringBuilder buffer = new StringBuilder();
+    for (Token token : tokens) {
+      if (buffer.length() > 0) {
+        buffer.append(' ');
+      }
+      buffer.append(token.kind.name());
+      if (token.value != null) {
+        buffer.append('(').append(token.value).append(')');
+      }
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Returns a string containing just the names of the tokens.
+   */
+  private static String names(Token[] tokens) {
+    StringBuilder buf = new StringBuilder();
+    for (Token tok : tokens) {
+      if (buf.length() > 0) {
+        buf.append(' ');
+      }
+      buf.append(tok.kind.name());
+    }
+    return buf.toString();
+  }
+
+  /**
+   * Returns a string containing just the half-open position intervals of each
+   * token. e.g. "[3,4) [4,9)".
+   */
+  private static String positions(Token[] tokens) {
+    StringBuilder buf = new StringBuilder();
+    for (Token tok : tokens) {
+      if (buf.length() > 0) {
+        buf.append(' ');
+      }
+      buf.append('[')
+         .append(tok.left)
+         .append(',')
+         .append(tok.right)
+         .append(')');
+    }
+    return buf.toString();
+  }
+
+  public void testBasics1() throws Exception {
+    assertEquals("IDENTIFIER RPAREN NEWLINE EOF", names(tokens("wiz) ")));
+    assertEquals("IDENTIFIER RPAREN NEWLINE EOF", names(tokens("wiz )")));
+    assertEquals("IDENTIFIER RPAREN NEWLINE EOF", names(tokens(" wiz)")));
+    assertEquals("IDENTIFIER RPAREN NEWLINE EOF", names(tokens(" wiz ) ")));
+    assertEquals("IDENTIFIER RPAREN NEWLINE EOF", names(tokens("wiz\t)")));
+  }
+
+  public void testBasics2() throws Exception {
+    assertEquals("RPAREN NEWLINE EOF", names(tokens(")")));
+    assertEquals("RPAREN NEWLINE EOF", names(tokens(" )")));
+    assertEquals("RPAREN NEWLINE EOF", names(tokens(" ) ")));
+    assertEquals("RPAREN NEWLINE EOF", names(tokens(") ")));
+  }
+
+  public void testBasics3() throws Exception {
+    assertEquals("INT COMMENT NEWLINE INT NEWLINE EOF", names(tokens("123#456\n789")));
+    assertEquals("INT COMMENT NEWLINE INT NEWLINE EOF", names(tokens("123 #456\n789")));
+    assertEquals("INT COMMENT NEWLINE INT NEWLINE EOF", names(tokens("123#456 \n789")));
+    assertEquals("INT COMMENT NEWLINE INDENT INT NEWLINE OUTDENT NEWLINE EOF",
+                 names(tokens("123#456\n 789")));
+    assertEquals("INT COMMENT NEWLINE INT NEWLINE EOF", names(tokens("123#456\n789 ")));
+  }
+
+  public void testBasics4() throws Exception {
+    assertEquals("NEWLINE EOF", names(tokens("")));
+    assertEquals("COMMENT NEWLINE EOF", names(tokens("# foo")));
+    assertEquals("INT INT INT INT NEWLINE EOF", names(tokens("1 2 3 4")));
+    assertEquals("INT DOT INT NEWLINE EOF", names(tokens("1.234")));
+    assertEquals("IDENTIFIER LPAREN IDENTIFIER COMMA IDENTIFIER RPAREN "
+                 + "NEWLINE EOF", names(tokens("foo(bar, wiz)")));
+  }
+
+  public void testIntegers() throws Exception {
+    // Detection of MINUS immediately following integer constant proves we
+    // don't consume too many chars.
+
+    // decimal
+    assertEquals("INT(12345) MINUS NEWLINE EOF", values(tokens("12345-")));
+
+    // octal
+    assertEquals("INT(5349) MINUS NEWLINE EOF", values(tokens("012345-")));
+
+    // octal (bad)
+    assertEquals("INT(0) MINUS NEWLINE EOF", values(tokens("012349-")));
+    assertEquals("/some/path.txt:1: invalid base-8 integer constant: 012349",
+                 lastError.toString());
+
+    // hexadecimal (uppercase)
+    assertEquals("INT(1193055) MINUS NEWLINE EOF", values(tokens("0X12345F-")));
+
+    // hexadecimal (lowercase)
+    assertEquals("INT(1193055) MINUS NEWLINE EOF", values(tokens("0x12345f-")));
+
+    // hexadecimal (lowercase) [note: "g" cause termination of token]
+    assertEquals("INT(74565) IDENTIFIER(g) MINUS NEWLINE EOF",
+                 values(tokens("0x12345g-")));
+  }
+
+  public void testIntegersAndDot() throws Exception {
+    assertEquals("INT(1) DOT INT(2345) NEWLINE EOF", values(tokens("1.2345")));
+
+    assertEquals("INT(1) DOT INT(2) DOT INT(345) NEWLINE EOF",
+                 values(tokens("1.2.345")));
+
+    assertEquals("INT(1) DOT INT(0) NEWLINE EOF", values(tokens("1.23E10")));
+    assertEquals("/some/path.txt:1: invalid base-10 integer constant: 23E10",
+                 lastError.toString());
+
+    assertEquals("INT(1) DOT INT(0) MINUS INT(10) NEWLINE EOF",
+                 values(tokens("1.23E-10")));
+    assertEquals("/some/path.txt:1: invalid base-10 integer constant: 23E",
+                 lastError.toString());
+
+    assertEquals("DOT INT(123) NEWLINE EOF", values(tokens(". 123")));
+    assertEquals("DOT INT(123) NEWLINE EOF", values(tokens(".123")));
+    assertEquals("DOT IDENTIFIER(abc) NEWLINE EOF", values(tokens(".abc")));
+
+    assertEquals("IDENTIFIER(foo) DOT INT(123) NEWLINE EOF",
+                 values(tokens("foo.123")));
+    assertEquals("IDENTIFIER(foo) DOT IDENTIFIER(bcd) NEWLINE EOF",
+                 values(tokens("foo.bcd"))); // 'b' are hex chars
+    assertEquals("IDENTIFIER(foo) DOT IDENTIFIER(xyz) NEWLINE EOF",
+                 values(tokens("foo.xyz")));
+  }
+
+  public void testStringDelimiters() throws Exception {
+    assertEquals("STRING(foo) NEWLINE EOF", values(tokens("\"foo\"")));
+    assertEquals("STRING(foo) NEWLINE EOF", values(tokens("'foo'")));
+  }
+
+  public void testQuotesInStrings() throws Exception {
+    assertEquals("STRING(foo'bar) NEWLINE EOF", values(tokens("'foo\\'bar'")));
+    assertEquals("STRING(foo'bar) NEWLINE EOF", values(tokens("\"foo'bar\"")));
+    assertEquals("STRING(foo\"bar) NEWLINE EOF", values(tokens("'foo\"bar'")));
+    assertEquals("STRING(foo\"bar) NEWLINE EOF",
+                 values(tokens("\"foo\\\"bar\"")));
+  }
+
+  public void testStringEscapes() throws Exception {
+    assertEquals("STRING(a\tb\nc\rd) NEWLINE EOF",
+                 values(tokens("'a\\tb\\nc\\rd'"))); // \t \r \n
+    assertEquals("STRING(x\\hx) NEWLINE EOF",
+                 values(tokens("'x\\hx'"))); // \h is unknown => "\h"
+    assertEquals("STRING(\\$$) NEWLINE EOF", values(tokens("'\\$$'")));
+    assertEquals("STRING(ab) NEWLINE EOF",
+                 values(tokens("'a\\\nb'"))); // escape end of line
+
+    assertEquals("STRING(abcd) NEWLINE EOF",
+                 values(tokens("r'abcd'")));
+    assertEquals("STRING(abcd) NEWLINE EOF",
+                 values(tokens("r\"abcd\"")));
+    assertEquals("STRING(a\\tb\\nc\\rd) NEWLINE EOF",
+                 values(tokens("r'a\\tb\\nc\\rd'"))); // r'a\tb\nc\rd'
+    assertEquals("STRING(a\\\") NEWLINE EOF",
+                 values(tokens("r\"a\\\"\""))); // r"a\""
+    assertEquals("STRING(a\\\\b) NEWLINE EOF",
+                 values(tokens("r'a\\\\b'"))); // r'a\\b'
+    assertEquals("STRING(ab) IDENTIFIER(r) NEWLINE EOF",
+                 values(tokens("r'ab'r")));
+
+    assertEquals("STRING(abcd) NEWLINE EOF",
+                 values(tokens("\"ab\\ucd\"")));
+    assertEquals("/some/path.txt:1: escape sequence not implemented: \\u",
+                 lastError.toString());
+  }
+
+  public void testOctalEscapes() throws Exception {
+    // Regression test for a bug.
+    assertEquals("STRING(\0 \1 \t \u003f I I1 \u00ff \u00ff \u00fe) NEWLINE EOF",
+                 values(tokens("'\\0 \\1 \\11 \\77 \\111 \\1111 \\377 \\777 \\776'")));
+    // Test boundaries (non-octal char, EOF).
+    assertEquals("STRING(\1b \1) NEWLINE EOF", values(tokens("'\\1b \\1'")));
+  }
+
+  public void testTripleQuotedStrings() throws Exception {
+    assertEquals("STRING(a\"b'c \n d\"\"e) NEWLINE EOF",
+                 values(tokens("\"\"\"a\"b'c \n d\"\"e\"\"\"")));
+    assertEquals("STRING(a\"b'c \n d\"\"e) NEWLINE EOF",
+                 values(tokens("'''a\"b'c \n d\"\"e'''")));
+  }
+
+  public void testBadChar() throws Exception {
+    assertEquals("IDENTIFIER(a) IDENTIFIER(b) NEWLINE EOF",
+                 values(tokens("a$b")));
+    assertEquals("/some/path.txt:1: invalid character: '$'",
+                 lastError.toString());
+  }
+
+  public void testIndentation() throws Exception {
+    assertEquals("INT(1) NEWLINE INT(2) NEWLINE INT(3) NEWLINE EOF",
+                 values(tokens("1\n2\n3")));
+    assertEquals("INT(1) NEWLINE INDENT INT(2) NEWLINE INT(3) NEWLINE OUTDENT "
+                 + "INT(4) NEWLINE EOF", values(tokens("1\n  2\n  3\n4 ")));
+    assertEquals("INT(1) NEWLINE INDENT INT(2) NEWLINE INT(3) NEWLINE OUTDENT "
+                 + "NEWLINE EOF", values(tokens("1\n  2\n  3")));
+    assertEquals("INT(1) NEWLINE INDENT INT(2) NEWLINE INDENT INT(3) NEWLINE "
+                 + "OUTDENT OUTDENT NEWLINE EOF",
+                 values(tokens("1\n  2\n    3")));
+    assertEquals("INT(1) NEWLINE INDENT INT(2) NEWLINE INDENT INT(3) NEWLINE "
+                 + "OUTDENT INT(4) NEWLINE OUTDENT INT(5) NEWLINE EOF",
+                 values(tokens("1\n  2\n    3\n  4\n5")));
+
+    assertEquals("INT(1) NEWLINE INDENT INT(2) NEWLINE INDENT INT(3) NEWLINE "
+                 + "OUTDENT INT(4) NEWLINE OUTDENT INT(5) NEWLINE EOF",
+                 values(tokens("1\n  2\n    3\n   4\n5")));
+    assertEquals("/some/path.txt:4: indentation error", lastError.toString());
+  }
+
+  public void testIndentationInsideParens() throws Exception {
+    // Indentation is ignored inside parens:
+    assertEquals("INT(1) LPAREN INT(2) INT(3) INT(4) INT(5) NEWLINE EOF",
+                 values(tokens("1 (\n  2\n    3\n  4\n5")));
+    assertEquals("INT(1) LBRACE INT(2) INT(3) INT(4) INT(5) NEWLINE EOF",
+                 values(tokens("1 {\n  2\n    3\n  4\n5")));
+    assertEquals("INT(1) LBRACKET INT(2) INT(3) INT(4) INT(5) NEWLINE EOF",
+                 values(tokens("1 [\n  2\n    3\n  4\n5")));
+    assertEquals("INT(1) LBRACKET INT(2) RBRACKET NEWLINE INDENT INT(3) "
+                 + "NEWLINE INT(4) NEWLINE OUTDENT INT(5) NEWLINE EOF",
+                 values(tokens("1 [\n  2]\n    3\n    4\n5")));
+  }
+
+  public void testIndentationAtEOF() throws Exception {
+    // Matching OUTDENTS are created at EOF:
+    assertEquals("INDENT INT(1) NEWLINE OUTDENT NEWLINE EOF",
+                 values(tokens("\n  1")));
+  }
+
+  public void testBlankLineIndentation() throws Exception {
+    // Blank lines and comment lines should not generate any newlines indents
+    // (but note that every input ends with NEWLINE EOF).
+    assertEquals("COMMENT NEWLINE EOF", names(tokens("\n      #\n")));
+    assertEquals("COMMENT NEWLINE EOF", names(tokens("      #")));
+    assertEquals("COMMENT NEWLINE EOF", names(tokens("      #\n")));
+    assertEquals("COMMENT NEWLINE EOF", names(tokens("      #comment\n")));
+    assertEquals("DEF IDENTIFIER LPAREN IDENTIFIER RPAREN COLON NEWLINE "
+                 + "COMMENT INDENT RETURN IDENTIFIER NEWLINE "
+                 + "OUTDENT NEWLINE EOF",
+                 names(tokens("def f(x):\n"
+                              + "  # comment\n"
+                              + "\n"
+                              + "  \n"
+                              + "  return x\n")));
+  }
+
+  public void testMultipleCommentLines() throws Exception {
+    assertEquals("COMMENT NEWLINE COMMENT COMMENT COMMENT "
+                 + "DEF IDENTIFIER LPAREN IDENTIFIER RPAREN COLON NEWLINE "
+                 + "INDENT RETURN IDENTIFIER NEWLINE OUTDENT NEWLINE EOF",
+                 names(tokens("# Copyright\n"
+                              + "#\n"
+                              + "# A comment line\n"
+                              + "# An adjoining line\n"
+                              + "def f(x):\n"
+                              + "  return x\n")));
+  }
+
+  public void testBackslash() throws Exception {
+    assertEquals("IDENTIFIER IDENTIFIER NEWLINE EOF",
+                 names(tokens("a\\\nb")));
+    assertEquals("IDENTIFIER ILLEGAL IDENTIFIER NEWLINE EOF",
+                 names(tokens("a\\ b")));
+    assertEquals("IDENTIFIER LPAREN INT RPAREN NEWLINE EOF",
+                 names(tokens("a(\\\n2)")));
+  }
+
+  public void testTokenPositions() throws Exception {
+    //            foo   (     bar   ,     {      1       :
+    assertEquals("[0,3) [3,4) [4,7) [7,8) [9,10) [10,11) [11,12)"
+             //      'quux'  }       )       NEWLINE EOF
+                 + " [13,19) [19,20) [20,21) [20,21) [21,21)",
+                 positions(tokens("foo(bar, {1: 'quux'})")));
+  }
+
+  public void testLineNumbers() throws Exception {
+    assertEquals("1 1 1 1 2 2 2 2 4 4 4 4 4",
+                 linenums("foo = 1\nbar = 2\n\nwiz = 3"));
+
+    assertEquals("IDENTIFIER(foo) EQUALS INT(1) NEWLINE "
+                 + "IDENTIFIER(bar) EQUALS INT(2) NEWLINE "
+                 + "IDENTIFIER(wiz) EQUALS NEWLINE "
+                 + "IDENTIFIER(bar) EQUALS INT(2) NEWLINE EOF",
+                 values(tokens("foo = 1\nbar = 2\n\nwiz = $\nbar = 2")));
+    assertEquals("/some/path.txt:4: invalid character: '$'",
+                 lastError.toString());
+
+    // '\\n' in string should not increment linenum:
+    String s = "1\n'foo\\nbar'\3";
+    assertEquals("INT(1) NEWLINE STRING(foo\nbar) NEWLINE EOF",
+                 values(tokens(s)));
+    assertEquals("1 1 2 2 2", linenums(s));
+  }
+
+  public void testContainsErrors() throws Exception {
+    Lexer lexerSuccess = createLexer("foo");
+    assertFalse(lexerSuccess.containsErrors());
+
+    Lexer lexerFail = createLexer("f$o");
+    assertTrue(lexerFail.containsErrors());
+
+    String s = "'unterminated";
+    lexerFail = createLexer(s);
+    assertTrue(lexerFail.containsErrors());
+    assertEquals(0, lastErrorLocation.getStartOffset());
+    assertEquals(s.length(), lastErrorLocation.getEndOffset());
+    assertEquals("STRING(unterminated) NEWLINE EOF", values(tokens(s)));
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java b/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java
new file mode 100644
index 0000000..f1fdd77
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/LineNumberTableTest.java
@@ -0,0 +1,113 @@
+// Copyright 2006 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.syntax;
+
+import com.google.devtools.build.lib.events.Location.LineAndColumn;
+import com.google.devtools.build.lib.util.Pair;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link LineNumberTable}.
+ */
+public class LineNumberTableTest extends TestCase {
+  private FsApparatus scratch = FsApparatus.newInMemory();
+
+  private LineNumberTable create(String buffer) {
+    return LineNumberTable.create(buffer.toCharArray(),
+        scratch.path("/fake/file"));
+  }
+
+  public void testEmpty() {
+    LineNumberTable table = create("");
+    assertEquals(new LineAndColumn(1, 1), table.getLineAndColumn(0));
+  }
+
+  public void testNewline() {
+    LineNumberTable table = create("\n");
+    assertEquals(new LineAndColumn(1, 1), table.getLineAndColumn(0));
+    assertEquals(new LineAndColumn(2, 1), table.getLineAndColumn(1));
+  }
+
+  public void testOneLiner() {
+    LineNumberTable table = create("foo");
+    assertEquals(new LineAndColumn(1, 1), table.getLineAndColumn(0));
+    assertEquals(new LineAndColumn(1, 2), table.getLineAndColumn(1));
+    assertEquals(new LineAndColumn(1, 3), table.getLineAndColumn(2));
+    assertEquals(Pair.of(0, 3), table.getOffsetsForLine(1));
+  }
+
+  public void testMultiLiner() {
+    LineNumberTable table = create("\ntwo\nthree\n\nfive\n");
+
+    // \n
+    assertEquals(new LineAndColumn(1, 1), table.getLineAndColumn(0));
+    assertEquals(Pair.of(0, 1), table.getOffsetsForLine(1));
+
+    // two\n
+    assertEquals(new LineAndColumn(2, 1), table.getLineAndColumn(1));
+    assertEquals(new LineAndColumn(2, 2), table.getLineAndColumn(2));
+    assertEquals(new LineAndColumn(2, 3), table.getLineAndColumn(3));
+    assertEquals(new LineAndColumn(2, 4), table.getLineAndColumn(4));
+    assertEquals(Pair.of(1, 5), table.getOffsetsForLine(2));
+
+    // three\n
+    assertEquals(new LineAndColumn(3, 1), table.getLineAndColumn(5));
+    assertEquals(new LineAndColumn(3, 6), table.getLineAndColumn(10));
+    assertEquals(Pair.of(5, 11), table.getOffsetsForLine(3));
+
+    // \n
+    assertEquals(new LineAndColumn(4, 1), table.getLineAndColumn(11));
+    assertEquals(Pair.of(11, 12), table.getOffsetsForLine(4));
+
+    // five\n
+    assertEquals(new LineAndColumn(5, 1), table.getLineAndColumn(12));
+    assertEquals(new LineAndColumn(5, 5), table.getLineAndColumn(16));
+    assertEquals(Pair.of(12, 17), table.getOffsetsForLine(5));
+  }
+
+  public void testHashLine() {
+    String data = "#\n"
+        + "#line 67 \"/foo\"\n"
+        + "cc_binary(name='a',\n"
+        + "          srcs=[])\n"
+        + "#line 23 \"/ba.r\"\n"
+        + "vardef(x,y)\n";
+
+    LineNumberTable table = create(data);
+
+    // Note: no attempt is made to return accurate column information.
+    assertEquals(new LineAndColumn(67, 1), table.getLineAndColumn(data.indexOf("cc_binary")));
+    assertEquals(new LineAndColumn(67, 1), table.getLineAndColumn(data.indexOf("name='a'")));
+    assertEquals("/fake/file", table.getPath(0).toString());
+    // Note: newlines ignored; "srcs" is still (intentionally) considered to be
+    // on L67.  Consider the alternative, and assume that rule 'a' is 50 lines
+    // when pretty-printed: the last line of 'a' would be reported as line 67 +
+    // 50, which may be in a part of the original BUILD file that has nothing
+    // to do with this rule.  In other words, the size of rules before and
+    // after pretty printing are essentially unrelated.
+    assertEquals(new LineAndColumn(67, 1), table.getLineAndColumn(data.indexOf("srcs")));
+    assertEquals("/foo", table.getPath(data.indexOf("srcs")).toString());
+    assertEquals(Pair.of(2, 57), table.getOffsetsForLine(67));
+
+    assertEquals(new LineAndColumn(23, 1), table.getLineAndColumn(data.indexOf("vardef")));
+    assertEquals(new LineAndColumn(23, 1), table.getLineAndColumn(data.indexOf("x,y")));
+    assertEquals("/ba.r", table.getPath(data.indexOf("x,y")).toString());
+    assertEquals(Pair.of(57, 86), table.getOffsetsForLine(23));
+
+    assertEquals(Pair.of(0, 0), table.getOffsetsForLine(42));
+  }
+
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
new file mode 100644
index 0000000..c7c2c40
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
@@ -0,0 +1,130 @@
+// Copyright 2006 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.syntax;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.Arrays;
+
+/**
+ * Tests for {@link MixedModeFunction}.
+ */
+public class MixedModeFunctionTest extends AbstractEvaluationTestCase {
+
+  private Environment singletonEnv(String id, Object value) {
+    Environment env = new Environment();
+    env.update(id, value);
+    return env;
+  }
+
+  /**
+   * Handy implementation of {@link MixedModeFunction} that just tuples up its args and returns
+   * them.
+   */
+  private static class TestingMixedModeFunction extends MixedModeFunction {
+    TestingMixedModeFunction(Iterable<String> parameters,
+                             int numMandatoryParameters,
+                             boolean onlyNamedArguments) {
+      super("mixed", parameters, numMandatoryParameters, onlyNamedArguments);
+    }
+    @Override
+    public Object call(Object[] namedParameters, FuncallExpression ast) {
+      return Arrays.asList(namedParameters);
+    }
+  }
+
+  private void checkMixedMode(Function func,
+                              String callExpression,
+                              String expectedOutput) throws Exception {
+    Environment env = singletonEnv(func.getName(), func);
+
+    if (expectedOutput.charAt(0) == '[') { // a tuple => expected to pass
+      assertEquals(expectedOutput,
+                   eval(callExpression, env).toString());
+    } else { // expected to fail with an exception
+      try {
+        eval(callExpression, env);
+        fail();
+      } catch (EvalException e) {
+        assertEquals(expectedOutput, e.getMessage());
+      }
+    }
+  }
+
+  private static final String[] mixedModeExpressions = {
+    "mixed()",
+    "mixed(1)",
+    "mixed(1, 2)",
+    "mixed(1, 2, 3)",
+    "mixed(1, 2, wiz=3, quux=4)",
+    "mixed(foo=1)",
+    "mixed(foo=1, bar=2)",
+    "mixed(bar=2, foo=1)",
+    "mixed(2, foo=1)",
+    "mixed(bar=2, foo=1, wiz=3)",
+  };
+
+  public void checkMixedModeFunctions(boolean onlyNamedArguments,
+                                      String expectedSignature,
+                                      String[] expectedResults)
+      throws Exception {
+    MixedModeFunction func =
+        new TestingMixedModeFunction(ImmutableList.of("foo", "bar"), 1, onlyNamedArguments);
+
+    assertEquals(expectedSignature, func.getSignature());
+
+    for (int ii = 0; ii < mixedModeExpressions.length; ++ii) {
+      String expr = mixedModeExpressions[ii];
+      String expected = expectedResults[ii];
+      checkMixedMode(func, expr, expected);
+    }
+  }
+
+  public void testNoSurplusArguments() throws Exception {
+    checkMixedModeFunctions(false,
+                            "mixed(foo, bar = null)",
+                            new String[]
+      {
+        "mixed(foo, bar = null) received insufficient arguments",
+        "[1, null]",
+        "[1, 2]",
+        "too many positional arguments in call to mixed(foo, bar = null)",
+        "unexpected keywords 'quux', 'wiz' in call to mixed(foo, bar = null)",
+        "[1, null]",
+        "[1, 2]",
+        "[1, 2]",
+        "mixed(foo, bar = null) got multiple values for keyword"
+        + " argument 'foo'",
+        "unexpected keyword 'wiz' in call to mixed(foo, bar = null)",
+      });
+  }
+
+  public void testOnlyNamedArguments() throws Exception {
+    checkMixedModeFunctions(true,
+                            "mixed(foo, bar = null)",
+                            new String[]
+      {
+        "mixed(foo, bar = null) received insufficient arguments",
+        "mixed(foo, bar = null) does not accept positional arguments",
+        "mixed(foo, bar = null) does not accept positional arguments",
+        "mixed(foo, bar = null) does not accept positional arguments",
+        "mixed(foo, bar = null) does not accept positional arguments",
+        "[1, null]",
+        "[1, 2]",
+        "[1, 2]",
+        "mixed(foo, bar = null) does not accept positional arguments",
+        "unexpected keyword 'wiz' in call to mixed(foo, bar = null)",
+      });
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
new file mode 100644
index 0000000..1d0e50c
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserInputSourceTest.java
@@ -0,0 +1,116 @@
+// Copyright 2006 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.syntax;
+
+import static com.google.devtools.build.lib.util.StringUtilities.joinLines;
+
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A test case for {@link ParserInputSource}.
+ */
+public class ParserInputSourceTest extends TestCase {
+
+  private FsApparatus scratch = FsApparatus.newInMemory();
+
+  public void testCreateFromFile() throws IOException {
+    String content = joinLines("Line 1", "Line 2", "Line 3", "");
+    Path file = scratch.file("/tmp/my/file.txt", content);
+    ParserInputSource input = ParserInputSource.create(file);
+    assertEquals(content, new String(input.getContent()));
+    assertEquals("/tmp/my/file.txt", input.getPath().toString());
+  }
+
+  public void testCreateFromString() {
+    String content = "Content provided as a string.";
+    String pathName = "/the/name/of/the/content.txt";
+    Path path = scratch.path(pathName);
+    ParserInputSource input = ParserInputSource.create(content, path);
+    assertEquals(content, new String(input.getContent()));
+    assertEquals(pathName, input.getPath().toString());
+  }
+
+  public void testCreateFromCharArray() {
+    String content = "Content provided as a string.";
+    String pathName = "/the/name/of/the/content.txt";
+    Path path = scratch.path(pathName);
+    char[] contentChars = content.toCharArray();
+    ParserInputSource input = ParserInputSource.create(contentChars, path);
+    assertEquals(content, new String(input.getContent()));
+    assertEquals(pathName, input.getPath().toString());
+  }
+
+  public void testCreateFromInputStream() throws IOException {
+    String content = "Content provided as a string.";
+    byte[] bytes = content.getBytes("ISO-8859-1");
+    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
+    String pathName = "/the/name/of/the/content.txt";
+    Path path = scratch.path(pathName);
+    ParserInputSource input = ParserInputSource.create(in, path);
+    assertEquals(content, new String(input.getContent()));
+    assertEquals(pathName, input.getPath().toString());
+  }
+
+  public void testIOExceptionIfInputFileDoesNotExistForSingleArgConstructor() {
+    try {
+      Path path = scratch.path("/does/not/exist");
+      ParserInputSource.create(path);
+      fail();
+    } catch (IOException e) {
+      String expected = "/does/not/exist (No such file or directory)";
+      assertEquals(expected, e.getMessage());
+    }
+  }
+
+  public void testWillNotTryToReadInputFileIfContentProvidedAsString() {
+    Path path = scratch.path("/will/not/try/to/read");
+    ParserInputSource.create("Content provided as string.", path);
+  }
+
+  public void testWillNotTryToReadInputFileIfContentProvidedAsChars() {
+    Path path = scratch.path("/will/not/try/to/read");
+    char[] content = "Content provided as char array.".toCharArray();
+    ParserInputSource.create(content, path);
+  }
+
+  public void testWillCloseStreamWhenReadingFromInputStream() {
+    final StringBuilder log = new StringBuilder();
+    InputStream in = new InputStream() {
+      @Override
+      public int read() throws IOException {
+        throw new IOException("Fault injected.");
+      }
+      @Override
+      public void close() {
+        log.append("Stream closed.");
+      }
+    };
+    try {
+      Path path = scratch.path("/will/not/try/to/read");
+      ParserInputSource.create(in, path);
+      fail();
+    } catch (IOException e) {
+      assertEquals("Fault injected.", e.getMessage());
+    }
+    assertEquals("Stream closed.", log.toString());
+  }
+
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
new file mode 100644
index 0000000..e698728
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -0,0 +1,876 @@
+// Copyright 2014 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.syntax;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.syntax.DictionaryLiteral.DictionaryEntryLiteral;
+
+import java.util.List;
+
+/**
+ *  Tests of parser behaviour.
+ *
+ */
+public class ParserTest extends AbstractParserTestCase {
+
+  private static String getText(String text, ASTNode node) {
+    return text.substring(node.getLocation().getStartOffset(),
+                          node.getLocation().getEndOffset());
+  }
+
+  // helper func for testListLiterals:
+  private static int getIntElem(DictionaryEntryLiteral entry, boolean key) {
+    return ((IntegerLiteral) (key ? entry.getKey() : entry.getValue())).getValue();
+  }
+
+  // helper func for testListLiterals:
+  private static DictionaryEntryLiteral getElem(DictionaryLiteral list, int index) {
+    return list.getEntries().get(index);
+  }
+
+  // helper func for testListLiterals:
+  private static int getIntElem(ListLiteral list, int index) {
+    return ((IntegerLiteral) list.getElements().get(index)).getValue();
+  }
+
+  // helper func for testListLiterals:
+  private static Expression getElem(ListLiteral list, int index) {
+    return list.getElements().get(index);
+  }
+
+  // helper func for testing arguments:
+  private static Expression getArg(FuncallExpression f, int index) {
+    return f.getArguments().get(index).getValue();
+  }
+
+  public void testPrecedence1() throws Exception {
+    BinaryOperatorExpression e =
+      (BinaryOperatorExpression) parseExpr("'%sx' % 'foo' + 'bar'");
+
+    assertEquals(Operator.PLUS, e.getOperator());
+  }
+
+  public void testPrecedence2() throws Exception {
+    BinaryOperatorExpression e =
+      (BinaryOperatorExpression) parseExpr("('%sx' % 'foo') + 'bar'");
+    assertEquals(Operator.PLUS, e.getOperator());
+  }
+
+  public void testPrecedence3() throws Exception {
+    BinaryOperatorExpression e =
+      (BinaryOperatorExpression) parseExpr("'%sx' % ('foo' + 'bar')");
+    assertEquals(Operator.PERCENT, e.getOperator());
+  }
+
+  public void testPrecedence4() throws Exception {
+    BinaryOperatorExpression e =
+        (BinaryOperatorExpression) parseExpr("1 + - (2 - 3)");
+    assertEquals(Operator.PLUS, e.getOperator());
+  }
+
+  public void testUnaryMinusExpr() throws Exception {
+    FuncallExpression e = (FuncallExpression) parseExpr("-5");
+    FuncallExpression e2 = (FuncallExpression) parseExpr("- 5");
+
+    assertEquals("-", e.getFunction().getName());
+    assertEquals("-", e2.getFunction().getName());
+
+    assertThat(e.getArguments()).hasSize(1);
+    assertEquals(1, e.getNumPositionalArguments());
+
+    IntegerLiteral arg0 = (IntegerLiteral) e.getArguments().get(0).getValue();
+    assertEquals(5, (int) arg0.getValue());
+  }
+
+  public void testFuncallExpr() throws Exception {
+    FuncallExpression e = (FuncallExpression) parseExpr("foo(1, 2, bar=wiz)");
+
+    Ident ident = e.getFunction();
+    assertEquals("foo", ident.getName());
+
+    assertThat(e.getArguments()).hasSize(3);
+    assertEquals(2, e.getNumPositionalArguments());
+
+    IntegerLiteral arg0 = (IntegerLiteral) e.getArguments().get(0).getValue();
+    assertEquals(1, (int) arg0.getValue());
+
+    IntegerLiteral arg1 = (IntegerLiteral) e.getArguments().get(1).getValue();
+    assertEquals(2, (int) arg1.getValue());
+
+    Argument.Passed arg2 = e.getArguments().get(2);
+    assertEquals("bar", arg2.getName());
+    Ident arg2val = (Ident) arg2.getValue();
+    assertEquals("wiz", arg2val.getName());
+  }
+
+  public void testMethCallExpr() throws Exception {
+    FuncallExpression e =
+      (FuncallExpression) parseExpr("foo.foo(1, 2, bar=wiz)");
+
+    Ident ident = e.getFunction();
+    assertEquals("foo", ident.getName());
+
+    assertThat(e.getArguments()).hasSize(3);
+    assertEquals(2, e.getNumPositionalArguments());
+
+    IntegerLiteral arg0 = (IntegerLiteral) e.getArguments().get(0).getValue();
+    assertEquals(1, (int) arg0.getValue());
+
+    IntegerLiteral arg1 = (IntegerLiteral) e.getArguments().get(1).getValue();
+    assertEquals(2, (int) arg1.getValue());
+
+    Argument.Passed arg2 = e.getArguments().get(2);
+    assertEquals("bar", arg2.getName());
+    Ident arg2val = (Ident) arg2.getValue();
+    assertEquals("wiz", arg2val.getName());
+  }
+
+  public void testChainedMethCallExpr() throws Exception {
+    FuncallExpression e =
+      (FuncallExpression) parseExpr("foo.replace().split(1)");
+
+    Ident ident = e.getFunction();
+    assertEquals("split", ident.getName());
+
+    assertThat(e.getArguments()).hasSize(1);
+    assertEquals(1, e.getNumPositionalArguments());
+
+    IntegerLiteral arg0 = (IntegerLiteral) e.getArguments().get(0).getValue();
+    assertEquals(1, (int) arg0.getValue());
+  }
+
+  public void testPropRefExpr() throws Exception {
+    DotExpression e = (DotExpression) parseExpr("foo.foo");
+
+    Ident ident = e.getField();
+    assertEquals("foo", ident.getName());
+  }
+
+  public void testStringMethExpr() throws Exception {
+    FuncallExpression e = (FuncallExpression) parseExpr("'foo'.foo()");
+
+    Ident ident = e.getFunction();
+    assertEquals("foo", ident.getName());
+
+    assertThat(e.getArguments()).isEmpty();
+  }
+
+  public void testStringLiteralOptimizationValue() throws Exception {
+    StringLiteral l = (StringLiteral) parseExpr("'abc' + 'def'");
+    assertEquals("abcdef", l.value);
+  }
+
+  public void testStringLiteralOptimizationToString() throws Exception {
+    StringLiteral l = (StringLiteral) parseExpr("'abc' + 'def'");
+    assertEquals("'abcdef'", l.toString());
+  }
+
+  public void testStringLiteralOptimizationLocation() throws Exception {
+    StringLiteral l = (StringLiteral) parseExpr("'abc' + 'def'");
+    assertEquals(0, l.getLocation().getStartOffset());
+    assertEquals(13, l.getLocation().getEndOffset());
+  }
+
+  public void testStringLiteralOptimizationDifferentQuote() throws Exception {
+    assertThat(parseExpr("'abc' + \"def\"")).isInstanceOf(BinaryOperatorExpression.class);
+  }
+
+  public void testSubstring() throws Exception {
+    FuncallExpression e = (FuncallExpression) parseExpr("'FOO.CC'[:].lower()[1:]");
+    assertEquals("$substring", e.getFunction().getName());
+    assertThat(e.getArguments()).hasSize(2);
+
+    e = (FuncallExpression) parseExpr("'FOO.CC'.lower()[1:].startswith('oo')");
+    assertEquals("startswith", e.getFunction().getName());
+    assertThat(e.getArguments()).hasSize(1);
+
+    e = (FuncallExpression) parseExpr("'FOO.CC'[1:][:2]");
+    assertEquals("$substring", e.getFunction().getName());
+    assertThat(e.getArguments()).hasSize(2);
+  }
+
+  private void assertLocation(int start, int end, Location location)
+      throws Exception {
+    int actualStart = location.getStartOffset();
+    int actualEnd = location.getEndOffset();
+
+    if (actualStart != start || actualEnd != end) {
+      fail("Expected location = [" + start + ", " + end + "), found ["
+          + actualStart + ", " + actualEnd + ")");
+    }
+  }
+
+  public void testErrorRecovery() throws Exception {
+    syntaxEvents.setFailFast(false);
+
+    String expr = "f(1, [x for foo foo foo], 3)";
+    FuncallExpression e = (FuncallExpression) parseExpr(expr);
+
+    syntaxEvents.assertContainsEvent("syntax error at 'foo'");
+
+    // Test that the actual parameters are: (1, $error$, 3):
+
+    Ident ident = e.getFunction();
+    assertEquals("f", ident.getName());
+
+    assertThat(e.getArguments()).hasSize(3);
+    assertEquals(3, e.getNumPositionalArguments());
+
+    IntegerLiteral arg0 = (IntegerLiteral) e.getArguments().get(0).getValue();
+    assertEquals(1, (int) arg0.getValue());
+
+    Argument.Passed arg1 = e.getArguments().get(1);
+    Ident arg1val = ((Ident) arg1.getValue());
+    assertEquals("$error$", arg1val.getName());
+
+    assertLocation(5, 24, arg1val.getLocation());
+    assertEquals("[x for foo foo foo]", expr.substring(5, 24));
+    assertEquals(25, arg1val.getLocation().getEndLineAndColumn().getColumn());
+
+    IntegerLiteral arg2 = (IntegerLiteral) e.getArguments().get(2).getValue();
+    assertEquals(3, (int) arg2.getValue());
+  }
+
+  public void testDoesntGetStuck() throws Exception {
+    syntaxEvents.setFailFast(false);
+
+    // Make sure the parser does not get stuck when trying
+    // to parse an expression containing a syntax error.
+    // This usually results in OutOfMemoryError because the
+    // parser keeps filling up the error log.
+    // We need to make sure that we will always advance
+    // in the token stream.
+    parseExpr("f(1, ], 3)");
+    parseExpr("f(1, ), 3)");
+    parseExpr("[ ) for v in 3)");
+
+    syntaxEvents.assertContainsEvent(""); // "" matches any;
+                                          // i.e. there were some events
+  }
+
+  public void testSecondaryLocation() {
+    String expr = "f(1 % 2)";
+    FuncallExpression call = (FuncallExpression) parseExpr(expr);
+    Argument.Passed arg = call.getArguments().get(0);
+    assertTrue(arg.getLocation().getEndOffset() < call.getLocation().getEndOffset());
+  }
+
+  public void testPrimaryLocation() {
+    String expr = "f(1 + 2)";
+    FuncallExpression call = (FuncallExpression) parseExpr(expr);
+    Argument.Passed arg = call.getArguments().get(0);
+    assertTrue(arg.getLocation().getEndOffset() < call.getLocation().getEndOffset());
+  }
+
+  public void testAssignLocation() {
+    String expr = "a = b;c = d\n";
+    List<Statement> statements = parseFile(expr);
+    Statement statement = statements.get(0);
+    assertEquals(5, statement.getLocation().getEndOffset());
+  }
+
+  public void testAssign() {
+    String expr = "list[0] = 5; dict['key'] = value\n";
+    List<Statement> statements = parseFile(expr);
+    assertThat(statements).hasSize(2);
+  }
+
+  public void testInvalidAssign() {
+    syntaxEvents.setFailFast(false);
+    parseExpr("1 + (b = c)");
+    syntaxEvents.assertContainsEvent("syntax error");
+    syntaxEvents.collector().clear();
+  }
+
+  public void testAugmentedAssign() throws Exception {
+    assertEquals("[x = x + 1\n]", parseFile("x += 1").toString());
+  }
+
+  public void testPrettyPrintFunctions() throws Exception {
+    assertEquals("[x[1:3]\n]", parseFile("x[1:3]").toString());
+    assertEquals("[str[42]\n]", parseFile("str[42]").toString());
+    assertEquals("[ctx.new_file(['hello'])\n]", parseFile("ctx.new_file('hello')").toString());
+    assertEquals("[new_file(['hello'])\n]", parseFile("new_file('hello')").toString());
+  }
+
+  public void testFuncallLocation() {
+    String expr = "a(b);c = d\n";
+    List<Statement> statements = parseFile(expr);
+    Statement statement = statements.get(0);
+    assertEquals(4, statement.getLocation().getEndOffset());
+  }
+
+  public void testSpecialFuncallLocation() throws Exception {
+    List<Statement> statements = parseFile("-x\n");
+    assertLocation(0, 3, statements.get(0).getLocation());
+
+    statements = parseFile("arr[15]\n");
+    assertLocation(0, 8, statements.get(0).getLocation());
+
+    statements = parseFile("str[1:12]\n");
+    assertLocation(0, 10, statements.get(0).getLocation());
+  }
+
+  public void testListPositions() throws Exception {
+    String expr = "[0,f(1),2]";
+    ListLiteral list = (ListLiteral) parseExpr(expr);
+    assertEquals("[0,f(1),2]", getText(expr, list));
+    assertEquals("0",    getText(expr, getElem(list, 0)));
+    assertEquals("f(1)", getText(expr, getElem(list, 1)));
+    assertEquals("2",    getText(expr, getElem(list, 2)));
+  }
+
+  public void testDictPositions() throws Exception {
+    String expr = "{1:2,2:f(1),3:4}";
+    DictionaryLiteral list = (DictionaryLiteral) parseExpr(expr);
+    assertEquals("{1:2,2:f(1),3:4}", getText(expr, list));
+    assertEquals("1:2",    getText(expr, getElem(list, 0)));
+    assertEquals("2:f(1)", getText(expr, getElem(list, 1)));
+    assertEquals("3:4",    getText(expr, getElem(list, 2)));
+  }
+
+  public void testArgumentPositions() throws Exception {
+    String stmt = "f(0,g(1,2),2)";
+    FuncallExpression f = (FuncallExpression) parseExpr(stmt);
+    assertEquals(stmt, getText(stmt, f));
+    assertEquals("0",    getText(stmt, getArg(f, 0)));
+    assertEquals("g(1,2)", getText(stmt, getArg(f, 1)));
+    assertEquals("2",    getText(stmt, getArg(f, 2)));
+  }
+
+  public void testListLiterals1() throws Exception {
+    ListLiteral list = (ListLiteral) parseExpr("[0,1,2]");
+    assertFalse(list.isTuple());
+    assertThat(list.getElements()).hasSize(3);
+    assertFalse(list.isTuple());
+    for (int i = 0; i < 3; ++i) {
+      assertEquals(i, getIntElem(list, i));
+    }
+  }
+
+  public void testTupleLiterals2() throws Exception {
+    ListLiteral tuple = (ListLiteral) parseExpr("(0,1,2)");
+    assertTrue(tuple.isTuple());
+    assertThat(tuple.getElements()).hasSize(3);
+    assertTrue(tuple.isTuple());
+    for (int i = 0; i < 3; ++i) {
+      assertEquals(i, getIntElem(tuple, i));
+    }
+  }
+
+  public void testTupleLiterals3() throws Exception {
+    ListLiteral emptyTuple = (ListLiteral) parseExpr("()");
+    assertTrue(emptyTuple.isTuple());
+    assertThat(emptyTuple.getElements()).isEmpty();
+  }
+
+  public void testTupleLiterals4() throws Exception {
+    ListLiteral singletonTuple = (ListLiteral) parseExpr("(42,)");
+    assertTrue(singletonTuple.isTuple());
+    assertThat(singletonTuple.getElements()).hasSize(1);
+    assertEquals(42, getIntElem(singletonTuple, 0));
+  }
+
+  public void testTupleLiterals5() throws Exception {
+    IntegerLiteral intLit = (IntegerLiteral) parseExpr("(42)"); // not a tuple!
+    assertEquals(42, (int) intLit.getValue());
+  }
+
+  public void testListLiterals6() throws Exception {
+    ListLiteral emptyList = (ListLiteral) parseExpr("[]");
+    assertFalse(emptyList.isTuple());
+    assertThat(emptyList.getElements()).isEmpty();
+  }
+
+  public void testListLiterals7() throws Exception {
+    ListLiteral singletonList = (ListLiteral) parseExpr("[42,]");
+    assertFalse(singletonList.isTuple());
+    assertThat(singletonList.getElements()).hasSize(1);
+    assertEquals(42, getIntElem(singletonList, 0));
+  }
+
+  public void testListLiterals8() throws Exception {
+    ListLiteral singletonList = (ListLiteral) parseExpr("[42]"); // a singleton
+    assertFalse(singletonList.isTuple());
+    assertThat(singletonList.getElements()).hasSize(1);
+    assertEquals(42, getIntElem(singletonList, 0));
+  }
+
+  public void testDictionaryLiterals() throws Exception {
+    DictionaryLiteral dictionaryList =
+      (DictionaryLiteral) parseExpr("{1:42}"); // a singleton dictionary
+    assertThat(dictionaryList.getEntries()).hasSize(1);
+    DictionaryEntryLiteral tuple = getElem(dictionaryList, 0);
+    assertEquals(1, getIntElem(tuple, true));
+    assertEquals(42, getIntElem(tuple, false));
+  }
+
+  public void testDictionaryLiterals1() throws Exception {
+    DictionaryLiteral dictionaryList =
+      (DictionaryLiteral) parseExpr("{}"); // an empty dictionary
+    assertThat(dictionaryList.getEntries()).isEmpty();
+  }
+
+  public void testDictionaryLiterals2() throws Exception {
+    DictionaryLiteral dictionaryList =
+      (DictionaryLiteral) parseExpr("{1:42,}"); // a singleton dictionary
+    assertThat(dictionaryList.getEntries()).hasSize(1);
+    DictionaryEntryLiteral tuple = getElem(dictionaryList, 0);
+    assertEquals(1, getIntElem(tuple, true));
+    assertEquals(42, getIntElem(tuple, false));
+  }
+
+  public void testDictionaryLiterals3() throws Exception {
+    DictionaryLiteral dictionaryList = (DictionaryLiteral) parseExpr("{1:42,2:43,3:44}");
+    assertThat(dictionaryList.getEntries()).hasSize(3);
+    for (int i = 0; i < 3; i++) {
+      DictionaryEntryLiteral tuple = getElem(dictionaryList, i);
+      assertEquals(i + 1, getIntElem(tuple, true));
+      assertEquals(i + 42, getIntElem(tuple, false));
+    }
+  }
+
+  public void testListLiterals9() throws Exception {
+    ListLiteral singletonList =
+      (ListLiteral) parseExpr("[ abi + opt_level + \'/include\' ]");
+    assertFalse(singletonList.isTuple());
+    assertThat(singletonList.getElements()).hasSize(1);
+  }
+
+  public void testListComprehensionSyntax() throws Exception {
+    syntaxEvents.setFailFast(false);
+
+    parseExpr("[x for");
+    syntaxEvents.assertContainsEvent("syntax error at 'newline'");
+    syntaxEvents.collector().clear();
+
+    parseExpr("[x for x");
+    syntaxEvents.assertContainsEvent("syntax error at 'newline'");
+    syntaxEvents.collector().clear();
+
+    parseExpr("[x for x in");
+    syntaxEvents.assertContainsEvent("syntax error at 'newline'");
+    syntaxEvents.collector().clear();
+
+    parseExpr("[x for x in []");
+    syntaxEvents.assertContainsEvent("syntax error at 'newline'");
+    syntaxEvents.collector().clear();
+
+    parseExpr("[x for x for y in ['a']]");
+    syntaxEvents.assertContainsEvent("syntax error at 'for'");
+    syntaxEvents.collector().clear();
+  }
+
+  public void testListComprehension() throws Exception {
+    ListComprehension list =
+      (ListComprehension) parseExpr(
+          "['foo/%s.java' % x "
+          + "for x in []]");
+    assertThat(list.getLists()).hasSize(1);
+
+    list = (ListComprehension) parseExpr("['foo/%s.java' % x "
+        + "for x in ['bar', 'wiz', 'quux']]");
+    assertThat(list.getLists()).hasSize(1);
+
+    list = (ListComprehension) parseExpr("['%s/%s.java' % (x, y) "
+        + "for x in ['foo', 'bar'] for y in ['baz', 'wiz', 'quux']]");
+    assertThat(list.getLists()).hasSize(2);
+  }
+
+  public void testParserContainsErrorsIfSyntaxException() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseExpr("'foo' %%");
+    syntaxEvents.assertContainsEvent("syntax error at '%'");
+  }
+
+  public void testParserDoesNotContainErrorsIfSuccess() throws Exception {
+    parseExpr("'foo'");
+  }
+
+  public void testParserContainsErrors() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseStmt("+");
+    syntaxEvents.assertContainsEvent("syntax error at '+'");
+  }
+
+  public void testSemicolonAndNewline() throws Exception {
+    List<Statement> stmts = parseFile(
+      "foo='bar'; foo(bar)" + '\n'
+      + "" + '\n'
+      + "foo='bar'; foo(bar)"
+    );
+    assertThat(stmts).hasSize(4);
+  }
+
+  public void testSemicolonAndNewline2() throws Exception {
+    syntaxEvents.setFailFast(false);
+    List<Statement> stmts = parseFile(
+      "foo='foo' error(bar)" + '\n'
+      + "" + '\n'
+    );
+    syntaxEvents.assertContainsEvent("syntax error at 'error'");
+    assertThat(stmts).hasSize(2);
+  }
+
+  public void testExprAsStatement() throws Exception {
+    List<Statement> stmts = parseFile(
+      "li = []\n"
+      + "li.append('a.c')\n"
+      + "\"\"\" string comment \"\"\"\n"
+      + "foo(bar)"
+    );
+    assertThat(stmts).hasSize(4);
+  }
+
+  public void testParseBuildFileWithSingeRule() throws Exception {
+    List<Statement> stmts = parseFile(
+      "genrule(name = 'foo'," + '\n'
+      + "   srcs = ['input.csv']," + '\n'
+      + "   outs = [ 'result.txt'," + '\n'
+      + "           'result.log']," + '\n'
+      + "   cmd = 'touch result.txt result.log')" + '\n'
+      );
+    assertThat(stmts).hasSize(1);
+  }
+
+  public void testParseBuildFileWithMultipleRules() throws Exception {
+    List<Statement> stmts = parseFile(
+      "genrule(name = 'foo'," + '\n'
+      + "   srcs = ['input.csv']," + '\n'
+      + "   outs = [ 'result.txt'," + '\n'
+      + "           'result.log']," + '\n'
+      + "   cmd = 'touch result.txt result.log')" + '\n'
+      + "" + '\n'
+      + "genrule(name = 'bar'," + '\n'
+      + "   srcs = ['input.csv']," + '\n'
+      + "   outs = [ 'graph.svg']," + '\n'
+      + "   cmd = 'touch graph.svg')" + '\n'
+      );
+    assertThat(stmts).hasSize(2);
+  }
+
+  public void testParseBuildFileWithComments() throws Exception {
+    Parser.ParseResult result = parseFileWithComments(
+      "# Test BUILD file" + '\n'
+      + "# with multi-line comment" + '\n'
+      + "" + '\n'
+      + "genrule(name = 'foo'," + '\n'
+      + "   srcs = ['input.csv']," + '\n'
+      + "   outs = [ 'result.txt'," + '\n'
+      + "           'result.log']," + '\n'
+      + "   cmd = 'touch result.txt result.log')" + '\n'
+      );
+    assertThat(result.statements).hasSize(1);
+    assertThat(result.comments).hasSize(2);
+  }
+
+  public void testParseBuildFileWithManyComments() throws Exception {
+    Parser.ParseResult result = parseFileWithComments(
+      "# 1" + '\n'
+      + "# 2" + '\n'
+      + "" + '\n'
+      + "# 4 " + '\n'
+      + "# 5" + '\n'
+      + "#" + '\n' // 6 - find empty comment for syntax highlighting
+      + "# 7 " + '\n'
+      + "# 8" + '\n'
+      + "genrule(name = 'foo'," + '\n'
+      + "   srcs = ['input.csv']," + '\n'
+      + "   # 11" + '\n'
+      + "   outs = [ 'result.txt'," + '\n'
+      + "           'result.log'], # 13" + '\n'
+      + "   cmd = 'touch result.txt result.log')" + '\n'
+      + "# 15" + '\n'
+      );
+    assertThat(result.statements).hasSize(1); // Single genrule
+    StringBuilder commentLines = new StringBuilder();
+    for (Comment comment : result.comments) {
+      // Comments start and end on the same line
+      assertEquals(comment.getLocation().getStartLineAndColumn().getLine() + " ends on "
+          + comment.getLocation().getEndLineAndColumn().getLine(),
+          comment.getLocation().getStartLineAndColumn().getLine(),
+          comment.getLocation().getEndLineAndColumn().getLine());
+      commentLines.append('(');
+      commentLines.append(comment.getLocation().getStartLineAndColumn().getLine());
+      commentLines.append(',');
+      commentLines.append(comment.getLocation().getStartLineAndColumn().getColumn());
+      commentLines.append(") ");
+    }
+    assertWithMessage("Found: " + commentLines)
+        .that(result.comments.size()).isEqualTo(10); // One per '#'
+  }
+
+  public void testMissingComma() throws Exception {
+    syntaxEvents.setFailFast(false);
+    // Regression test.
+    // Note: missing comma after name='foo'
+    parseFile("genrule(name = 'foo'\n"
+              + "      srcs = ['in'])");
+    syntaxEvents.assertContainsEvent("syntax error at 'srcs'");
+  }
+
+  public void testDoubleSemicolon() throws Exception {
+    syntaxEvents.setFailFast(false);
+    // Regression test.
+    parseFile("x = 1; ; x = 2;");
+    syntaxEvents.assertContainsEvent("syntax error at ';'");
+  }
+
+  public void testFunctionDefinitionErrorRecovery() throws Exception {
+    // Parser skips over entire function definitions, and reports a meaningful
+    // error.
+    syntaxEvents.setFailFast(false);
+    List<Statement> stmts = parseFile(
+        "x = 1;\n"
+        + "def foo(x, y, **z):\n"
+        + "  # a comment\n"
+        + "  x = 2\n"
+        + "  foo(bar)\n"
+        + "  return z\n"
+        + "x = 3");
+    assertThat(stmts).hasSize(2);
+  }
+
+  public void testFunctionDefinitionIgnored() throws Exception {
+    // Parser skips over entire function definitions without reporting error,
+    // when parsePython is set to true.
+    List<Statement> stmts = parseFile(
+        "x = 1;\n"
+        + "def foo(x, y, **z):\n"
+        + "  # a comment\n"
+        + "  if true:"
+        + "    x = 2\n"
+        + "  foo(bar)\n"
+        + "  return z\n"
+        + "x = 3", true /* parsePython */);
+    assertThat(stmts).hasSize(2);
+
+    stmts = parseFile(
+        "x = 1;\n"
+        + "def foo(x, y, **z): return x\n"
+        + "x = 3", true /* parsePython */);
+    assertThat(stmts).hasSize(2);
+  }
+
+  public void testMissingBlock() throws Exception {
+    syntaxEvents.setFailFast(false);
+    List<Statement> stmts = parseFile(
+        "x = 1;\n"
+        + "def foo(x):\n"
+        + "x = 2;\n",
+        true /* parsePython */);
+    assertThat(stmts).hasSize(2);
+    syntaxEvents.assertContainsEvent("expected an indented block");
+  }
+
+  public void testInvalidDef() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile(
+        "x = 1;\n"
+        + "def foo(x)\n"
+        + "x = 2;\n",
+        true /* parsePython */);
+    syntaxEvents.assertContainsEvent("syntax error at 'EOF'");
+  }
+
+  public void testSkipIfBlock() throws Exception {
+    // Skip over 'if' blocks, when parsePython is set
+    List<Statement> stmts = parseFile(
+        "x = 1;\n"
+        + "if x == 1:\n"
+        + "  foo(x)\n"
+        + "else:\n"
+        + "  bar(x)\n"
+        + "x = 3;\n",
+        true /* parsePython */);
+    assertThat(stmts).hasSize(2);
+  }
+
+  public void testSkipIfBlockFail() throws Exception {
+    // Do not parse 'if' blocks, when parsePython is not set
+    syntaxEvents.setFailFast(false);
+    List<Statement> stmts = parseFile(
+        "x = 1;\n"
+        + "if x == 1:\n"
+        + "  x = 2\n"
+        + "x = 3;\n",
+        false /* no parsePython */);
+    assertThat(stmts).hasSize(2);
+    syntaxEvents.assertContainsEvent("This Python-style construct is not supported");
+  }
+
+  public void testForLoopMultipleVariablesFail() throws Exception {
+    // For loops with multiple variables are not allowed, when parsePython is not set
+    syntaxEvents.setFailFast(false);
+    List<Statement> stmts = parseFile(
+        "[ i for i, j, k in [(1, 2, 3)] ]\n",
+        false /* no parsePython */);
+    assertThat(stmts).hasSize(1);
+    syntaxEvents.assertContainsEvent("For loops with multiple variables are not yet supported.");
+  }
+
+  public void testForLoopMultipleVariables() throws Exception {
+    // For loops with multiple variables is ok, when parsePython is set
+    List<Statement> stmts1 = parseFile(
+        "[ i for i, j, k in [(1, 2, 3)] ]\n",
+        true /* parsePython */);
+    assertThat(stmts1).hasSize(1);
+
+    List<Statement> stmts2 = parseFile(
+        "[ i for i, j in [(1, 2, 3)] ]\n",
+        true /* parsePython */);
+    assertThat(stmts2).hasSize(1);
+
+    List<Statement> stmts3 = parseFile(
+        "[ i for (i, j, k) in [(1, 2, 3)] ]\n",
+        true /* parsePython */);
+    assertThat(stmts3).hasSize(1);
+  }
+
+  public void testForLoopBadSyntax() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile(
+        "[1 for (a, b, c in var]\n",
+        false /* no parsePython */);
+    syntaxEvents.assertContainsEvent("syntax error");
+  }
+
+  public void testForLoopBadSyntax2() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile(
+        "[1 for () in var]\n",
+        false /* no parsePython */);
+    syntaxEvents.assertContainsEvent("syntax error");
+  }
+
+  public void testFunCallBadSyntax() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile("f(1,\n");
+    syntaxEvents.assertContainsEvent("syntax error");
+  }
+
+  public void testFunCallBadSyntax2() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile("f(1, 5, ,)\n");
+    syntaxEvents.assertContainsEvent("syntax error");
+  }
+
+  public void testLoadOneSymbol() throws Exception {
+    List<Statement> statements = parseFileForSkylark(
+        "load('/foo/bar/file', 'fun_test')\n");
+    LoadStatement stmt = (LoadStatement) statements.get(0);
+    assertEquals("/foo/bar/file.bzl", stmt.getImportPath().toString());
+    assertThat(stmt.getSymbols()).hasSize(1);
+  }
+
+  public void testLoadMultipleSymbols() throws Exception {
+    List<Statement> statements = parseFileForSkylark(
+        "load('file', 'foo', 'bar')\n");
+    LoadStatement stmt = (LoadStatement) statements.get(0);
+    assertEquals("file.bzl", stmt.getImportPath().toString());
+    assertThat(stmt.getSymbols()).hasSize(2);
+  }
+
+  public void testLoadSyntaxError() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark("load(non_quoted, 'a')\n");
+    syntaxEvents.assertContainsEvent("syntax error");
+  }
+
+  public void testLoadSyntaxError2() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark("load('non_quoted', a)\n");
+    syntaxEvents.assertContainsEvent("syntax error");
+  }
+
+  public void testLoadNotAtTopLevel() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark("if 1: load(8)\n");
+    syntaxEvents.assertContainsEvent("function 'load' does not exist");
+  }
+
+  public void testParseErrorNotComparison() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile("2 < not 3");
+    syntaxEvents.assertContainsEvent("syntax error at 'not'");
+  }
+
+  public void testNotWithArithmeticOperatorsBadSyntax() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile("0 + not 0");
+    syntaxEvents.assertContainsEvent("syntax error at 'not'");
+  }
+
+  public void testOptionalArgBeforeMandatoryArgInFuncDef() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark("def func(a, b = 'a', c):\n  return 0\n");
+    syntaxEvents.assertContainsEvent(
+        "a mandatory positional parameter must not follow an optional parameter");
+  }
+
+  public void testKwargBeforePositionalArg() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark(
+        "def func(a, b): return a + b\n"
+        + "func(**{'b': 1}, 'a')");
+    syntaxEvents.assertContainsEvent("unexpected tokens after kwarg");
+  }
+
+  public void testDuplicateKwarg() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark(
+        "def func(a, b): return a + b\n"
+        + "func(**{'b': 1}, **{'a': 2})");
+    syntaxEvents.assertContainsEvent("unexpected tokens after kwarg");
+  }
+
+  public void testUnnamedStar() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark(
+        "def func(a, b1=2, b2=3, *, c1, c2, d=4): return a + b1 + b2 + c1 + c2 + d\n");
+    syntaxEvents.assertContainsEvent("no star, star-star or named-only parameters (for now)");
+  }
+
+  public void testTopLevelForFails() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark("for i in []: 0\n");
+    syntaxEvents.assertContainsEvent(
+        "for loops are not allowed on top-level. Put it into a function");
+  }
+
+  public void testNestedFunctionFails() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark(
+          "def func(a):\n"
+        + "  def bar(): return 0\n"
+        + "  return bar()\n");
+    syntaxEvents.assertContainsEvent(
+        "nested functions are not allowed. Move the function to top-level");
+  }
+
+  public void testIncludeFailureSkylark() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark("include('//foo:bar')");
+    syntaxEvents.assertContainsEvent("function 'include' does not exist");
+  }
+
+  public void testIncludeFailure() throws Exception {
+    syntaxEvents.setFailFast(false);
+    parseFile("include('nonexistent')\n");
+    syntaxEvents.assertContainsEvent("Invalid label 'nonexistent'");
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
new file mode 100644
index 0000000..5ddb2af2
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -0,0 +1,799 @@
+// Copyright 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.syntax;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
+import com.google.devtools.build.lib.analysis.FileConfiguredTarget;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.events.EventKind;
+import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
+import com.google.devtools.build.lib.packages.MethodLibrary;
+import com.google.devtools.build.lib.rules.SkylarkModules;
+import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject;
+
+import java.util.List;
+
+/**
+ * Evaluation tests with Skylark Environment.
+ */
+public class SkylarkEvaluationTest extends EvaluationTest {
+
+  @SkylarkModule(name = "Mock", doc = "")
+  static class Mock {
+    @SkylarkCallable(doc = "")
+    public static Integer valueOf(String str) {
+      return Integer.valueOf(str);
+    }
+    @SkylarkCallable(doc = "")
+    public Boolean isEmpty(String str) {
+      return str.isEmpty();
+    }
+    public void value() {}
+    @SkylarkCallable(doc = "")
+    public Mock returnMutable() {
+      return new Mock();
+    }
+    @SkylarkCallable(name = "struct_field", doc = "", structField = true)
+    public String structField() {
+      return "a";
+    }
+    @SkylarkCallable(name = "function", doc = "", structField = false)
+    public String function() {
+      return "a";
+    }
+    @SuppressWarnings("unused")
+    @SkylarkCallable(name = "nullfunc_failing", doc = "", allowReturnNones = false)
+    public Object nullfuncFailing(String p1, Integer p2) {
+      return null;
+    }
+    @SkylarkCallable(name = "nullfunc_working", doc = "", allowReturnNones = true)
+    public Object nullfuncWorking() {
+      return null;
+    }
+    @SkylarkCallable(name = "voidfunc", doc = "")
+    public void voidfunc() {}
+    @SkylarkCallable(name = "string_list", doc = "")
+    public ImmutableList<String> stringList() {
+      return ImmutableList.<String>of("a", "b");
+    }
+    @SkylarkCallable(name = "string", doc = "")
+    public String string() {
+      return "a";
+    }
+  }
+
+  @SkylarkModule(name = "MockInterface", doc = "")
+  static interface MockInterface {
+    @SkylarkCallable(doc = "")
+    public Boolean isEmptyInterface(String str);
+  }
+
+  static final class MockSubClass extends Mock implements MockInterface {
+    @Override
+    public Boolean isEmpty(String str) {
+      return str.isEmpty();
+    }
+    @Override
+    public Boolean isEmptyInterface(String str) {
+      return str.isEmpty();
+    }
+    @SkylarkCallable(doc = "")
+    public Boolean isEmptyClassNotAnnotated(String str) {
+      return str.isEmpty();
+    }
+  }
+
+  static final class MockClassObject implements ClassObject {
+    @Override
+    public Object getValue(String name) {
+      switch (name) {
+        case "field": return "a";
+        case "nset": return NestedSetBuilder.stableOrder().build();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public ImmutableCollection<String> getKeys() {
+      return ImmutableList.of("field", "nset");
+    }
+
+    @Override
+    public String errorMessage(String name) {
+      return null;
+    }
+  }
+
+  @SkylarkModule(name = "MockMultipleMethodClass", doc = "")
+  static final class MockMultipleMethodClass {
+    @SuppressWarnings("unused")
+    @SkylarkCallable(doc = "")
+    public void method(Object o) {}
+    @SuppressWarnings("unused")
+    @SkylarkCallable(doc = "")
+    public void method(String i) {}
+  }
+
+  private static final ImmutableMap<String, SkylarkType> MOCK_TYPES = ImmutableMap
+      .<String, SkylarkType>of("mock", SkylarkType.UNKNOWN, "Mock", SkylarkType.UNKNOWN);
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    syntaxEvents = new EventCollectionApparatus(EventKind.ALL_EVENTS);
+    env = new SkylarkEnvironment(syntaxEvents.collector());
+    MethodLibrary.setupMethodEnvironment(env);
+  }
+
+  @Override
+  public Environment singletonEnv(String id, Object value) {
+    SkylarkEnvironment env = new SkylarkEnvironment(syntaxEvents.collector());
+    env.update(id, value);
+    return env;
+  }
+
+  public void testSimpleIf() throws Exception {
+    exec(parseFileForSkylark(
+        "def foo():\n"
+        + "  a = 0\n"
+        + "  x = 0\n"
+        + "  if x: a = 5\n"
+        + "  return a\n"
+        + "a = foo()"), env);
+    assertEquals(0, env.lookup("a"));
+  }
+
+  public void testNestedIf() throws Exception {
+    executeNestedIf(0, 0, env);
+    assertEquals(0, env.lookup("x"));
+
+    executeNestedIf(1, 0, env);
+    assertEquals(3, env.lookup("x"));
+
+    executeNestedIf(1, 1, env);
+    assertEquals(5, env.lookup("x"));
+  }
+
+  private void executeNestedIf(int x, int y, Environment env) throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  x = " + x + "\n"
+        + "  y = " + y + "\n"
+        + "  a = 0\n"
+        + "  b = 0\n"
+        + "  if x:\n"
+        + "    if y:\n"
+        + "      a = 2\n"
+        + "    b = 3\n"
+        + "  return a + b\n"
+        + "x = foo()");
+    exec(input, env);
+  }
+
+  public void testIfElse() throws Exception {
+    executeIfElse("something", 2);
+    executeIfElse("", 3);
+  }
+
+  private void executeIfElse(String y, int expectedA) throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  y = '" + y + "'\n"
+        + "  x = 5\n"
+        + "  if x:\n"
+        + "    if y: a = 2\n"
+        + "    else: a = 3\n"
+        + "  return a\n"
+        + "a = foo()");
+
+    exec(input, env);
+    assertEquals(expectedA, env.lookup("a"));
+  }
+
+  public void testIfElifElse_IfExecutes() throws Exception {
+    execIfElifElse(1, 0, 1);
+  }
+
+  public void testIfElifElse_ElifExecutes() throws Exception {
+    execIfElifElse(0, 1, 2);
+  }
+
+  public void testIfElifElse_ElseExecutes() throws Exception {
+    execIfElifElse(0, 0, 3);
+  }
+
+  private void execIfElifElse(int x, int y, int v) throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  x = " + x + "\n"
+        + "  y = " + y + "\n"
+        + "  if x:\n"
+        + "    return 1\n"
+        + "  elif y:\n"
+        + "    return 2\n"
+        + "  else:\n"
+        + "    return 3\n"
+        + "v = foo()");
+    exec(input, env);
+    assertEquals(v, env.lookup("v"));
+  }
+
+  public void testForOnList() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  s = ''\n"
+        + "  for i in ['hello', ' ', 'world']:\n"
+        + "    s = s + i\n"
+        + "  return s\n"
+        + "s = foo()\n");
+
+    exec(input, env);
+    assertEquals("hello world", env.lookup("s"));
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testForOnString() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  s = []\n"
+        + "  for i in 'abc':\n"
+        + "    s = s + [i]\n"
+        + "  return s\n"
+        + "s = foo()\n");
+
+    exec(input, env);
+    assertThat((Iterable<Object>) env.lookup("s")).containsExactly("a", "b", "c").inOrder();
+  }
+
+  public void testForAssignmentList() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  d = ['a', 'b', 'c']\n"
+        + "  s = ''\n"
+        + "  for i in d:\n"
+        + "    s = s + i\n"
+        + "    d = ['d', 'e', 'f']\n"  // check that we use the old list
+        + "  return s\n"
+        + "s = foo()\n");
+
+    exec(input, env);
+    assertEquals("abc", env.lookup("s"));
+  }
+
+  public void testForAssignmentDict() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+          "def func():\n"
+        + "  d = {'a' : 1, 'b' : 2, 'c' : 3}\n"
+        + "  s = ''\n"
+        + "  for i in d:\n"
+        + "    s = s + i\n"
+        + "    d = {'d' : 1, 'e' : 2, 'f' : 3}\n"
+        + "  return s\n"
+        + "s = func()");
+
+    exec(input, env);
+    assertEquals("abc", env.lookup("s"));
+  }
+
+  public void testForNotIterable() throws Exception {
+    env.update("mock", new Mock());
+    List<Statement> input = parseFileForSkylark(
+          "def func():\n"
+        + "  for i in mock.value_of('1'): a = i\n"
+        + "func()\n", MOCK_TYPES);
+    checkEvalError(input, env, "type 'int' is not an iterable");
+  }
+
+  public void testForOnDictionary() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  d = {1: 'a', 2: 'b', 3: 'c'}\n"
+        + "  s = ''\n"
+        + "  for i in d: s = s + d[i]\n"
+        + "  return s\n"
+        + "s = foo()");
+
+    exec(input, env);
+    assertEquals("abc", env.lookup("s"));
+  }
+
+  public void testForLoopReuseVariable() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  s = ''\n"
+        + "  for i in ['a', 'b']:\n"
+        + "    for i in ['c', 'd']: s = s + i\n"
+        + "  return s\n"
+        + "s = foo()");
+
+    exec(input, env);
+    assertEquals("cdcd", env.lookup("s"));
+  }
+
+  public void testNoneAssignment() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo(x=None):\n"
+        + "  x = 1\n"
+        + "  x = None\n"
+        + "  return 2\n"
+        + "s = foo()");
+
+    exec(input, env);
+    assertEquals(2, env.lookup("s"));
+  }
+
+  public void testJavaCalls() throws Exception {
+    env.update("mock", new Mock());
+    List<Statement> input = parseFileForSkylark(
+        "b = mock.is_empty('a')", MOCK_TYPES);
+    exec(input, env);
+    assertEquals(Boolean.FALSE, env.lookup("b"));
+  }
+
+  public void testJavaCallsOnSubClass() throws Exception {
+    env.update("mock", new MockSubClass());
+    List<Statement> input = parseFileForSkylark(
+        "b = mock.is_empty('a')", MOCK_TYPES);
+    exec(input, env);
+    assertEquals(Boolean.FALSE, env.lookup("b"));
+  }
+
+  public void testJavaCallsOnInterface() throws Exception {
+    env.update("mock", new MockSubClass());
+    List<Statement> input = parseFileForSkylark(
+        "b = mock.is_empty_interface('a')", MOCK_TYPES);
+    exec(input, env);
+    assertEquals(Boolean.FALSE, env.lookup("b"));
+  }
+
+  public void testJavaCallsNotSkylarkCallable() throws Exception {
+    env.update("mock", new Mock());
+    List<Statement> input = parseFileForSkylark("mock.value()", MOCK_TYPES);
+    checkEvalError(input, env, "No matching method found for value() in Mock");
+  }
+
+  public void testJavaCallsNoMethod() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "s = 3.bad()");
+    checkEvalError(input, env, "No matching method found for bad() in int");
+  }
+
+  public void testJavaCallsNoMethodErrorMsg() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "s = 3.bad('a', 'b', 'c')");
+    checkEvalError(input, env,
+        "No matching method found for bad(string, string, string) in int");
+  }
+
+  public void testJavaCallsMultipleMethod() throws Exception {
+    env.update("mock", new MockMultipleMethodClass());
+    List<Statement> input = parseFileForSkylark(
+        "s = mock.method('string')", MOCK_TYPES);
+    checkEvalError(input, env,
+        "Multiple matching methods for method(string) in MockMultipleMethodClass");
+  }
+
+  public void testJavaCallWithKwargs() throws Exception {
+    List<Statement> input = parseFileForSkylark("comp = 3.compare_to(x = 4)");
+    checkEvalError(input, env, "Keyword arguments are not allowed when calling a java method"
+                   + "\nwhile calling method 'compare_to' on object 3 of type int");
+  }
+
+  public void testNoJavaCallsWithoutSkylark() throws Exception {
+    List<Statement> input = parseFileForSkylark("s = 3.to_string()\n");
+    checkEvalError(input, env, "No matching method found for to_string() in int");
+  }
+
+  public void testNoJavaCallsIfClassNotAnnotated() throws Exception {
+    env.update("mock", new MockSubClass());
+    List<Statement> input = parseFileForSkylark(
+        "b = mock.is_empty_class_not_annotated('a')", MOCK_TYPES);
+    checkEvalError(input, env,
+        "No matching method found for is_empty_class_not_annotated(string) in MockSubClass");
+  }
+
+  public void testStructAccess() throws Exception {
+    env.update("mock", new Mock());
+    List<Statement> input = parseFileForSkylark(
+        "v = mock.struct_field", MOCK_TYPES);
+    exec(input, env);
+    assertEquals("a", env.lookup("v"));
+  }
+
+  public void testStructAccessAsFuncall() throws Exception {
+    env.update("mock", new Mock());
+    checkEvalError(parseFileForSkylark("v = mock.struct_field()", MOCK_TYPES), env,
+        "No matching method found for struct_field() in Mock");
+  }
+
+  public void testStructAccessOfMethod() throws Exception {
+    env.update("mock", new Mock());
+    checkEvalError(parseFileForSkylark(
+        "v = mock.function", MOCK_TYPES), env, "Object of type 'Mock' has no field 'function'");
+  }
+
+  public void testJavaFunctionReturnsMutableObject() throws Exception {
+    env.update("mock", new Mock());
+    List<Statement> input = parseFileForSkylark("mock.return_mutable()", MOCK_TYPES);
+    checkEvalError(input, env, "Method 'return_mutable' returns a mutable object (type of Mock)");
+  }
+
+  public void testJavaFunctionReturnsNullFails() throws Exception {
+    env.update("mock", new Mock());
+    List<Statement> input = parseFileForSkylark("mock.nullfunc_failing('abc', 1)", MOCK_TYPES);
+    checkEvalError(input, env, "Method invocation returned None,"
+        + " please contact Skylark developers: nullfunc_failing(\"abc\", 1)");
+  }
+
+  public void testClassObjectAccess() throws Exception {
+    env.update("mock", new MockClassObject());
+    exec(parseFileForSkylark("v = mock.field", MOCK_TYPES), env);
+    assertEquals("a", env.lookup("v"));
+  }
+
+  public void testClassObjectCannotAccessNestedSet() throws Exception {
+    env.update("mock", new MockClassObject());
+    checkEvalError(parseFileForSkylark("v = mock.nset", MOCK_TYPES), env,
+        "Type is not allowed in Skylark: EmptyNestedSet");
+  }
+
+  public void testJavaFunctionReturnsNone() throws Exception {
+    env.update("mock", new Mock());
+    exec(parseFileForSkylark("v = mock.nullfunc_working()", MOCK_TYPES), env);
+    assertSame(Environment.NONE, env.lookup("v"));
+  }
+
+  public void testVoidJavaFunctionReturnsNone() throws Exception {
+    env.update("mock", new Mock());
+    exec(parseFileForSkylark("v = mock.voidfunc()", MOCK_TYPES), env);
+    assertSame(Environment.NONE, env.lookup("v"));
+  }
+
+  public void testAugmentedAssignment() throws Exception {
+    exec(parseFileForSkylark(
+        "def f1(x):\n"
+        + "  x += 1\n"
+        + "  return x\n"
+        + "\n"
+        + "foo = f1(41)\n"), env);
+    assertEquals(42, env.lookup("foo"));
+  }
+
+  public void testStaticDirectJavaCall() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "val = Mock.value_of('8')", MOCK_TYPES);
+
+    env.update("Mock", Mock.class);
+    exec(input, env);
+    assertEquals(8, env.lookup("val"));
+  }
+
+  public void testStaticDirectJavaCallMethodIsNonStatic() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "val = Mock.is_empty('a')", MOCK_TYPES);
+
+    env.update("Mock", Mock.class);
+    checkEvalError(input, env, "Method 'is_empty' is not static");
+  }
+
+  public void testDictComprehensions_IterationOrder() throws Exception {
+    List<Statement> input = parseFileForSkylark(
+        "def foo():\n"
+        + "  d = {x : x for x in ['c', 'a', 'b']}\n"
+        + "  s = ''\n"
+        + "  for a in d:\n"
+        + "    s += a\n"
+        + "  return s\n"
+        + "s = foo()");
+    exec(input, env);
+    assertEquals("cab", env.lookup("s"));
+  }
+
+  public void testStructCreation() throws Exception {
+    exec(parseFileForSkylark("x = struct(a = 1, b = 2)"), env);
+    assertThat(env.lookup("x")).isInstanceOf(ClassObject.class);
+  }
+
+  public void testStructFields() throws Exception {
+    exec(parseFileForSkylark("x = struct(a = 1, b = 2)"), env);
+    ClassObject x = (ClassObject) env.lookup("x");
+    assertEquals(1, x.getValue("a"));
+    assertEquals(2, x.getValue("b"));
+  }
+
+  public void testStructAccessingFieldsFromSkylark() throws Exception {
+    exec(parseFileForSkylark(
+          "x = struct(a = 1, b = 2)\n"
+        + "x1 = x.a\n"
+        + "x2 = x.b\n"), env);
+    assertEquals(1, env.lookup("x1"));
+    assertEquals(2, env.lookup("x2"));
+  }
+
+  public void testStructAccessingUnknownField() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "x = struct(a = 1, b = 2)\n"
+        + "y = x.c\n"), env, "Object of type 'struct' has no field 'c'");
+  }
+
+  public void testStructAccessingFieldsWithArgs() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "x = struct(a = 1, b = 2)\n"
+        + "x1 = x.a(1)\n"),
+        env, "No matching method found for a(int) in struct");
+  }
+
+  public void testStructPosArgs() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "x = struct(1, b = 2)\n"),
+        env, "struct only supports keyword arguments");
+  }
+
+  public void testStructConcatenationFieldNames() throws Exception {
+    exec(parseFileForSkylark(
+          "x = struct(a = 1, b = 2)\n"
+        + "y = struct(c = 1, d = 2)\n"
+        + "z = x + y\n"), env);
+    SkylarkClassObject z = (SkylarkClassObject) env.lookup("z");
+    assertEquals(ImmutableSet.of("a", "b", "c", "d"), z.getKeys());
+  }
+
+  public void testStructConcatenationFieldValues() throws Exception {
+    exec(parseFileForSkylark(
+          "x = struct(a = 1, b = 2)\n"
+        + "y = struct(c = 1, d = 2)\n"
+        + "z = x + y\n"), env);
+    SkylarkClassObject z = (SkylarkClassObject) env.lookup("z");
+    assertEquals(1, z.getValue("a"));
+    assertEquals(2, z.getValue("b"));
+    assertEquals(1, z.getValue("c"));
+    assertEquals(2, z.getValue("d"));
+  }
+
+  public void testStructConcatenationCommonFields() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "x = struct(a = 1, b = 2)\n"
+        + "y = struct(c = 1, a = 2)\n"
+        + "z = x + y\n"), env, "Cannot concat structs with common field(s): a");
+  }
+
+  public void testDotExpressionOnNonStructObject() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "x = 'a'.field"), env, "Object of type 'string' has no field 'field'");
+  }
+
+  public void testPlusEqualsOnDict() throws Exception {
+    MethodLibrary.setupMethodEnvironment(env);
+    exec(parseFileForSkylark(
+          "def func():\n"
+        + "  d = {'a' : 1}\n"
+        + "  d += {'b' : 2}\n"
+        + "  return d\n"
+        + "d = func()"), env);
+    assertEquals(ImmutableMap.of("a", 1, "b", 2), env.lookup("d"));
+  }
+
+  public void testDictAssignmentAsLValue() throws Exception {
+    exec(parseFileForSkylark(
+          "def func():\n"
+        + "  d = {'a' : 1}\n"
+        + "  d['b'] = 2\n"
+        + "  return d\n"
+        + "d = func()"), env);
+    assertEquals(ImmutableMap.of("a", 1, "b", 2), env.lookup("d"));
+  }
+
+  public void testDictAssignmentAsLValueNoSideEffects() throws Exception {
+    MethodLibrary.setupMethodEnvironment(env);
+    exec(parseFileForSkylark(
+          "def func(d):\n"
+        + "  d['b'] = 2\n"
+        + "d = {'a' : 1}\n"
+        + "func(d)"), env);
+    assertEquals(ImmutableMap.of("a", 1), env.lookup("d"));
+  }
+
+  public void testListIndexAsLValueAsLValue() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "def id(l):\n"
+        + "  return l\n"
+        + "def func():\n"
+        + "  l = id([1])\n"
+        + "  l[0] = 2\n"
+        + "  return l\n"
+        + "l = func()"), env, "unsupported operand type(s) for +: 'list' and 'dict'");
+  }
+
+  public void testTopLevelDict() throws Exception {
+    exec(parseFileForSkylark(
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  v = 'b'"), env);
+    assertEquals("a", env.lookup("v"));
+  }
+
+  public void testUserFunctionKeywordArgs() throws Exception {
+    exec(parseFileForSkylark(
+        "def foo(a, b, c):\n"
+      + "  return a + b + c\n"
+      + "s = foo(1, c=2, b=3)"), env);
+    assertEquals(6, env.lookup("s"));
+  }
+
+  public void testNoneTrueFalseInSkylark() throws Exception {
+    exec(parseFileForSkylark(
+        "a = None\n"
+      + "b = True\n"
+      + "c = False"), env);
+    assertSame(Environment.NONE, env.lookup("a"));
+    assertTrue((Boolean) env.lookup("b"));
+    assertFalse((Boolean) env.lookup("c"));
+  }
+
+  public void testHasattr() throws Exception {
+    exec(parseFileForSkylark(
+        "s = struct(a=1)\n"
+      + "x = hasattr(s, 'a')\n"
+      + "y = hasattr(s, 'b')\n"), env);
+    assertTrue((Boolean) env.lookup("x"));
+    assertFalse((Boolean) env.lookup("y"));
+  }
+
+  public void testHasattrMethods() throws Exception {
+    env.update("mock", new Mock());
+    ValidationEnvironment validEnv = SkylarkModules.getValidationEnvironment();
+    validEnv.update("mock", SkylarkType.of(Mock.class), null);
+    exec(Parser.parseFileForSkylark(createLexer(
+          "a = hasattr(mock, 'struct_field')\n"
+        + "b = hasattr(mock, 'function')\n"
+        + "c = hasattr(mock, 'is_empty')\n"
+        + "d = hasattr('str', 'replace')\n"
+        + "e = hasattr(mock, 'other')\n"),
+            syntaxEvents.reporter(), null, validEnv).statements, env);
+    assertTrue((Boolean) env.lookup("a"));
+    assertTrue((Boolean) env.lookup("b"));
+    assertTrue((Boolean) env.lookup("c"));
+    assertTrue((Boolean) env.lookup("d"));
+    assertFalse((Boolean) env.lookup("e"));
+  }
+
+  public void testGetattr() throws Exception {
+    exec(parseFileForSkylark(
+        "s = struct(a='val')\n"
+      + "x = getattr(s, 'a')\n"
+      + "y = getattr(s, 'b', 'def')\n"
+      + "z = getattr(s, 'b', default = 'def')\n"
+      + "w = getattr(s, 'a', default='ignored')"), env);
+    assertEquals("val", env.lookup("x"));
+    assertEquals("def", env.lookup("y"));
+    assertEquals("def", env.lookup("z"));
+    assertEquals("val", env.lookup("w"));
+  }
+
+  public void testGetattrNoAttr() throws Exception {
+    checkEvalError(parseFileForSkylark(
+          "s = struct(a='val')\n"
+        + "getattr(s, 'b')"),
+        env, "Object of type 'struct' has no field 'b'");
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testListAnTupleConcatenationDoesNotWorkInSkylark() throws Exception {
+    checkEvalError(parseFileForSkylark("[1, 2] + (3, 4)"), env,
+        "cannot concatenate lists and tuples");
+  }
+
+  public void testCannotCreateMixedListInSkylark() throws Exception {
+    env.update("mock", new Mock());
+    checkEvalError(parseFileForSkylark("[mock.string(), 1, 2]", MOCK_TYPES), env,
+        "Incompatible types in list: found a int but the first element is a string");
+  }
+
+  public void testCannotConcatListInSkylarkWithDifferentGenericTypes() throws Exception {
+    env.update("mock", new Mock());
+    checkEvalError(parseFileForSkylark("mock.string_list() + [1, 2]", MOCK_TYPES), env,
+        "cannot concatenate list of string with list of int");
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testConcatEmptyListWithNonEmptyWorks() throws Exception {
+    exec(parseFileForSkylark("l = [] + ['a', 'b']", MOCK_TYPES), env);
+    assertThat((Iterable<Object>) env.lookup("l")).containsExactly("a", "b").inOrder();
+  }
+
+  public void testFormatStringWithTuple() throws Exception {
+    exec(parseFileForSkylark("v = '%s%s' % ('a', 1)"), env);
+    assertEquals("a1", env.lookup("v"));
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testDirFindsClassObjectFields() throws Exception {
+    env.update("mock", new MockClassObject());
+    exec(parseFileForSkylark("v = dir(mock)", MOCK_TYPES), env);
+    assertThat((Iterable<String>) env.lookup("v")).containsExactly("field", "nset").inOrder();
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testDirFindsJavaObjectStructFieldsAndMethods() throws Exception {
+    env.update("mock", new Mock());
+    exec(parseFileForSkylark("v = dir(mock)", MOCK_TYPES), env);
+    assertThat((Iterable<String>) env.lookup("v")).containsExactly("function", "is_empty",
+        "nullfunc_failing", "nullfunc_working", "return_mutable", "string", "string_list",
+        "struct_field", "value_of", "voidfunc").inOrder();
+  }
+
+  public void testPrint() throws Exception {
+    exec(parseFileForSkylark("print('hello')"), env);
+    syntaxEvents.assertContainsEvent("hello");
+    exec(parseFileForSkylark("print('a', 'b')"), env);
+    syntaxEvents.assertContainsEvent("a b");
+    exec(parseFileForSkylark("print('a', 'b', sep='x')"), env);
+    syntaxEvents.assertContainsEvent("axb");
+  }
+
+  public void testPrintBadKwargs() throws Exception {
+    checkEvalError("print(end='x', other='y')", "unexpected keywords: '[end, other]'");
+  }
+
+  public void testSkylarkTypes() {
+    assertEquals(TransitiveInfoCollection.class,
+        EvalUtils.getSkylarkType(FileConfiguredTarget.class));
+    assertEquals(TransitiveInfoCollection.class,
+        EvalUtils.getSkylarkType(RuleConfiguredTarget.class));
+    assertEquals(Artifact.class, EvalUtils.getSkylarkType(SpecialArtifact.class));
+  }
+
+  // Override tests in EvaluationTest incompatible with Skylark
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void testConcatLists() throws Exception {
+    // list
+    Object x = eval("[1,2] + [3,4]");
+    assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
+    assertFalse(((SkylarkList) x).isTuple());
+
+    // tuple
+    x = eval("(1,2)");
+    assertThat((Iterable<Object>) x).containsExactly(1, 2).inOrder();
+    assertTrue(((SkylarkList) x).isTuple());
+
+    x = eval("(1,2) + (3,4)");
+    assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
+    assertTrue(((SkylarkList) x).isTuple());
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void testListExprs() throws Exception {
+    assertThat((Iterable<Object>) eval("[1, 2, 3]")).containsExactly(1, 2, 3).inOrder();
+    assertThat((Iterable<Object>) eval("(1, 2, 3)")).containsExactly(1, 2, 3).inOrder();
+  }
+
+  @Override
+  public void testListConcatenation() throws Exception {}
+
+  @Override
+  public void testKeywordArgs() {}
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
new file mode 100644
index 0000000..2347198
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
@@ -0,0 +1,139 @@
+// Copyright 2014 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.syntax;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.MethodLibrary;
+
+import java.util.Iterator;
+
+/**
+ * Tests for SkylarkList.
+ */
+public class SkylarkListTest extends AbstractEvaluationTestCase {
+
+  @Immutable
+  private static final class CustomIterable implements Iterable<Object> {
+
+    @Override
+    public Iterator<Object> iterator() {
+      // Throw an exception whenever we request the iterator, to test that lazy lists
+      // are truly lazy.
+      throw new IllegalArgumentException("Iterator requested");
+    }
+  }
+
+  private static final SkylarkList list =
+      SkylarkList.lazyList(new CustomIterable(), Integer.class);
+  private static final ImmutableMap<String, SkylarkType> extraObjects =
+      ImmutableMap.of("lazy", SkylarkType.of(SkylarkList.class, Integer.class));
+
+  private Environment env;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    env = new SkylarkEnvironment(syntaxEvents.collector());
+    env.update("lazy", list);
+    MethodLibrary.setupMethodEnvironment(env);
+  }
+
+  public void testLazyListIndex() throws Exception {
+    checkError("Iterator requested", "a = lazy[0]");
+  }
+
+  public void testLazyListSize() throws Exception {
+    checkError("Iterator requested", "a = len(lazy)");
+  }
+
+  public void testLazyListEmpty() throws Exception {
+    checkError("Iterator requested", "if lazy:\n  a = 1");
+  }
+
+  public void testLazyListConcat() throws Exception {
+    exec("v = [1, 2] + lazy");
+    assertTrue(env.lookup("v") instanceof SkylarkList);
+  }
+
+  public void testConcatListIndex() throws Exception {
+    exec("l = [1, 2] + [3, 4]",
+         "e0 = l[0]",
+         "e1 = l[1]",
+         "e2 = l[2]",
+         "e3 = l[3]");
+    assertEquals(1, env.lookup("e0"));
+    assertEquals(2, env.lookup("e1"));
+    assertEquals(3, env.lookup("e2"));
+    assertEquals(4, env.lookup("e3"));
+  }
+
+  public void testConcatListHierarchicalIndex() throws Exception {
+    exec("l = [1] + (([2] + [3, 4]) + [5])",
+         "e0 = l[0]",
+         "e1 = l[1]",
+         "e2 = l[2]",
+         "e3 = l[3]",
+         "e4 = l[4]");
+    assertEquals(1, env.lookup("e0"));
+    assertEquals(2, env.lookup("e1"));
+    assertEquals(3, env.lookup("e2"));
+    assertEquals(4, env.lookup("e3"));
+    assertEquals(5, env.lookup("e4"));
+  }
+
+  public void testConcatListSize() throws Exception {
+    exec("l = [1, 2] + [3, 4]",
+         "s = len(l)");
+    assertEquals(4, env.lookup("s"));
+  }
+
+  public void testConcatListToString() throws Exception {
+    exec("l = [1, 2] + [3, 4]",
+         "s = str(l)");
+    assertEquals("[1, 2, 3, 4]", env.lookup("s"));
+  }
+
+  public void testConcatListNotEmpty() throws Exception {
+    exec("l = [1, 2] + [3, 4]",
+        "if l:",
+        "  v = 1",
+        "else:",
+        "  v = 0");
+    assertEquals(1, env.lookup("v"));
+  }
+
+  public void testConcatListEmpty() throws Exception {
+    exec("l = [] + []",
+        "if l:",
+        "  v = 1",
+        "else:",
+        "  v = 0");
+    assertEquals(0, env.lookup("v"));
+  }
+
+  private void exec(String... input) throws Exception {
+    exec(parseFileForSkylark(Joiner.on("\n").join(input), extraObjects), env);
+  }
+
+  private void checkError(String msg, String... input) throws Exception {
+    try {
+      exec(input);
+      fail();
+    } catch (Exception e) {
+      assertEquals(msg, e.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
new file mode 100644
index 0000000..4a9a446
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
@@ -0,0 +1,170 @@
+// Copyright 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.syntax;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.packages.MethodLibrary;
+import com.google.devtools.build.lib.syntax.Environment.NoSuchVariableException;
+
+/**
+ * Tests for SkylarkNestedSet.
+ */
+public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
+
+  private Environment env;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    env = new SkylarkEnvironment(syntaxEvents.collector());
+    MethodLibrary.setupMethodEnvironment(env);
+  }
+
+  public void testNsetBuilder() throws Exception {
+    exec("n = set(order='stable')");
+    assertTrue(env.lookup("n") instanceof SkylarkNestedSet);
+  }
+
+  public void testNsetOrder() throws Exception {
+    exec("n = set(['a', 'b'], order='compile')");
+    assertEquals(Order.COMPILE_ORDER, get("n").getSet(String.class).getOrder());
+  }
+
+  public void testEmptyNsetGenericType() throws Exception {
+    exec("n = set()");
+    assertEquals(Object.class, get("n").getGenericType());
+  }
+
+  public void testFunctionReturnsNset() throws Exception {
+    exec("def func():",
+         "  n = set()",
+         "  n += ['a']",
+         "  return n",
+         "s = func()");
+    assertEquals(ImmutableList.of("a"), get("s").toCollection());
+  }
+
+  public void testNsetTwoReferences() throws Exception {
+    exec("def func():",
+         "  n1 = set()",
+         "  n1 += ['a']",
+         "  n2 = n1",
+         "  n2 += ['b']",
+         "  return n1",
+         "n = func()");
+    assertEquals(ImmutableList.of("a"), get("n").toCollection());
+  }
+
+  public void testNsetNestedItem() throws Exception {
+    exec("def func():",
+        "  n1 = set()",
+        "  n2 = set()",
+        "  n1 += ['a']",
+        "  n2 += ['b']",
+        "  n1 += n2",
+        "  return n1",
+        "n = func()");
+    assertEquals(ImmutableList.of("b", "a"), get("n").toCollection());
+  }
+
+  public void testNsetNestedItemBadOrder() throws Exception {
+    checkError("LINK_ORDER != COMPILE_ORDER",
+        "set(['a', 'b'], order='compile') + set(['c', 'd'], order='link')");
+  }
+
+  public void testNsetItemList() throws Exception {
+    exec("def func():",
+        "  n = set()",
+        "  n += ['a', 'b']",
+        "  return n",
+        "n = func()");
+    assertEquals(ImmutableList.of("a", "b"), get("n").toCollection());
+  }
+
+  public void testNsetFuncParamNoSideEffects() throws Exception {
+    exec("def func1(n):",
+        "  n += ['b']",
+        "def func2():",
+        "  n = set()",
+        "  n += ['a']",
+        "  func1(n)",
+        "  return n",
+        "n = func2()");
+    assertEquals(ImmutableList.of("a"), get("n").toCollection());
+  }
+
+  public void testNsetTransitiveOrdering() throws Exception {
+    exec("def func():",
+        "  na = set(['a'], order='compile')",
+        "  nb = set(['b'], order='compile')",
+        "  nc = set(['c'], order='compile') + na",
+        "  return set() + nb + nc",
+        "n = func()");
+    // The iterator lists the Transitive sets first
+    assertEquals(ImmutableList.of("b", "a", "c"), get("n").toCollection());
+  }
+
+  public void testNsetOrdering() throws Exception {
+    exec("def func():",
+        "  na = set()",
+        "  na += [4]",
+        "  na += [2, 4]",
+        "  na += [3, 4, 5]",
+        "  return na",
+        "n = func()");
+    // The iterator lists the Transitive sets first
+    assertEquals(ImmutableList.of(4, 2, 3, 5), get("n").toCollection());
+  }
+
+  public void testNsetBadOrder() throws Exception {
+    checkError("Invalid order: non_existing",
+        "set(order='non_existing')");
+  }
+
+  public void testNsetBadRightOperand() throws Exception {
+    checkError("cannot add 'string'-s to nested sets",
+        "l = ['a']\n",
+        "set() + l[0]");
+  }
+
+  public void testNsetBadCompositeItem() throws Exception {
+    checkError("nested set item is composite (type of struct)",
+        "set([struct(a='a')])");
+  }
+
+  public void testNsetToString() throws Exception {
+    exec("s = set() + [2, 4, 6] + [3, 4, 5]",
+        "x = str(s)");
+    assertEquals("set([2, 4, 6, 3, 5])", env.lookup("x"));
+  }
+
+  private void exec(String... input) throws Exception {
+    exec(parseFileForSkylark(Joiner.on("\n").join(input)), env);
+  }
+
+  private SkylarkNestedSet get(String varname) throws NoSuchVariableException {
+    return (SkylarkNestedSet) env.lookup(varname);
+  }
+
+  private void checkError(String msg, String... input) throws Exception {
+    try {
+      exec(input);
+      fail();
+    } catch (Exception e) {
+      assertEquals(msg, e.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkShell.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkShell.java
new file mode 100644
index 0000000..6c394f9
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkShell.java
@@ -0,0 +1,94 @@
+// Copyright 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.syntax;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
+import com.google.devtools.build.lib.packages.CachingPackageLocator;
+import com.google.devtools.build.lib.rules.SkylarkModules;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * SkylarkShell is a standalone shell executing Skylark. This is intended for
+ * testing purposes and not for end-users. This is very limited (environment is
+ * almost empty), but it can be used to play with the language and reproduce
+ * bugs. Imports and includes are not supported.
+ */
+class SkylarkShell {
+  static final EventCollectionApparatus syntaxEvents = new EventCollectionApparatus();
+  static final FsApparatus scratch = FsApparatus.newInMemory();
+  static final CachingPackageLocator locator = new AbstractParserTestCase.EmptyPackageLocator();
+  static final Path path = scratch.path("stdin");
+
+  private static void exec(String inputSource, Environment env) {
+    try {
+      ParserInputSource input = ParserInputSource.create(inputSource, path);
+      Lexer lexer = new Lexer(input, syntaxEvents.reporter());
+      Parser.ParseResult result =
+          Parser.parseFileForSkylark(lexer, syntaxEvents.reporter(), locator,
+              SkylarkModules.getValidationEnvironment(
+                  ImmutableMap.<String, SkylarkType>of()));
+
+      Object last = null;
+      for (Statement st : result.statements) {
+        if (st instanceof ExpressionStatement) {
+          last = ((ExpressionStatement) st).getExpression().eval(env);
+        } else {
+          st.exec(env);
+          last = null;
+        }
+      }
+      if (last != null) {
+        System.out.println(last);
+      }
+    } catch (Throwable e) { // Catch everything to avoid killing the shell.
+      e.printStackTrace();
+    }
+  }
+
+  public static void main(String[] args) {
+    Environment env = SkylarkModules.getNewEnvironment(new EventHandler() {
+      @Override
+      public void handle(Event event) {
+        System.out.println(event.getMessage());
+      }
+    });
+    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+
+    String currentInput = "";
+    String line;
+    System.out.print(">> ");
+    try {
+      while ((line = br.readLine()) != null) {
+        if (line.isEmpty()) {
+          exec(currentInput, env);
+          currentInput = "";
+          System.out.print(">> ");
+        } else {
+          currentInput = currentInput + "\n" + line;
+          System.out.print(".. ");
+        }
+      }
+    } catch (IOException io) {
+      io.printStackTrace();
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
new file mode 100644
index 0000000..723d72c
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
@@ -0,0 +1,576 @@
+// Copyright 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.syntax;
+
+import com.google.common.base.Joiner;
+
+/**
+ * Tests for the validation process of Skylark files.
+ */
+public class ValidationTests extends AbstractParserTestCase {
+
+  public void testIncompatibleLiteralTypesStringInt() {
+    checkError("bad variable 'a': int is incompatible with string at /some/file.txt",
+        "def foo():\n",
+        "  a = '1'",
+        "  a = 1");
+  }
+
+  public void testIncompatibleLiteralTypesDictString() {
+    checkError("bad variable 'a': int is incompatible with dict at /some/file.txt",
+        "def foo():\n",
+        "  a = {1 : 'x'}",
+        "  a = 1");
+  }
+
+  public void testIncompatibleLiteralTypesInIf() {
+    checkError("bad variable 'a': int is incompatible with string at /some/file.txt",
+        "def foo():\n",
+        "  if 1:",
+        "    a = 'a'",
+        "  else:",
+        "    a = 1");
+  }
+
+  public void testAssignmentNotValidLValue() {
+    checkError("can only assign to variables, not to ''a''", "'a' = 1");
+  }
+
+  public void testForNotIterable() throws Exception {
+    checkError("type 'int' is not iterable",
+          "def func():\n"
+        + "  for i in 5: a = i\n");
+  }
+
+  public void testForIterableWithUknownArgument() throws Exception {
+    parse("def func(x=None):\n"
+        + "  for i in x: a = i\n");
+  }
+
+  public void testForNotIterableBinaryExpression() throws Exception {
+    checkError("type 'int' is not iterable",
+          "def func():\n"
+        + "  for i in 1 + 1: a = i\n");
+  }
+
+  public void testOptionalArgument() throws Exception {
+    checkError("type 'int' is not iterable",
+          "def func(x=5):\n"
+        + "  for i in x: a = i\n");
+  }
+
+  public void testOptionalArgumentHasError() throws Exception {
+    checkError("unsupported operand type(s) for +: 'int' and 'string'",
+          "def func(x=5+'a'):\n"
+        + "  return 0\n");
+  }
+
+  public void testTopLevelForStatement() throws Exception {
+    checkError("'For' is not allowed as a top level statement", "for i in [1,2,3]: a = i\n");
+  }
+
+  public void testReturnOutsideFunction() throws Exception {
+    checkError("Return statements must be inside a function", "return 2\n");
+  }
+
+  public void testTwoReturnTypes() throws Exception {
+    checkError("bad return type of foo: string is incompatible with int at /some/file.txt:3:5",
+        "def foo(x):",
+        "  if x:",
+        "    return 1",
+        "  else:",
+        "    return 'a'");
+  }
+
+  public void testTwoFunctionsWithTheSameName() throws Exception {
+    checkError("function foo already exists",
+        "def foo():",
+        "  return 1",
+        "def foo(x, y):",
+        "  return 1");
+  }
+
+  public void testDynamicTypeCheck() throws Exception {
+    checkError("bad variable 'a': string is incompatible with int at /some/file.txt:2:3",
+        "def foo():",
+        "  a = 1",
+        "  a = '1'");
+  }
+
+  public void testFunctionLocalVariable() throws Exception {
+    checkError("name 'a' is not defined",
+        "def func2(b):",
+        "  c = b",
+        "  c = a",
+        "def func1():",
+        "  a = 1",
+        "  func2(2)");
+  }
+
+  public void testFunctionLocalVariableDoesNotEffectGlobalValidationEnv() throws Exception {
+    checkError("name 'a' is not defined",
+        "def func1():",
+        "  a = 1",
+        "def func2(b):",
+        "  b = a");
+  }
+
+  public void testFunctionParameterDoesNotEffectGlobalValidationEnv() throws Exception {
+    checkError("name 'a' is not defined",
+        "def func1(a):",
+        "  return a",
+        "def func2():",
+        "  b = a");
+  }
+
+  public void testLocalValidationEnvironmentsAreSeparated() throws Exception {
+    parse(
+          "def func1():\n"
+        + "  a = 1\n"
+        + "def func2():\n"
+        + "  a = 'abc'\n");
+  }
+
+  public void testListComprehensionNotIterable() throws Exception {
+    checkError("type 'int' is not iterable",
+        "[i for i in 1 for j in [2]]");
+  }
+
+  public void testListComprehensionNotIterable2() throws Exception {
+    checkError("type 'int' is not iterable",
+        "[i for i in [1] for j in 123]");
+  }
+
+  public void testListIsNotComparable() {
+    checkError("list is not comparable", "['a'] > 1");
+  }
+
+  public void testStringCompareToInt() {
+    checkError("bad comparison: int is incompatible with string", "'a' > 1");
+  }
+
+  public void testInOnInt() {
+    checkError("operand 'in' only works on strings, dictionaries, "
+        + "lists, sets or tuples, not on a(n) int", "1 in 2");
+  }
+
+  public void testUnsupportedOperator() {
+    checkError("unsupported operand type(s) for -: 'string' and 'int'", "'a' - 1");
+  }
+
+  public void testBuiltinSymbolsAreReadOnly() throws Exception {
+    checkError("Variable rule is read only", "rule = 1");
+  }
+
+  public void testSkylarkGlobalVariablesAreReadonly() throws Exception {
+    checkError("Variable a is read only",
+        "a = 1\n"
+        + "a = 2");
+  }
+
+  public void testFunctionDefRecursion() throws Exception {
+    checkError("function 'func' does not exist",
+        "def func():\n"
+      + "  func()\n");
+  }
+
+  public void testMutualRecursion() throws Exception {
+    checkError("function 'bar' does not exist",
+        "def foo(i):\n"
+      + "  bar(i)\n"
+      + "def bar(i):\n"
+      + "  foo(i)\n"
+      + "foo(4)");
+  }
+
+  public void testFunctionReturnValue() {
+    checkError("unsupported operand type(s) for +: 'int' and 'string'",
+          "def foo(): return 1\n"
+        + "a = foo() + 'a'\n");
+  }
+
+  public void testFunctionReturnValueInFunctionDef() {
+    checkError("unsupported operand type(s) for +: 'int' and 'string'",
+          "def foo(): return 1\n"
+        + "def bar(): a = foo() + 'a'\n");
+  }
+
+  public void testFunctionDoesNotExistInFunctionDef() {
+    checkError("function 'foo' does not exist",
+          "def bar(): a = foo() + 'a'\n"
+        + "def foo(): return 1\n");
+  }
+
+  public void testStructMembersAreImmutable() {
+    checkError("can only assign to variables, not to 's.x'",
+        "s = struct(x = 'a')\n"
+      + "s.x = 'b'\n");
+  }
+
+  public void testStructDictMembersAreImmutable() {
+    checkError("can only assign to variables, not to 's.x['b']'",
+        "s = struct(x = {'a' : 1})\n"
+      + "s.x['b'] = 2\n");
+  }
+
+  public void testTupleAssign() throws Exception {
+    checkError("unsupported operand type(s) for +: 'list' and 'dict'",
+        "d = (1, 2)\n"
+      + "d[0] = 2\n");
+  }
+
+  public void testAssignOnNonCollection() throws Exception {
+    checkError("unsupported operand type(s) for +: 'string' and 'dict'",
+        "d = 'abc'\n"
+      + "d[0] = 2");
+  }
+
+  public void testNsetBadRightOperand() throws Exception {
+    checkError("can only concatenate nested sets with other nested sets or list of items, "
+        + "not 'string'", "set() + 'a'");
+  }
+
+  public void testNsetBadItemType() throws Exception {
+    checkError("bad nested set: incompatible generic variable types int with string",
+        "(set() + ['a']) + [1]");
+  }
+
+  public void testNsetBadNestedItemType() throws Exception {
+    checkError("bad nested set: incompatible generic variable types int with string",
+        "(set() + ['b']) + (set() + [1])");
+  }
+
+  public void testTypeInferenceForMethodLibraryFunction() throws Exception {
+    checkError("bad variable 'l': string is incompatible with int at /some/file.txt:2:3",
+          "def foo():\n"
+        + "  l = len('abc')\n"
+        + "  l = 'a'");
+  }
+
+  public void testListLiteralBadTypes() throws Exception {
+    checkError("bad list literal: int is incompatible with string at /some/file.txt:1:1",
+        "['a', 1]");
+  }
+
+  public void testTupleLiteralWorksForDifferentTypes() throws Exception {
+    parse("('a', 1)");
+  }
+
+  public void testDictLiteralBadKeyTypes() throws Exception {
+    checkError("bad dict literal: int is incompatible with string at /some/file.txt:1:1",
+        "{'a': 1, 1: 2}");
+  }
+
+  public void testDictLiteralDifferentValueTypeWorks() throws Exception {
+    parse("{'a': 1, 'b': 'c'}");
+  }
+
+  public void testListConcatBadTypes() throws Exception {
+    checkError("bad list concatenation: incompatible generic variable types int with string",
+        "['a'] + [1]");
+  }
+
+  public void testDictConcatBadKeyTypes() throws Exception {
+    checkError("bad dict concatenation: incompatible generic variable types int with string",
+        "{'a': 1} + {1: 2}");
+  }
+
+  public void testDictLiteralBadKeyType() throws Exception {
+    checkError("Dict cannot contain composite type 'list' as key", "{['a']: 1}");
+  }
+
+  public void testAndTypeInfer() throws Exception {
+    checkError("unsupported operand type(s) for +: 'string' and 'int'", "('a' and 'b') + 1");
+  }
+
+  public void testOrTypeInfer() throws Exception {
+    checkError("unsupported operand type(s) for +: 'string' and 'int'", "('' or 'b') + 1");
+  }
+
+  public void testAndDifferentTypes() throws Exception {
+    checkError("bad and operator: int is incompatible with string at /some/file.txt:1:1",
+        "'ab' and 3");
+  }
+
+  public void testOrDifferentTypes() throws Exception {
+    checkError("bad or operator: int is incompatible with string at /some/file.txt:1:1",
+        "'ab' or 3");
+  }
+
+  public void testOrNone() throws Exception {
+    parse("a = None or 3");
+  }
+
+  public void testNoneAssignment() throws Exception {
+    parse("def func():\n"
+        + "  a = None\n"
+        + "  a = 2\n"
+        + "  a = None\n");
+  }
+
+  public void testNoneAssignmentError() throws Exception {
+    checkError("bad variable 'a': string is incompatible with int at /some/file.txt",
+          "def func():\n"
+        + "  a = None\n"
+        + "  a = 2\n"
+        + "  a = None\n"
+        + "  a = 'b'\n");
+  }
+
+  public void testDictComprehensionNotOnList() throws Exception {
+    checkError("Dict comprehension elements must be a list", "{k : k for k in 'abc'}");
+  }
+
+  public void testTypeInferenceForUserDefinedFunction() throws Exception {
+    checkError("bad variable 'a': string is incompatible with int at /some/file.txt",
+          "def func():\n"
+        + "  return 'a'\n"
+        + "def foo():\n"
+        + "  a = 1\n"
+        + "  a = func()\n");
+  }
+
+  public void testCallingNonFunction() {
+    checkError("a is not a function",
+        "a = '1':\n"
+      + "a()\n");
+  }
+
+  public void testFuncallArgument() {
+    checkError("unsupported operand type(s) for +: 'int' and 'string'",
+        "def foo(x): return x\n"
+      + "a = foo(1 + 'a')");
+  }
+
+  // Skylark built-in functions specific tests
+
+  public void testTypeInferenceForSkylarkBuiltinGlobalFunction() throws Exception {
+    checkError("bad variable 'a': string is incompatible with function at /some/file.txt:3:3",
+          "def impl(ctx): return None\n"
+        + "def foo():\n"
+        + "  a = rule(impl)\n"
+        + "  a = 'a'\n");
+  }
+
+  public void testTypeInferenceForSkylarkBuiltinObjectFunction() throws Exception {
+    checkError("bad variable 'a': string is incompatible with Attribute at /some/file.txt",
+        "def foo():\n"
+        + "  a = attr.int()\n"
+        + "  a = 'a'\n");
+  }
+
+  public void testFuncReturningDictAssignmentAsLValue() throws Exception {
+    checkError("can only assign to variables, not to 'dict([])['b']'",
+          "def dict():\n"
+        + "  return {'a': 1}\n"
+        + "def func():\n"
+        + "  dict()['b'] = 2\n"
+        + "  return d\n");
+  }
+
+  public void testListIndexAsLValue() {
+    checkError("unsupported operand type(s) for +: 'list' and 'dict'",
+        "def func():\n"
+      + "  l = [1]\n"
+      + "  l[0] = 2\n"
+      + "  return l\n");
+  }
+
+  public void testStringIndexAsLValue() {
+    checkError("unsupported operand type(s) for +: 'string' and 'dict'",
+        "def func():\n"
+      + "  s = 'abc'\n"
+      + "  s[0] = 'd'\n"
+      + "  return s\n");
+  }
+
+  public void testEmptyLiteralGenericIsSetInLaterConcatWorks() {
+    parse("def func():\n"
+        + "  s = {}\n"
+        + "  s['a'] = 'b'\n");
+  }
+
+  public void testTypeIsInferredForStructs() {
+    checkError("unsupported operand type(s) for +: 'struct' and 'string'",
+        "(struct(a = 1) + struct(b = 1)) + 'x'");
+  }
+
+  public void testReadOnlyWorksForSimpleBranching() {
+    parse("if 1:\n"
+        + "  v = 'a'\n"
+        + "else:\n"
+        + "  v = 'b'");
+  }
+
+  public void testReadOnlyWorksForNestedBranching() {
+    parse("if 1:\n"
+        + "  if 0:\n"
+        + "    v = 'a'\n"
+        + "  else:\n"
+        + "    v = 'b'\n"
+        + "else:\n"
+        + "  if 0:\n"
+        + "    v = 'c'\n"
+        + "  else:\n"
+        + "    v = 'd'\n");
+  }
+
+  public void testTypeCheckWorksForSimpleBranching() {
+    checkError("bad variable 'v': int is incompatible with string at /some/file.txt:2:3",
+          "if 1:\n"
+        + "  v = 'a'\n"
+        + "else:\n"
+        + "  v = 1");
+  }
+
+  public void testTypeCheckWorksForNestedBranching() {
+    checkError("bad variable 'v': int is incompatible with string at /some/file.txt:5:5",
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  if 0:\n"
+      + "    v = 'b'\n"
+      + "  else:\n"
+      + "    v = 1\n");
+  }
+
+  public void testTypeCheckWorksForDifferentLevelBranches() {
+    checkError("bad variable 'v': int is incompatible with string at /some/file.txt:2:3",
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  if 0:\n"
+      + "    v = 1\n");
+  }
+
+  public void testReadOnlyWorksForDifferentLevelBranches() {
+    checkError("Variable v is read only",
+        "if 1:\n"
+      + "  if 1:\n"
+      + "    v = 'a'\n"
+      + "  v = 'b'\n");
+  }
+
+  public void testReadOnlyWorksWithinSimpleBranch() {
+    checkError("Variable v is read only",
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  v = 'b'\n"
+      + "  v = 'c'\n");
+  }
+
+  public void testReadOnlyWorksWithinNestedBranch() {
+    checkError("Variable v is read only",
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  if 1:\n"
+      + "    v = 'b'\n"
+      + "  else:\n"
+      + "    v = 'c'\n"
+      + "    v = 'd'\n");
+  }
+
+  public void testReadOnlyWorksAfterSimpleBranch() {
+    checkError("Variable v is read only",
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  w = 'a'\n"
+      + "v = 'b'");
+  }
+
+  public void testReadOnlyWorksAfterNestedBranch() {
+    checkError("Variable v is read only",
+        "if 1:\n"
+      + "  if 1:\n"
+      + "    v = 'a'\n"
+      + "v = 'b'");
+  }
+
+  public void testReadOnlyWorksAfterNestedBranch2() {
+    checkError("Variable v is read only",
+        "if 1:\n"
+      + "  v = 'a'\n"
+      + "else:\n"
+      + "  if 0:\n"
+      + "    w = 1\n"
+      + "v = 'b'\n");
+  }
+
+  public void testModulesReadOnlyInFuncDefBody() {
+    checkError("Variable cmd_helper is read only",
+        "def func():",
+        "  cmd_helper = set()");
+  }
+
+  public void testBuiltinGlobalFunctionsReadOnlyInFuncDefBody() {
+    checkError("Variable rule is read only",
+        "def func():",
+        "  rule = 'abc'");
+  }
+
+  public void testBuiltinGlobalFunctionsReadOnlyAsFuncDefArg() {
+    checkError("Variable rule is read only",
+        "def func(rule):",
+        "  return rule");
+  }
+
+  public void testFilesModulePlusStringErrorMessage() throws Exception {
+    checkError("unsupported operand type(s) for +: 'cmd_helper (a language module)' and 'string'",
+        "cmd_helper += 'a'");
+  }
+
+  public void testFunctionReturnsFunction() {
+    parse(
+        "def impl(ctx):",
+        "  return None",
+        "",
+        "skylark_rule = rule(implementation = impl)",
+        "",
+        "def macro(name):",
+        "  skylark_rule(name = name)");
+  }
+
+  public void testTypeForBooleanLiterals() {
+    parse("len([1, 2]) == 0 and True");
+    parse("len([1, 2]) == 0 and False");
+  }
+
+  public void testLoadRelativePathOneSegment() throws Exception {
+    parse("load('extension', 'a')\n");
+  }
+
+  public void testLoadAbsolutePathMultipleSegments() throws Exception {
+    parse("load('/pkg/extension', 'a')\n");
+  }
+
+  public void testLoadRelativePathMultipleSegments() throws Exception {
+    checkError("Path 'pkg/extension.bzl' is not valid. It should either start with "
+        + "a slash or refer to a file in the current directory.",
+        "load('pkg/extension', 'a')\n");
+  }
+
+  private void parse(String... lines) {
+    parseFileForSkylark(Joiner.on("\n").join(lines));
+    syntaxEvents.assertNoEvents();
+  }
+
+  private void checkError(String errorMsg, String... lines) {
+    syntaxEvents.setFailFast(false);
+    parseFileForSkylark(Joiner.on("\n").join(lines));
+    syntaxEvents.assertContainsEvent(errorMsg);
+  }
+}
