Internal change

PiperOrigin-RevId: 405717262
Change-Id: Ia055c28b59dae6447d37f408fcab1813f3836cb7
diff --git a/google3/third_party/java_src/junit/LICENSE b/google3/third_party/java_src/junit/LICENSE
new file mode 100644
index 0000000..fb68629
--- /dev/null
+++ b/google3/third_party/java_src/junit/LICENSE
@@ -0,0 +1,214 @@
+JUnit
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+      a) in the case of the initial Contributor, the initial code and
+         documentation distributed under this Agreement, and
+      b) in the case of each subsequent Contributor:
+
+      i) changes to the Program, and
+
+      ii) additions to the Program;
+
+      where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are
+not derivative works of the Program. 
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+
+      a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly perform,
+distribute and sublicense the Contribution of such Contributor, if any, and
+such derivative works, in source code and object code form.
+
+      b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under
+Licensed Patents to make, use, sell, offer to sell, import and otherwise
+transfer the Contribution of such Contributor, if any, in source code and
+object code form. This patent license shall apply to the combination of the
+Contribution and the Program if, at the time the Contribution is added by the
+Contributor, such addition of the Contribution causes such combination to be
+covered by the Licensed Patents. The patent license shall not apply to any
+other combinations which include the Contribution. No hardware per se is
+licensed hereunder. 
+
+      c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are provided by
+any Contributor that the Program does not infringe the patent or other
+intellectual property rights of any other entity. Each Contributor disclaims
+any liability to Recipient for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a condition to
+exercising the rights and licenses granted hereunder, each Recipient hereby
+assumes sole responsibility to secure any other intellectual property rights
+needed, if any. For example, if a third party patent license is required to
+allow Recipient to distribute the Program, it is Recipient's responsibility to
+acquire that license before distributing the Program.
+
+      d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright license
+set forth in this Agreement. 
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+      a) it complies with the terms and conditions of this Agreement; and
+
+      b) its license agreement:
+
+      i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; 
+
+      ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and consequential
+damages, such as lost profits; 
+
+      iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+      iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable manner on
+or through a medium customarily used for software exchange. 
+
+When the Program is made available in source code form:
+
+      a) it must be made available under this Agreement; and 
+
+      b) a copy of this Agreement must be included with each copy of the
+Program. 
+
+Contributors may not remove or alter any copyright notices contained within the
+Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore, if
+a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses, damages
+and costs (collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to the
+extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If that
+Commercial Contributor then makes performance claims, or offers warranties
+related to Product X, those performance claims and warranties are such
+Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a court
+requires any other Contributor to pay any damages as a result, the Commercial
+Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using
+and distributing the Program and assumes all risks associated with its exercise
+of rights under this Agreement, including but not limited to the risks and
+costs of program errors, compliance with applicable laws, damage to or loss of
+data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
+GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this Agreement, and without further action by the parties hereto, such
+provision shall be reformed to the minimum extent necessary to make such
+provision valid and enforceable.
+
+If Recipient institutes patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's rights
+granted under Section 2(b) shall terminate as of the date such litigation is
+filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue
+and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to time.
+No one other than the Agreement Steward has the right to modify this Agreement.
+The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial
+in any resulting litigation. 
+
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/ActiveTestSuite.java b/google3/third_party/java_src/junit/main/java/junit/extensions/ActiveTestSuite.java
new file mode 100644
index 0000000..6f0f99d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/ActiveTestSuite.java
@@ -0,0 +1,70 @@
+package junit.extensions;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+/**
+ * A TestSuite for active Tests. It runs each
+ * test in a separate thread and waits until all
+ * threads have terminated.
+ * -- Aarhus Radisson Scandinavian Center 11th floor
+ */
+public class ActiveTestSuite extends TestSuite {
+    private volatile int fActiveTestDeathCount;
+
+    public ActiveTestSuite() {
+    }
+
+    public ActiveTestSuite(Class<? extends TestCase> theClass) {
+        super(theClass);
+    }
+
+    public ActiveTestSuite(String name) {
+        super(name);
+    }
+
+    public ActiveTestSuite(Class<? extends TestCase> theClass, String name) {
+        super(theClass, name);
+    }
+
+    @Override
+    public void run(TestResult result) {
+        fActiveTestDeathCount = 0;
+        super.run(result);
+        waitUntilFinished();
+    }
+
+    @Override
+    public void runTest(final Test test, final TestResult result) {
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    // inlined due to limitation in VA/Java
+                    //ActiveTestSuite.super.runTest(test, result);
+                    test.run(result);
+                } finally {
+                    ActiveTestSuite.this.runFinished();
+                }
+            }
+        };
+        t.start();
+    }
+
+    synchronized void waitUntilFinished() {
+        while (fActiveTestDeathCount < testCount()) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                return; // ignore
+            }
+        }
+    }
+
+    public synchronized void runFinished() {
+        fActiveTestDeathCount++;
+        notifyAll();
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/RepeatedTest.java b/google3/third_party/java_src/junit/main/java/junit/extensions/RepeatedTest.java
new file mode 100644
index 0000000..22c690a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/RepeatedTest.java
@@ -0,0 +1,39 @@
+package junit.extensions;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+/**
+ * A Decorator that runs a test repeatedly.
+ */
+public class RepeatedTest extends TestDecorator {
+    private int fTimesRepeat;
+
+    public RepeatedTest(Test test, int repeat) {
+        super(test);
+        if (repeat < 0) {
+            throw new IllegalArgumentException("Repetition count must be >= 0");
+        }
+        fTimesRepeat = repeat;
+    }
+
+    @Override
+    public int countTestCases() {
+        return super.countTestCases() * fTimesRepeat;
+    }
+
+    @Override
+    public void run(TestResult result) {
+        for (int i = 0; i < fTimesRepeat; i++) {
+            if (result.shouldStop()) {
+                break;
+            }
+            super.run(result);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "(repeated)";
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/TestDecorator.java b/google3/third_party/java_src/junit/main/java/junit/extensions/TestDecorator.java
new file mode 100644
index 0000000..a3c5e08
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/TestDecorator.java
@@ -0,0 +1,43 @@
+package junit.extensions;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+/**
+ * A Decorator for Tests. Use TestDecorator as the base class for defining new
+ * test decorators. Test decorator subclasses can be introduced to add behaviour
+ * before or after a test is run.
+ */
+@SuppressWarnings("deprecation")
+public class TestDecorator extends Assert implements Test {
+    protected Test fTest;
+
+    public TestDecorator(Test test) {
+        fTest = test;
+    }
+
+    /**
+     * The basic run behaviour.
+     */
+    public void basicRun(TestResult result) {
+        fTest.run(result);
+    }
+
+    public int countTestCases() {
+        return fTest.countTestCases();
+    }
+
+    public void run(TestResult result) {
+        basicRun(result);
+    }
+
+    @Override
+    public String toString() {
+        return fTest.toString();
+    }
+
+    public Test getTest() {
+        return fTest;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/TestSetup.java b/google3/third_party/java_src/junit/main/java/junit/extensions/TestSetup.java
new file mode 100644
index 0000000..fcdca8c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/TestSetup.java
@@ -0,0 +1,42 @@
+package junit.extensions;
+
+import junit.framework.Protectable;
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+/**
+ * A Decorator to set up and tear down additional fixture state. Subclass
+ * TestSetup and insert it into your tests when you want to set up additional
+ * state once before the tests are run.
+ */
+public class TestSetup extends TestDecorator {
+
+    public TestSetup(Test test) {
+        super(test);
+    }
+
+    @Override
+    public void run(final TestResult result) {
+        Protectable p = new Protectable() {
+            public void protect() throws Exception {
+                setUp();
+                basicRun(result);
+                tearDown();
+            }
+        };
+        result.runProtected(this, p);
+    }
+
+    /**
+     * Sets up the fixture. Override to set up additional fixture state.
+     */
+    protected void setUp() throws Exception {
+    }
+
+    /**
+     * Tears down the fixture. Override to tear down the additional fixture
+     * state.
+     */
+    protected void tearDown() throws Exception {
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/package-info.java b/google3/third_party/java_src/junit/main/java/junit/extensions/package-info.java
new file mode 100644
index 0000000..a1c5bb4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides extended functionality for JUnit v3.x.
+ */
+package junit.extensions;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/Assert.java b/google3/third_party/java_src/junit/main/java/junit/framework/Assert.java
new file mode 100644
index 0000000..43482a1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/Assert.java
@@ -0,0 +1,339 @@
+package junit.framework;
+
+/**
+ * A set of assert methods.  Messages are only displayed when an assert fails.
+ *
+ * @deprecated Please use {@link org.junit.Assert} instead.
+ */
+@Deprecated
+public class Assert {
+    /**
+     * Protect constructor since it is a static only class
+     */
+    protected Assert() {
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws
+     * an AssertionFailedError with the given message.
+     */
+    public static void assertTrue(String message, boolean condition) {
+        if (!condition) {
+            fail(message);
+        }
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws
+     * an AssertionFailedError.
+     */
+    public static void assertTrue(boolean condition) {
+        assertTrue(null, condition);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws
+     * an AssertionFailedError with the given message.
+     */
+    public static void assertFalse(String message, boolean condition) {
+        assertTrue(message, !condition);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws
+     * an AssertionFailedError.
+     */
+    public static void assertFalse(boolean condition) {
+        assertFalse(null, condition);
+    }
+
+    /**
+     * Fails a test with the given message.
+     */
+    public static void fail(String message) {
+        if (message == null) {
+            throw new AssertionFailedError();
+        }
+        throw new AssertionFailedError(message);
+    }
+
+    /**
+     * Fails a test with no message.
+     */
+    public static void fail() {
+        fail(null);
+    }
+
+    /**
+     * Asserts that two objects are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, Object expected, Object actual) {
+        if (expected == null && actual == null) {
+            return;
+        }
+        if (expected != null && expected.equals(actual)) {
+            return;
+        }
+        failNotEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects are equal. If they are not
+     * an AssertionFailedError is thrown.
+     */
+    public static void assertEquals(Object expected, Object actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two Strings are equal.
+     */
+    public static void assertEquals(String message, String expected, String actual) {
+        if (expected == null && actual == null) {
+            return;
+        }
+        if (expected != null && expected.equals(actual)) {
+            return;
+        }
+        String cleanMessage = message == null ? "" : message;
+        throw new ComparisonFailure(cleanMessage, expected, actual);
+    }
+
+    /**
+     * Asserts that two Strings are equal.
+     */
+    public static void assertEquals(String expected, String actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two doubles are equal concerning a delta.  If they are not
+     * an AssertionFailedError is thrown with the given message.  If the expected
+     * value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(String message, double expected, double actual, double delta) {
+        if (Double.compare(expected, actual) == 0) {
+            return;
+        }
+        if (!(Math.abs(expected - actual) <= delta)) {
+            failNotEquals(message, Double.valueOf(expected), Double.valueOf(actual));
+        }
+    }
+
+    /**
+     * Asserts that two doubles are equal concerning a delta. If the expected
+     * value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(double expected, double actual, double delta) {
+        assertEquals(null, expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two floats are equal concerning a positive delta. If they
+     * are not an AssertionFailedError is thrown with the given message. If the
+     * expected value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(String message, float expected, float actual, float delta) {
+        if (Float.compare(expected, actual) == 0) {
+            return;
+        }
+        if (!(Math.abs(expected - actual) <= delta)) {
+            failNotEquals(message, Float.valueOf(expected), Float.valueOf(actual));
+        }
+    }
+
+    /**
+     * Asserts that two floats are equal concerning a delta. If the expected
+     * value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(float expected, float actual, float delta) {
+        assertEquals(null, expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two longs are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, long expected, long actual) {
+        assertEquals(message, Long.valueOf(expected), Long.valueOf(actual));
+    }
+
+    /**
+     * Asserts that two longs are equal.
+     */
+    public static void assertEquals(long expected, long actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two booleans are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, boolean expected, boolean actual) {
+        assertEquals(message, Boolean.valueOf(expected), Boolean.valueOf(actual));
+    }
+
+    /**
+     * Asserts that two booleans are equal.
+     */
+    public static void assertEquals(boolean expected, boolean actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two bytes are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, byte expected, byte actual) {
+        assertEquals(message, Byte.valueOf(expected), Byte.valueOf(actual));
+    }
+
+    /**
+     * Asserts that two bytes are equal.
+     */
+    public static void assertEquals(byte expected, byte actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two chars are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, char expected, char actual) {
+        assertEquals(message, Character.valueOf(expected), Character.valueOf(actual));
+    }
+
+    /**
+     * Asserts that two chars are equal.
+     */
+    public static void assertEquals(char expected, char actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two shorts are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, short expected, short actual) {
+        assertEquals(message, Short.valueOf(expected), Short.valueOf(actual));
+    }
+
+    /**
+     * Asserts that two shorts are equal.
+     */
+    public static void assertEquals(short expected, short actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two ints are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, int expected, int actual) {
+        assertEquals(message, Integer.valueOf(expected), Integer.valueOf(actual));
+    }
+
+    /**
+     * Asserts that two ints are equal.
+     */
+    public static void assertEquals(int expected, int actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that an object isn't null.
+     */
+    public static void assertNotNull(Object object) {
+        assertNotNull(null, object);
+    }
+
+    /**
+     * Asserts that an object isn't null. If it is
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertNotNull(String message, Object object) {
+        assertTrue(message, object != null);
+    }
+
+    /**
+     * Asserts that an object is null. If it isn't an {@link AssertionError} is
+     * thrown.
+     * Message contains: Expected: <null> but was: object
+     *
+     * @param object Object to check or <code>null</code>
+     */
+    public static void assertNull(Object object) {
+        if (object != null) {
+            assertNull("Expected: <null> but was: " + object.toString(), object);
+        }
+    }
+
+    /**
+     * Asserts that an object is null.  If it is not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertNull(String message, Object object) {
+        assertTrue(message, object == null);
+    }
+
+    /**
+     * Asserts that two objects refer to the same object. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertSame(String message, Object expected, Object actual) {
+        if (expected == actual) {
+            return;
+        }
+        failNotSame(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects refer to the same object. If they are not
+     * the same an AssertionFailedError is thrown.
+     */
+    public static void assertSame(Object expected, Object actual) {
+        assertSame(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects do not refer to the same object. If they do
+     * refer to the same object an AssertionFailedError is thrown with the
+     * given message.
+     */
+    public static void assertNotSame(String message, Object expected, Object actual) {
+        if (expected == actual) {
+            failSame(message);
+        }
+    }
+
+    /**
+     * Asserts that two objects do not refer to the same object. If they do
+     * refer to the same object an AssertionFailedError is thrown.
+     */
+    public static void assertNotSame(Object expected, Object actual) {
+        assertNotSame(null, expected, actual);
+    }
+
+    public static void failSame(String message) {
+        String formatted = (message != null) ? message + " " : "";
+        fail(formatted + "expected not same");
+    }
+
+    public static void failNotSame(String message, Object expected, Object actual) {
+        String formatted = (message != null) ? message + " " : "";
+        fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">");
+    }
+
+    public static void failNotEquals(String message, Object expected, Object actual) {
+        fail(format(message, expected, actual));
+    }
+
+    public static String format(String message, Object expected, Object actual) {
+        String formatted = "";
+        if (message != null && message.length() > 0) {
+            formatted = message + " ";
+        }
+        return formatted + "expected:<" + expected + "> but was:<" + actual + ">";
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/AssertionFailedError.java b/google3/third_party/java_src/junit/main/java/junit/framework/AssertionFailedError.java
new file mode 100644
index 0000000..e11fbec
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/AssertionFailedError.java
@@ -0,0 +1,29 @@
+package junit.framework;
+
+/**
+ * Thrown when an assertion failed.
+ */
+public class AssertionFailedError extends AssertionError {
+
+    private static final long serialVersionUID = 1L;
+    
+    /**
+     * Constructs a new AssertionFailedError without a detail message.
+     */
+    public AssertionFailedError() {
+    }
+
+    /**
+     * Constructs a new AssertionFailedError with the specified detail message.
+     * A null message is replaced by an empty String.
+     * @param message the detail message. The detail message is saved for later 
+     * retrieval by the {@code Throwable.getMessage()} method.
+     */
+    public AssertionFailedError(String message) {
+        super(defaultString(message));
+    }
+
+    private static String defaultString(String message) {
+        return message == null ? "" : message;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonCompactor.java b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonCompactor.java
new file mode 100644
index 0000000..81ddd5b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonCompactor.java
@@ -0,0 +1,78 @@
+package junit.framework;
+
+public class ComparisonCompactor {
+
+    private static final String ELLIPSIS = "...";
+    private static final String DELTA_END = "]";
+    private static final String DELTA_START = "[";
+
+    private int fContextLength;
+    private String fExpected;
+    private String fActual;
+    private int fPrefix;
+    private int fSuffix;
+
+    public ComparisonCompactor(int contextLength, String expected, String actual) {
+        fContextLength = contextLength;
+        fExpected = expected;
+        fActual = actual;
+    }
+
+    @SuppressWarnings("deprecation")
+    public String compact(String message) {
+        if (fExpected == null || fActual == null || areStringsEqual()) {
+            return Assert.format(message, fExpected, fActual);
+        }
+
+        findCommonPrefix();
+        findCommonSuffix();
+        String expected = compactString(fExpected);
+        String actual = compactString(fActual);
+        return Assert.format(message, expected, actual);
+    }
+
+    private String compactString(String source) {
+        String result = DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END;
+        if (fPrefix > 0) {
+            result = computeCommonPrefix() + result;
+        }
+        if (fSuffix > 0) {
+            result = result + computeCommonSuffix();
+        }
+        return result;
+    }
+
+    private void findCommonPrefix() {
+        fPrefix = 0;
+        int end = Math.min(fExpected.length(), fActual.length());
+        for (; fPrefix < end; fPrefix++) {
+            if (fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) {
+                break;
+            }
+        }
+    }
+
+    private void findCommonSuffix() {
+        int expectedSuffix = fExpected.length() - 1;
+        int actualSuffix = fActual.length() - 1;
+        for (; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) {
+            if (fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) {
+                break;
+            }
+        }
+        fSuffix = fExpected.length() - expectedSuffix;
+    }
+
+    private String computeCommonPrefix() {
+        return (fPrefix > fContextLength ? ELLIPSIS : "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix);
+    }
+
+    private String computeCommonSuffix() {
+        int end = Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length());
+        return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength ? ELLIPSIS : "");
+    }
+
+    private boolean areStringsEqual() {
+        return fExpected.equals(fActual);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonFailure.java b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonFailure.java
new file mode 100644
index 0000000..66433ef
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonFailure.java
@@ -0,0 +1,56 @@
+package junit.framework;
+
+/**
+ * Thrown when an assert equals for Strings failed.
+ *
+ * Inspired by a patch from Alex Chaffee mailto:alex@purpletech.com
+ */
+public class ComparisonFailure extends AssertionFailedError {
+    private static final int MAX_CONTEXT_LENGTH = 20;
+    private static final long serialVersionUID = 1L;
+
+    private String fExpected;
+    private String fActual;
+
+    /**
+     * Constructs a comparison failure.
+     *
+     * @param message the identifying message or null
+     * @param expected the expected string value
+     * @param actual the actual string value
+     */
+    public ComparisonFailure(String message, String expected, String actual) {
+        super(message);
+        fExpected = expected;
+        fActual = actual;
+    }
+
+    /**
+     * Returns "..." in place of common prefix and "..." in
+     * place of common suffix between expected and actual.
+     *
+     * @see Throwable#getMessage()
+     */
+    @Override
+    public String getMessage() {
+        return new ComparisonCompactor(MAX_CONTEXT_LENGTH, fExpected, fActual).compact(super.getMessage());
+    }
+
+    /**
+     * Gets the actual string value
+     *
+     * @return the actual string value
+     */
+    public String getActual() {
+        return fActual;
+    }
+
+    /**
+     * Gets the expected string value
+     *
+     * @return the expected string value
+     */
+    public String getExpected() {
+        return fExpected;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapter.java b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapter.java
new file mode 100644
index 0000000..9d32031
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapter.java
@@ -0,0 +1,107 @@
+package junit.framework;
+
+import java.util.List;
+
+import org.junit.Ignore;
+import org.junit.runner.Describable;
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sorter;
+
+/**
+ * The JUnit4TestAdapter enables running JUnit-4-style tests using a JUnit-3-style test runner.
+ *
+ * <p> To use it, add the following to a test class:
+ * <pre>
+      public static Test suite() {
+        return new JUnit4TestAdapter(<em>YourJUnit4TestClass</em>.class);
+      }
+</pre>
+ */
+public class JUnit4TestAdapter implements Test, Filterable, Orderable, Describable {
+    private final Class<?> fNewTestClass;
+
+    private final Runner fRunner;
+
+    private final JUnit4TestAdapterCache fCache;
+
+    public JUnit4TestAdapter(Class<?> newTestClass) {
+        this(newTestClass, JUnit4TestAdapterCache.getDefault());
+    }
+
+    public JUnit4TestAdapter(final Class<?> newTestClass, JUnit4TestAdapterCache cache) {
+        fCache = cache;
+        fNewTestClass = newTestClass;
+        fRunner = Request.classWithoutSuiteMethod(newTestClass).getRunner();
+    }
+
+    public int countTestCases() {
+        return fRunner.testCount();
+    }
+
+    public void run(TestResult result) {
+        fRunner.run(fCache.getNotifier(result, this));
+    }
+
+    // reflective interface for Eclipse
+    public List<Test> getTests() {
+        return fCache.asTestList(getDescription());
+    }
+
+    // reflective interface for Eclipse
+    public Class<?> getTestClass() {
+        return fNewTestClass;
+    }
+
+    public Description getDescription() {
+        Description description = fRunner.getDescription();
+        return removeIgnored(description);
+    }
+
+    private Description removeIgnored(Description description) {
+        if (isIgnored(description)) {
+            return Description.EMPTY;
+        }
+        Description result = description.childlessCopy();
+        for (Description each : description.getChildren()) {
+            Description child = removeIgnored(each);
+            if (!child.isEmpty()) {
+                result.addChild(child);
+            }
+        }
+        return result;
+    }
+
+    private boolean isIgnored(Description description) {
+        return description.getAnnotation(Ignore.class) != null;
+    }
+
+    @Override
+    public String toString() {
+        return fNewTestClass.getName();
+    }
+
+    public void filter(Filter filter) throws NoTestsRemainException {
+        filter.apply(fRunner);
+    }
+
+    public void sort(Sorter sorter) {
+        sorter.apply(fRunner);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 4.13
+     */
+    public void order(Orderer orderer) throws InvalidOrderingException {
+        orderer.apply(fRunner);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapterCache.java b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapterCache.java
new file mode 100644
index 0000000..603f261
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapterCache.java
@@ -0,0 +1,77 @@
+package junit.framework;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+public class JUnit4TestAdapterCache extends HashMap<Description, Test> {
+    private static final long serialVersionUID = 1L;
+    private static final JUnit4TestAdapterCache fInstance = new JUnit4TestAdapterCache();
+
+    public static JUnit4TestAdapterCache getDefault() {
+        return fInstance;
+    }
+
+    public Test asTest(Description description) {
+        if (description.isSuite()) {
+            return createTest(description);
+        } else {
+            if (!containsKey(description)) {
+                put(description, createTest(description));
+            }
+            return get(description);
+        }
+    }
+
+    Test createTest(Description description) {
+        if (description.isTest()) {
+            return new JUnit4TestCaseFacade(description);
+        } else {
+            TestSuite suite = new TestSuite(description.getDisplayName());
+            for (Description child : description.getChildren()) {
+                suite.addTest(asTest(child));
+            }
+            return suite;
+        }
+    }
+
+    public RunNotifier getNotifier(final TestResult result, final JUnit4TestAdapter adapter) {
+        RunNotifier notifier = new RunNotifier();
+        notifier.addListener(new RunListener() {
+            @Override
+            public void testFailure(Failure failure) throws Exception {
+                result.addError(asTest(failure.getDescription()), failure.getException());
+            }
+
+            @Override
+            public void testFinished(Description description) throws Exception {
+                result.endTest(asTest(description));
+            }
+
+            @Override
+            public void testStarted(Description description) throws Exception {
+                result.startTest(asTest(description));
+            }
+        });
+        return notifier;
+    }
+
+    public List<Test> asTestList(Description description) {
+        if (description.isTest()) {
+            return Arrays.asList(asTest(description));
+        } else {
+            List<Test> returnThis = new ArrayList<Test>();
+            for (Description child : description.getChildren()) {
+                returnThis.add(asTest(child));
+            }
+            return returnThis;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestCaseFacade.java b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestCaseFacade.java
new file mode 100644
index 0000000..5fd8ac7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestCaseFacade.java
@@ -0,0 +1,30 @@
+package junit.framework;
+
+import org.junit.runner.Describable;
+import org.junit.runner.Description;
+
+public class JUnit4TestCaseFacade implements Test, Describable {
+    private final Description fDescription;
+
+    JUnit4TestCaseFacade(Description description) {
+        fDescription = description;
+    }
+
+    @Override
+    public String toString() {
+        return getDescription().toString();
+    }
+
+    public int countTestCases() {
+        return 1;
+    }
+
+    public void run(TestResult result) {
+        throw new RuntimeException(
+                "This test stub created only for informational purposes.");
+    }
+
+    public Description getDescription() {
+        return fDescription;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/Protectable.java b/google3/third_party/java_src/junit/main/java/junit/framework/Protectable.java
new file mode 100644
index 0000000..c5ceb16
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/Protectable.java
@@ -0,0 +1,14 @@
+package junit.framework;
+
+/**
+ * A <em>Protectable</em> can be run and can throw a Throwable.
+ *
+ * @see TestResult
+ */
+public interface Protectable {
+
+    /**
+     * Run the following method protected.
+     */
+    public abstract void protect() throws Throwable;
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/Test.java b/google3/third_party/java_src/junit/main/java/junit/framework/Test.java
new file mode 100644
index 0000000..db95c6c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/Test.java
@@ -0,0 +1,18 @@
+package junit.framework;
+
+/**
+ * A <em>Test</em> can be run and collect its results.
+ *
+ * @see TestResult
+ */
+public interface Test {
+    /**
+     * Counts the number of test cases that will be run by this test.
+     */
+    public abstract int countTestCases();
+
+    /**
+     * Runs a test and collects its result in a TestResult instance.
+     */
+    public abstract void run(TestResult result);
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestCase.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestCase.java
new file mode 100644
index 0000000..8e4385f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestCase.java
@@ -0,0 +1,524 @@
+package junit.framework;
+
+import com.google.j2objc.annotations.AutoreleasePool;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * A test case defines the fixture to run multiple tests. To define a test case<br/>
+ * <ol>
+ *   <li>implement a subclass of <code>TestCase</code></li>
+ *   <li>define instance variables that store the state of the fixture</li>
+ *   <li>initialize the fixture state by overriding {@link #setUp()}</li>
+ *   <li>clean-up after a test by overriding {@link #tearDown()}.</li>
+ * </ol>
+ * Each test runs in its own fixture so there
+ * can be no side effects among test runs.
+ * Here is an example:
+ * <pre>
+ * public class MathTest extends TestCase {
+ *    protected double fValue1;
+ *    protected double fValue2;
+ *
+ *    protected void setUp() {
+ *       fValue1= 2.0;
+ *       fValue2= 3.0;
+ *    }
+ * }
+ * </pre>
+ *
+ * For each test implement a method which interacts
+ * with the fixture. Verify the expected results with assertions specified
+ * by calling {@link junit.framework.Assert#assertTrue(String, boolean)} with a boolean.
+ * <pre>
+ *    public void testAdd() {
+ *       double result= fValue1 + fValue2;
+ *       assertTrue(result == 5.0);
+ *    }
+ * </pre>
+ *
+ * Once the methods are defined you can run them. The framework supports
+ * both a static type safe and more dynamic way to run a test.
+ * In the static way you override the runTest method and define the method to
+ * be invoked. A convenient way to do so is with an anonymous inner class.
+ * <pre>
+ * TestCase test= new MathTest("add") {
+ *    public void runTest() {
+ *       testAdd();
+ *    }
+ * };
+ * test.run();
+ * </pre>
+ * The dynamic way uses reflection to implement {@link #runTest()}. It dynamically finds
+ * and invokes a method.
+ * In this case the name of the test case has to correspond to the test method
+ * to be run.
+ * <pre>
+ * TestCase test= new MathTest("testAdd");
+ * test.run();
+ * </pre>
+ *
+ * The tests to be run can be collected into a TestSuite. JUnit provides
+ * different <i>test runners</i> which can run a test suite and collect the results.
+ * A test runner either expects a static method <code>suite</code> as the entry
+ * point to get a test to run or it will extract the suite automatically.
+ * <pre>
+ * public static Test suite() {
+ *    suite.addTest(new MathTest("testAdd"));
+ *    suite.addTest(new MathTest("testDivideByZero"));
+ *    return suite;
+ * }
+ * </pre>
+ *
+ * @see TestResult
+ * @see TestSuite
+ */
+@SuppressWarnings("deprecation")
+public abstract class TestCase extends Assert implements Test {
+    /**
+     * the name of the test case
+     */
+    private String fName;
+
+    /**
+     * No-arg constructor to enable serialization. This method
+     * is not intended to be used by mere mortals without calling setName().
+     */
+    public TestCase() {
+        fName = null;
+    }
+
+    /**
+     * Constructs a test case with the given name.
+     */
+    public TestCase(String name) {
+        fName = name;
+    }
+
+    /**
+     * Counts the number of test cases executed by run(TestResult result).
+     */
+    public int countTestCases() {
+        return 1;
+    }
+
+    /**
+     * Creates a default TestResult object.
+     *
+     * @see TestResult
+     */
+    protected TestResult createResult() {
+        return new TestResult();
+    }
+
+    /**
+     * A convenience method to run this test, collecting the results with a
+     * default TestResult object.
+     *
+     * @see TestResult
+     */
+    public TestResult run() {
+        TestResult result = createResult();
+        run(result);
+        return result;
+    }
+
+    /**
+     * Runs the test case and collects the results in TestResult.
+     */
+    public void run(TestResult result) {
+        result.run(this);
+    }
+
+    /**
+     * Runs the bare test sequence.
+     *
+     * @throws Throwable if any exception is thrown
+     */
+    public void runBare() throws Throwable {
+        Throwable exception = null;
+        setUp();
+        try {
+            runTest();
+        } catch (Throwable running) {
+            exception = running;
+        } finally {
+            try {
+                tearDown();
+            } catch (Throwable tearingDown) {
+                if (exception == null) exception = tearingDown;
+            }
+        }
+        if (exception != null) throw exception;
+    }
+
+    /**
+     * Override to run the test and assert its state.
+     *
+     * @throws Throwable if any exception is thrown
+     */
+    protected void runTest() throws Throwable {
+        assertNotNull("TestCase.fName cannot be null", fName); // Some VMs crash when calling getMethod(null,null);
+        Method runMethod = null;
+        try {
+            // use getMethod to get all public inherited
+            // methods. getDeclaredMethods returns all
+            // methods of this class but excludes the
+            // inherited ones.
+            runMethod = getClass().getMethod(fName, (Class[]) null);
+        } catch (NoSuchMethodException e) {
+            fail("Method \"" + fName + "\" not found");
+        }
+        if (!Modifier.isPublic(runMethod.getModifiers())) {
+            fail("Method \"" + fName + "\" should be public");
+        }
+
+        try {
+            runTest0(runMethod);
+        } catch (InvocationTargetException e) {
+            e.fillInStackTrace();
+            throw e.getTargetException();
+        } catch (IllegalAccessException e) {
+            e.fillInStackTrace();
+            throw e;
+        }
+    }
+
+    /**
+     * Invocation of the test method is pulled into this helper function so that
+     * AutoreleasePool can be applied to the invocation.
+     * This is a local modification to support translation of this code to
+     * Objective-C using J2ObjC. It causes the translator to add an autorelease
+     * pool around this method which is Objective-C's way of collecting and
+     * cleaning up garbage memory.
+     */
+    @AutoreleasePool
+    private void runTest0(Method m) throws InvocationTargetException, IllegalAccessException {
+        m.invoke(this);
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws
+     * an AssertionFailedError with the given message.
+     */
+    public static void assertTrue(String message, boolean condition) {
+        Assert.assertTrue(message, condition);
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws
+     * an AssertionFailedError.
+     */
+    public static void assertTrue(boolean condition) {
+        Assert.assertTrue(condition);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws
+     * an AssertionFailedError with the given message.
+     */
+    public static void assertFalse(String message, boolean condition) {
+        Assert.assertFalse(message, condition);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws
+     * an AssertionFailedError.
+     */
+    public static void assertFalse(boolean condition) {
+        Assert.assertFalse(condition);
+    }
+
+    /**
+     * Fails a test with the given message.
+     */
+    public static void fail(String message) {
+        Assert.fail(message);
+    }
+
+    /**
+     * Fails a test with no message.
+     */
+    public static void fail() {
+        Assert.fail();
+    }
+
+    /**
+     * Asserts that two objects are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, Object expected, Object actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects are equal. If they are not
+     * an AssertionFailedError is thrown.
+     */
+    public static void assertEquals(Object expected, Object actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two Strings are equal.
+     */
+    public static void assertEquals(String message, String expected, String actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two Strings are equal.
+     */
+    public static void assertEquals(String expected, String actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two doubles are equal concerning a delta.  If they are not
+     * an AssertionFailedError is thrown with the given message.  If the expected
+     * value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(String message, double expected, double actual, double delta) {
+        Assert.assertEquals(message, expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two doubles are equal concerning a delta. If the expected
+     * value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(double expected, double actual, double delta) {
+        Assert.assertEquals(expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two floats are equal concerning a positive delta. If they
+     * are not an AssertionFailedError is thrown with the given message. If the
+     * expected value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(String message, float expected, float actual, float delta) {
+        Assert.assertEquals(message, expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two floats are equal concerning a delta. If the expected
+     * value is infinity then the delta value is ignored.
+     */
+    public static void assertEquals(float expected, float actual, float delta) {
+        Assert.assertEquals(expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two longs are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, long expected, long actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two longs are equal.
+     */
+    public static void assertEquals(long expected, long actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two booleans are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, boolean expected, boolean actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two booleans are equal.
+     */
+    public static void assertEquals(boolean expected, boolean actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two bytes are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, byte expected, byte actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two bytes are equal.
+     */
+    public static void assertEquals(byte expected, byte actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two chars are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, char expected, char actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two chars are equal.
+     */
+    public static void assertEquals(char expected, char actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two shorts are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, short expected, short actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two shorts are equal.
+     */
+    public static void assertEquals(short expected, short actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that two ints are equal. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertEquals(String message, int expected, int actual) {
+        Assert.assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two ints are equal.
+     */
+    public static void assertEquals(int expected, int actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Asserts that an object isn't null.
+     */
+    public static void assertNotNull(Object object) {
+        Assert.assertNotNull(object);
+    }
+
+    /**
+     * Asserts that an object isn't null. If it is
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertNotNull(String message, Object object) {
+        Assert.assertNotNull(message, object);
+    }
+
+    /**
+     * Asserts that an object is null. If it isn't an {@link AssertionError} is
+     * thrown.
+     * Message contains: Expected: <null> but was: object
+     *
+     * @param object Object to check or <code>null</code>
+     */
+    public static void assertNull(Object object) {
+        Assert.assertNull(object);
+    }
+
+    /**
+     * Asserts that an object is null.  If it is not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertNull(String message, Object object) {
+        Assert.assertNull(message, object);
+    }
+
+    /**
+     * Asserts that two objects refer to the same object. If they are not
+     * an AssertionFailedError is thrown with the given message.
+     */
+    public static void assertSame(String message, Object expected, Object actual) {
+        Assert.assertSame(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects refer to the same object. If they are not
+     * the same an AssertionFailedError is thrown.
+     */
+    public static void assertSame(Object expected, Object actual) {
+        Assert.assertSame(expected, actual);
+    }
+
+    /**
+     * Asserts that two objects do not refer to the same object. If they do
+     * refer to the same object an AssertionFailedError is thrown with the
+     * given message.
+     */
+    public static void assertNotSame(String message, Object expected, Object actual) {
+        Assert.assertNotSame(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects do not refer to the same object. If they do
+     * refer to the same object an AssertionFailedError is thrown.
+     */
+    public static void assertNotSame(Object expected, Object actual) {
+        Assert.assertNotSame(expected, actual);
+    }
+
+    public static void failSame(String message) {
+        Assert.failSame(message);
+    }
+
+    public static void failNotSame(String message, Object expected, Object actual) {
+        Assert.failNotSame(message, expected, actual);
+    }
+
+    public static void failNotEquals(String message, Object expected, Object actual) {
+        Assert.failNotEquals(message, expected, actual);
+    }
+
+    public static String format(String message, Object expected, Object actual) {
+        return Assert.format(message, expected, actual);
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected void setUp() throws Exception {
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection.
+     * This method is called after a test is executed.
+     */
+    protected void tearDown() throws Exception {
+    }
+
+    /**
+     * Returns a string representation of the test case.
+     */
+    @Override
+    public String toString() {
+        return getName() + "(" + getClass().getName() + ")";
+    }
+
+    /**
+     * Gets the name of a TestCase.
+     *
+     * @return the name of the TestCase
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Sets the name of a TestCase.
+     *
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        fName = name;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestFailure.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestFailure.java
new file mode 100644
index 0000000..d1ddfbc
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestFailure.java
@@ -0,0 +1,69 @@
+package junit.framework;
+
+import org.junit.internal.Throwables;
+
+
+/**
+ * A {@code TestFailure} collects a failed test together with
+ * the caught exception.
+ *
+ * @see TestResult
+ */
+public class TestFailure {
+    protected Test fFailedTest;
+    protected Throwable fThrownException;
+
+    /**
+     * Constructs a TestFailure with the given test and exception.
+     */
+    public TestFailure(Test failedTest, Throwable thrownException) {
+        fFailedTest = failedTest;
+        fThrownException = thrownException;
+    }
+
+    /**
+     * Gets the failed test.
+     */
+    public Test failedTest() {
+        return fFailedTest;
+    }
+
+    /**
+     * Gets the thrown exception.
+     */
+    public Throwable thrownException() {
+        return fThrownException;
+    }
+
+    /**
+     * Returns a short description of the failure.
+     */
+    @Override
+    public String toString() {
+        return fFailedTest + ": " + fThrownException.getMessage();
+    }
+    
+    /**
+     * Returns a String containing the stack trace of the error
+     * thrown by TestFailure.
+     */
+    public String trace() {
+        return Throwables.getStacktrace(thrownException());
+    }
+
+    /**
+     * Returns a String containing the message from the thrown exception.
+     */
+    public String exceptionMessage() {
+        return thrownException().getMessage();
+    }
+
+    /**
+     * Returns {@code true} if the error is considered a failure
+     * (i.e. if it is an instance of {@code AssertionFailedError}),
+     * {@code false} otherwise.
+     */
+    public boolean isFailure() {
+        return thrownException() instanceof AssertionFailedError;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestListener.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestListener.java
new file mode 100644
index 0000000..32d1a7f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestListener.java
@@ -0,0 +1,26 @@
+package junit.framework;
+
+/**
+ * A Listener for test progress
+ */
+public interface TestListener {
+    /**
+     * An error occurred.
+     */
+    public void addError(Test test, Throwable e);
+
+    /**
+     * A failure occurred.
+     */
+    public void addFailure(Test test, AssertionFailedError e);
+
+    /**
+     * A test ended.
+     */
+    public void endTest(Test test);
+
+    /**
+     * A test started.
+     */
+    public void startTest(Test test);
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestResult.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestResult.java
new file mode 100644
index 0000000..e01a2b0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestResult.java
@@ -0,0 +1,185 @@
+package junit.framework;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * A <code>TestResult</code> collects the results of executing
+ * a test case. It is an instance of the Collecting Parameter pattern.
+ * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
+ * A failure is anticipated and checked for with assertions. Errors are
+ * unanticipated problems like an {@link ArrayIndexOutOfBoundsException}.
+ *
+ * @see Test
+ */
+public class TestResult {
+    protected List<TestFailure> fFailures;
+    protected List<TestFailure> fErrors;
+    protected List<TestListener> fListeners;
+    protected int fRunTests;
+    private boolean fStop;
+
+    public TestResult() {
+        fFailures = new ArrayList<TestFailure>();
+        fErrors = new ArrayList<TestFailure>();
+        fListeners = new ArrayList<TestListener>();
+        fRunTests = 0;
+        fStop = false;
+    }
+
+    /**
+     * Adds an error to the list of errors. The passed in exception
+     * caused the error.
+     */
+    public synchronized void addError(Test test, Throwable e) {
+        fErrors.add(new TestFailure(test, e));
+        for (TestListener each : cloneListeners()) {
+            each.addError(test, e);
+        }
+    }
+
+    /**
+     * Adds a failure to the list of failures. The passed in exception
+     * caused the failure.
+     */
+    public synchronized void addFailure(Test test, AssertionFailedError e) {
+        fFailures.add(new TestFailure(test, e));
+        for (TestListener each : cloneListeners()) {
+            each.addFailure(test, e);
+        }
+    }
+
+    /**
+     * Registers a TestListener.
+     */
+    public synchronized void addListener(TestListener listener) {
+        fListeners.add(listener);
+    }
+
+    /**
+     * Unregisters a TestListener.
+     */
+    public synchronized void removeListener(TestListener listener) {
+        fListeners.remove(listener);
+    }
+
+    /**
+     * Returns a copy of the listeners.
+     */
+    private synchronized List<TestListener> cloneListeners() {
+        List<TestListener> result = new ArrayList<TestListener>();
+        result.addAll(fListeners);
+        return result;
+    }
+
+    /**
+     * Informs the result that a test was completed.
+     */
+    public void endTest(Test test) {
+        for (TestListener each : cloneListeners()) {
+            each.endTest(test);
+        }
+    }
+
+    /**
+     * Gets the number of detected errors.
+     */
+    public synchronized int errorCount() {
+        return fErrors.size();
+    }
+
+    /**
+     * Returns an Enumeration for the errors.
+     */
+    public synchronized Enumeration<TestFailure> errors() {
+        return Collections.enumeration(fErrors);
+    }
+
+
+    /**
+     * Gets the number of detected failures.
+     */
+    public synchronized int failureCount() {
+        return fFailures.size();
+    }
+
+    /**
+     * Returns an Enumeration for the failures.
+     */
+    public synchronized Enumeration<TestFailure> failures() {
+        return Collections.enumeration(fFailures);
+    }
+
+    /**
+     * Runs a TestCase.
+     */
+    protected void run(final TestCase test) {
+        startTest(test);
+        Protectable p = new Protectable() {
+            public void protect() throws Throwable {
+                test.runBare();
+            }
+        };
+        runProtected(test, p);
+
+        endTest(test);
+    }
+
+    /**
+     * Gets the number of run tests.
+     */
+    public synchronized int runCount() {
+        return fRunTests;
+    }
+
+    /**
+     * Runs a TestCase.
+     */
+    public void runProtected(final Test test, Protectable p) {
+        try {
+            p.protect();
+        } catch (AssertionFailedError e) {
+            addFailure(test, e);
+        } catch (ThreadDeath e) { // don't catch ThreadDeath by accident
+            throw e;
+        } catch (Throwable e) {
+            addError(test, e);
+        }
+    }
+
+    /**
+     * Checks whether the test run should stop.
+     */
+    public synchronized boolean shouldStop() {
+        return fStop;
+    }
+
+    /**
+     * Informs the result that a test will be started.
+     */
+    public void startTest(Test test) {
+        final int count = test.countTestCases();
+        synchronized (this) {
+            fRunTests += count;
+        }
+        for (TestListener each : cloneListeners()) {
+            each.startTest(test);
+        }
+    }
+
+    /**
+     * Marks that the test run should stop.
+     */
+    public synchronized void stop() {
+        fStop = true;
+    }
+
+    /**
+     * Returns whether the entire test was successful or not.
+     */
+    public synchronized boolean wasSuccessful() {
+        return failureCount() == 0 && errorCount() == 0;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestSuite.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestSuite.java
new file mode 100644
index 0000000..50cd5f8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestSuite.java
@@ -0,0 +1,308 @@
+package junit.framework;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Vector;
+
+import org.junit.internal.MethodSorter;
+import org.junit.internal.Throwables;
+
+/**
+ * A <code>TestSuite</code> is a <code>Composite</code> of Tests.
+ * It runs a collection of test cases. Here is an example using
+ * the dynamic test definition.
+ * <pre>
+ * TestSuite suite= new TestSuite();
+ * suite.addTest(new MathTest("testAdd"));
+ * suite.addTest(new MathTest("testDivideByZero"));
+ * </pre>
+ * <p>
+ * Alternatively, a TestSuite can extract the tests to be run automatically.
+ * To do so you pass the class of your TestCase class to the
+ * TestSuite constructor.
+ * <pre>
+ * TestSuite suite= new TestSuite(MathTest.class);
+ * </pre>
+ * <p>
+ * This constructor creates a suite with all the methods
+ * starting with "test" that take no arguments.
+ * <p>
+ * A final option is to do the same for a large array of test classes.
+ * <pre>
+ * Class[] testClasses = { MathTest.class, AnotherTest.class };
+ * TestSuite suite= new TestSuite(testClasses);
+ * </pre>
+ *
+ * @see Test
+ */
+public class TestSuite implements Test {
+
+    /**
+     * ...as the moon sets over the early morning Merlin, Oregon
+     * mountains, our intrepid adventurers type...
+     */
+    static public Test createTest(Class<?> theClass, String name) {
+        Constructor<?> constructor;
+        try {
+            constructor = getTestConstructor(theClass);
+        } catch (NoSuchMethodException e) {
+            return warning("Class " + theClass.getName() + " has no public constructor TestCase(String name) or TestCase()");
+        }
+        Object test;
+        try {
+            if (constructor.getParameterTypes().length == 0) {
+                test = constructor.newInstance(new Object[0]);
+                if (test instanceof TestCase) {
+                    ((TestCase) test).setName(name);
+                }
+            } else {
+                test = constructor.newInstance(new Object[]{name});
+            }
+        } catch (InstantiationException e) {
+            return (warning("Cannot instantiate test case: " + name + " (" + Throwables.getStacktrace(e) + ")"));
+        } catch (InvocationTargetException e) {
+            return (warning("Exception in constructor: " + name + " (" + Throwables.getStacktrace(e.getTargetException()) + ")"));
+        } catch (IllegalAccessException e) {
+            return (warning("Cannot access test case: " + name + " (" + Throwables.getStacktrace(e) + ")"));
+        }
+        return (Test) test;
+    }
+
+    /**
+     * Gets a constructor which takes a single String as
+     * its argument or a no arg constructor.
+     */
+    public static Constructor<?> getTestConstructor(Class<?> theClass) throws NoSuchMethodException {
+        try {
+            return theClass.getConstructor(String.class);
+        } catch (NoSuchMethodException e) {
+            // fall through
+        }
+        return theClass.getConstructor();
+    }
+
+    /**
+     * Returns a test which will fail and log a warning message.
+     */
+    public static Test warning(final String message) {
+        return new TestCase("warning") {
+            @Override
+            protected void runTest() {
+                fail(message);
+            }
+        };
+    }
+
+    private String fName;
+
+    private Vector<Test> fTests = new Vector<Test>(10); // Cannot convert this to List because it is used directly by some test runners
+
+    /**
+     * Constructs an empty TestSuite.
+     */
+    public TestSuite() {
+    }
+
+    /**
+     * Constructs a TestSuite from the given class. Adds all the methods
+     * starting with "test" as test cases to the suite.
+     * Parts of this method were written at 2337 meters in the Hueffihuette,
+     * Kanton Uri
+     */
+    public TestSuite(final Class<?> theClass) {
+        addTestsFromTestCase(theClass);
+    }
+
+    private void addTestsFromTestCase(final Class<?> theClass) {
+        fName = theClass.getName();
+        try {
+            getTestConstructor(theClass); // Avoid generating multiple error messages
+        } catch (NoSuchMethodException e) {
+            addTest(warning("Class " + theClass.getName() + " has no public constructor TestCase(String name) or TestCase()"));
+            return;
+        }
+
+        if (!Modifier.isPublic(theClass.getModifiers())) {
+            addTest(warning("Class " + theClass.getName() + " is not public"));
+            return;
+        }
+
+        Class<?> superClass = theClass;
+        List<String> names = new ArrayList<String>();
+        while (Test.class.isAssignableFrom(superClass)) {
+            for (Method each : MethodSorter.getDeclaredMethods(superClass)) {
+                addTestMethod(each, names, theClass);
+            }
+            superClass = superClass.getSuperclass();
+        }
+        if (fTests.size() == 0) {
+            addTest(warning("No tests found in " + theClass.getName()));
+        }
+    }
+
+    /**
+     * Constructs a TestSuite from the given class with the given name.
+     *
+     * @see TestSuite#TestSuite(Class)
+     */
+    public TestSuite(Class<? extends TestCase> theClass, String name) {
+        this(theClass);
+        setName(name);
+    }
+
+    /**
+     * Constructs an empty TestSuite.
+     */
+    public TestSuite(String name) {
+        setName(name);
+    }
+
+    /**
+     * Constructs a TestSuite from the given array of classes.
+     *
+     * @param classes {@link TestCase}s
+     */
+    public TestSuite(Class<?>... classes) {
+        for (Class<?> each : classes) {
+            addTest(testCaseForClass(each));
+        }
+    }
+
+    private Test testCaseForClass(Class<?> each) {
+        if (TestCase.class.isAssignableFrom(each)) {
+            return new TestSuite(each.asSubclass(TestCase.class));
+        } else {
+            return warning(each.getCanonicalName() + " does not extend TestCase");
+        }
+    }
+
+    /**
+     * Constructs a TestSuite from the given array of classes with the given name.
+     *
+     * @see TestSuite#TestSuite(Class[])
+     */
+    public TestSuite(Class<? extends TestCase>[] classes, String name) {
+        this(classes);
+        setName(name);
+    }
+
+    /**
+     * Adds a test to the suite.
+     */
+    public void addTest(Test test) {
+        fTests.add(test);
+    }
+
+    /**
+     * Adds the tests from the given class to the suite.
+     */
+    public void addTestSuite(Class<? extends TestCase> testClass) {
+        addTest(new TestSuite(testClass));
+    }
+
+    /**
+     * Counts the number of test cases that will be run by this test.
+     */
+    public int countTestCases() {
+        int count = 0;
+        for (Test each : fTests) {
+            count += each.countTestCases();
+        }
+        return count;
+    }
+
+    /**
+     * Returns the name of the suite. Not all
+     * test suites have a name and this method
+     * can return null.
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Runs the tests and collects their result in a TestResult.
+     */
+    public void run(TestResult result) {
+        for (Test each : fTests) {
+            if (result.shouldStop()) {
+                break;
+            }
+            runTest(each, result);
+        }
+    }
+
+    public void runTest(Test test, TestResult result) {
+        test.run(result);
+    }
+
+    /**
+     * Sets the name of the suite.
+     *
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        fName = name;
+    }
+
+    /**
+     * Returns the test at the given index.
+     */
+    public Test testAt(int index) {
+        return fTests.get(index);
+    }
+
+    /**
+     * Returns the number of tests in this suite.
+     */
+    public int testCount() {
+        return fTests.size();
+    }
+
+    /**
+     * Returns the tests as an enumeration.
+     */
+    public Enumeration<Test> tests() {
+        return fTests.elements();
+    }
+
+    /**
+     */
+    @Override
+    public String toString() {
+        if (getName() != null) {
+            return getName();
+        }
+        return super.toString();
+    }
+
+    private void addTestMethod(Method m, List<String> names, Class<?> theClass) {
+        String name = m.getName();
+        if (names.contains(name)) {
+            return;
+        }
+        if (!isPublicTestMethod(m)) {
+            if (isTestMethod(m)) {
+                addTest(warning("Test method isn't public: " + m.getName() + "(" + theClass.getCanonicalName() + ")"));
+            }
+            return;
+        }
+        names.add(name);
+        addTest(createTest(theClass, name));
+    }
+
+    private boolean isPublicTestMethod(Method m) {
+        return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
+    }
+
+    private boolean isTestMethod(Method m) {
+        return m.getParameterTypes().length == 0 &&
+                m.getName().startsWith("test") &&
+                m.getReturnType().equals(Void.TYPE);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/package-info.java b/google3/third_party/java_src/junit/main/java/junit/framework/package-info.java
new file mode 100644
index 0000000..153a1c8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides JUnit v3.x core classes.
+ */
+package junit.framework;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/BaseTestRunner.java b/google3/third_party/java_src/junit/main/java/junit/runner/BaseTestRunner.java
new file mode 100644
index 0000000..d63fae7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/BaseTestRunner.java
@@ -0,0 +1,326 @@
+package junit.runner;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.text.NumberFormat;
+import java.util.Properties;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestSuite;
+
+import org.junit.internal.Throwables;
+
+/**
+ * Base class for all test runners.
+ * This class was born live on stage in Sardinia during XP2000.
+ */
+public abstract class BaseTestRunner implements TestListener {
+    public static final String SUITE_METHODNAME = "suite";
+
+    private static Properties fPreferences;
+    static int fgMaxMessageLength = 500;
+    static boolean fgFilterStack = true;
+    boolean fLoading = true;
+
+    /*
+    * Implementation of TestListener
+    */
+    public synchronized void startTest(Test test) {
+        testStarted(test.toString());
+    }
+
+    protected static void setPreferences(Properties preferences) {
+        fPreferences = preferences;
+    }
+
+    protected static Properties getPreferences() {
+        if (fPreferences == null) {
+            fPreferences = new Properties();
+            fPreferences.put("loading", "true");
+            fPreferences.put("filterstack", "true");
+            readPreferences();
+        }
+        return fPreferences;
+    }
+
+    public static void savePreferences() throws IOException {
+        FileOutputStream fos = new FileOutputStream(getPreferencesFile());
+        try {
+            getPreferences().store(fos, "");
+        } finally {
+            fos.close();
+        }
+    }
+
+    public static void setPreference(String key, String value) {
+        getPreferences().put(key, value);
+    }
+
+    public synchronized void endTest(Test test) {
+        testEnded(test.toString());
+    }
+
+    public synchronized void addError(final Test test, final Throwable e) {
+        testFailed(TestRunListener.STATUS_ERROR, test, e);
+    }
+
+    public synchronized void addFailure(final Test test, final AssertionFailedError e) {
+        testFailed(TestRunListener.STATUS_FAILURE, test, e);
+    }
+
+    // TestRunListener implementation
+
+    public abstract void testStarted(String testName);
+
+    public abstract void testEnded(String testName);
+
+    public abstract void testFailed(int status, Test test, Throwable e);
+
+    /**
+     * Returns the Test corresponding to the given suite. This is
+     * a template method, subclasses override runFailed(), clearStatus().
+     */
+    public Test getTest(String suiteClassName) {
+        if (suiteClassName.length() <= 0) {
+            clearStatus();
+            return null;
+        }
+        Class<?> testClass = null;
+        try {
+            testClass = loadSuiteClass(suiteClassName);
+        } catch (ClassNotFoundException e) {
+            String clazz = e.getMessage();
+            if (clazz == null) {
+                clazz = suiteClassName;
+            }
+            runFailed("Class not found \"" + clazz + "\"");
+            return null;
+        } catch (Exception e) {
+            runFailed("Error: " + e.toString());
+            return null;
+        }
+        Method suiteMethod = null;
+        try {
+            suiteMethod = testClass.getMethod(SUITE_METHODNAME);
+        } catch (Exception e) {
+            // try to extract a test suite automatically
+            clearStatus();
+            return new TestSuite(testClass);
+        }
+        if (!Modifier.isStatic(suiteMethod.getModifiers())) {
+            runFailed("Suite() method must be static");
+            return null;
+        }
+        Test test = null;
+        try {
+            test = (Test) suiteMethod.invoke(null); // static method
+            if (test == null) {
+                return test;
+            }
+        } catch (InvocationTargetException e) {
+            runFailed("Failed to invoke suite():" + e.getTargetException().toString());
+            return null;
+        } catch (IllegalAccessException e) {
+            runFailed("Failed to invoke suite():" + e.toString());
+            return null;
+        }
+
+        clearStatus();
+        return test;
+    }
+
+    /**
+     * Returns the formatted string of the elapsed time.
+     */
+    public String elapsedTimeAsString(long runTime) {
+        return NumberFormat.getInstance().format((double) runTime / 1000);
+    }
+
+    /**
+     * Processes the command line arguments and
+     * returns the name of the suite class to run or null
+     */
+    protected String processArguments(String[] args) {
+        String suiteName = null;
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("-noloading")) {
+                setLoading(false);
+            } else if (args[i].equals("-nofilterstack")) {
+                fgFilterStack = false;
+            } else if (args[i].equals("-c")) {
+                if (args.length > i + 1) {
+                    suiteName = extractClassName(args[i + 1]);
+                } else {
+                    System.out.println("Missing Test class name");
+                }
+                i++;
+            } else {
+                suiteName = args[i];
+            }
+        }
+        return suiteName;
+    }
+
+    /**
+     * Sets the loading behaviour of the test runner
+     */
+    public void setLoading(boolean enable) {
+        fLoading = enable;
+    }
+
+    /**
+     * Extract the class name from a String in VA/Java style
+     */
+    public String extractClassName(String className) {
+        if (className.startsWith("Default package for")) {
+            return className.substring(className.lastIndexOf(".") + 1);
+        }
+        return className;
+    }
+
+    /**
+     * Truncates a String to the maximum length.
+     */
+    public static String truncate(String s) {
+        if (fgMaxMessageLength != -1 && s.length() > fgMaxMessageLength) {
+            s = s.substring(0, fgMaxMessageLength) + "...";
+        }
+        return s;
+    }
+
+    /**
+     * Override to define how to handle a failed loading of
+     * a test suite.
+     */
+    protected abstract void runFailed(String message);
+
+    /**
+     * Returns the loaded Class for a suite name.
+     */
+    protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
+        return Class.forName(suiteClassName);
+    }
+
+    /**
+     * Clears the status message.
+     */
+    protected void clearStatus() { // Belongs in the GUI TestRunner class
+    }
+
+    protected boolean useReloadingTestSuiteLoader() {
+        return getPreference("loading").equals("true") && fLoading;
+    }
+
+    private static File getPreferencesFile() {
+        String home = System.getProperty("user.home");
+        return new File(home, "junit.properties");
+    }
+
+    private static void readPreferences() {
+        InputStream is = null;
+        try {
+            is = new FileInputStream(getPreferencesFile());
+            setPreferences(new Properties(getPreferences()));
+            getPreferences().load(is);
+        } catch (IOException ignored) {
+        } catch (SecurityException ignored) {
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException e1) {
+            }
+        }
+    }
+
+    public static String getPreference(String key) {
+        return getPreferences().getProperty(key);
+    }
+
+    public static int getPreference(String key, int dflt) {
+        String value = getPreference(key);
+        int intValue = dflt;
+        if (value == null) {
+            return intValue;
+        }
+        try {
+            intValue = Integer.parseInt(value);
+        } catch (NumberFormatException ne) {
+        }
+        return intValue;
+    }
+
+    /**
+     * Returns a filtered stack trace
+     */
+    public static String getFilteredTrace(Throwable e) {
+        return BaseTestRunner.getFilteredTrace(Throwables.getStacktrace(e));
+    }
+
+    /**
+     * Filters stack frames from internal JUnit classes
+     */
+    public static String getFilteredTrace(String stack) {
+        if (showStackRaw()) {
+            return stack;
+        }
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        StringReader sr = new StringReader(stack);
+        BufferedReader br = new BufferedReader(sr);
+
+        String line;
+        try {
+            while ((line = br.readLine()) != null) {
+                if (!filterLine(line)) {
+                    pw.println(line);
+                }
+            }
+        } catch (Exception IOException) {
+            return stack; // return the stack unfiltered
+        }
+        return sw.toString();
+    }
+
+    protected static boolean showStackRaw() {
+        return !getPreference("filterstack").equals("true") || fgFilterStack == false;
+    }
+
+    static boolean filterLine(String line) {
+        String[] patterns = new String[]{
+                "junit.framework.TestCase",
+                "junit.framework.TestResult",
+                "junit.framework.TestSuite",
+                "junit.framework.Assert.", // don't filter AssertionFailure
+                "junit.swingui.TestRunner",
+                "junit.awtui.TestRunner",
+                "junit.textui.TestRunner",
+                "java.lang.reflect.Method.invoke("
+        };
+        for (int i = 0; i < patterns.length; i++) {
+            if (line.indexOf(patterns[i]) > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static {
+        fgMaxMessageLength = getPreference("maxmessage", fgMaxMessageLength);
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/TestRunListener.java b/google3/third_party/java_src/junit/main/java/junit/runner/TestRunListener.java
new file mode 100644
index 0000000..ce5b3d5
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/TestRunListener.java
@@ -0,0 +1,25 @@
+package junit.runner;
+
+/**
+ * A listener interface for observing the
+ * execution of a test run. Unlike TestListener,
+ * this interface using only primitive objects,
+ * making it suitable for remote test execution.
+ */
+public interface TestRunListener {
+    /* test status constants*/
+    int STATUS_ERROR = 1;
+    int STATUS_FAILURE = 2;
+
+    void testRunStarted(String testSuiteName, int testCount);
+
+    void testRunEnded(long elapsedTime);
+
+    void testRunStopped(long elapsedTime);
+
+    void testStarted(String testName);
+
+    void testEnded(String testName);
+
+    void testFailed(int status, String testName, String trace);
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/Version.java b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java
new file mode 100644
index 0000000..bb12a70
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java
@@ -0,0 +1,18 @@
+package junit.runner;
+
+/**
+ * This class defines the current version of JUnit
+ */
+public class Version {
+	private Version() {
+		// don't instantiate
+	}
+
+	public static String id() {
+		return "4.13.2-SNAPSHOT";
+	}
+	
+	public static void main(String[] args) {
+		System.out.println(id());
+	}
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/Version.java.template b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java.template
new file mode 100644
index 0000000..3182cfd
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java.template
@@ -0,0 +1,18 @@
+package junit.runner;
+
+/**
+ * This class defines the current version of JUnit
+ */
+public class Version {
+	private Version() {
+		// don't instantiate
+	}
+
+	public static String id() {
+		return "@version@";
+	}
+	
+	public static void main(String[] args) {
+		System.out.println(id());
+	}
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/package-info.java b/google3/third_party/java_src/junit/main/java/junit/runner/package-info.java
new file mode 100644
index 0000000..b746185
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides JUnit v3.x test runners.
+ */
+package junit.runner;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/textui/ResultPrinter.java b/google3/third_party/java_src/junit/main/java/junit/textui/ResultPrinter.java
new file mode 100644
index 0000000..95f10f4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/textui/ResultPrinter.java
@@ -0,0 +1,137 @@
+package junit.textui;
+
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.Enumeration;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+
+public class ResultPrinter implements TestListener {
+    PrintStream fWriter;
+    int fColumn = 0;
+
+    public ResultPrinter(PrintStream writer) {
+        fWriter = writer;
+    }
+
+    /* API for use by textui.TestRunner */
+
+    synchronized void print(TestResult result, long runTime) {
+        printHeader(runTime);
+        printErrors(result);
+        printFailures(result);
+        printFooter(result);
+    }
+
+    void printWaitPrompt() {
+        getWriter().println();
+        getWriter().println("<RETURN> to continue");
+    }
+
+    /* Internal methods */
+
+    protected void printHeader(long runTime) {
+        getWriter().println();
+        getWriter().println("Time: " + elapsedTimeAsString(runTime));
+    }
+
+    protected void printErrors(TestResult result) {
+        printDefects(result.errors(), result.errorCount(), "error");
+    }
+
+    protected void printFailures(TestResult result) {
+        printDefects(result.failures(), result.failureCount(), "failure");
+    }
+
+    protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
+        if (count == 0) return;
+        if (count == 1) {
+            getWriter().println("There was " + count + " " + type + ":");
+        } else {
+            getWriter().println("There were " + count + " " + type + "s:");
+        }
+        for (int i = 1; booBoos.hasMoreElements(); i++) {
+            printDefect(booBoos.nextElement(), i);
+        }
+    }
+
+    public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
+        printDefectHeader(booBoo, count);
+        printDefectTrace(booBoo);
+    }
+
+    protected void printDefectHeader(TestFailure booBoo, int count) {
+        // I feel like making this a println, then adding a line giving the throwable a chance to print something
+        // before we get to the stack trace.
+        getWriter().print(count + ") " + booBoo.failedTest());
+    }
+
+    protected void printDefectTrace(TestFailure booBoo) {
+        getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
+    }
+
+    protected void printFooter(TestResult result) {
+        if (result.wasSuccessful()) {
+            getWriter().println();
+            getWriter().print("OK");
+            getWriter().println(" (" + result.runCount() + " test" + (result.runCount() == 1 ? "" : "s") + ")");
+
+        } else {
+            getWriter().println();
+            getWriter().println("FAILURES!!!");
+            getWriter().println("Tests run: " + result.runCount() +
+                    ",  Failures: " + result.failureCount() +
+                    ",  Errors: " + result.errorCount());
+        }
+        getWriter().println();
+    }
+
+    /**
+     * Returns the formatted string of the elapsed time.
+     * Duplicated from BaseTestRunner. Fix it.
+     */
+    protected String elapsedTimeAsString(long runTime) {
+        return NumberFormat.getInstance().format((double) runTime / 1000);
+    }
+
+    public PrintStream getWriter() {
+        return fWriter;
+    }
+
+    /**
+     * @see junit.framework.TestListener#addError(Test, Throwable)
+     */
+    public void addError(Test test, Throwable e) {
+        getWriter().print("E");
+    }
+
+    /**
+     * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
+     */
+    public void addFailure(Test test, AssertionFailedError t) {
+        getWriter().print("F");
+    }
+
+    /**
+     * @see junit.framework.TestListener#endTest(Test)
+     */
+    public void endTest(Test test) {
+    }
+
+    /**
+     * @see junit.framework.TestListener#startTest(Test)
+     */
+    public void startTest(Test test) {
+        getWriter().print(".");
+        if (fColumn++ >= 40) {
+            getWriter().println();
+            fColumn = 0;
+        }
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/textui/TestRunner.java b/google3/third_party/java_src/junit/main/java/junit/textui/TestRunner.java
new file mode 100644
index 0000000..913020a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/textui/TestRunner.java
@@ -0,0 +1,206 @@
+package junit.textui;
+
+
+import java.io.PrintStream;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+import junit.runner.Version;
+
+/**
+ * A command line based tool to run tests.
+ * <pre>
+ * java junit.textui.TestRunner [-wait] TestCaseClass
+ * </pre>
+ * <p>
+ * TestRunner expects the name of a TestCase class as argument.
+ * If this class defines a static <code>suite</code> method it
+ * will be invoked and the returned test is run. Otherwise all
+ * the methods starting with "test" having no arguments are run.
+ * <p>
+ * When the wait command line argument is given TestRunner
+ * waits until the users types RETURN.
+ * <p>
+ * TestRunner prints a trace as the tests are executed followed by a
+ * summary at the end.
+ */
+public class TestRunner extends BaseTestRunner {
+    private ResultPrinter fPrinter;
+
+    public static final int SUCCESS_EXIT = 0;
+    public static final int FAILURE_EXIT = 1;
+    public static final int EXCEPTION_EXIT = 2;
+
+    /**
+     * Constructs a TestRunner.
+     */
+    public TestRunner() {
+        this(System.out);
+    }
+
+    /**
+     * Constructs a TestRunner using the given stream for all the output
+     */
+    public TestRunner(PrintStream writer) {
+        this(new ResultPrinter(writer));
+    }
+
+    /**
+     * Constructs a TestRunner using the given ResultPrinter all the output
+     */
+    public TestRunner(ResultPrinter printer) {
+        fPrinter = printer;
+    }
+
+    /**
+     * Runs a suite extracted from a TestCase subclass.
+     */
+    static public void run(Class<? extends TestCase> testClass) {
+        run(new TestSuite(testClass));
+    }
+
+    /**
+     * Runs a single test and collects its results.
+     * This method can be used to start a test run
+     * from your program.
+     * <pre>
+     * public static void main (String[] args) {
+     *    test.textui.TestRunner.run(suite());
+     * }
+     * </pre>
+     */
+    static public TestResult run(Test test) {
+        TestRunner runner = new TestRunner();
+        return runner.doRun(test);
+    }
+
+    /**
+     * Runs a single test and waits until the user
+     * types RETURN.
+     */
+    static public void runAndWait(Test suite) {
+        TestRunner aTestRunner = new TestRunner();
+        aTestRunner.doRun(suite, true);
+    }
+
+    @Override
+    public void testFailed(int status, Test test, Throwable e) {
+    }
+
+    @Override
+    public void testStarted(String testName) {
+    }
+
+    @Override
+    public void testEnded(String testName) {
+    }
+
+    /**
+     * Creates the TestResult to be used for the test run.
+     */
+    protected TestResult createTestResult() {
+        return new TestResult();
+    }
+
+    public TestResult doRun(Test test) {
+        return doRun(test, false);
+    }
+
+    public TestResult doRun(Test suite, boolean wait) {
+        TestResult result = createTestResult();
+        result.addListener(fPrinter);
+        long startTime = System.currentTimeMillis();
+        suite.run(result);
+        long endTime = System.currentTimeMillis();
+        long runTime = endTime - startTime;
+        fPrinter.print(result, runTime);
+
+        pause(wait);
+        return result;
+    }
+
+    protected void pause(boolean wait) {
+        if (!wait) return;
+        fPrinter.printWaitPrompt();
+        try {
+            System.in.read();
+        } catch (Exception e) {
+        }
+    }
+
+    public static void main(String[] args) {
+        TestRunner aTestRunner = new TestRunner();
+        try {
+            TestResult r = aTestRunner.start(args);
+            if (!r.wasSuccessful()) {
+                System.exit(FAILURE_EXIT);
+            }
+            System.exit(SUCCESS_EXIT);
+        } catch (Exception e) {
+            System.err.println(e.getMessage());
+            System.exit(EXCEPTION_EXIT);
+        }
+    }
+
+    /**
+     * Starts a test run. Analyzes the command line arguments and runs the given
+     * test suite.
+     */
+    public TestResult start(String[] args) throws Exception {
+        String testCase = "";
+        String method = "";
+        boolean wait = false;
+
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("-wait")) {
+                wait = true;
+            } else if (args[i].equals("-c")) {
+                testCase = extractClassName(args[++i]);
+            } else if (args[i].equals("-m")) {
+                String arg = args[++i];
+                int lastIndex = arg.lastIndexOf('.');
+                testCase = arg.substring(0, lastIndex);
+                method = arg.substring(lastIndex + 1);
+            } else if (args[i].equals("-v")) {
+                System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma");
+            } else {
+                testCase = args[i];
+            }
+        }
+
+        if (testCase.equals("")) {
+            throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
+        }
+
+        try {
+            if (!method.equals("")) {
+                return runSingleMethod(testCase, method, wait);
+            }
+            Test suite = getTest(testCase);
+            return doRun(suite, wait);
+        } catch (Exception e) {
+            throw new Exception("Could not create and run test suite: " + e);
+        }
+    }
+
+    protected TestResult runSingleMethod(String testCase, String method, boolean wait) throws Exception {
+        Class<? extends TestCase> testClass = loadSuiteClass(testCase).asSubclass(TestCase.class);
+        Test test = TestSuite.createTest(testClass, method);
+        return doRun(test, wait);
+    }
+
+    @Override
+    protected void runFailed(String message) {
+        System.err.println(message);
+        System.exit(FAILURE_EXIT);
+    }
+
+    public void setPrinter(ResultPrinter printer) {
+        fPrinter = printer;
+    }
+
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/textui/package-info.java b/google3/third_party/java_src/junit/main/java/junit/textui/package-info.java
new file mode 100644
index 0000000..2aa5176
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/textui/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides JUnit v3.x command line based tool to run tests.
+ */
+package junit.textui;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/After.java b/google3/third_party/java_src/junit/main/java/org/junit/After.java
new file mode 100644
index 0000000..eae7e3a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/After.java
@@ -0,0 +1,41 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * If you allocate external resources in a {@link org.junit.Before} method you need to release them
+ * after the test runs. Annotating a <code>public void</code> method
+ * with <code>&#064;After</code> causes that method to be run after the {@link org.junit.Test} method. All <code>&#064;After</code>
+ * methods are guaranteed to run even if a {@link org.junit.Before} or {@link org.junit.Test} method throws an
+ * exception. The <code>&#064;After</code> methods declared in superclasses will be run after those of the current
+ * class, unless they are overridden in the current class.
+ * <p>
+ * Here is a simple example:
+ * <pre>
+ * public class Example {
+ *    File output;
+ *    &#064;Before public void createOutputFile() {
+ *          output= new File(...);
+ *    }
+ *    &#064;Test public void something() {
+ *          ...
+ *    }
+ *    &#064;After public void deleteOutputFile() {
+ *          output.delete();
+ *    }
+ * }
+ * </pre>
+ *
+ * @see org.junit.Before
+ * @see org.junit.Test
+ * @since 4.0
+ */
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface After {
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/AfterClass.java b/google3/third_party/java_src/junit/main/java/org/junit/AfterClass.java
new file mode 100644
index 0000000..dba4109
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/AfterClass.java
@@ -0,0 +1,42 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * If you allocate expensive external resources in a {@link org.junit.BeforeClass} method you need to release them
+ * after all the tests in the class have run. Annotating a <code>public static void</code> method
+ * with <code>&#064;AfterClass</code> causes that method to be run after all the tests in the class have been run. All <code>&#064;AfterClass</code>
+ * methods are guaranteed to run even if a {@link org.junit.BeforeClass} method throws an
+ * exception. The <code>&#064;AfterClass</code> methods declared in superclasses will be run after those of the current
+ * class, unless they are shadowed in the current class.
+ * <p>
+ * Here is a simple example:
+ * <pre>
+ * public class Example {
+ *    private static DatabaseConnection database;
+ *    &#064;BeforeClass public static void login() {
+ *          database= ...;
+ *    }
+ *    &#064;Test public void something() {
+ *          ...
+ *    }
+ *    &#064;Test public void somethingElse() {
+ *          ...
+ *    }
+ *    &#064;AfterClass public static void logout() {
+ *          database.logout();
+ *    }
+ * }
+ * </pre>
+ *
+ * @see org.junit.BeforeClass
+ * @see org.junit.Test
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AfterClass {
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Assert.java b/google3/third_party/java_src/junit/main/java/org/junit/Assert.java
new file mode 100644
index 0000000..65bbc9d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Assert.java
@@ -0,0 +1,1034 @@
+package org.junit;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.MatcherAssert;
+import org.junit.function.ThrowingRunnable;
+import org.junit.internal.ArrayComparisonFailure;
+import org.junit.internal.ExactComparisonCriteria;
+import org.junit.internal.InexactComparisonCriteria;
+
+/**
+ * A set of assertion methods useful for writing tests. Only failed assertions
+ * are recorded. These methods can be used directly:
+ * <code>Assert.assertEquals(...)</code>, however, they read better if they
+ * are referenced through static import:
+ *
+ * <pre>
+ * import static org.junit.Assert.*;
+ *    ...
+ *    assertEquals(...);
+ * </pre>
+ *
+ * @see AssertionError
+ * @since 4.0
+ */
+public class Assert {
+    /**
+     * Protect constructor since it is a static only class
+     */
+    protected Assert() {
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws an
+     * {@link AssertionError} with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param condition condition to be checked
+     */
+    public static void assertTrue(String message, boolean condition) {
+        if (!condition) {
+            fail(message);
+        }
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws an
+     * {@link AssertionError} without a message.
+     *
+     * @param condition condition to be checked
+     */
+    public static void assertTrue(boolean condition) {
+        assertTrue(null, condition);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws an
+     * {@link AssertionError} with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param condition condition to be checked
+     */
+    public static void assertFalse(String message, boolean condition) {
+        assertTrue(message, !condition);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws an
+     * {@link AssertionError} without a message.
+     *
+     * @param condition condition to be checked
+     */
+    public static void assertFalse(boolean condition) {
+        assertFalse(null, condition);
+    }
+
+    /**
+     * Fails a test with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @see AssertionError
+     */
+    public static void fail(String message) {
+        if (message == null) {
+            throw new AssertionError();
+        }
+        throw new AssertionError(message);
+    }
+
+    /**
+     * Fails a test with no message.
+     */
+    public static void fail() {
+        fail(null);
+    }
+
+    /**
+     * Asserts that two objects are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message. If
+     * <code>expected</code> and <code>actual</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expected expected value
+     * @param actual actual value
+     */
+    public static void assertEquals(String message, Object expected,
+            Object actual) {
+        if (equalsRegardingNull(expected, actual)) {
+            return;
+        }
+        if (expected instanceof String && actual instanceof String) {
+            String cleanMessage = message == null ? "" : message;
+            throw new ComparisonFailure(cleanMessage, (String) expected,
+                    (String) actual);
+        } else {
+            failNotEquals(message, expected, actual);
+        }
+    }
+
+    private static boolean equalsRegardingNull(Object expected, Object actual) {
+        if (expected == null) {
+            return actual == null;
+        }
+
+        return isEquals(expected, actual);
+    }
+
+    private static boolean isEquals(Object expected, Object actual) {
+        return expected.equals(actual);
+    }
+
+    /**
+     * Asserts that two objects are equal. If they are not, an
+     * {@link AssertionError} without a message is thrown. If
+     * <code>expected</code> and <code>actual</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param expected expected value
+     * @param actual the value to check against <code>expected</code>
+     */
+    public static void assertEquals(Object expected, Object actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects are <b>not</b> equals. If they are, an
+     * {@link AssertionError} is thrown with the given message. If
+     * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param unexpected unexpected value to check
+     * @param actual the value to check against <code>unexpected</code>
+     */
+    public static void assertNotEquals(String message, Object unexpected,
+            Object actual) {
+        if (equalsRegardingNull(unexpected, actual)) {
+            failEquals(message, actual);
+        }
+    }
+
+    /**
+     * Asserts that two objects are <b>not</b> equals. If they are, an
+     * {@link AssertionError} without a message is thrown. If
+     * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param unexpected unexpected value to check
+     * @param actual the value to check against <code>unexpected</code>
+     */
+    public static void assertNotEquals(Object unexpected, Object actual) {
+        assertNotEquals(null, unexpected, actual);
+    }
+
+    private static void failEquals(String message, Object actual) {
+        String formatted = "Values should be different. ";
+        if (message != null) {
+            formatted = message + ". ";
+        }
+
+        formatted += "Actual: " + actual;
+        fail(formatted);
+    }
+
+    /**
+     * Asserts that two longs are <b>not</b> equals. If they are, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param unexpected unexpected value to check
+     * @param actual the value to check against <code>unexpected</code>
+     */
+    public static void assertNotEquals(String message, long unexpected, long actual) {
+        if (unexpected == actual) {
+            failEquals(message, Long.valueOf(actual));
+        }
+    }
+
+    /**
+     * Asserts that two longs are <b>not</b> equals. If they are, an
+     * {@link AssertionError} without a message is thrown.
+     *
+     * @param unexpected unexpected value to check
+     * @param actual the value to check against <code>unexpected</code>
+     */
+    public static void assertNotEquals(long unexpected, long actual) {
+        assertNotEquals(null, unexpected, actual);
+    }
+
+    /**
+     * Asserts that two doubles are <b>not</b> equal to within a positive delta.
+     * If they are, an {@link AssertionError} is thrown with the given
+     * message. If the unexpected value is infinity then the delta value is
+     * ignored. NaNs are considered equal:
+     * <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param unexpected unexpected value
+     * @param actual the value to check against <code>unexpected</code>
+     * @param delta the maximum delta between <code>unexpected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertNotEquals(String message, double unexpected,
+            double actual, double delta) {
+        if (!doubleIsDifferent(unexpected, actual, delta)) {
+            failEquals(message, Double.valueOf(actual));
+        }
+    }
+
+    /**
+     * Asserts that two doubles are <b>not</b> equal to within a positive delta.
+     * If they are, an {@link AssertionError} is thrown. If the unexpected
+     * value is infinity then the delta value is ignored.NaNs are considered
+     * equal: <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
+     *
+     * @param unexpected unexpected value
+     * @param actual the value to check against <code>unexpected</code>
+     * @param delta the maximum delta between <code>unexpected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertNotEquals(double unexpected, double actual, double delta) {
+        assertNotEquals(null, unexpected, actual, delta);
+    }
+
+    /**
+     * Asserts that two floats are <b>not</b> equal to within a positive delta.
+     * If they are, an {@link AssertionError} is thrown. If the unexpected
+     * value is infinity then the delta value is ignored.NaNs are considered
+     * equal: <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
+     *
+     * @param unexpected unexpected value
+     * @param actual the value to check against <code>unexpected</code>
+     * @param delta the maximum delta between <code>unexpected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertNotEquals(float unexpected, float actual, float delta) {
+        assertNotEquals(null, unexpected, actual, delta);
+    }
+
+    /**
+     * Asserts that two object arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message. If
+     * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds Object array or array of arrays (multi-dimensional array) with
+     * expected values.
+     * @param actuals Object array or array of arrays (multi-dimensional array) with
+     * actual values
+     */
+    public static void assertArrayEquals(String message, Object[] expecteds,
+            Object[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two object arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown. If <code>expected</code> and
+     * <code>actual</code> are <code>null</code>, they are considered
+     * equal.
+     *
+     * @param expecteds Object array or array of arrays (multi-dimensional array) with
+     * expected values
+     * @param actuals Object array or array of arrays (multi-dimensional array) with
+     * actual values
+     */
+    public static void assertArrayEquals(Object[] expecteds, Object[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two boolean arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message. If
+     * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds boolean array with expected values.
+     * @param actuals boolean array with expected values.
+     */
+    public static void assertArrayEquals(String message, boolean[] expecteds,
+            boolean[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two boolean arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown. If <code>expected</code> and
+     * <code>actual</code> are <code>null</code>, they are considered
+     * equal.
+     *
+     * @param expecteds boolean array with expected values.
+     * @param actuals boolean array with expected values.
+     */
+    public static void assertArrayEquals(boolean[] expecteds, boolean[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two byte arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds byte array with expected values.
+     * @param actuals byte array with actual values
+     */
+    public static void assertArrayEquals(String message, byte[] expecteds,
+            byte[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two byte arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds byte array with expected values.
+     * @param actuals byte array with actual values
+     */
+    public static void assertArrayEquals(byte[] expecteds, byte[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two char arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds char array with expected values.
+     * @param actuals char array with actual values
+     */
+    public static void assertArrayEquals(String message, char[] expecteds,
+            char[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two char arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds char array with expected values.
+     * @param actuals char array with actual values
+     */
+    public static void assertArrayEquals(char[] expecteds, char[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two short arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds short array with expected values.
+     * @param actuals short array with actual values
+     */
+    public static void assertArrayEquals(String message, short[] expecteds,
+            short[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two short arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds short array with expected values.
+     * @param actuals short array with actual values
+     */
+    public static void assertArrayEquals(short[] expecteds, short[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two int arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds int array with expected values.
+     * @param actuals int array with actual values
+     */
+    public static void assertArrayEquals(String message, int[] expecteds,
+            int[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two int arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds int array with expected values.
+     * @param actuals int array with actual values
+     */
+    public static void assertArrayEquals(int[] expecteds, int[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two long arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds long array with expected values.
+     * @param actuals long array with actual values
+     */
+    public static void assertArrayEquals(String message, long[] expecteds,
+            long[] actuals) throws ArrayComparisonFailure {
+        internalArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two long arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds long array with expected values.
+     * @param actuals long array with actual values
+     */
+    public static void assertArrayEquals(long[] expecteds, long[] actuals) {
+        assertArrayEquals(null, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two double arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds double array with expected values.
+     * @param actuals double array with actual values
+     * @param delta the maximum delta between <code>expecteds[i]</code> and
+     * <code>actuals[i]</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertArrayEquals(String message, double[] expecteds,
+            double[] actuals, double delta) throws ArrayComparisonFailure {
+        new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two double arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds double array with expected values.
+     * @param actuals double array with actual values
+     * @param delta the maximum delta between <code>expecteds[i]</code> and
+     * <code>actuals[i]</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertArrayEquals(double[] expecteds, double[] actuals, double delta) {
+        assertArrayEquals(null, expecteds, actuals, delta);
+    }
+
+    /**
+     * Asserts that two float arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds float array with expected values.
+     * @param actuals float array with actual values
+     * @param delta the maximum delta between <code>expecteds[i]</code> and
+     * <code>actuals[i]</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertArrayEquals(String message, float[] expecteds,
+            float[] actuals, float delta) throws ArrayComparisonFailure {
+        new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two float arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expecteds float array with expected values.
+     * @param actuals float array with actual values
+     * @param delta the maximum delta between <code>expecteds[i]</code> and
+     * <code>actuals[i]</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertArrayEquals(float[] expecteds, float[] actuals, float delta) {
+        assertArrayEquals(null, expecteds, actuals, delta);
+    }
+
+    /**
+     * Asserts that two object arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message. If
+     * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds Object array or array of arrays (multi-dimensional array) with
+     * expected values.
+     * @param actuals Object array or array of arrays (multi-dimensional array) with
+     * actual values
+     */
+    private static void internalArrayEquals(String message, Object expecteds,
+            Object actuals) throws ArrayComparisonFailure {
+        new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two doubles are equal to within a positive delta.
+     * If they are not, an {@link AssertionError} is thrown with the given
+     * message. If the expected value is infinity then the delta value is
+     * ignored. NaNs are considered equal:
+     * <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expected expected value
+     * @param actual the value to check against <code>expected</code>
+     * @param delta the maximum delta between <code>expected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertEquals(String message, double expected,
+            double actual, double delta) {
+        if (doubleIsDifferent(expected, actual, delta)) {
+            failNotEquals(message, Double.valueOf(expected), Double.valueOf(actual));
+        }
+    }
+
+    /**
+     * Asserts that two floats are equal to within a positive delta.
+     * If they are not, an {@link AssertionError} is thrown with the given
+     * message. If the expected value is infinity then the delta value is
+     * ignored. NaNs are considered equal:
+     * <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expected expected value
+     * @param actual the value to check against <code>expected</code>
+     * @param delta the maximum delta between <code>expected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertEquals(String message, float expected,
+            float actual, float delta) {
+        if (floatIsDifferent(expected, actual, delta)) {
+            failNotEquals(message, Float.valueOf(expected), Float.valueOf(actual));
+        }
+    }
+
+    /**
+     * Asserts that two floats are <b>not</b> equal to within a positive delta.
+     * If they are, an {@link AssertionError} is thrown with the given
+     * message. If the unexpected value is infinity then the delta value is
+     * ignored. NaNs are considered equal:
+     * <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param unexpected unexpected value
+     * @param actual the value to check against <code>unexpected</code>
+     * @param delta the maximum delta between <code>unexpected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertNotEquals(String message, float unexpected,
+            float actual, float delta) {
+        if (!floatIsDifferent(unexpected, actual, delta)) {
+            failEquals(message, Float.valueOf(actual));
+        }
+    }
+
+    private static boolean doubleIsDifferent(double d1, double d2, double delta) {
+        if (Double.compare(d1, d2) == 0) {
+            return false;
+        }
+        if ((Math.abs(d1 - d2) <= delta)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static boolean floatIsDifferent(float f1, float f2, float delta) {
+        if (Float.compare(f1, f2) == 0) {
+            return false;
+        }
+        if ((Math.abs(f1 - f2) <= delta)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Asserts that two longs are equal. If they are not, an
+     * {@link AssertionError} is thrown.
+     *
+     * @param expected expected long value.
+     * @param actual actual long value
+     */
+    public static void assertEquals(long expected, long actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two longs are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expected long expected value.
+     * @param actual long actual value
+     */
+    public static void assertEquals(String message, long expected, long actual) {
+        if (expected != actual) {
+            failNotEquals(message, Long.valueOf(expected), Long.valueOf(actual));
+        }
+    }
+
+    /**
+     * @deprecated Use
+     *             <code>assertEquals(double expected, double actual, double delta)</code>
+     *             instead
+     */
+    @Deprecated
+    public static void assertEquals(double expected, double actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * @deprecated Use
+     *             <code>assertEquals(String message, double expected, double actual, double delta)</code>
+     *             instead
+     */
+    @Deprecated
+    public static void assertEquals(String message, double expected,
+            double actual) {
+        fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers");
+    }
+
+    /**
+     * Asserts that two doubles are equal to within a positive delta.
+     * If they are not, an {@link AssertionError} is thrown. If the expected
+     * value is infinity then the delta value is ignored.NaNs are considered
+     * equal: <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
+     *
+     * @param expected expected value
+     * @param actual the value to check against <code>expected</code>
+     * @param delta the maximum delta between <code>expected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertEquals(double expected, double actual, double delta) {
+        assertEquals(null, expected, actual, delta);
+    }
+
+    /**
+     * Asserts that two floats are equal to within a positive delta.
+     * If they are not, an {@link AssertionError} is thrown. If the expected
+     * value is infinity then the delta value is ignored. NaNs are considered
+     * equal: <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
+     *
+     * @param expected expected value
+     * @param actual the value to check against <code>expected</code>
+     * @param delta the maximum delta between <code>expected</code> and
+     * <code>actual</code> for which both numbers are still
+     * considered equal.
+     */
+    public static void assertEquals(float expected, float actual, float delta) {
+        assertEquals(null, expected, actual, delta);
+    }
+
+    /**
+     * Asserts that an object isn't null. If it is an {@link AssertionError} is
+     * thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param object Object to check or <code>null</code>
+     */
+    public static void assertNotNull(String message, Object object) {
+        assertTrue(message, object != null);
+    }
+
+    /**
+     * Asserts that an object isn't null. If it is an {@link AssertionError} is
+     * thrown.
+     *
+     * @param object Object to check or <code>null</code>
+     */
+    public static void assertNotNull(Object object) {
+        assertNotNull(null, object);
+    }
+
+    /**
+     * Asserts that an object is null. If it is not, an {@link AssertionError}
+     * is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param object Object to check or <code>null</code>
+     */
+    public static void assertNull(String message, Object object) {
+        if (object == null) {
+            return;
+        }
+        failNotNull(message, object);
+    }
+
+    /**
+     * Asserts that an object is null. If it isn't an {@link AssertionError} is
+     * thrown.
+     *
+     * @param object Object to check or <code>null</code>
+     */
+    public static void assertNull(Object object) {
+        assertNull(null, object);
+    }
+
+    private static void failNotNull(String message, Object actual) {
+        String formatted = "";
+        if (message != null) {
+            formatted = message + " ";
+        }
+        fail(formatted + "expected null, but was:<" + actual + ">");
+    }
+
+    /**
+     * Asserts that two objects refer to the same object. If they are not, an
+     * {@link AssertionError} is thrown with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expected the expected object
+     * @param actual the object to compare to <code>expected</code>
+     */
+    public static void assertSame(String message, Object expected, Object actual) {
+        if (expected == actual) {
+            return;
+        }
+        failNotSame(message, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects refer to the same object. If they are not the
+     * same, an {@link AssertionError} without a message is thrown.
+     *
+     * @param expected the expected object
+     * @param actual the object to compare to <code>expected</code>
+     */
+    public static void assertSame(Object expected, Object actual) {
+        assertSame(null, expected, actual);
+    }
+
+    /**
+     * Asserts that two objects do not refer to the same object. If they do
+     * refer to the same object, an {@link AssertionError} is thrown with the
+     * given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param unexpected the object you don't expect
+     * @param actual the object to compare to <code>unexpected</code>
+     */
+    public static void assertNotSame(String message, Object unexpected,
+            Object actual) {
+        if (unexpected == actual) {
+            failSame(message);
+        }
+    }
+
+    /**
+     * Asserts that two objects do not refer to the same object. If they do
+     * refer to the same object, an {@link AssertionError} without a message is
+     * thrown.
+     *
+     * @param unexpected the object you don't expect
+     * @param actual the object to compare to <code>unexpected</code>
+     */
+    public static void assertNotSame(Object unexpected, Object actual) {
+        assertNotSame(null, unexpected, actual);
+    }
+
+    private static void failSame(String message) {
+        String formatted = "";
+        if (message != null) {
+            formatted = message + " ";
+        }
+        fail(formatted + "expected not same");
+    }
+
+    private static void failNotSame(String message, Object expected,
+            Object actual) {
+        String formatted = "";
+        if (message != null) {
+            formatted = message + " ";
+        }
+        fail(formatted + "expected same:<" + expected + "> was not:<" + actual
+                + ">");
+    }
+
+    private static void failNotEquals(String message, Object expected,
+            Object actual) {
+        fail(format(message, expected, actual));
+    }
+
+    static String format(String message, Object expected, Object actual) {
+        String formatted = "";
+        if (message != null && !"".equals(message)) {
+            formatted = message + " ";
+        }
+        String expectedString = String.valueOf(expected);
+        String actualString = String.valueOf(actual);
+        if (equalsRegardingNull(expectedString, actualString)) {
+            return formatted + "expected: "
+                    + formatClassAndValue(expected, expectedString)
+                    + " but was: " + formatClassAndValue(actual, actualString);
+        } else {
+            return formatted + "expected:<" + expectedString + "> but was:<"
+                    + actualString + ">";
+        }
+    }
+
+    private static String formatClass(Class<?> value) {
+        String className = value.getCanonicalName();
+        return className == null ? value.getName() : className;
+    }
+
+    private static String formatClassAndValue(Object value, String valueString) {
+        String className = value == null ? "null" : value.getClass().getName();
+        return className + "<" + valueString + ">";
+    }
+
+    /**
+     * Asserts that two object arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown with the given message. If
+     * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+     * they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expecteds Object array or array of arrays (multi-dimensional array) with
+     * expected values.
+     * @param actuals Object array or array of arrays (multi-dimensional array) with
+     * actual values
+     * @deprecated use assertArrayEquals
+     */
+    @Deprecated
+    public static void assertEquals(String message, Object[] expecteds,
+            Object[] actuals) {
+        assertArrayEquals(message, expecteds, actuals);
+    }
+
+    /**
+     * Asserts that two object arrays are equal. If they are not, an
+     * {@link AssertionError} is thrown. If <code>expected</code> and
+     * <code>actual</code> are <code>null</code>, they are considered
+     * equal.
+     *
+     * @param expecteds Object array or array of arrays (multi-dimensional array) with
+     * expected values
+     * @param actuals Object array or array of arrays (multi-dimensional array) with
+     * actual values
+     * @deprecated use assertArrayEquals
+     */
+    @Deprecated
+    public static void assertEquals(Object[] expecteds, Object[] actuals) {
+        assertArrayEquals(expecteds, actuals);
+    }
+
+    /**
+     * Asserts that <code>actual</code> satisfies the condition specified by
+     * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
+     * information about the matcher and failing value. Example:
+     *
+     * <pre>
+     *   assertThat(0, is(1)); // fails:
+     *     // failure message:
+     *     // expected: is &lt;1&gt;
+     *     // got value: &lt;0&gt;
+     *   assertThat(0, is(not(1))) // passes
+     * </pre>
+     *
+     * <code>org.hamcrest.Matcher</code> does not currently document the meaning
+     * of its type parameter <code>T</code>.  This method assumes that a matcher
+     * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
+     * to values that could be assigned to a variable of type <code>T</code>.
+     *
+     * @param <T> the static type accepted by the matcher (this can flag obvious
+     * compile-time problems such as {@code assertThat(1, is("a"))}
+     * @param actual the computed value being compared
+     * @param matcher an expression, built of {@link Matcher}s, specifying allowed
+     * values
+     * @see org.hamcrest.CoreMatchers
+     * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()}
+     */
+    @Deprecated
+    public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
+        assertThat("", actual, matcher);
+    }
+
+    /**
+     * Asserts that <code>actual</code> satisfies the condition specified by
+     * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
+     * the reason and information about the matcher and failing value. Example:
+     *
+     * <pre>
+     *   assertThat(&quot;Help! Integers don't work&quot;, 0, is(1)); // fails:
+     *     // failure message:
+     *     // Help! Integers don't work
+     *     // expected: is &lt;1&gt;
+     *     // got value: &lt;0&gt;
+     *   assertThat(&quot;Zero is one&quot;, 0, is(not(1))) // passes
+     * </pre>
+     *
+     * <code>org.hamcrest.Matcher</code> does not currently document the meaning
+     * of its type parameter <code>T</code>.  This method assumes that a matcher
+     * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
+     * to values that could be assigned to a variable of type <code>T</code>.
+     *
+     * @param reason additional information about the error
+     * @param <T> the static type accepted by the matcher (this can flag obvious
+     * compile-time problems such as {@code assertThat(1, is("a"))}
+     * @param actual the computed value being compared
+     * @param matcher an expression, built of {@link Matcher}s, specifying allowed
+     * values
+     * @see org.hamcrest.CoreMatchers
+     * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()}
+     */
+    @Deprecated
+    public static <T> void assertThat(String reason, T actual,
+            Matcher<? super T> matcher) {
+        MatcherAssert.assertThat(reason, actual, matcher);
+    }
+
+    /**
+     * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
+     * executed. If it does, the exception object is returned. If it does not throw an exception, an
+     * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code
+     * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can
+     * be obtained by calling {@link AssertionError#getCause}.
+     *
+     * @param expectedThrowable the expected type of the exception
+     * @param runnable       a function that is expected to throw an exception when executed
+     * @return the exception thrown by {@code runnable}
+     * @since 4.13
+     */
+    public static <T extends Throwable> T assertThrows(Class<T> expectedThrowable,
+            ThrowingRunnable runnable) {
+        return assertThrows(null, expectedThrowable, runnable);
+    }
+
+    /**
+     * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
+     * executed. If it does, the exception object is returned. If it does not throw an exception, an
+     * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code
+     * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can
+     * be obtained by calling {@link AssertionError#getCause}.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     * okay)
+     * @param expectedThrowable the expected type of the exception
+     * @param runnable a function that is expected to throw an exception when executed
+     * @return the exception thrown by {@code runnable}
+     * @since 4.13
+     */
+    public static <T extends Throwable> T assertThrows(String message, Class<T> expectedThrowable,
+            ThrowingRunnable runnable) {
+        try {
+            runnable.run();
+        } catch (Throwable actualThrown) {
+            if (expectedThrowable.isInstance(actualThrown)) {
+                @SuppressWarnings("unchecked") T retVal = (T) actualThrown;
+                return retVal;
+            } else {
+                String expected = formatClass(expectedThrowable);
+                Class<? extends Throwable> actualThrowable = actualThrown.getClass();
+                String actual = formatClass(actualThrowable);
+                if (expected.equals(actual)) {
+                    // There must be multiple class loaders. Add the identity hash code so the message
+                    // doesn't say "expected: java.lang.String<my.package.MyException> ..."
+                    expected += "@" + Integer.toHexString(System.identityHashCode(expectedThrowable));
+                    actual += "@" + Integer.toHexString(System.identityHashCode(actualThrowable));
+                }
+                String mismatchMessage = buildPrefix(message)
+                        + format("unexpected exception type thrown;", expected, actual);
+
+                // The AssertionError(String, Throwable) ctor is only available on JDK7.
+                AssertionError assertionError = new AssertionError(mismatchMessage);
+                assertionError.initCause(actualThrown);
+                throw assertionError;
+            }
+        }
+        String notThrownMessage = buildPrefix(message) + String
+                .format("expected %s to be thrown, but nothing was thrown",
+                        formatClass(expectedThrowable));
+        throw new AssertionError(notThrownMessage);
+    }
+
+    private static String buildPrefix(String message) {
+        return message != null && message.length() != 0 ? message + ": " : "";
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Assume.java b/google3/third_party/java_src/junit/main/java/org/junit/Assume.java
new file mode 100644
index 0000000..29b705b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Assume.java
@@ -0,0 +1,169 @@
+package org.junit;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import org.hamcrest.Matcher;
+
+/**
+ * A set of methods useful for stating assumptions about the conditions in which a test is meaningful.
+ * A failed assumption does not mean the code is broken, but that the test provides no useful information. Assume
+ * basically means "don't run this test if these conditions don't apply". The default JUnit runner skips tests with
+ * failing assumptions. Custom runners may behave differently.
+ * <p>
+ *     A good example of using assumptions is in <a href="https://github.com/junit-team/junit4/wiki/Theories">Theories</a> where they are needed to exclude certain datapoints that aren't suitable or allowed for a certain test case.
+ * </p>
+ * Failed assumptions are usually not logged, because there may be many tests that don't apply to certain
+ * configurations.
+ *
+ * <p>
+ * These methods can be used directly: <code>Assume.assumeTrue(...)</code>, however, they
+ * read better if they are referenced through static import:<br/>
+ * <pre>
+ * import static org.junit.Assume.*;
+ *    ...
+ *    assumeTrue(...);
+ * </pre>
+ * </p>
+ *
+ * @see <a href="https://github.com/junit-team/junit4/wiki/Theories">Theories</a>
+ *
+ * @since 4.4
+ */
+public class Assume {
+
+    /**
+     * Do not instantiate.
+     * @deprecated since 4.13.
+     */
+    @Deprecated
+    public Assume() {
+    }
+
+    /**
+     * If called with an expression evaluating to {@code false}, the test will halt and be ignored.
+     */
+    public static void assumeTrue(boolean b) {
+        assumeThat(b, is(true));
+    }
+
+    /**
+     * The inverse of {@link #assumeTrue(boolean)}.
+     */
+    public static void assumeFalse(boolean b) {
+        assumeThat(b, is(false));
+    }
+
+    /**
+     * If called with an expression evaluating to {@code false}, the test will halt and be ignored.
+     *
+     * @param b If <code>false</code>, the method will attempt to stop the test and ignore it by
+     * throwing {@link AssumptionViolatedException}.
+     * @param message A message to pass to {@link AssumptionViolatedException}.
+     */
+    public static void assumeTrue(String message, boolean b) {
+        if (!b) throw new AssumptionViolatedException(message);
+    }
+
+    /**
+     * The inverse of {@link #assumeTrue(String, boolean)}.
+     */
+    public static void assumeFalse(String message, boolean b) {
+        assumeTrue(message, !b);
+    }
+
+    /**
+     * If called with a {@code null} array or one or more {@code null} elements in {@code objects},
+     * the test will halt and be ignored.
+     */
+    public static void assumeNotNull(Object... objects) {
+        assumeThat(objects, notNullValue());
+        assumeThat(asList(objects), everyItem(notNullValue()));
+    }
+
+    /**
+     * Call to assume that <code>actual</code> satisfies the condition specified by <code>matcher</code>.
+     * If not, the test halts and is ignored.
+     * Example:
+     * <pre>:
+     *   assumeThat(1, is(1)); // passes
+     *   foo(); // will execute
+     *   assumeThat(0, is(1)); // assumption failure! test halts
+     *   int x = 1 / 0; // will never execute
+     * </pre>
+     *
+     * @param <T> the static type accepted by the matcher (this can flag obvious compile-time problems such as {@code assumeThat(1, is("a"))}
+     * @param actual the computed value being compared
+     * @param matcher an expression, built of {@link Matcher}s, specifying allowed values
+     * @see org.hamcrest.CoreMatchers
+     * @see org.junit.matchers.JUnitMatchers
+     */
+    public static <T> void assumeThat(T actual, Matcher<T> matcher) {
+        if (!matcher.matches(actual)) {
+            throw new AssumptionViolatedException(actual, matcher);
+        }
+    }
+
+    /**
+     * Call to assume that <code>actual</code> satisfies the condition specified by <code>matcher</code>.
+     * If not, the test halts and is ignored.
+     * Example:
+     * <pre>:
+     *   assumeThat("alwaysPasses", 1, is(1)); // passes
+     *   foo(); // will execute
+     *   assumeThat("alwaysFails", 0, is(1)); // assumption failure! test halts
+     *   int x = 1 / 0; // will never execute
+     * </pre>
+     *
+     * @param <T> the static type accepted by the matcher (this can flag obvious compile-time problems such as {@code assumeThat(1, is("a"))}
+     * @param actual the computed value being compared
+     * @param matcher an expression, built of {@link Matcher}s, specifying allowed values
+     * @see org.hamcrest.CoreMatchers
+     * @see org.junit.matchers.JUnitMatchers
+     */
+    public static <T> void assumeThat(String message, T actual, Matcher<T> matcher) {
+        if (!matcher.matches(actual)) {
+            throw new AssumptionViolatedException(message, actual, matcher);
+        }
+    }
+
+    /**
+     * Use to assume that an operation completes normally.  If {@code e} is non-null, the test will halt and be ignored.
+     *
+     * For example:
+     * <pre>
+     * \@Test public void parseDataFile() {
+     *   DataFile file;
+     *   try {
+     *     file = DataFile.open("sampledata.txt");
+     *   } catch (IOException e) {
+     *     // stop test and ignore if data can't be opened
+     *     assumeNoException(e);
+     *   }
+     *   // ...
+     * }
+     * </pre>
+     *
+     * @param e if non-null, the offending exception
+     */
+    public static void assumeNoException(Throwable e) {
+        assumeThat(e, nullValue());
+    }
+
+    /**
+     * Attempts to halt the test and ignore it if Throwable <code>e</code> is
+     * not <code>null</code>. Similar to {@link #assumeNoException(Throwable)},
+     * but provides an additional message that can explain the details
+     * concerning the assumption.
+     *
+     * @param e if non-null, the offending exception
+     * @param message Additional message to pass to {@link AssumptionViolatedException}.
+     * @see #assumeNoException(Throwable)
+     */
+    public static void assumeNoException(String message, Throwable e) {
+        assumeThat(message, e, nullValue());
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/AssumptionViolatedException.java b/google3/third_party/java_src/junit/main/java/org/junit/AssumptionViolatedException.java
new file mode 100644
index 0000000..1d62190
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/AssumptionViolatedException.java
@@ -0,0 +1,46 @@
+package org.junit;
+
+import org.hamcrest.Matcher;
+
+/**
+ * An exception class used to implement <i>assumptions</i> (state in which a given test
+ * is meaningful and should or should not be executed). A test for which an assumption
+ * fails should not generate a test case failure.
+ *
+ * @see org.junit.Assume
+ * @since 4.12
+ */
+@SuppressWarnings("deprecation")
+public class AssumptionViolatedException extends org.junit.internal.AssumptionViolatedException {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * An assumption exception with the given <i>actual</i> value and a <i>matcher</i> describing 
+     * the expectation that failed.
+     */
+    public <T> AssumptionViolatedException(T actual, Matcher<T> matcher) {
+        super(actual, matcher);
+    }
+
+    /**
+     * An assumption exception with a message with the given <i>actual</i> value and a
+     * <i>matcher</i> describing the expectation that failed.
+     */
+    public <T> AssumptionViolatedException(String message, T expected, Matcher<T> matcher) {
+        super(message, expected, matcher);
+    }
+
+    /**
+     * An assumption exception with the given message only.
+     */
+    public AssumptionViolatedException(String message) {
+        super(message);
+    }
+
+    /**
+     * An assumption exception with the given message and a cause.
+     */
+    public AssumptionViolatedException(String message, Throwable t) {
+        super(message, t);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Before.java b/google3/third_party/java_src/junit/main/java/org/junit/Before.java
new file mode 100644
index 0000000..def8adb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Before.java
@@ -0,0 +1,39 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * When writing tests, it is common to find that several tests need similar
+ * objects created before they can run. Annotating a <code>public void</code> method
+ * with <code>&#064;Before</code> causes that method to be run before the {@link org.junit.Test} method.
+ * The <code>&#064;Before</code> methods of superclasses will be run before those of the current class,
+ * unless they are overridden in the current class. No other ordering is defined.
+ * <p>
+ * Here is a simple example:
+ * <pre>
+ * public class Example {
+ *    List empty;
+ *    &#064;Before public void initialize() {
+ *       empty= new ArrayList();
+ *    }
+ *    &#064;Test public void size() {
+ *       ...
+ *    }
+ *    &#064;Test public void remove() {
+ *       ...
+ *    }
+ * }
+ * </pre>
+ *
+ * @see org.junit.BeforeClass
+ * @see org.junit.After
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Before {
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/BeforeClass.java b/google3/third_party/java_src/junit/main/java/org/junit/BeforeClass.java
new file mode 100644
index 0000000..8183fa0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/BeforeClass.java
@@ -0,0 +1,37 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Sometimes several tests need to share computationally expensive setup
+ * (like logging into a database). While this can compromise the independence of
+ * tests, sometimes it is a necessary optimization. Annotating a <code>public static void</code> no-arg method
+ * with <code>@BeforeClass</code> causes it to be run once before any of
+ * the test methods in the class. The <code>@BeforeClass</code> methods of superclasses
+ * will be run before those of the current class, unless they are shadowed in the current class.
+ * <p>
+ * For example:
+ * <pre>
+ * public class Example {
+ *    &#064;BeforeClass public static void onlyOnce() {
+ *       ...
+ *    }
+ *    &#064;Test public void one() {
+ *       ...
+ *    }
+ *    &#064;Test public void two() {
+ *       ...
+ *    }
+ * }
+ * </pre>
+ *
+ * @see org.junit.AfterClass
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface BeforeClass {
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/ClassRule.java b/google3/third_party/java_src/junit/main/java/org/junit/ClassRule.java
new file mode 100644
index 0000000..94ee29f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/ClassRule.java
@@ -0,0 +1,118 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates static fields that reference rules or methods that return them. A field must be public,
+ * static, and a subtype of {@link org.junit.rules.TestRule}.  A method must be public static, and return
+ * a subtype of {@link org.junit.rules.TestRule}.
+ * <p>
+ * The {@link org.junit.runners.model.Statement} passed
+ * to the {@link org.junit.rules.TestRule} will run any {@link BeforeClass} methods,
+ * then the entire body of the test class (all contained methods, if it is
+ * a standard JUnit test class, or all contained classes, if it is a
+ * {@link org.junit.runners.Suite}), and finally any {@link AfterClass} methods.
+ * <p>
+ * The statement passed to the {@link org.junit.rules.TestRule} will never throw an exception,
+ * and throwing an exception from the {@link org.junit.rules.TestRule} will result in undefined
+ * behavior.  This means that some {@link org.junit.rules.TestRule}s, such as
+ * {@link org.junit.rules.ErrorCollector},
+ * {@link org.junit.rules.ExpectedException},
+ * and {@link org.junit.rules.Timeout},
+ * have undefined behavior when used as {@link ClassRule}s.
+ * <p>
+ * If there are multiple
+ * annotated {@link ClassRule}s on a class, they will be applied in an order
+ * that depends on your JVM's implementation of the reflection API, which is
+ * undefined, in general. However, Rules defined by fields will always be applied
+ * after Rules defined by methods, i.e. the Statements returned by the former will
+ * be executed around those returned by the latter.
+ *
+ * <h3>Usage</h3>
+ * <p>
+ * For example, here is a test suite that connects to a server once before
+ * all the test classes run, and disconnects after they are finished:
+ * <pre>
+ * &#064;RunWith(Suite.class)
+ * &#064;SuiteClasses({A.class, B.class, C.class})
+ * public class UsesExternalResource {
+ *     public static Server myServer= new Server();
+ *
+ *     &#064;ClassRule
+ *     public static ExternalResource resource= new ExternalResource() {
+ *       &#064;Override
+ *       protected void before() throws Throwable {
+ *          myServer.connect();
+ *      }
+ *
+ *      &#064;Override
+ *      protected void after() {
+ * 	        myServer.disconnect();
+ *      }
+ *   };
+ * }
+ * </pre>
+ * <p>
+ * and the same using a method
+ * <pre>
+ * &#064;RunWith(Suite.class)
+ * &#064;SuiteClasses({A.class, B.class, C.class})
+ * public class UsesExternalResource {
+ *     public static Server myServer= new Server();
+ *
+ *     &#064;ClassRule
+ *     public static ExternalResource getResource() {
+ *         return new ExternalResource() {
+ *             &#064;Override
+ *             protected void before() throws Throwable {
+ *                 myServer.connect();
+ *             }
+ *
+ *             &#064;Override
+ *             protected void after() {
+ *                 myServer.disconnect();
+ *             }
+ *         };
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * For more information and more examples, see {@link org.junit.rules.TestRule}.
+ *
+ * <h3>Ordering</h3>
+ * <p>
+ * You can use {@link #order()} if you want to have control over the order in
+ * which the Rules are applied.
+ *
+ * <pre>
+ * public class ThreeClassRules {
+ *     &#064;ClassRule(order = 0)
+ *     public static LoggingRule outer = new LoggingRule("outer rule");
+ *
+ *     &#064;ClassRule(order = 1)
+ *     public static LoggingRule middle = new LoggingRule("middle rule");
+ *
+ *     &#064;ClassRule(order = 2)
+ *     public static LoggingRule inner = new LoggingRule("inner rule");
+ *
+ *     // ...
+ * }
+ * </pre>
+ *
+ * @since 4.9
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface ClassRule {
+
+    /**
+     * Specifies the order in which rules are applied. The rules with a higher value are inner.
+     *
+     * @since 4.13
+     */
+    int order() default Rule.DEFAULT_ORDER;
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/ComparisonFailure.java b/google3/third_party/java_src/junit/main/java/org/junit/ComparisonFailure.java
new file mode 100644
index 0000000..d1daa86
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/ComparisonFailure.java
@@ -0,0 +1,171 @@
+package org.junit;
+
+/**
+ * Thrown when an {@link org.junit.Assert#assertEquals(Object, Object) assertEquals(String, String)} fails.
+ * Create and throw a <code>ComparisonFailure</code> manually if you want to show users the
+ * difference between two complex strings.
+ * <p/>
+ * Inspired by a patch from Alex Chaffee (alex@purpletech.com)
+ *
+ * @since 4.0
+ */
+public class ComparisonFailure extends AssertionError {
+    /**
+     * The maximum length for expected and actual strings. If it is exceeded, the strings should be shortened.
+     *
+     * @see ComparisonCompactor
+     */
+    private static final int MAX_CONTEXT_LENGTH = 20;
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * We have to use the f prefix until the next major release to ensure
+     * serialization compatibility. 
+     * See https://github.com/junit-team/junit4/issues/976
+     */
+    private String fExpected;
+    private String fActual;
+
+    /**
+     * Constructs a comparison failure.
+     *
+     * @param message the identifying message or null
+     * @param expected the expected string value
+     * @param actual the actual string value
+     */
+    public ComparisonFailure(String message, String expected, String actual) {
+        super(message);
+        this.fExpected = expected;
+        this.fActual = actual;
+    }
+
+    /**
+     * Returns "..." in place of common prefix and "..." in place of common suffix between expected and actual.
+     *
+     * @see Throwable#getMessage()
+     */
+    @Override
+    public String getMessage() {
+        return new ComparisonCompactor(MAX_CONTEXT_LENGTH, fExpected, fActual).compact(super.getMessage());
+    }
+
+    /**
+     * Returns the actual string value
+     *
+     * @return the actual string value
+     */
+    public String getActual() {
+        return fActual;
+    }
+
+    /**
+     * Returns the expected string value
+     *
+     * @return the expected string value
+     */
+    public String getExpected() {
+        return fExpected;
+    }
+
+    private static class ComparisonCompactor {
+        private static final String ELLIPSIS = "...";
+        private static final String DIFF_END = "]";
+        private static final String DIFF_START = "[";
+
+        /**
+         * The maximum length for <code>expected</code> and <code>actual</code> strings to show. When
+         * <code>contextLength</code> is exceeded, the Strings are shortened.
+         */
+        private final int contextLength;
+        private final String expected;
+        private final String actual;
+
+        /**
+         * @param contextLength the maximum length of context surrounding the difference between the compared strings.
+         * When context length is exceeded, the prefixes and suffixes are compacted.
+         * @param expected the expected string value
+         * @param actual the actual string value
+         */
+        public ComparisonCompactor(int contextLength, String expected, String actual) {
+            this.contextLength = contextLength;
+            this.expected = expected;
+            this.actual = actual;
+        }
+
+        public String compact(String message) {
+            if (expected == null || actual == null || expected.equals(actual)) {
+                return Assert.format(message, expected, actual);
+            } else {
+                DiffExtractor extractor = new DiffExtractor();
+                String compactedPrefix = extractor.compactPrefix();
+                String compactedSuffix = extractor.compactSuffix();
+                return Assert.format(message,
+                        compactedPrefix + extractor.expectedDiff() + compactedSuffix,
+                        compactedPrefix + extractor.actualDiff() + compactedSuffix);
+            }
+        }
+
+        private String sharedPrefix() {
+            int end = Math.min(expected.length(), actual.length());
+            for (int i = 0; i < end; i++) {
+                if (expected.charAt(i) != actual.charAt(i)) {
+                    return expected.substring(0, i);
+                }
+            }
+            return expected.substring(0, end);
+        }
+
+        private String sharedSuffix(String prefix) {
+            int suffixLength = 0;
+            int maxSuffixLength = Math.min(expected.length() - prefix.length(),
+                    actual.length() - prefix.length()) - 1;
+            for (; suffixLength <= maxSuffixLength; suffixLength++) {
+                if (expected.charAt(expected.length() - 1 - suffixLength)
+                        != actual.charAt(actual.length() - 1 - suffixLength)) {
+                    break;
+                }
+            }
+            return expected.substring(expected.length() - suffixLength);
+        }
+
+        private class DiffExtractor {
+            private final String sharedPrefix;
+            private final String sharedSuffix;
+
+            /**
+             * Can not be instantiated outside {@link org.junit.ComparisonFailure.ComparisonCompactor}.
+             */
+            private DiffExtractor() {
+                sharedPrefix = sharedPrefix();
+                sharedSuffix = sharedSuffix(sharedPrefix);
+            }
+
+            public String expectedDiff() {
+                return extractDiff(expected);
+            }
+
+            public String actualDiff() {
+                return extractDiff(actual);
+            }
+
+            public String compactPrefix() {
+                if (sharedPrefix.length() <= contextLength) {
+                    return sharedPrefix;
+                }
+                return ELLIPSIS + sharedPrefix.substring(sharedPrefix.length() - contextLength);
+            }
+
+            public String compactSuffix() {
+                if (sharedSuffix.length() <= contextLength) {
+                    return sharedSuffix;
+                }
+                return sharedSuffix.substring(0, contextLength) + ELLIPSIS;
+            }
+
+            private String extractDiff(String source) {
+                return DIFF_START + source.substring(sharedPrefix.length(), source.length() - sharedSuffix.length())
+                        + DIFF_END;
+            }
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/FixMethodOrder.java b/google3/third_party/java_src/junit/main/java/org/junit/FixMethodOrder.java
new file mode 100644
index 0000000..aaa0313
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/FixMethodOrder.java
@@ -0,0 +1,41 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.runners.MethodSorters;
+
+/**
+ * This class allows the user to choose the order of execution of the methods within a test class.
+ *
+ * <p>The default order of execution of JUnit tests within a class is deterministic but not predictable.
+ * The order of execution is not guaranteed for Java 7 (and some previous versions), and can even change
+ * from run to run, so the order of execution was changed to be deterministic (in JUnit 4.11)
+ *
+ * <p>It is recommended that test methods be written so that they are independent of the order that they are executed.
+ * However, there may be a number of dependent tests either through error or by design.
+ * This class allows the user to specify the order of execution of test methods.
+ *
+ * <p>For possibilities, see {@link MethodSorters}
+ *
+ * Here is an example:
+ *
+ * <pre>
+ * &#064;FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ * public class MyTest {
+ * }
+ * </pre>
+ *
+ * @see org.junit.runners.MethodSorters
+ * @since 4.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface FixMethodOrder {
+    /**
+     * Optionally specify <code>value</code> to have the methods executed in a particular order
+     */
+    MethodSorters value() default MethodSorters.DEFAULT;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Ignore.java b/google3/third_party/java_src/junit/main/java/org/junit/Ignore.java
new file mode 100644
index 0000000..db23581
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Ignore.java
@@ -0,0 +1,40 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Sometimes you want to temporarily disable a test or a group of tests. Methods annotated with
+ * {@link org.junit.Test} that are also annotated with <code>&#064;Ignore</code> will not be executed as tests.
+ * Also, you can annotate a class containing test methods with <code>&#064;Ignore</code> and none of the containing
+ * tests will be executed. Native JUnit 4 test runners should report the number of ignored tests along with the
+ * number of tests that ran and the number of tests that failed.
+ *
+ * <p>For example:
+ * <pre>
+ *    &#064;Ignore &#064;Test public void something() { ...
+ * </pre>
+ * &#064;Ignore takes an optional default parameter if you want to record why a test is being ignored:
+ * <pre>
+ *    &#064;Ignore("not ready yet") &#064;Test public void something() { ...
+ * </pre>
+ * &#064;Ignore can also be applied to the test class:
+ * <pre>
+ *      &#064;Ignore public class IgnoreMe {
+ *          &#064;Test public void test1() { ... }
+ *          &#064;Test public void test2() { ... }
+ *         }
+ * </pre>
+ *
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface Ignore {
+    /**
+     * The optional reason why the test is ignored.
+     */
+    String value() default "";
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Rule.java b/google3/third_party/java_src/junit/main/java/org/junit/Rule.java
new file mode 100644
index 0000000..9370e94
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Rule.java
@@ -0,0 +1,101 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates fields that reference rules or methods that return a rule. A field must be public, not
+ * static, and a subtype of {@link org.junit.rules.TestRule} (preferred) or
+ * {@link org.junit.rules.MethodRule}. A method must be public, not static,
+ * and must return a subtype of {@link org.junit.rules.TestRule} (preferred) or
+ * {@link org.junit.rules.MethodRule}.
+ * <p>
+ * The {@link org.junit.runners.model.Statement} passed
+ * to the {@link org.junit.rules.TestRule} will run any {@link Before} methods,
+ * then the {@link Test} method, and finally any {@link After} methods,
+ * throwing an exception if any of these fail.  If there are multiple
+ * annotated {@link Rule}s on a class, they will be applied in order of methods first, then fields.
+ * However, if there are multiple fields (or methods) they will be applied in an order
+ * that depends on your JVM's implementation of the reflection API, which is
+ * undefined, in general. Rules defined by fields will always be applied
+ * after Rules defined by methods, i.e. the Statements returned by the former will
+ * be executed around those returned by the latter.
+ *
+ * <h3>Usage</h3>
+ * <p>
+ * For example, here is a test class that creates a temporary folder before
+ * each test method, and deletes it after each:
+ * <pre>
+ * public static class HasTempFolder {
+ *     &#064;Rule
+ *     public TemporaryFolder folder= new TemporaryFolder();
+ *
+ *     &#064;Test
+ *     public void testUsingTempFolder() throws IOException {
+ *         File createdFile= folder.newFile(&quot;myfile.txt&quot;);
+ *         File createdFolder= folder.newFolder(&quot;subfolder&quot;);
+ *         // ...
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * And the same using a method.
+ * <pre>
+ * public static class HasTempFolder {
+ *     private TemporaryFolder folder= new TemporaryFolder();
+ *
+ *     &#064;Rule
+ *     public TemporaryFolder getFolder() {
+ *         return folder;
+ *     }
+ *
+ *     &#064;Test
+ *     public void testUsingTempFolder() throws IOException {
+ *         File createdFile= folder.newFile(&quot;myfile.txt&quot;);
+ *         File createdFolder= folder.newFolder(&quot;subfolder&quot;);
+ *         // ...
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * For more information and more examples, see
+ * {@link org.junit.rules.TestRule}.
+ *
+ * <h3>Ordering</h3>
+ * <p>
+ * You can use {@link #order()} if you want to have control over the order in
+ * which the Rules are applied.
+ *
+ * <pre>
+ * public class ThreeRules {
+ *     &#064;Rule(order = 0)
+ *     public LoggingRule outer = new LoggingRule("outer rule");
+ *
+ *     &#064;Rule(order = 1)
+ *     public LoggingRule middle = new LoggingRule("middle rule");
+ *
+ *     &#064;Rule(order = 2)
+ *     public LoggingRule inner = new LoggingRule("inner rule");
+ *
+ *     // ...
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface Rule {
+
+    int DEFAULT_ORDER = -1;
+
+    /**
+     * Specifies the order in which rules are applied. The rules with a higher value are inner.
+     *
+     * @since 4.13
+     */
+    int order() default DEFAULT_ORDER;
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Test.java b/google3/third_party/java_src/junit/main/java/org/junit/Test.java
new file mode 100644
index 0000000..1db6fc7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Test.java
@@ -0,0 +1,117 @@
+package org.junit;
+
+import org.junit.function.ThrowingRunnable;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The <code>Test</code> annotation tells JUnit that the <code>public void</code> method
+ * to which it is attached can be run as a test case. To run the method,
+ * JUnit first constructs a fresh instance of the class then invokes the
+ * annotated method. Any exceptions thrown by the test will be reported
+ * by JUnit as a failure. If no exceptions are thrown, the test is assumed
+ * to have succeeded.
+ * <p>
+ * A simple test looks like this:
+ * <pre>
+ * public class Example {
+ *    <b>&#064;Test</b>
+ *    public void method() {
+ *       org.junit.Assert.assertTrue( new ArrayList().isEmpty() );
+ *    }
+ * }
+ * </pre>
+ * <p>
+ * The <code>Test</code> annotation supports two optional parameters for
+ * exception testing and for limiting test execution time.
+ *
+ * <h3>Exception Testing</h3>
+ * <p>
+ * The parameter <code>expected</code> declares that a test method should throw
+ * an exception. If it doesn't throw an exception or if it throws a different exception
+ * than the one declared, the test fails. For example, the following test succeeds:
+ * <pre>
+ *    &#064;Test(<b>expected=IndexOutOfBoundsException.class</b>)
+ *    public void outOfBounds() {
+ *       new ArrayList&lt;Object&gt;().get(1);
+ *    }
+ * </pre>
+ *
+ * Using the parameter <code>expected</code> for exception testing comes with
+ * some limitations: only the exception's type can be checked and it is not
+ * possible to precisely specify the code that throws the exception. Therefore
+ * JUnit 4 has improved its support for exception testing with
+ * {@link Assert#assertThrows(Class, ThrowingRunnable)} and the
+ * {@link org.junit.rules.ExpectedException ExpectedException} rule.
+ * With <code>assertThrows</code> the code that throws the exception can be
+ * precisely specified. If the exception's message or one of its properties
+ * should be verified, the <code>ExpectedException</code> rule can be used. Further
+ * information about exception testing can be found at the
+ * <a href="https://github.com/junit-team/junit4/wiki/Exception-testing">JUnit Wiki</a>.
+ *
+ * <h3>Timeout</h3>
+ * <p>
+ * The parameter <code>timeout</code> causes a test to fail if it takes
+ * longer than a specified amount of clock time (measured in milliseconds). The following test fails:
+ * <pre>
+ *    &#064;Test(<b>timeout=100</b>)
+ *    public void infinity() {
+ *       while(true);
+ *    }
+ * </pre>
+ * <b>Warning</b>: while <code>timeout</code> is useful to catch and terminate
+ * infinite loops, it should <em>not</em> be considered deterministic. The
+ * following test may or may not fail depending on how the operating system
+ * schedules threads:
+ * <pre>
+ *    &#064;Test(<b>timeout=100</b>)
+ *    public void sleep100() {
+ *       Thread.sleep(100);
+ *    }
+ * </pre>
+ * <b>THREAD SAFETY WARNING:</b> Test methods with a timeout parameter are run in a thread other than the
+ * thread which runs the fixture's @Before and @After methods. This may yield different behavior for
+ * code that is not thread safe when compared to the same test method without a timeout parameter.
+ * <b>Consider using the {@link org.junit.rules.Timeout} rule instead</b>, which ensures a test method is run on the
+ * same thread as the fixture's @Before and @After methods.
+ *
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Test {
+
+    /**
+     * Default empty exception.
+     */
+    static class None extends Throwable {
+        private static final long serialVersionUID = 1L;
+
+        private None() {
+        }
+    }
+
+    /**
+     * Optionally specify <code>expected</code>, a Throwable, to cause a test method to succeed if
+     * and only if an exception of the specified class is thrown by the method. If the Throwable's
+     * message or one of its properties should be verified, the
+     * {@link org.junit.rules.ExpectedException ExpectedException} rule can be used instead.
+     */
+    Class<? extends Throwable> expected() default None.class;
+
+    /**
+     * Optionally specify <code>timeout</code> in milliseconds to cause a test method to fail if it
+     * takes longer than that number of milliseconds.
+     * <p>
+     * <b>THREAD SAFETY WARNING:</b> Test methods with a timeout parameter are run in a thread other than the
+     * thread which runs the fixture's @Before and @After methods. This may yield different behavior for
+     * code that is not thread safe when compared to the same test method without a timeout parameter.
+     * <b>Consider using the {@link org.junit.rules.Timeout} rule instead</b>, which ensures a test method is run on the
+     * same thread as the fixture's @Before and @After methods.
+     * </p>
+     */
+    long timeout() default 0L;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/TestCouldNotBeSkippedException.java b/google3/third_party/java_src/junit/main/java/org/junit/TestCouldNotBeSkippedException.java
new file mode 100644
index 0000000..4804493
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/TestCouldNotBeSkippedException.java
@@ -0,0 +1,19 @@
+package org.junit;
+
+/**
+ * Indicates that a test that indicated that it should be skipped could not be skipped.
+ * This can be thrown if a test uses the methods in {@link Assume} to indicate that
+ * it should be skipped, but before processing of the test was completed, other failures
+ * occured.
+ *
+ * @see org.junit.Assume
+ * @since 4.13
+ */
+public class TestCouldNotBeSkippedException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    /** Creates an instance using the given assumption failure. */
+    public TestCouldNotBeSkippedException(org.junit.internal.AssumptionViolatedException cause) {
+        super("Test could not be skipped due to other failures", cause);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/ParallelComputer.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/ParallelComputer.java
new file mode 100644
index 0000000..97da0f7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/ParallelComputer.java
@@ -0,0 +1,67 @@
+package org.junit.experimental;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.runner.Computer;
+import org.junit.runner.Runner;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+import org.junit.runners.model.RunnerScheduler;
+
+public class ParallelComputer extends Computer {
+    private final boolean classes;
+
+    private final boolean methods;
+
+    public ParallelComputer(boolean classes, boolean methods) {
+        this.classes = classes;
+        this.methods = methods;
+    }
+
+    public static Computer classes() {
+        return new ParallelComputer(true, false);
+    }
+
+    public static Computer methods() {
+        return new ParallelComputer(false, true);
+    }
+
+    private static Runner parallelize(Runner runner) {
+        if (runner instanceof ParentRunner) {
+            ((ParentRunner<?>) runner).setScheduler(new RunnerScheduler() {
+                private final ExecutorService fService = Executors.newCachedThreadPool();
+
+                public void schedule(Runnable childStatement) {
+                    fService.submit(childStatement);
+                }
+
+                public void finished() {
+                    try {
+                        fService.shutdown();
+                        fService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace(System.err);
+                    }
+                }
+            });
+        }
+        return runner;
+    }
+
+    @Override
+    public Runner getSuite(RunnerBuilder builder, java.lang.Class<?>[] classes)
+            throws InitializationError {
+        Runner suite = super.getSuite(builder, classes);
+        return this.classes ? parallelize(suite) : suite;
+    }
+
+    @Override
+    protected Runner getRunner(RunnerBuilder builder, Class<?> testClass)
+            throws Throwable {
+        Runner runner = super.getRunner(builder, testClass);
+        return methods ? parallelize(runner) : runner;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Categories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Categories.java
new file mode 100644
index 0000000..0c73ed8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Categories.java
@@ -0,0 +1,375 @@
+package org.junit.experimental.categories;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * From a given set of test classes, runs only the classes and methods that are
+ * annotated with either the category given with the @IncludeCategory
+ * annotation, or a subtype of that category.
+ * <p>
+ * Note that, for now, annotating suites with {@code @Category} has no effect.
+ * Categories must be annotated on the direct method or class.
+ * <p>
+ * Example:
+ * <pre>
+ * public interface FastTests {
+ * }
+ *
+ * public interface SlowTests {
+ * }
+ *
+ * public interface SmokeTests
+ * }
+ *
+ * public static class A {
+ *     &#064;Test
+ *     public void a() {
+ *         fail();
+ *     }
+ *
+ *     &#064;Category(SlowTests.class)
+ *     &#064;Test
+ *     public void b() {
+ *     }
+ *
+ *     &#064;Category({FastTests.class, SmokeTests.class})
+ *     &#064;Test
+ *     public void c() {
+ *     }
+ * }
+ *
+ * &#064;Category({SlowTests.class, FastTests.class})
+ * public static class B {
+ *     &#064;Test
+ *     public void d() {
+ *     }
+ * }
+ *
+ * &#064;RunWith(Categories.class)
+ * &#064;IncludeCategory(SlowTests.class)
+ * &#064;SuiteClasses({A.class, B.class})
+ * // Note that Categories is a kind of Suite
+ * public static class SlowTestSuite {
+ *     // Will run A.b and B.d, but not A.a and A.c
+ * }
+ * </pre>
+ * <p>
+ * Example to run multiple categories:
+ * <pre>
+ * &#064;RunWith(Categories.class)
+ * &#064;IncludeCategory({FastTests.class, SmokeTests.class})
+ * &#064;SuiteClasses({A.class, B.class})
+ * public static class FastOrSmokeTestSuite {
+ *     // Will run A.c and B.d, but not A.b because it is not any of FastTests or SmokeTests
+ * }
+ * </pre>
+ *
+ * @version 4.12
+ * @see <a href="https://github.com/junit-team/junit4/wiki/Categories">Categories at JUnit wiki</a>
+ */
+public class Categories extends Suite {
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface IncludeCategory {
+        /**
+         * Determines the tests to run that are annotated with categories specified in
+         * the value of this annotation or their subtypes unless excluded with {@link ExcludeCategory}.
+         */
+        Class<?>[] value() default {};
+
+        /**
+         * If <tt>true</tt>, runs tests annotated with <em>any</em> of the categories in
+         * {@link IncludeCategory#value()}. Otherwise, runs tests only if annotated with <em>all</em> of the categories.
+         */
+        boolean matchAny() default true;
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface ExcludeCategory {
+        /**
+         * Determines the tests which do not run if they are annotated with categories specified in the
+         * value of this annotation or their subtypes regardless of being included in {@link IncludeCategory#value()}.
+         */
+        Class<?>[] value() default {};
+
+        /**
+         * If <tt>true</tt>, the tests annotated with <em>any</em> of the categories in {@link ExcludeCategory#value()}
+         * do not run. Otherwise, the tests do not run if and only if annotated with <em>all</em> categories.
+         */
+        boolean matchAny() default true;
+    }
+
+    public static class CategoryFilter extends Filter {
+        private final Set<Class<?>> included;
+        private final Set<Class<?>> excluded;
+        private final boolean includedAny;
+        private final boolean excludedAny;
+
+        public static CategoryFilter include(boolean matchAny, Class<?>... categories) {
+            return new CategoryFilter(matchAny, categories, true, null);
+        }
+
+        public static CategoryFilter include(Class<?> category) {
+            return include(true, category);
+        }
+
+        public static CategoryFilter include(Class<?>... categories) {
+            return include(true, categories);
+        }
+
+        public static CategoryFilter exclude(boolean matchAny, Class<?>... categories) {
+            return new CategoryFilter(true, null, matchAny, categories);
+        }
+
+        public static CategoryFilter exclude(Class<?> category) {
+            return exclude(true, category);
+        }
+
+        public static CategoryFilter exclude(Class<?>... categories) {
+            return exclude(true, categories);
+        }
+
+        public static CategoryFilter categoryFilter(boolean matchAnyInclusions, Set<Class<?>> inclusions,
+                                                    boolean matchAnyExclusions, Set<Class<?>> exclusions) {
+            return new CategoryFilter(matchAnyInclusions, inclusions, matchAnyExclusions, exclusions);
+        }
+
+        @Deprecated
+        public CategoryFilter(Class<?> includedCategory, Class<?> excludedCategory) {
+            includedAny = true;
+            excludedAny = true;
+            included = nullableClassToSet(includedCategory);
+            excluded = nullableClassToSet(excludedCategory);
+        }
+
+        protected CategoryFilter(boolean matchAnyIncludes, Set<Class<?>> includes,
+                                 boolean matchAnyExcludes, Set<Class<?>> excludes) {
+            includedAny = matchAnyIncludes;
+            excludedAny = matchAnyExcludes;
+            included = copyAndRefine(includes);
+            excluded = copyAndRefine(excludes);
+        }
+
+        private CategoryFilter(boolean matchAnyIncludes, Class<?>[] inclusions,
+                               boolean matchAnyExcludes, Class<?>[] exclusions) {
+            includedAny = matchAnyIncludes; 
+            excludedAny = matchAnyExcludes;
+            included = createSet(inclusions);
+            excluded = createSet(exclusions);
+        }
+
+        /**
+         * @see #toString()
+         */
+        @Override
+        public String describe() {
+            return toString();
+        }
+
+        /**
+         * Returns string in the form <tt>&quot;[included categories] - [excluded categories]&quot;</tt>, where both
+         * sets have comma separated names of categories.
+         *
+         * @return string representation for the relative complement of excluded categories set
+         * in the set of included categories. Examples:
+         * <ul>
+         *  <li> <tt>&quot;categories [all]&quot;</tt> for all included categories and no excluded ones;
+         *  <li> <tt>&quot;categories [all] - [A, B]&quot;</tt> for all included categories and given excluded ones;
+         *  <li> <tt>&quot;categories [A, B] - [C, D]&quot;</tt> for given included categories and given excluded ones.
+         * </ul>
+         * @see Class#toString() name of category
+         */
+        @Override public String toString() {
+            StringBuilder description= new StringBuilder("categories ")
+                .append(included.isEmpty() ? "[all]" : included);
+            if (!excluded.isEmpty()) {
+                description.append(" - ").append(excluded);
+            }
+            return description.toString();
+        }
+
+        @Override
+        public boolean shouldRun(Description description) {
+            if (hasCorrectCategoryAnnotation(description)) {
+                return true;
+            }
+
+            for (Description each : description.getChildren()) {
+                if (shouldRun(each)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private boolean hasCorrectCategoryAnnotation(Description description) {
+            final Set<Class<?>> childCategories= categories(description);
+
+            // If a child has no categories, immediately return.
+            if (childCategories.isEmpty()) {
+                return included.isEmpty();
+            }
+
+            if (!excluded.isEmpty()) {
+                if (excludedAny) {
+                    if (matchesAnyParentCategories(childCategories, excluded)) {
+                        return false;
+                    }
+                } else {
+                    if (matchesAllParentCategories(childCategories, excluded)) {
+                        return false;
+                    }
+                }
+            }
+
+            if (included.isEmpty()) {
+                // Couldn't be excluded, and with no suite's included categories treated as should run.
+                return true;
+            } else {
+                if (includedAny) {
+                    return matchesAnyParentCategories(childCategories, included);
+                } else {
+                    return matchesAllParentCategories(childCategories, included);
+                }
+            }
+        }
+
+        /**
+         * @return <tt>true</tt> if at least one (any) parent category match a child, otherwise <tt>false</tt>.
+         * If empty <tt>parentCategories</tt>, returns <tt>false</tt>.
+         */
+        private boolean matchesAnyParentCategories(Set<Class<?>> childCategories, Set<Class<?>> parentCategories) {
+            for (Class<?> parentCategory : parentCategories) {
+                if (hasAssignableTo(childCategories, parentCategory)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * @return <tt>false</tt> if at least one parent category does not match children, otherwise <tt>true</tt>.
+         * If empty <tt>parentCategories</tt>, returns <tt>true</tt>.
+         */
+        private boolean matchesAllParentCategories(Set<Class<?>> childCategories, Set<Class<?>> parentCategories) {
+            for (Class<?> parentCategory : parentCategories) {
+                if (!hasAssignableTo(childCategories, parentCategory)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private static Set<Class<?>> categories(Description description) {
+            Set<Class<?>> categories= new HashSet<Class<?>>();
+            Collections.addAll(categories, directCategories(description));
+            Collections.addAll(categories, directCategories(parentDescription(description)));
+            return categories;
+        }
+
+        private static Description parentDescription(Description description) {
+            Class<?> testClass= description.getTestClass();
+            return testClass == null ? null : Description.createSuiteDescription(testClass);
+        }
+
+        private static Class<?>[] directCategories(Description description) {
+            if (description == null) {
+                return new Class<?>[0];
+            }
+
+            Category annotation= description.getAnnotation(Category.class);
+            return annotation == null ? new Class<?>[0] : annotation.value();
+        }
+
+        private static Set<Class<?>> copyAndRefine(Set<Class<?>> classes) {
+            Set<Class<?>> c= new LinkedHashSet<Class<?>>();
+            if (classes != null) {
+                c.addAll(classes);
+            }
+            c.remove(null);
+            return c;
+        }
+    }
+
+    public Categories(Class<?> klass, RunnerBuilder builder) throws InitializationError {
+        super(klass, builder);
+        try {
+            Set<Class<?>> included= getIncludedCategory(klass);
+            Set<Class<?>> excluded= getExcludedCategory(klass);
+            boolean isAnyIncluded= isAnyIncluded(klass);
+            boolean isAnyExcluded= isAnyExcluded(klass);
+
+            filter(CategoryFilter.categoryFilter(isAnyIncluded, included, isAnyExcluded, excluded));
+        } catch (NoTestsRemainException e) {
+            throw new InitializationError(e);
+        }
+    }
+
+    private static Set<Class<?>> getIncludedCategory(Class<?> klass) {
+        IncludeCategory annotation= klass.getAnnotation(IncludeCategory.class);
+        return createSet(annotation == null ? null : annotation.value());
+    }
+
+    private static boolean isAnyIncluded(Class<?> klass) {
+        IncludeCategory annotation= klass.getAnnotation(IncludeCategory.class);
+        return annotation == null || annotation.matchAny();
+    }
+
+    private static Set<Class<?>> getExcludedCategory(Class<?> klass) {
+        ExcludeCategory annotation= klass.getAnnotation(ExcludeCategory.class);
+        return createSet(annotation == null ? null : annotation.value());
+    }
+
+    private static boolean isAnyExcluded(Class<?> klass) {
+        ExcludeCategory annotation= klass.getAnnotation(ExcludeCategory.class);
+        return annotation == null || annotation.matchAny();
+    }
+
+    private static boolean hasAssignableTo(Set<Class<?>> assigns, Class<?> to) {
+        for (final Class<?> from : assigns) {
+            if (to.isAssignableFrom(from)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static Set<Class<?>> createSet(Class<?>[] classes) {
+        // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.12
+        // for include(boolean, Class<?>...) and exclude(boolean, Class<?>...)
+        if (classes == null || classes.length == 0) {
+            return Collections.emptySet();
+        }
+        for (Class<?> category : classes) {
+            if (category == null) {
+                throw new NullPointerException("has null category");
+            }
+        }
+
+        return classes.length == 1
+            ? Collections.<Class<?>>singleton(classes[0])
+            : new LinkedHashSet<Class<?>>(Arrays.asList(classes));
+    }
+
+    private static Set<Class<?>> nullableClassToSet(Class<?> nullableClass) {
+        // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.11
+        // for CategoryFilter(Class<?> includedCategory, Class<?> excludedCategory)
+        return nullableClass == null
+                ? Collections.<Class<?>>emptySet()
+                : Collections.<Class<?>>singleton(nullableClass);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Category.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Category.java
new file mode 100644
index 0000000..8eae836
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Category.java
@@ -0,0 +1,48 @@
+package org.junit.experimental.categories;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import org.junit.validator.ValidateWith;
+
+/**
+ * Marks a test class or test method as belonging to one or more categories of tests.
+ * The value is an array of arbitrary classes.
+ *
+ * This annotation is only interpreted by the Categories runner (at present).
+ *
+ * For example:
+ * <pre>
+ * public interface FastTests {}
+ * public interface SlowTests {}
+ *
+ * public static class A {
+ * &#064;Test
+ * public void a() {
+ * fail();
+ * }
+ *
+ * &#064;Category(SlowTests.class)
+ * &#064;Test
+ * public void b() {
+ * }
+ * }
+ *
+ * &#064;Category({SlowTests.class, FastTests.class})
+ * public static class B {
+ * &#064;Test
+ * public void c() {
+ *
+ * }
+ * }
+ * </pre>
+ *
+ * For more usage, see code example on {@link Categories}.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@ValidateWith(CategoryValidator.class)
+public @interface Category {
+    Class<?>[] value();
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryFilterFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryFilterFactory.java
new file mode 100644
index 0000000..405feeb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryFilterFactory.java
@@ -0,0 +1,51 @@
+package org.junit.experimental.categories;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.internal.Classes;
+import org.junit.runner.FilterFactory;
+import org.junit.runner.FilterFactoryParams;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Implementation of FilterFactory for Category filtering.
+ */
+abstract class CategoryFilterFactory implements FilterFactory {
+    /**
+     * Creates a {@link org.junit.experimental.categories.Categories.CategoryFilter} given a
+     * {@link FilterFactoryParams} argument.
+     *
+     * @param params Parameters needed to create the {@link Filter}
+     */
+    public Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException {
+        try {
+            return createFilter(parseCategories(params.getArgs()));
+        } catch (ClassNotFoundException e) {
+            throw new FilterNotCreatedException(e);
+        }
+    }
+
+    /**
+     * Creates a {@link org.junit.experimental.categories.Categories.CategoryFilter} given an array of classes.
+     *
+     * @param categories Category classes.
+     */
+    protected abstract Filter createFilter(List<Class<?>> categories);
+
+    private List<Class<?>> parseCategories(String categories) throws ClassNotFoundException {
+        List<Class<?>> categoryClasses = new ArrayList<Class<?>>();
+
+        for (String category : categories.split(",")) {
+            /*
+             * Load the category class using the context class loader.
+             * If there is no context class loader, use the class loader for this class.
+             */
+            Class<?> categoryClass = Classes.getClass(category, getClass());
+
+            categoryClasses.add(categoryClass);
+        }
+
+        return categoryClasses;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryValidator.java
new file mode 100644
index 0000000..491d8ac
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryValidator.java
@@ -0,0 +1,62 @@
+package org.junit.experimental.categories;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableSet;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.validator.AnnotationValidator;
+
+/**
+ * Validates that there are no errors in the use of the {@code Category}
+ * annotation. If there is, a {@code Throwable} object will be added to the list
+ * of errors.
+ *
+ * @since 4.12
+ */
+public final class CategoryValidator extends AnnotationValidator {
+
+    @SuppressWarnings("unchecked")
+    private static final Set<Class<? extends Annotation>> INCOMPATIBLE_ANNOTATIONS = unmodifiableSet(new HashSet<Class<? extends Annotation>>(
+            asList(BeforeClass.class, AfterClass.class, Before.class, After.class)));
+
+    /**
+     * Adds to {@code errors} a throwable for each problem detected. Looks for
+     * {@code BeforeClass}, {@code AfterClass}, {@code Before} and {@code After}
+     * annotations.
+     *
+     * @param method the method that is being validated
+     * @return A list of exceptions detected
+     *
+     * @since 4.12
+     */
+    @Override
+    public List<Exception> validateAnnotatedMethod(FrameworkMethod method) {
+        List<Exception> errors = new ArrayList<Exception>();
+        Annotation[] annotations = method.getAnnotations();
+        for (Annotation annotation : annotations) {
+            for (Class<?> clazz : INCOMPATIBLE_ANNOTATIONS) {
+                if (annotation.annotationType().isAssignableFrom(clazz)) {
+                    addErrorMessage(errors, clazz);
+                }
+            }
+        }
+        return unmodifiableList(errors);
+    }
+
+    private void addErrorMessage(List<Exception> errors, Class<?> clazz) {
+        String message = String.format("@%s can not be combined with @Category",
+                clazz.getSimpleName());
+        errors.add(new Exception(message));
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/ExcludeCategories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/ExcludeCategories.java
new file mode 100644
index 0000000..5117eef
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/ExcludeCategories.java
@@ -0,0 +1,52 @@
+package org.junit.experimental.categories;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.experimental.categories.Categories.CategoryFilter;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * {@link org.junit.runner.FilterFactory} to exclude categories.
+ *
+ * The {@link Filter} that is created will filter out tests that are categorized with any of the
+ * given categories.
+ *
+ * Usage from command line:
+ * <code>
+ *     --filter=org.junit.experimental.categories.ExcludeCategories=pkg.of.Cat1,pkg.of.Cat2
+ * </code>
+ *
+ * Usage from API:
+ * <code>
+ *     new ExcludeCategories().createFilter(Cat1.class, Cat2.class);
+ * </code>
+ */
+public final class ExcludeCategories extends CategoryFilterFactory {
+    /**
+     * Creates a {@link Filter} which is only passed by tests that are
+     * not categorized with any of the specified categories.
+     *
+     * @param categories Category classes.
+     */
+    @Override
+    protected Filter createFilter(List<Class<?>> categories) {
+        return new ExcludesAny(categories);
+    }
+
+    private static class ExcludesAny extends CategoryFilter {
+        public ExcludesAny(List<Class<?>> categories) {
+            this(new HashSet<Class<?>>(categories));
+        }
+
+        public ExcludesAny(Set<Class<?>> categories) {
+            super(true, null, true, categories);
+        }
+
+        @Override
+        public String describe() {
+            return "excludes " + super.describe();
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/IncludeCategories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/IncludeCategories.java
new file mode 100644
index 0000000..b7f7507
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/IncludeCategories.java
@@ -0,0 +1,52 @@
+package org.junit.experimental.categories;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.experimental.categories.Categories.CategoryFilter;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * {@link org.junit.runner.FilterFactory} to include categories.
+ *
+ * The {@link Filter} that is created will filter out tests that are categorized with any of the
+ * given categories.
+ *
+ * Usage from command line:
+ * <code>
+ *     --filter=org.junit.experimental.categories.IncludeCategories=pkg.of.Cat1,pkg.of.Cat2
+ * </code>
+ *
+ * Usage from API:
+ * <code>
+ *     new IncludeCategories().createFilter(Cat1.class, Cat2.class);
+ * </code>
+ */
+public final class IncludeCategories extends CategoryFilterFactory {
+    /**
+     * Creates a {@link Filter} which is only passed by tests that are
+     * categorized with any of the specified categories.
+     *
+     * @param categories Category classes.
+     */
+    @Override
+    protected Filter createFilter(List<Class<?>> categories) {
+        return new IncludesAny(categories);
+    }
+
+    private static class IncludesAny extends CategoryFilter {
+        public IncludesAny(List<Class<?>> categories) {
+            this(new HashSet<Class<?>>(categories));
+        }
+
+        public IncludesAny(Set<Class<?>> categories) {
+            super(true, categories, true, null);
+        }
+
+        @Override
+        public String describe() {
+            return "includes " + super.describe();
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/CouldNotReadCoreException.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/CouldNotReadCoreException.java
new file mode 100644
index 0000000..116d755
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/CouldNotReadCoreException.java
@@ -0,0 +1,15 @@
+package org.junit.experimental.max;
+
+/**
+ * Thrown when Max cannot read the MaxCore serialization
+ */
+public class CouldNotReadCoreException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs
+     */
+    public CouldNotReadCoreException(Throwable e) {
+        super(e);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxCore.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxCore.java
new file mode 100644
index 0000000..625cade
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxCore.java
@@ -0,0 +1,181 @@
+package org.junit.experimental.max;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.TestSuite;
+import org.junit.internal.requests.SortingRequest;
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * A replacement for JUnitCore, which keeps track of runtime and failure history, and reorders tests
+ * to maximize the chances that a failing test occurs early in the test run.
+ *
+ * The rules for sorting are:
+ * <ol>
+ * <li> Never-run tests first, in arbitrary order
+ * <li> Group remaining tests by the date at which they most recently failed.
+ * <li> Sort groups such that the most recent failure date is first, and never-failing tests are at the end.
+ * <li> Within a group, run the fastest tests first.
+ * </ol>
+ */
+public class MaxCore {
+    private static final String MALFORMED_JUNIT_3_TEST_CLASS_PREFIX = "malformed JUnit 3 test class: ";
+
+    /**
+     * Create a new MaxCore from a serialized file stored at storedResults
+     *
+     * @deprecated use storedLocally()
+     */
+    @Deprecated
+    public static MaxCore forFolder(String folderName) {
+        return storedLocally(new File(folderName));
+    }
+
+    /**
+     * Create a new MaxCore from a serialized file stored at storedResults
+     */
+    public static MaxCore storedLocally(File storedResults) {
+        return new MaxCore(storedResults);
+    }
+
+    private final MaxHistory history;
+
+    private MaxCore(File storedResults) {
+        history = MaxHistory.forFolder(storedResults);
+    }
+
+    /**
+     * Run all the tests in <code>class</code>.
+     *
+     * @return a {@link Result} describing the details of the test run and the failed tests.
+     */
+    public Result run(Class<?> testClass) {
+        return run(Request.aClass(testClass));
+    }
+
+    /**
+     * Run all the tests contained in <code>request</code>.
+     *
+     * @param request the request describing tests
+     * @return a {@link Result} describing the details of the test run and the failed tests.
+     */
+    public Result run(Request request) {
+        return run(request, new JUnitCore());
+    }
+
+    /**
+     * Run all the tests contained in <code>request</code>.
+     *
+     * This variant should be used if {@code core} has attached listeners that this
+     * run should notify.
+     *
+     * @param request the request describing tests
+     * @param core a JUnitCore to delegate to.
+     * @return a {@link Result} describing the details of the test run and the failed tests.
+     */
+    public Result run(Request request, JUnitCore core) {
+        core.addListener(history.listener());
+        return core.run(sortRequest(request).getRunner());
+    }
+
+    /**
+     * @return a new Request, which contains all of the same tests, but in a new order.
+     */
+    public Request sortRequest(Request request) {
+        if (request instanceof SortingRequest) {
+            // We'll pay big karma points for this
+            return request;
+        }
+        List<Description> leaves = findLeaves(request);
+        Collections.sort(leaves, history.testComparator());
+        return constructLeafRequest(leaves);
+    }
+
+    private Request constructLeafRequest(List<Description> leaves) {
+        final List<Runner> runners = new ArrayList<Runner>();
+        for (Description each : leaves) {
+            runners.add(buildRunner(each));
+        }
+        return new Request() {
+            @Override
+            public Runner getRunner() {
+                try {
+                    return new Suite((Class<?>) null, runners) {
+                    };
+                } catch (InitializationError e) {
+                    return new ErrorReportingRunner(null, e);
+                }
+            }
+        };
+    }
+
+    private Runner buildRunner(Description each) {
+        if (each.toString().equals("TestSuite with 0 tests")) {
+            return Suite.emptySuite();
+        }
+        if (each.toString().startsWith(MALFORMED_JUNIT_3_TEST_CLASS_PREFIX)) {
+            // This is cheating, because it runs the whole class
+            // to get the warning for this method, but we can't do better,
+            // because JUnit 3.8's
+            // thrown away which method the warning is for.
+            return new JUnit38ClassRunner(new TestSuite(getMalformedTestClass(each)));
+        }
+        Class<?> type = each.getTestClass();
+        if (type == null) {
+            throw new RuntimeException("Can't build a runner from description [" + each + "]");
+        }
+        String methodName = each.getMethodName();
+        if (methodName == null) {
+            return Request.aClass(type).getRunner();
+        }
+        return Request.method(type, methodName).getRunner();
+    }
+
+    private Class<?> getMalformedTestClass(Description each) {
+        try {
+            return Class.forName(each.toString().replace(MALFORMED_JUNIT_3_TEST_CLASS_PREFIX, ""));
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * @param request a request to run
+     * @return a list of method-level tests to run, sorted in the order
+     *         specified in the class comment.
+     */
+    public List<Description> sortedLeavesForTest(Request request) {
+        return findLeaves(sortRequest(request));
+    }
+
+    private List<Description> findLeaves(Request request) {
+        List<Description> results = new ArrayList<Description>();
+        findLeaves(null, request.getRunner().getDescription(), results);
+        return results;
+    }
+
+    private void findLeaves(Description parent, Description description, List<Description> results) {
+        if (description.getChildren().isEmpty()) {
+            if (description.toString().equals("warning(junit.framework.TestSuite$1)")) {
+                results.add(Description.createSuiteDescription(MALFORMED_JUNIT_3_TEST_CLASS_PREFIX + parent));
+            } else {
+                results.add(description);
+            }
+        } else {
+            for (Description each : description.getChildren()) {
+                findLeaves(description, each, results);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxHistory.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxHistory.java
new file mode 100644
index 0000000..ab7443f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxHistory.java
@@ -0,0 +1,178 @@
+package org.junit.experimental.max;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * Stores a subset of the history of each test:
+ * <ul>
+ * <li>Last failure timestamp
+ * <li>Duration of last execution
+ * </ul>
+ */
+public class MaxHistory implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Loads a {@link MaxHistory} from {@code file}, or generates a new one that
+     * will be saved to {@code file}.
+     */
+    public static MaxHistory forFolder(File file) {
+        if (file.exists()) {
+            try {
+                return readHistory(file);
+            } catch (CouldNotReadCoreException e) {
+                e.printStackTrace();
+                file.delete();
+            }
+        }
+        return new MaxHistory(file);
+    }
+
+    private static MaxHistory readHistory(File storedResults)
+            throws CouldNotReadCoreException {
+        try {
+            FileInputStream file = new FileInputStream(storedResults);
+            try {
+                ObjectInputStream stream = new ObjectInputStream(file);
+                try {
+                    return (MaxHistory) stream.readObject();
+                } finally {
+                    stream.close();
+                }
+            } finally {
+                file.close();
+            }
+        } catch (Exception e) {
+            throw new CouldNotReadCoreException(e);
+        }
+    }
+
+    /*
+     * We have to use the f prefix until the next major release to ensure
+     * serialization compatibility. 
+     * See https://github.com/junit-team/junit4/issues/976
+     */
+    private final Map<String, Long> fDurations = new HashMap<String, Long>();
+    private final Map<String, Long> fFailureTimestamps = new HashMap<String, Long>();
+    private final File fHistoryStore;
+
+    private MaxHistory(File storedResults) {
+        fHistoryStore = storedResults;
+    }
+
+    private void save() throws IOException {
+        ObjectOutputStream stream = null;
+        try {
+            stream = new ObjectOutputStream(new FileOutputStream(fHistoryStore));
+            stream.writeObject(this);
+        } finally {
+            if (stream != null) {
+                stream.close();
+            }
+        }
+    }
+
+    Long getFailureTimestamp(Description key) {
+        return fFailureTimestamps.get(key.toString());
+    }
+
+    void putTestFailureTimestamp(Description key, long end) {
+        fFailureTimestamps.put(key.toString(), end);
+    }
+
+    boolean isNewTest(Description key) {
+        return !fDurations.containsKey(key.toString());
+    }
+
+    Long getTestDuration(Description key) {
+        return fDurations.get(key.toString());
+    }
+
+    void putTestDuration(Description description, long duration) {
+        fDurations.put(description.toString(), duration);
+    }
+
+    private final class RememberingListener extends RunListener {
+        private long overallStart = System.currentTimeMillis();
+
+        private Map<Description, Long> starts = new HashMap<Description, Long>();
+
+        @Override
+        public void testStarted(Description description) throws Exception {
+            starts.put(description, System.nanoTime()); // Get most accurate
+            // possible time
+        }
+
+        @Override
+        public void testFinished(Description description) throws Exception {
+            long end = System.nanoTime();
+            long start = starts.get(description);
+            putTestDuration(description, end - start);
+        }
+
+        @Override
+        public void testFailure(Failure failure) throws Exception {
+            putTestFailureTimestamp(failure.getDescription(), overallStart);
+        }
+
+        @Override
+        public void testRunFinished(Result result) throws Exception {
+            save();
+        }
+    }
+
+    private class TestComparator implements Comparator<Description> {
+        public int compare(Description o1, Description o2) {
+            // Always prefer new tests
+            if (isNewTest(o1)) {
+                return -1;
+            }
+            if (isNewTest(o2)) {
+                return 1;
+            }
+            // Then most recently failed first
+            int result = getFailure(o2).compareTo(getFailure(o1));
+            return result != 0 ? result
+                    // Then shorter tests first
+                    : getTestDuration(o1).compareTo(getTestDuration(o2));
+        }
+
+        private Long getFailure(Description key) {
+            Long result = getFailureTimestamp(key);
+            if (result == null) {
+                return 0L; // 0 = "never failed (that I know about)"
+            }
+            return result;
+        }
+    }
+
+    /**
+     * @return a listener that will update this history based on the test
+     *         results reported.
+     */
+    public RunListener listener() {
+        return new RememberingListener();
+    }
+
+    /**
+     * @return a comparator that ranks tests based on the JUnit Max sorting
+     *         rules, as described in the {@link MaxCore} class comment.
+     */
+    public Comparator<Description> testComparator() {
+        return new TestComparator();
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/FailureList.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/FailureList.java
new file mode 100644
index 0000000..e02eeae
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/FailureList.java
@@ -0,0 +1,28 @@
+package org.junit.experimental.results;
+
+import java.util.List;
+
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+class FailureList {
+    private final List<Failure> failures;
+
+    public FailureList(List<Failure> failures) {
+        this.failures = failures;
+    }
+
+    public Result result() {
+        Result result = new Result();
+        RunListener listener = result.createListener();
+        for (Failure failure : failures) {
+            try {
+                listener.testFailure(failure);
+            } catch (Exception e) {
+                throw new RuntimeException("I can't believe this happened");
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/PrintableResult.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/PrintableResult.java
new file mode 100644
index 0000000..0f67766
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/PrintableResult.java
@@ -0,0 +1,72 @@
+package org.junit.experimental.results;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+/**
+ * A test result that prints nicely in error messages.
+ * This is only intended to be used in JUnit self-tests.
+ * For example:
+ *
+ * <pre>
+ *    assertThat(testResult(HasExpectedException.class), isSuccessful());
+ * </pre>
+ */
+public class PrintableResult {
+    private Result result;
+
+    /**
+     * The result of running JUnit on {@code type}
+     */
+    public static PrintableResult testResult(Class<?> type) {
+        return testResult(Request.aClass(type));
+    }
+
+    /**
+     * The result of running JUnit on Request {@code request}
+     */
+    public static PrintableResult testResult(Request request) {
+        return new PrintableResult(new JUnitCore().run(request));
+    }
+
+    /**
+     * A result that includes the given {@code failures}
+     */
+    public PrintableResult(List<Failure> failures) {
+        this(new FailureList(failures).result());
+    }
+
+    private PrintableResult(Result result) {
+        this.result = result;
+    }
+
+    /**
+     * Returns the number of failures in this result.
+     */
+    public int failureCount() {
+        return result.getFailures().size();
+    }
+
+    /**
+     * Returns the failures in this result.
+     *
+     * @since 4.13
+     */
+    public List<Failure> failures() {
+        return result.getFailures();
+    }
+
+    @Override
+    public String toString() {
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        new TextListener(new PrintStream(stream)).testRunFinished(result);
+        return stream.toString();
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/ResultMatchers.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/ResultMatchers.java
new file mode 100644
index 0000000..92f2e6b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/ResultMatchers.java
@@ -0,0 +1,99 @@
+package org.junit.experimental.results;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matchers on a PrintableResult, to enable JUnit self-tests.
+ * For example:
+ *
+ * <pre>
+ * assertThat(testResult(HasExpectedException.class), isSuccessful());
+ * </pre>
+ */
+public class ResultMatchers {
+
+    /**
+     * Do not instantiate.
+     * @deprecated will be private soon.
+     */
+    @Deprecated
+    public ResultMatchers() {
+    }
+
+    /**
+     * Matches if the tests are all successful
+     */
+    public static Matcher<PrintableResult> isSuccessful() {
+        return failureCountIs(0);
+    }
+
+    /**
+     * Matches if there are {@code count} failures
+     */
+    public static Matcher<PrintableResult> failureCountIs(final int count) {
+        return new TypeSafeMatcher<PrintableResult>() {
+            public void describeTo(Description description) {
+                description.appendText("has " + count + " failures");
+            }
+
+            @Override
+            public boolean matchesSafely(PrintableResult item) {
+                return item.failureCount() == count;
+            }
+        };
+    }
+
+    /**
+     * Matches if the result has exactly one failure, and it contains {@code string}
+     */
+    public static Matcher<Object> hasSingleFailureContaining(final String string) {
+        return new BaseMatcher<Object>() {
+            public boolean matches(Object item) {
+                return item.toString().contains(string) && failureCountIs(1).matches(item);
+            }
+
+            public void describeTo(Description description) {
+                description.appendText("has single failure containing " + string);
+            }
+        };
+    }
+
+    /**
+     * Matches if the result has exactly one failure matching the given matcher.
+     *
+     * @since 4.13
+     */
+    public static Matcher<PrintableResult> hasSingleFailureMatching(final Matcher<Throwable> matcher) {
+        return new TypeSafeMatcher<PrintableResult>() {
+            @Override
+            public boolean matchesSafely(PrintableResult item) {
+                return item.failureCount() == 1 && matcher.matches(item.failures().get(0).getException());
+            }
+
+            public void describeTo(Description description) {
+                description.appendText("has failure with exception matching ");
+                matcher.describeTo(description);
+            }
+        };
+    }
+
+    /**
+     * Matches if the result has one or more failures, and at least one of them
+     * contains {@code string}
+     */
+    public static Matcher<PrintableResult> hasFailureContaining(final String string) {
+        return new TypeSafeMatcher<PrintableResult>() {
+            @Override
+            public boolean matchesSafely(PrintableResult item) {
+                return item.failureCount() > 0 && item.toString().contains(string);
+            }
+
+            public void describeTo(Description description) {
+                description.appendText("has failure containing " + string);
+            }
+        };
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/runners/Enclosed.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/runners/Enclosed.java
new file mode 100644
index 0000000..610b970
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/runners/Enclosed.java
@@ -0,0 +1,45 @@
+package org.junit.experimental.runners;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runners.Suite;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * If you put tests in inner classes, Ant, for example, won't find them. By running the outer class
+ * with Enclosed, the tests in the inner classes will be run. You might put tests in inner classes
+ * to group them for convenience or to share constants. Abstract inner classes are ignored.
+ * <p>
+ * So, for example:
+ * <pre>
+ * &#064;RunWith(Enclosed.class)
+ * public class ListTests {
+ *     ...useful shared stuff...
+ *     public static class OneKindOfListTest {...}
+ *     public static class AnotherKind {...}
+ *     abstract public static class Ignored {...}
+ * }
+ * </pre>
+ */
+public class Enclosed extends Suite {
+    /**
+     * Only called reflectively. Do not use programmatically.
+     */
+    public Enclosed(Class<?> klass, RunnerBuilder builder) throws Throwable {
+        super(builder, klass, filterAbstractClasses(klass.getClasses()));
+    }
+    
+    private static Class<?>[] filterAbstractClasses(final Class<?>[] classes) {     
+        final List<Class<?>> filteredList= new ArrayList<Class<?>>(classes.length);
+
+        for (final Class<?> clazz : classes) {
+            if (!Modifier.isAbstract(clazz.getModifiers())) {
+                filteredList.add(clazz);
+            }
+        }
+        
+        return filteredList.toArray(new Class<?>[filteredList.size()]);
+    }   
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoint.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoint.java
new file mode 100644
index 0000000..0a017bb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoint.java
@@ -0,0 +1,56 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotating an field or method with &#064;DataPoint will cause the field value
+ * or the value returned by the method to be used as a potential parameter for
+ * theories in that class, when run with the
+ * {@link org.junit.experimental.theories.Theories Theories} runner.
+ * <p>
+ * A DataPoint is only considered as a potential value for parameters for
+ * which its type is assignable. When multiple {@code DataPoint}s exist 
+ * with overlapping types more control can be obtained by naming each DataPoint 
+ * using the value of this annotation, e.g. with
+ * <code>&#064;DataPoint({"dataset1", "dataset2"})</code>, and then specifying
+ * which named set to consider as potential values for each parameter using the
+ * {@link org.junit.experimental.theories.FromDataPoints &#064;FromDataPoints}
+ * annotation.
+ * <p>
+ * Parameters with no specified source (i.e. without &#064;FromDataPoints or
+ * other {@link org.junit.experimental.theories.ParametersSuppliedBy
+ * &#064;ParameterSuppliedBy} annotations) will use all {@code DataPoint}s that are
+ * assignable to the parameter type as potential values, including named sets of
+ * {@code DataPoint}s.
+ * 
+ * <pre>
+ * &#064;DataPoint
+ * public static String dataPoint = "value";
+ * 
+ * &#064;DataPoint("generated")
+ * public static String generatedDataPoint() {
+ *     return "generated value";
+ * }
+ * 
+ * &#064;Theory
+ * public void theoryMethod(String param) {
+ *     ...
+ * }
+ * </pre>
+ * 
+ * @see org.junit.experimental.theories.Theories
+ * @see org.junit.experimental.theories.Theory
+ * @see org.junit.experimental.theories.DataPoint
+ * @see org.junit.experimental.theories.FromDataPoints
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({FIELD, METHOD})
+public @interface DataPoint {
+    String[] value() default {};
+    Class<? extends Throwable>[] ignoredExceptions() default {};
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoints.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoints.java
new file mode 100644
index 0000000..b47461b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoints.java
@@ -0,0 +1,64 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotating an array or iterable-typed field or method with &#064;DataPoints
+ * will cause the values in the array or iterable given to be used as potential
+ * parameters for theories in that class when run with the
+ * {@link org.junit.experimental.theories.Theories Theories} runner.
+ * <p>
+ * DataPoints will only be considered as potential values for parameters for
+ * which their types are assignable. When multiple sets of DataPoints exist with
+ * overlapping types more control can be obtained by naming the DataPoints using
+ * the value of this annotation, e.g. with
+ * <code>&#064;DataPoints({"dataset1", "dataset2"})</code>, and then specifying
+ * which named set to consider as potential values for each parameter using the
+ * {@link org.junit.experimental.theories.FromDataPoints &#064;FromDataPoints}
+ * annotation.
+ * <p>
+ * Parameters with no specified source (i.e. without &#064;FromDataPoints or
+ * other {@link org.junit.experimental.theories.ParametersSuppliedBy
+ * &#064;ParameterSuppliedBy} annotations) will use all DataPoints that are
+ * assignable to the parameter type as potential values, including named sets of
+ * DataPoints.
+ * <p>
+ * DataPoints methods whose array types aren't assignable from the target
+ * parameter type (and so can't possibly return relevant values) will not be
+ * called when generating values for that parameter. Iterable-typed datapoints
+ * methods must always be called though, as this information is not available
+ * here after generic type erasure, so expensive methods returning iterable
+ * datapoints are a bad idea.
+ * 
+ * <pre>
+ * &#064;DataPoints
+ * public static String[] dataPoints = new String[] { ... };
+ * 
+ * &#064;DataPoints
+ * public static String[] generatedDataPoints() {
+ *     return new String[] { ... };
+ * }
+ * 
+ * &#064;Theory
+ * public void theoryMethod(String param) {
+ *     ...
+ * }
+ * </pre>
+ * 
+ * @see org.junit.experimental.theories.Theories
+ * @see org.junit.experimental.theories.Theory
+ * @see org.junit.experimental.theories.DataPoint
+ * @see org.junit.experimental.theories.FromDataPoints
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ FIELD, METHOD })
+public @interface DataPoints {
+    String[] value() default {};
+
+    Class<? extends Throwable>[] ignoredExceptions() default {};
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/FromDataPoints.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/FromDataPoints.java
new file mode 100644
index 0000000..2b149ca
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/FromDataPoints.java
@@ -0,0 +1,54 @@
+package org.junit.experimental.theories;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.experimental.theories.internal.SpecificDataPointsSupplier;
+
+/**
+ * Annotating a parameter of a {@link org.junit.experimental.theories.Theory
+ * &#064;Theory} method with <code>&#064;FromDataPoints</code> will limit the
+ * datapoints considered as potential values for that parameter to just the
+ * {@link org.junit.experimental.theories.DataPoints DataPoints} with the given
+ * name. DataPoint names can be given as the value parameter of the
+ * &#064;DataPoints annotation.
+ * <p>
+ * DataPoints without names will not be considered as values for any parameters
+ * annotated with &#064;FromDataPoints.
+ * <pre>
+ * &#064;DataPoints
+ * public static String[] unnamed = new String[] { ... };
+ * 
+ * &#064;DataPoints("regexes")
+ * public static String[] regexStrings = new String[] { ... };
+ * 
+ * &#064;DataPoints({"forMatching", "alphanumeric"})
+ * public static String[] testStrings = new String[] { ... }; 
+ * 
+ * &#064;Theory
+ * public void stringTheory(String param) {
+ *     // This will be called with every value in 'regexStrings',
+ *     // 'testStrings' and 'unnamed'.
+ * }
+ * 
+ * &#064;Theory
+ * public void regexTheory(&#064;FromDataPoints("regexes") String regex,
+ *                         &#064;FromDataPoints("forMatching") String value) {
+ *     // This will be called with only the values in 'regexStrings' as 
+ *     // regex, only the values in 'testStrings' as value, and none 
+ *     // of the values in 'unnamed'.
+ * }
+ * </pre>
+ * 
+ * @see org.junit.experimental.theories.Theory
+ * @see org.junit.experimental.theories.DataPoint
+ * @see org.junit.experimental.theories.DataPoints
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+@ParametersSuppliedBy(SpecificDataPointsSupplier.class)
+public @interface FromDataPoints {
+    String value();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSignature.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSignature.java
new file mode 100644
index 0000000..cf22583
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSignature.java
@@ -0,0 +1,134 @@
+package org.junit.experimental.theories;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ParameterSignature {
+    
+    private static final Map<Class<?>, Class<?>> CONVERTABLE_TYPES_MAP = buildConvertableTypesMap();
+    
+    private static Map<Class<?>, Class<?>> buildConvertableTypesMap() {
+        Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
+
+        putSymmetrically(map, boolean.class, Boolean.class);
+        putSymmetrically(map, byte.class, Byte.class);
+        putSymmetrically(map, short.class, Short.class);
+        putSymmetrically(map, char.class, Character.class);
+        putSymmetrically(map, int.class, Integer.class);
+        putSymmetrically(map, long.class, Long.class);
+        putSymmetrically(map, float.class, Float.class);
+        putSymmetrically(map, double.class, Double.class);
+
+        return Collections.unmodifiableMap(map);
+    }
+    
+    private static <T> void putSymmetrically(Map<T, T> map, T a, T b) {
+        map.put(a, b);
+        map.put(b, a);
+    }
+    
+    public static ArrayList<ParameterSignature> signatures(Method method) {
+        return signatures(method.getParameterTypes(), method
+                .getParameterAnnotations());
+    }
+
+    public static List<ParameterSignature> signatures(Constructor<?> constructor) {
+        return signatures(constructor.getParameterTypes(), constructor
+                .getParameterAnnotations());
+    }
+
+    private static ArrayList<ParameterSignature> signatures(
+            Class<?>[] parameterTypes, Annotation[][] parameterAnnotations) {
+        ArrayList<ParameterSignature> sigs = new ArrayList<ParameterSignature>();
+        for (int i = 0; i < parameterTypes.length; i++) {
+            sigs.add(new ParameterSignature(parameterTypes[i],
+                    parameterAnnotations[i]));
+        }
+        return sigs;
+    }
+
+    private final Class<?> type;
+
+    private final Annotation[] annotations;
+
+    private ParameterSignature(Class<?> type, Annotation[] annotations) {
+        this.type = type;
+        this.annotations = annotations;
+    }
+
+    public boolean canAcceptValue(Object candidate) {
+        return (candidate == null) ? !type.isPrimitive() : canAcceptType(candidate.getClass());
+    }
+
+    public boolean canAcceptType(Class<?> candidate) {
+        return type.isAssignableFrom(candidate) ||
+                isAssignableViaTypeConversion(type, candidate);
+    }
+    
+    public boolean canPotentiallyAcceptType(Class<?> candidate) {
+        return candidate.isAssignableFrom(type) ||
+                isAssignableViaTypeConversion(candidate, type) ||
+                canAcceptType(candidate);
+    }
+
+    private boolean isAssignableViaTypeConversion(Class<?> targetType, Class<?> candidate) {
+        if (CONVERTABLE_TYPES_MAP.containsKey(candidate)) {
+            Class<?> wrapperClass = CONVERTABLE_TYPES_MAP.get(candidate);
+            return targetType.isAssignableFrom(wrapperClass);
+        } else {
+            return false;
+        }
+    }
+
+    public Class<?> getType() {
+        return type;
+    }
+
+    public List<Annotation> getAnnotations() {
+        return Arrays.asList(annotations);
+    }
+
+    public boolean hasAnnotation(Class<? extends Annotation> type) {
+        return getAnnotation(type) != null;
+    }
+
+    public <T extends Annotation> T findDeepAnnotation(Class<T> annotationType) {
+        Annotation[] annotations2 = annotations;
+        return findDeepAnnotation(annotations2, annotationType, 3);
+    }
+
+    private <T extends Annotation> T findDeepAnnotation(
+            Annotation[] annotations, Class<T> annotationType, int depth) {
+        if (depth == 0) {
+            return null;
+        }
+        for (Annotation each : annotations) {
+            if (annotationType.isInstance(each)) {
+                return annotationType.cast(each);
+            }
+            Annotation candidate = findDeepAnnotation(each.annotationType()
+                    .getAnnotations(), annotationType, depth - 1);
+            if (candidate != null) {
+                return annotationType.cast(candidate);
+            }
+        }
+
+        return null;
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+        for (Annotation each : getAnnotations()) {
+            if (annotationType.isInstance(each)) {
+                return annotationType.cast(each);
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSupplier.java
new file mode 100644
index 0000000..bac8b34
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSupplier.java
@@ -0,0 +1,43 @@
+package org.junit.experimental.theories;
+
+import java.util.List;
+
+/**
+ * Abstract parent class for suppliers of input data points for theories. Extend this class to customize how {@link
+ * org.junit.experimental.theories.Theories Theories} runner
+ * finds accepted data points. Then use your class together with <b>&#064;ParametersSuppliedBy</b> on input
+ * parameters for theories.
+ *
+ * <p>
+ * For example, here is a supplier for values between two integers, and an annotation that references it:
+ *
+ * <pre>
+ *     &#064;Retention(RetentionPolicy.RUNTIME)
+ *     <b>&#064;ParametersSuppliedBy</b>(BetweenSupplier.class)
+ *     public @interface Between {
+ *         int first();
+ *
+ *         int last();
+ *     }
+ *
+ *     public static class BetweenSupplier extends <b>ParameterSupplier</b> {
+ *         &#064;Override
+ *         public List&lt;<b>PotentialAssignment</b>&gt; getValueSources(<b>ParameterSignature</b> sig) {
+ *             List&lt;<b>PotentialAssignment</b>&gt; list = new ArrayList&lt;PotentialAssignment&gt;();
+ *             Between annotation = (Between) sig.getSupplierAnnotation();
+ *
+ *             for (int i = annotation.first(); i &lt;= annotation.last(); i++)
+ *                 list.add(<b>PotentialAssignment</b>.forValue("ints", i));
+ *             return list;
+ *         }
+ *     }
+ * </pre>
+ * </p>
+ *
+ * @see org.junit.experimental.theories.ParametersSuppliedBy
+ * @see org.junit.experimental.theories.Theories
+ * @see org.junit.experimental.theories.FromDataPoints
+ */
+public abstract class ParameterSupplier {
+    public abstract List<PotentialAssignment> getValueSources(ParameterSignature sig) throws Throwable;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java
new file mode 100644
index 0000000..846a39e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java
@@ -0,0 +1,48 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotating a {@link org.junit.experimental.theories.Theory Theory} method
+ * parameter with &#064;ParametersSuppliedBy causes it to be supplied with
+ * values from the named
+ * {@link org.junit.experimental.theories.ParameterSupplier ParameterSupplier}
+ * when run as a theory by the {@link org.junit.experimental.theories.Theories
+ * Theories} runner.
+ * 
+ * In addition, annotations themselves can be annotated with
+ * &#064;ParametersSuppliedBy, and then used similarly. ParameterSuppliedBy
+ * annotations on parameters are detected by searching up this hierarchy such
+ * that these act as syntactic sugar, making:
+ * 
+ * <pre>
+ * &#064;ParametersSuppliedBy(Supplier.class)
+ * public &#064;interface SpecialParameter { }
+ * 
+ * &#064;Theory
+ * public void theoryMethod(&#064;SpecialParameter String param) {
+ *   ...
+ * }
+ * </pre>
+ * 
+ * equivalent to:
+ * 
+ * <pre>
+ * &#064;Theory
+ * public void theoryMethod(&#064;ParametersSuppliedBy(Supplier.class) String param) {
+ *   ...
+ * }
+ * </pre>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ANNOTATION_TYPE, PARAMETER })
+public @interface ParametersSuppliedBy {
+
+    Class<? extends ParameterSupplier> value();
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/PotentialAssignment.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/PotentialAssignment.java
new file mode 100644
index 0000000..18ca07a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/PotentialAssignment.java
@@ -0,0 +1,52 @@
+package org.junit.experimental.theories;
+
+import static java.lang.String.format;
+
+public abstract class PotentialAssignment {
+    public static class CouldNotGenerateValueException extends Exception {
+        private static final long serialVersionUID = 1L;
+        
+        public CouldNotGenerateValueException() {
+        }
+        
+        public CouldNotGenerateValueException(Throwable e) {
+            super(e);
+        }
+    }
+
+    public static PotentialAssignment forValue(final String name, final Object value) {
+        return new PotentialAssignment() {
+            @Override
+            public Object getValue() {
+                return value;
+            }
+
+            @Override
+            public String toString() {
+                return format("[%s]", value);
+            }
+
+            @Override
+            public String getDescription() {
+                String valueString;
+
+                if (value == null) {
+                    valueString = "null";
+                } else {
+                    try {
+                        valueString = format("\"%s\"", value);
+                    } catch (Throwable e) {
+                        valueString = format("[toString() threw %s: %s]", 
+                                             e.getClass().getSimpleName(), e.getMessage());
+                    }
+                }
+
+                return format("%s <from %s>", valueString, name);
+            }
+        };
+    }
+
+    public abstract Object getValue() throws CouldNotGenerateValueException;
+
+    public abstract String getDescription() throws CouldNotGenerateValueException;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theories.java
new file mode 100644
index 0000000..ac88a36
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theories.java
@@ -0,0 +1,310 @@
+package org.junit.experimental.theories;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.experimental.theories.internal.Assignments;
+import org.junit.experimental.theories.internal.ParameterizedAssertionError;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+/**
+ * The Theories runner allows to test a certain functionality against a subset of an infinite set of data points.
+ * <p>
+ * A Theory is a piece of functionality (a method) that is executed against several data inputs called data points.
+ * To make a test method a theory you mark it with <b>&#064;Theory</b>. To create a data point you create a public
+ * field in your test class and mark it with <b>&#064;DataPoint</b>. The Theories runner then executes your test
+ * method as many times as the number of data points declared, providing a different data point as
+ * the input argument on each invocation.
+ * </p>
+ * <p>
+ * A Theory differs from standard test method in that it captures some aspect of the intended behavior in possibly
+ * infinite numbers of scenarios which corresponds to the number of data points declared. Using assumptions and
+ * assertions properly together with covering multiple scenarios with different data points can make your tests more
+ * flexible and bring them closer to scientific theories (hence the name).
+ * </p>
+ * <p>
+ * For example:
+ * <pre>
+ *
+ * &#064;RunWith(<b>Theories.class</b>)
+ * public class UserTest {
+ *      <b>&#064;DataPoint</b>
+ *      public static String GOOD_USERNAME = "optimus";
+ *      <b>&#064;DataPoint</b>
+ *      public static String USERNAME_WITH_SLASH = "optimus/prime";
+ *
+ *      <b>&#064;Theory</b>
+ *      public void filenameIncludesUsername(String username) {
+ *          assumeThat(username, not(containsString("/")));
+ *          assertThat(new User(username).configFileName(), containsString(username));
+ *      }
+ * }
+ * </pre>
+ * This makes it clear that the username should be included in the config file name,
+ * only if it doesn't contain a slash. Another test or theory might define what happens when a username does contain
+ * a slash. <code>UserTest</code> will attempt to run <code>filenameIncludesUsername</code> on every compatible data
+ * point defined in the class. If any of the assumptions fail, the data point is silently ignored. If all of the
+ * assumptions pass, but an assertion fails, the test fails. If no parameters can be found that satisfy all assumptions, the test fails.
+ * <p>
+ * Defining general statements as theories allows data point reuse across a bunch of functionality tests and also
+ * allows automated tools to search for new, unexpected data points that expose bugs.
+ * </p>
+ * <p>
+ * The support for Theories has been absorbed from the Popper project, and more complete documentation can be found
+ * from that projects archived documentation.
+ * </p>
+ *
+ * @see <a href="http://web.archive.org/web/20071012143326/popper.tigris.org/tutorial.html">Archived Popper project documentation</a>
+ * @see <a href="http://web.archive.org/web/20110608210825/http://shareandenjoy.saff.net/tdd-specifications.pdf">Paper on Theories</a>
+ */
+public class Theories extends BlockJUnit4ClassRunner {
+    public Theories(Class<?> klass) throws InitializationError {
+        super(klass);
+    }
+
+    /** @since 4.13 */
+    protected Theories(TestClass testClass) throws InitializationError {
+        super(testClass);
+    }
+
+    @Override
+    protected void collectInitializationErrors(List<Throwable> errors) {
+        super.collectInitializationErrors(errors);
+        validateDataPointFields(errors);
+        validateDataPointMethods(errors);
+    }
+
+    private void validateDataPointFields(List<Throwable> errors) {
+        Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
+
+        for (Field field : fields) {
+            if (field.getAnnotation(DataPoint.class) == null && field.getAnnotation(DataPoints.class) == null) {
+                continue;
+            }
+            if (!Modifier.isStatic(field.getModifiers())) {
+                errors.add(new Error("DataPoint field " + field.getName() + " must be static"));
+            }
+            if (!Modifier.isPublic(field.getModifiers())) {
+                errors.add(new Error("DataPoint field " + field.getName() + " must be public"));
+            }
+        }
+    }
+
+    private void validateDataPointMethods(List<Throwable> errors) {
+        Method[] methods = getTestClass().getJavaClass().getDeclaredMethods();
+        
+        for (Method method : methods) {
+            if (method.getAnnotation(DataPoint.class) == null && method.getAnnotation(DataPoints.class) == null) {
+                continue;
+            }
+            if (!Modifier.isStatic(method.getModifiers())) {
+                errors.add(new Error("DataPoint method " + method.getName() + " must be static"));
+            }
+            if (!Modifier.isPublic(method.getModifiers())) {
+                errors.add(new Error("DataPoint method " + method.getName() + " must be public"));
+            }
+        }
+    }
+
+    @Override
+    protected void validateConstructor(List<Throwable> errors) {
+        validateOnlyOneConstructor(errors);
+    }
+
+    @Override
+    protected void validateTestMethods(List<Throwable> errors) {
+        for (FrameworkMethod each : computeTestMethods()) {
+            if (each.getAnnotation(Theory.class) != null) {
+                each.validatePublicVoid(false, errors);
+                each.validateNoTypeParametersOnArgs(errors);
+            } else {
+                each.validatePublicVoidNoArg(false, errors);
+            }
+            
+            for (ParameterSignature signature : ParameterSignature.signatures(each.getMethod())) {
+                ParametersSuppliedBy annotation = signature.findDeepAnnotation(ParametersSuppliedBy.class);
+                if (annotation != null) {
+                    validateParameterSupplier(annotation.value(), errors);
+                }
+            }
+        }
+    }
+
+    private void validateParameterSupplier(Class<? extends ParameterSupplier> supplierClass, List<Throwable> errors) {
+        Constructor<?>[] constructors = supplierClass.getConstructors();
+        
+        if (constructors.length != 1) {
+            errors.add(new Error("ParameterSupplier " + supplierClass.getName() + 
+                                 " must have only one constructor (either empty or taking only a TestClass)"));
+        } else {
+            Class<?>[] paramTypes = constructors[0].getParameterTypes();
+            if (!(paramTypes.length == 0) && !paramTypes[0].equals(TestClass.class)) {
+                errors.add(new Error("ParameterSupplier " + supplierClass.getName() + 
+                                     " constructor must take either nothing or a single TestClass instance"));
+            }
+        }
+    }
+
+    @Override
+    protected List<FrameworkMethod> computeTestMethods() {
+        List<FrameworkMethod> testMethods = new ArrayList<FrameworkMethod>(super.computeTestMethods());
+        List<FrameworkMethod> theoryMethods = getTestClass().getAnnotatedMethods(Theory.class);
+        testMethods.removeAll(theoryMethods);
+        testMethods.addAll(theoryMethods);
+        return testMethods;
+    }
+
+    @Override
+    public Statement methodBlock(final FrameworkMethod method) {
+        return new TheoryAnchor(method, getTestClass());
+    }
+
+    public static class TheoryAnchor extends Statement {
+        private int successes = 0;
+
+        private final FrameworkMethod testMethod;
+        private final TestClass testClass;
+
+        private List<AssumptionViolatedException> fInvalidParameters = new ArrayList<AssumptionViolatedException>();
+
+        public TheoryAnchor(FrameworkMethod testMethod, TestClass testClass) {
+            this.testMethod = testMethod;
+            this.testClass = testClass;
+        }
+
+        private TestClass getTestClass() {
+            return testClass;
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            runWithAssignment(Assignments.allUnassigned(
+                    testMethod.getMethod(), getTestClass()));
+            
+            //if this test method is not annotated with Theory, then no successes is a valid case
+            boolean hasTheoryAnnotation = testMethod.getAnnotation(Theory.class) != null;
+            if (successes == 0 && hasTheoryAnnotation) {
+                Assert
+                        .fail("Never found parameters that satisfied method assumptions.  Violated assumptions: "
+                                + fInvalidParameters);
+            }
+        }
+
+        protected void runWithAssignment(Assignments parameterAssignment)
+                throws Throwable {
+            if (!parameterAssignment.isComplete()) {
+                runWithIncompleteAssignment(parameterAssignment);
+            } else {
+                runWithCompleteAssignment(parameterAssignment);
+            }
+        }
+
+        protected void runWithIncompleteAssignment(Assignments incomplete)
+                throws Throwable {
+            for (PotentialAssignment source : incomplete
+                    .potentialsForNextUnassigned()) {
+                runWithAssignment(incomplete.assignNext(source));
+            }
+        }
+
+        protected void runWithCompleteAssignment(final Assignments complete)
+                throws Throwable {
+            new BlockJUnit4ClassRunner(getTestClass()) {
+                @Override
+                protected void collectInitializationErrors(
+                        List<Throwable> errors) {
+                    // do nothing
+                }
+
+                @Override
+                public Statement methodBlock(FrameworkMethod method) {
+                    final Statement statement = super.methodBlock(method);
+                    return new Statement() {
+                        @Override
+                        public void evaluate() throws Throwable {
+                            try {
+                                statement.evaluate();
+                                handleDataPointSuccess();
+                            } catch (AssumptionViolatedException e) {
+                                handleAssumptionViolation(e);
+                            } catch (Throwable e) {
+                                reportParameterizedError(e, complete
+                                        .getArgumentStrings(nullsOk()));
+                            }
+                        }
+
+                    };
+                }
+
+                @Override
+                protected Statement methodInvoker(FrameworkMethod method, Object test) {
+                    return methodCompletesWithParameters(method, complete, test);
+                }
+
+                @Override
+                public Object createTest() throws Exception {
+                    Object[] params = complete.getConstructorArguments();
+                    
+                    if (!nullsOk()) {
+                        Assume.assumeNotNull(params);
+                    }
+                    
+                    return getTestClass().getOnlyConstructor().newInstance(params);
+                }
+            }.methodBlock(testMethod).evaluate();
+        }
+
+        private Statement methodCompletesWithParameters(
+                final FrameworkMethod method, final Assignments complete, final Object freshInstance) {
+            return new Statement() {
+                @Override
+                public void evaluate() throws Throwable {
+                    final Object[] values = complete.getMethodArguments();
+                    
+                    if (!nullsOk()) {
+                        Assume.assumeNotNull(values);
+                    }
+                    
+                    method.invokeExplosively(freshInstance, values);
+                }
+            };
+        }
+
+        protected void handleAssumptionViolation(AssumptionViolatedException e) {
+            fInvalidParameters.add(e);
+        }
+
+        protected void reportParameterizedError(Throwable e, Object... params)
+                throws Throwable {
+            if (params.length == 0) {
+                throw e;
+            }
+            throw new ParameterizedAssertionError(e, testMethod.getName(),
+                    params);
+        }
+
+        private boolean nullsOk() {
+            Theory annotation = testMethod.getMethod().getAnnotation(
+                    Theory.class);
+            if (annotation == null) {
+                return false;
+            }
+            return annotation.nullsAccepted();
+        }
+
+        protected void handleDataPointSuccess() {
+            successes++;
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theory.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theory.java
new file mode 100644
index 0000000..0b9f2c4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theory.java
@@ -0,0 +1,18 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks test methods that should be read as theories by the {@link org.junit.experimental.theories.Theories Theories} runner.
+ *
+ * @see org.junit.experimental.theories.Theories
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(METHOD)
+public @interface Theory {
+    boolean nullsAccepted() default true;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java
new file mode 100644
index 0000000..f15fb28
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java
@@ -0,0 +1,204 @@
+package org.junit.experimental.theories.internal;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Assume;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+/**
+ * Supplies Theory parameters based on all public members of the target class.
+ */
+public class AllMembersSupplier extends ParameterSupplier {
+    static class MethodParameterValue extends PotentialAssignment {
+        private final FrameworkMethod method;
+
+        private MethodParameterValue(FrameworkMethod dataPointMethod) {
+            method = dataPointMethod;
+        }
+
+        @Override
+        public Object getValue() throws CouldNotGenerateValueException {
+            try {
+                return method.invokeExplosively(null);
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException(
+                        "unexpected: argument length is checked");
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException(
+                        "unexpected: getMethods returned an inaccessible method");
+            } catch (Throwable throwable) {
+                DataPoint annotation = method.getAnnotation(DataPoint.class);
+                Assume.assumeTrue(annotation == null || !isAssignableToAnyOf(annotation.ignoredExceptions(), throwable));
+                
+                throw new CouldNotGenerateValueException(throwable);
+            }
+        }
+
+        @Override
+        public String getDescription() throws CouldNotGenerateValueException {
+            return method.getName();
+        }
+    }
+    
+    private final TestClass clazz;
+
+    /**
+     * Constructs a new supplier for {@code type}
+     */
+    public AllMembersSupplier(TestClass type) {
+        clazz = type;
+    }
+
+    @Override
+    public List<PotentialAssignment> getValueSources(ParameterSignature sig) throws Throwable {
+        List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
+
+        addSinglePointFields(sig, list);
+        addMultiPointFields(sig, list);
+        addSinglePointMethods(sig, list);
+        addMultiPointMethods(sig, list);
+
+        return list;
+    }
+
+    private void addMultiPointMethods(ParameterSignature sig, List<PotentialAssignment> list) throws Throwable {
+        for (FrameworkMethod dataPointsMethod : getDataPointsMethods(sig)) {
+            Class<?> returnType = dataPointsMethod.getReturnType();
+            
+            if ((returnType.isArray() && sig.canPotentiallyAcceptType(returnType.getComponentType())) ||
+                    Iterable.class.isAssignableFrom(returnType)) {
+                try {
+                    addDataPointsValues(returnType, sig, dataPointsMethod.getName(), list, 
+                            dataPointsMethod.invokeExplosively(null));
+                } catch (Throwable throwable) {
+                    DataPoints annotation = dataPointsMethod.getAnnotation(DataPoints.class);
+                    if (annotation != null && isAssignableToAnyOf(annotation.ignoredExceptions(), throwable)) {
+                        return;
+                    } else {
+                        throw throwable;
+                    }
+                }
+            }
+        }
+    }
+
+    private void addSinglePointMethods(ParameterSignature sig, List<PotentialAssignment> list) {
+        for (FrameworkMethod dataPointMethod : getSingleDataPointMethods(sig)) {
+            if (sig.canAcceptType(dataPointMethod.getType())) {
+                list.add(new MethodParameterValue(dataPointMethod));
+            }
+        }
+    }
+    
+    private void addMultiPointFields(ParameterSignature sig, List<PotentialAssignment> list) {
+        for (final Field field : getDataPointsFields(sig)) {
+            Class<?> type = field.getType();
+            addDataPointsValues(type, sig, field.getName(), list, getStaticFieldValue(field));
+        }
+    }
+
+    private void addSinglePointFields(ParameterSignature sig, List<PotentialAssignment> list) {
+        for (final Field field : getSingleDataPointFields(sig)) {
+            Object value = getStaticFieldValue(field);
+            
+            if (sig.canAcceptValue(value)) {
+                list.add(PotentialAssignment.forValue(field.getName(), value));
+            }
+        }
+    }
+    
+    private void addDataPointsValues(Class<?> type, ParameterSignature sig, String name, 
+            List<PotentialAssignment> list, Object value) {
+        if (type.isArray()) {
+            addArrayValues(sig, name, list, value);
+        }
+        else if (Iterable.class.isAssignableFrom(type)) {
+            addIterableValues(sig, name, list, (Iterable<?>) value);
+        }
+    }
+
+    private void addArrayValues(ParameterSignature sig, String name, List<PotentialAssignment> list, Object array) {
+        for (int i = 0; i < Array.getLength(array); i++) {
+            Object value = Array.get(array, i);
+            if (sig.canAcceptValue(value)) {
+                list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
+            }
+        }
+    }
+    
+    private void addIterableValues(ParameterSignature sig, String name, List<PotentialAssignment> list, Iterable<?> iterable) {
+        Iterator<?> iterator = iterable.iterator();
+        int i = 0;
+        while (iterator.hasNext()) {
+            Object value = iterator.next();
+            if (sig.canAcceptValue(value)) {
+                list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
+            }
+            i += 1;
+        }
+    }
+
+    private Object getStaticFieldValue(final Field field) {
+        try {
+            return field.get(null);
+        } catch (IllegalArgumentException e) {
+            throw new RuntimeException(
+                    "unexpected: field from getClass doesn't exist on object");
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(
+                    "unexpected: getFields returned an inaccessible field");
+        }
+    }
+    
+    private static boolean isAssignableToAnyOf(Class<?>[] typeArray, Object target) {
+        for (Class<?> type : typeArray) {
+            if (type.isAssignableFrom(target.getClass())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected Collection<FrameworkMethod> getDataPointsMethods(ParameterSignature sig) {
+        return clazz.getAnnotatedMethods(DataPoints.class);
+    }
+    
+    protected Collection<Field> getSingleDataPointFields(ParameterSignature sig) {
+        List<FrameworkField> fields = clazz.getAnnotatedFields(DataPoint.class);
+        Collection<Field> validFields = new ArrayList<Field>();
+
+        for (FrameworkField frameworkField : fields) {
+            validFields.add(frameworkField.getField());
+        }
+
+        return validFields;
+    }
+    
+    protected Collection<Field> getDataPointsFields(ParameterSignature sig) {
+        List<FrameworkField> fields = clazz.getAnnotatedFields(DataPoints.class);
+        Collection<Field> validFields = new ArrayList<Field>();
+
+        for (FrameworkField frameworkField : fields) {
+            validFields.add(frameworkField.getField());
+        }
+
+        return validFields;
+    }
+    
+    protected Collection<FrameworkMethod> getSingleDataPointMethods(ParameterSignature sig) {
+        return clazz.getAnnotatedMethods(DataPoint.class);
+    }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/Assignments.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/Assignments.java
new file mode 100644
index 0000000..6626797
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/Assignments.java
@@ -0,0 +1,153 @@
+package org.junit.experimental.theories.internal;
+
+import static java.util.Collections.emptyList;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.ParametersSuppliedBy;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.PotentialAssignment.CouldNotGenerateValueException;
+import org.junit.runners.model.TestClass;
+
+/**
+ * A potentially incomplete list of value assignments for a method's formal
+ * parameters
+ */
+public class Assignments {
+    private final List<PotentialAssignment> assigned;
+
+    private final List<ParameterSignature> unassigned;
+
+    private final TestClass clazz;
+
+    private Assignments(List<PotentialAssignment> assigned,
+            List<ParameterSignature> unassigned, TestClass clazz) {
+        this.unassigned = unassigned;
+        this.assigned = assigned;
+        this.clazz = clazz;
+    }
+
+    /**
+     * Returns a new assignment list for {@code testMethod}, with no params
+     * assigned.
+     */
+    public static Assignments allUnassigned(Method testMethod,
+            TestClass testClass) {
+        List<ParameterSignature> signatures;
+        signatures = ParameterSignature.signatures(testClass
+                .getOnlyConstructor());
+        signatures.addAll(ParameterSignature.signatures(testMethod));
+        return new Assignments(new ArrayList<PotentialAssignment>(),
+                signatures, testClass);
+    }
+
+    public boolean isComplete() {
+        return unassigned.isEmpty();
+    }
+
+    public ParameterSignature nextUnassigned() {
+        return unassigned.get(0);
+    }
+
+    public Assignments assignNext(PotentialAssignment source) {
+        List<PotentialAssignment> potentialAssignments = new ArrayList<PotentialAssignment>(assigned);
+        potentialAssignments.add(source);
+
+        return new Assignments(potentialAssignments, unassigned.subList(1,
+                unassigned.size()), clazz);
+    }
+
+    public Object[] getActualValues(int start, int stop) 
+            throws CouldNotGenerateValueException {
+        Object[] values = new Object[stop - start];
+        for (int i = start; i < stop; i++) {
+            values[i - start] = assigned.get(i).getValue();
+        }
+        return values;
+    }
+
+    public List<PotentialAssignment> potentialsForNextUnassigned()
+            throws Throwable {
+        ParameterSignature unassigned = nextUnassigned();
+        List<PotentialAssignment> assignments = getSupplier(unassigned).getValueSources(unassigned);
+        
+        if (assignments.isEmpty()) {
+            assignments = generateAssignmentsFromTypeAlone(unassigned);
+        }
+        
+        return assignments;
+    }
+
+    private List<PotentialAssignment> generateAssignmentsFromTypeAlone(ParameterSignature unassigned) {
+        Class<?> paramType = unassigned.getType();
+        
+        if (paramType.isEnum()) {
+            return new EnumSupplier(paramType).getValueSources(unassigned);  
+        } else if (paramType.equals(Boolean.class) || paramType.equals(boolean.class)) {
+            return new BooleanSupplier().getValueSources(unassigned);
+        } else {
+            return emptyList();
+        }
+    }
+
+    private ParameterSupplier getSupplier(ParameterSignature unassigned)
+            throws Exception {
+        ParametersSuppliedBy annotation = unassigned
+                .findDeepAnnotation(ParametersSuppliedBy.class);
+        
+        if (annotation != null) {
+            return buildParameterSupplierFromClass(annotation.value());
+        } else {
+            return new AllMembersSupplier(clazz);
+        }
+    }
+
+    private ParameterSupplier buildParameterSupplierFromClass(
+            Class<? extends ParameterSupplier> cls) throws Exception {
+        Constructor<?>[] supplierConstructors = cls.getConstructors();
+
+        for (Constructor<?> constructor : supplierConstructors) {
+            Class<?>[] parameterTypes = constructor.getParameterTypes();
+            if (parameterTypes.length == 1
+                    && parameterTypes[0].equals(TestClass.class)) {
+                return (ParameterSupplier) constructor.newInstance(clazz);
+            }
+        }
+
+        return cls.newInstance();
+    }
+
+    public Object[] getConstructorArguments()
+            throws CouldNotGenerateValueException {
+        return getActualValues(0, getConstructorParameterCount());
+    }
+
+    public Object[] getMethodArguments() throws CouldNotGenerateValueException {
+        return getActualValues(getConstructorParameterCount(), assigned.size());
+    }
+
+    public Object[] getAllArguments() throws CouldNotGenerateValueException {
+        return getActualValues(0, assigned.size());
+    }
+
+    private int getConstructorParameterCount() {
+        List<ParameterSignature> signatures = ParameterSignature
+                .signatures(clazz.getOnlyConstructor());
+        int constructorParameterCount = signatures.size();
+        return constructorParameterCount;
+    }
+
+    public Object[] getArgumentStrings(boolean nullsOk)
+            throws CouldNotGenerateValueException {
+        Object[] values = new Object[assigned.size()];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = assigned.get(i).getDescription();
+        }
+        return values;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/BooleanSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/BooleanSupplier.java
new file mode 100644
index 0000000..5f7032f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/BooleanSupplier.java
@@ -0,0 +1,18 @@
+package org.junit.experimental.theories.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+
+public class BooleanSupplier extends ParameterSupplier {
+
+    @Override
+    public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+        return Arrays.asList(PotentialAssignment.forValue("true", true),
+                             PotentialAssignment.forValue("false", false));
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/EnumSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/EnumSupplier.java
new file mode 100644
index 0000000..1f3ab90
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/EnumSupplier.java
@@ -0,0 +1,30 @@
+package org.junit.experimental.theories.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+
+public class EnumSupplier extends ParameterSupplier {
+
+    private Class<?> enumType;
+
+    public EnumSupplier(Class<?> enumType) {
+        this.enumType = enumType;
+    }
+
+    @Override
+    public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+        Object[] enumValues = enumType.getEnumConstants();
+        
+        List<PotentialAssignment> assignments = new ArrayList<PotentialAssignment>();
+        for (Object value : enumValues) {
+            assignments.add(PotentialAssignment.forValue(value.toString(), value));
+        }
+        
+        return assignments;
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java
new file mode 100644
index 0000000..5b9e947
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java
@@ -0,0 +1,50 @@
+package org.junit.experimental.theories.internal;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+public class ParameterizedAssertionError extends AssertionError {
+    private static final long serialVersionUID = 1L;
+
+    public ParameterizedAssertionError(Throwable targetException,
+            String methodName, Object... params) {
+        super(String.format("%s(%s)", methodName, join(", ", params)));
+        this.initCause(targetException);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof ParameterizedAssertionError && toString().equals(obj.toString());
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    public static String join(String delimiter, Object... params) {
+        return join(delimiter, Arrays.asList(params));
+    }
+
+    public static String join(String delimiter, Collection<Object> values) {
+        StringBuilder sb = new StringBuilder();
+        Iterator<Object> iter = values.iterator();
+        while (iter.hasNext()) {
+            Object next = iter.next();
+            sb.append(stringValueOf(next));
+            if (iter.hasNext()) {
+                sb.append(delimiter);
+            }
+        }
+        return sb.toString();
+    }
+
+    private static String stringValueOf(Object next) {
+        try {
+            return String.valueOf(next);
+        } catch (Throwable e) {
+            return "[toString failed]";
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/SpecificDataPointsSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/SpecificDataPointsSupplier.java
new file mode 100644
index 0000000..7b571e3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/SpecificDataPointsSupplier.java
@@ -0,0 +1,90 @@
+package org.junit.experimental.theories.internal;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+public class SpecificDataPointsSupplier extends AllMembersSupplier {
+
+    public SpecificDataPointsSupplier(TestClass testClass) {
+        super(testClass);
+    }
+    
+    @Override
+    protected Collection<Field> getSingleDataPointFields(ParameterSignature sig) {
+        Collection<Field> fields = super.getSingleDataPointFields(sig);        
+        String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+
+        List<Field> fieldsWithMatchingNames = new ArrayList<Field>();
+        
+        for (Field field : fields) {
+            String[] fieldNames = field.getAnnotation(DataPoint.class).value();
+            if (Arrays.asList(fieldNames).contains(requestedName)) {
+                fieldsWithMatchingNames.add(field);
+            }
+        }
+        
+        return fieldsWithMatchingNames;
+    }
+    
+    @Override
+    protected Collection<Field> getDataPointsFields(ParameterSignature sig) {
+        Collection<Field> fields = super.getDataPointsFields(sig);        
+        String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+        
+        List<Field> fieldsWithMatchingNames = new ArrayList<Field>();
+        
+        for (Field field : fields) {
+            String[] fieldNames = field.getAnnotation(DataPoints.class).value();
+            if (Arrays.asList(fieldNames).contains(requestedName)) {
+                fieldsWithMatchingNames.add(field);
+            }
+        }
+        
+        return fieldsWithMatchingNames;
+    }
+    
+    @Override
+    protected Collection<FrameworkMethod> getSingleDataPointMethods(ParameterSignature sig) {
+        Collection<FrameworkMethod> methods = super.getSingleDataPointMethods(sig);
+        String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+        
+        List<FrameworkMethod> methodsWithMatchingNames = new ArrayList<FrameworkMethod>();
+        
+        for (FrameworkMethod method : methods) {
+            String[] methodNames = method.getAnnotation(DataPoint.class).value();
+            if (Arrays.asList(methodNames).contains(requestedName)) {
+                methodsWithMatchingNames.add(method);
+            }
+        }
+        
+        return methodsWithMatchingNames;
+    }
+    
+    @Override
+    protected Collection<FrameworkMethod> getDataPointsMethods(ParameterSignature sig) {
+        Collection<FrameworkMethod> methods = super.getDataPointsMethods(sig);
+        String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+        
+        List<FrameworkMethod> methodsWithMatchingNames = new ArrayList<FrameworkMethod>();
+        
+        for (FrameworkMethod method : methods) {
+            String[] methodNames = method.getAnnotation(DataPoints.class).value();
+            if (Arrays.asList(methodNames).contains(requestedName)) {
+                methodsWithMatchingNames.add(method);
+            }
+        }
+        
+        return methodsWithMatchingNames;
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOn.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOn.java
new file mode 100644
index 0000000..a19f20a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOn.java
@@ -0,0 +1,31 @@
+package org.junit.experimental.theories.suppliers;
+
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.experimental.theories.ParametersSuppliedBy;
+
+/**
+ * Annotating a {@link org.junit.experimental.theories.Theory Theory} method int
+ * parameter with &#064;TestedOn causes it to be supplied with values from the
+ * ints array given when run as a theory by the
+ * {@link org.junit.experimental.theories.Theories Theories} runner. For
+ * example, the below method would be called three times by the Theories runner,
+ * once with each of the int parameters specified.
+ * 
+ * <pre>
+ * &#064;Theory
+ * public void shouldPassForSomeInts(&#064;TestedOn(ints={1, 2, 3}) int param) {
+ *     ...
+ * }
+ * </pre>
+ */
+@ParametersSuppliedBy(TestedOnSupplier.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target(PARAMETER)
+public @interface TestedOn {
+    int[] ints();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOnSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOnSupplier.java
new file mode 100644
index 0000000..dc3d0c9
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOnSupplier.java
@@ -0,0 +1,25 @@
+package org.junit.experimental.theories.suppliers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+
+/**
+ * @see org.junit.experimental.theories.suppliers.TestedOn
+ * @see org.junit.experimental.theories.ParameterSupplier
+ */
+public class TestedOnSupplier extends ParameterSupplier {
+    @Override
+    public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+        List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
+        TestedOn testedOn = sig.getAnnotation(TestedOn.class);
+        int[] ints = testedOn.ints();
+        for (final int i : ints) {
+            list.add(PotentialAssignment.forValue("ints", i));
+        }
+        return list;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/function/ThrowingRunnable.java b/google3/third_party/java_src/junit/main/java/org/junit/function/ThrowingRunnable.java
new file mode 100644
index 0000000..d0eb782
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/function/ThrowingRunnable.java
@@ -0,0 +1,14 @@
+package org.junit.function;
+
+/**
+ * This interface facilitates the use of
+ * {@link org.junit.Assert#assertThrows(Class, ThrowingRunnable)} from Java 8. It allows method
+ * references to void methods (that declare checked exceptions) to be passed directly into
+ * {@code assertThrows}
+ * without wrapping. It is not meant to be implemented directly.
+ *
+ * @since 4.13
+ */
+public interface ThrowingRunnable {
+    void run() throws Throwable;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/ArrayComparisonFailure.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/ArrayComparisonFailure.java
new file mode 100644
index 0000000..d300e7e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/ArrayComparisonFailure.java
@@ -0,0 +1,74 @@
+package org.junit.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+
+/**
+ * Thrown when two array elements differ
+ *
+ * @see Assert#assertArrayEquals(String, Object[], Object[])
+ */
+public class ArrayComparisonFailure extends AssertionError {
+
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * We have to use the f prefix until the next major release to ensure
+     * serialization compatibility.
+     * See https://github.com/junit-team/junit4/issues/976
+     */
+    private final List<Integer> fIndices = new ArrayList<Integer>();
+    private final String fMessage;
+    private final AssertionError fCause;
+
+    /**
+     * Construct a new <code>ArrayComparisonFailure</code> with an error text and the array's
+     * dimension that was not equal
+     *
+     * @param cause the exception that caused the array's content to fail the assertion test
+     * @param index the array position of the objects that are not equal.
+     * @see Assert#assertArrayEquals(String, Object[], Object[])
+     */
+    public ArrayComparisonFailure(String message, AssertionError cause, int index) {
+        this.fMessage = message;
+        this.fCause = cause;
+        initCause(fCause);
+        addDimension(index);
+    }
+
+    public void addDimension(int index) {
+        fIndices.add(0, index);
+    }
+
+    @Override
+    public synchronized Throwable getCause() {
+        return super.getCause() == null ? fCause : super.getCause();
+    }
+
+    @Override
+    public String getMessage() {
+        StringBuilder sb = new StringBuilder();
+        if (fMessage != null) {
+            sb.append(fMessage);
+        }
+        sb.append("arrays first differed at element ");
+        for (int each : fIndices) {
+            sb.append("[");
+            sb.append(each);
+            sb.append("]");
+        }
+        sb.append("; ");
+        sb.append(getCause().getMessage());
+        return sb.toString();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return getMessage();
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/AssumptionViolatedException.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/AssumptionViolatedException.java
new file mode 100644
index 0000000..0e79b56
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/AssumptionViolatedException.java
@@ -0,0 +1,139 @@
+package org.junit.internal;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.SelfDescribing;
+import org.hamcrest.StringDescription;
+
+/**
+ * An exception class used to implement <i>assumptions</i> (state in which a given test
+ * is meaningful and should or should not be executed). A test for which an assumption
+ * fails should not generate a test case failure.
+ *
+ * @see org.junit.Assume
+ */
+public class AssumptionViolatedException extends RuntimeException implements SelfDescribing {
+    private static final long serialVersionUID = 2L;
+
+    /*
+     * We have to use the f prefix until the next major release to ensure
+     * serialization compatibility. 
+     * See https://github.com/junit-team/junit4/issues/976
+     */
+    private final String fAssumption;
+    private final boolean fValueMatcher;
+    private final Object fValue;
+    private final Matcher<?> fMatcher;
+
+    /**
+     * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+     */
+    @Deprecated
+    public AssumptionViolatedException(String assumption, boolean hasValue, Object value, Matcher<?> matcher) {
+        this.fAssumption = assumption;
+        this.fValue = value;
+        this.fMatcher = matcher;
+        this.fValueMatcher = hasValue;
+
+        if (value instanceof Throwable) {
+          initCause((Throwable) value);
+        }
+    }
+
+    /**
+     * An assumption exception with the given <i>value</i> (String or
+     * Throwable) and an additional failing {@link Matcher}.
+     *
+     * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+     */
+    @Deprecated
+    public AssumptionViolatedException(Object value, Matcher<?> matcher) {
+        this(null, true, value, matcher);
+    }
+
+    /**
+     * An assumption exception with the given <i>value</i> (String or
+     * Throwable) and an additional failing {@link Matcher}.
+     *
+     * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+     */
+    @Deprecated
+    public AssumptionViolatedException(String assumption, Object value, Matcher<?> matcher) {
+        this(assumption, true, value, matcher);
+    }
+
+    /**
+     * An assumption exception with the given message only.
+     *
+     * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+     */
+    @Deprecated
+    public AssumptionViolatedException(String assumption) {
+        this(assumption, false, null, null);
+    }
+
+    /**
+     * An assumption exception with the given message and a cause.
+     *
+     * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+     */
+    @Deprecated
+    public AssumptionViolatedException(String assumption, Throwable e) {
+        this(assumption, false, null, null);
+        initCause(e);
+    }
+
+    @Override
+    public String getMessage() {
+        return StringDescription.asString(this);
+    }
+
+    public void describeTo(Description description) {
+        if (fAssumption != null) {
+            description.appendText(fAssumption);
+        }
+
+        if (fValueMatcher) {
+            // a value was passed in when this instance was constructed; print it
+            if (fAssumption != null) {
+                description.appendText(": ");
+            }
+
+            description.appendText("got: ");
+            description.appendValue(fValue);
+
+            if (fMatcher != null) {
+                description.appendText(", expected: ");
+                description.appendDescriptionOf(fMatcher);
+            }
+        }
+    }
+
+    /**
+     * Override default Java object serialization to correctly deal with potentially unserializable matchers or values.
+     * By not implementing readObject, we assure ourselves of backwards compatibility and compatibility with the
+     * standard way of Java serialization.
+     *
+     * @param objectOutputStream The outputStream to write our representation to
+     * @throws IOException When serialization fails
+     */
+    private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
+        ObjectOutputStream.PutField putField = objectOutputStream.putFields();
+        putField.put("fAssumption", fAssumption);
+        putField.put("fValueMatcher", fValueMatcher);
+
+        // We have to wrap the matcher into a serializable form.
+        putField.put("fMatcher", SerializableMatcherDescription.asSerializableMatcher(fMatcher));
+
+        // We have to wrap the value inside a non-String class (instead of serializing the String value directly) as
+        // A Description will handle a String and non-String object differently (1st is surrounded by '"' while the
+        // latter will be surrounded by '<' '>'. Wrapping it makes sure that the description of a serialized and
+        // non-serialized instance produce the exact same description
+        putField.put("fValue", SerializableValueDescription.asSerializableValue(fValue));
+
+        objectOutputStream.writeFields();
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/Checks.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/Checks.java
new file mode 100644
index 0000000..9724947
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/Checks.java
@@ -0,0 +1,37 @@
+package org.junit.internal;
+
+/** @since 4.13 */
+public final class Checks {
+
+    private Checks() {}
+
+    /**
+     * Checks that the given value is not {@code null}.
+     *
+     * @param value object reference to check
+     * @return the passed-in value, if not {@code null}
+     * @throws NullPointerException if {@code value} is {@code null}
+     */
+    public static <T> T notNull(T value) {
+        if (value == null) {
+            throw new NullPointerException();
+        }
+        return value;
+    }
+
+    /**
+     * Checks that the given value is not {@code null}, using the given message
+     * as the exception message if an exception is thrown.
+     *
+     * @param value object reference to check
+     * @param message message to use if {@code value} is {@code null}
+     * @return the passed-in value, if not {@code null}
+     * @throws NullPointerException if {@code value} is {@code null}
+     */
+    public static <T> T notNull(T value, String message) {
+        if (value == null) {
+            throw new NullPointerException(message);
+        }
+        return value;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/Classes.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/Classes.java
new file mode 100644
index 0000000..0693836
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/Classes.java
@@ -0,0 +1,44 @@
+package org.junit.internal;
+
+import static java.lang.Thread.currentThread;
+
+/**
+ * Miscellaneous functions dealing with classes.
+ */
+public class Classes {
+
+    /**
+     * Do not instantiate.
+     * @deprecated will be private soon.
+     */
+    @Deprecated
+    public Classes() {
+    }
+
+    /**
+     * Returns Class.forName for {@code className} using the current thread's class loader.
+     * If the current thread does not have a class loader, falls back to the class loader for
+     * {@link Classes}.
+     *
+     * @param className Name of the class.
+     * @throws ClassNotFoundException
+     */
+    public static Class<?> getClass(String className) throws ClassNotFoundException {
+        return getClass(className, Classes.class);
+    }
+
+    /**
+     * Returns Class.forName for {@code className} using the current thread's class loader.
+     * If the current thread does not have a class loader, falls back to the class loader for the
+     * passed-in class.
+     *
+     * @param className Name of the class.
+     * @param callingClass Class that is requesting a the class
+     * @throws ClassNotFoundException
+     * @since 4.13
+     */
+    public static Class<?> getClass(String className, Class<?> callingClass) throws ClassNotFoundException {
+        ClassLoader classLoader = currentThread().getContextClassLoader();
+        return Class.forName(className, true, classLoader == null ? callingClass.getClassLoader() : classLoader);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/ComparisonCriteria.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/ComparisonCriteria.java
new file mode 100644
index 0000000..ed1c674
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/ComparisonCriteria.java
@@ -0,0 +1,132 @@
+package org.junit.internal;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+import org.junit.Assert;
+
+/**
+ * Defines criteria for finding two items "equal enough". Concrete subclasses
+ * may demand exact equality, or, for example, equality within a given delta.
+ */
+public abstract class ComparisonCriteria {
+    /**
+     * Asserts that two arrays are equal, according to the criteria defined by
+     * the concrete subclass. If they are not, an {@link AssertionError} is
+     * thrown with the given message. If <code>expecteds</code> and
+     * <code>actuals</code> are <code>null</code>, they are considered equal.
+     *
+     * @param message the identifying message for the {@link AssertionError} (
+     * <code>null</code> okay)
+     * @param expecteds Object array or array of arrays (multi-dimensional array) with
+     * expected values.
+     * @param actuals Object array or array of arrays (multi-dimensional array) with
+     * actual values
+     */
+    public void arrayEquals(String message, Object expecteds, Object actuals)
+            throws ArrayComparisonFailure {
+        arrayEquals(message, expecteds, actuals, true);
+    }
+
+    private void arrayEquals(String message, Object expecteds, Object actuals, boolean outer)
+            throws ArrayComparisonFailure {
+        if (expecteds == actuals
+            || Arrays.deepEquals(new Object[] {expecteds}, new Object[] {actuals})) {
+            // The reflection-based loop below is potentially very slow, especially for primitive
+            // arrays. The deepEquals check allows us to circumvent it in the usual case where
+            // the arrays are exactly equal.
+            return;
+        }
+        String header = message == null ? "" : message + ": ";
+
+        // Only include the user-provided message in the outer exception.
+        String exceptionMessage = outer ? header : "";
+
+        if (expecteds == null) {
+            Assert.fail(exceptionMessage + "expected array was null");
+        }
+        if (actuals == null) {
+            Assert.fail(exceptionMessage + "actual array was null");
+        }
+
+        int actualsLength = Array.getLength(actuals);
+        int expectedsLength = Array.getLength(expecteds);
+        if (actualsLength != expectedsLength) {
+            header += "array lengths differed, expected.length="
+                    + expectedsLength + " actual.length=" + actualsLength + "; ";
+        }
+        int prefixLength = Math.min(actualsLength, expectedsLength);
+
+        for (int i = 0; i < prefixLength; i++) {
+            Object expected = Array.get(expecteds, i);
+            Object actual = Array.get(actuals, i);
+
+            if (isArray(expected) && isArray(actual)) {
+                try {
+                    arrayEquals(message, expected, actual, false);
+                } catch (ArrayComparisonFailure e) {
+                    e.addDimension(i);
+                    throw e;
+                } catch (AssertionError e) {
+                    // Array lengths differed.
+                    throw new ArrayComparisonFailure(header, e, i);
+                }
+            } else {
+                try {
+                    assertElementsEqual(expected, actual);
+                } catch (AssertionError e) {
+                    throw new ArrayComparisonFailure(header, e, i);
+                }
+            }
+        }
+
+        if (actualsLength != expectedsLength) {
+            Object expected = getToStringableArrayElement(expecteds, expectedsLength, prefixLength);
+            Object actual = getToStringableArrayElement(actuals, actualsLength, prefixLength);
+            try {
+                Assert.assertEquals(expected, actual);
+            } catch (AssertionError e) {
+                throw new ArrayComparisonFailure(header, e, prefixLength);
+            }
+        }
+    }
+
+    private static final Object END_OF_ARRAY_SENTINEL = objectWithToString("end of array");
+
+    private Object getToStringableArrayElement(Object array, int length, int index) {
+        if (index < length) {
+            Object element = Array.get(array, index);
+            if (isArray(element)) {
+                return objectWithToString(componentTypeName(element.getClass()) + "[" + Array.getLength(element) + "]");
+            } else {
+                return element;
+            }
+        } else {
+            return END_OF_ARRAY_SENTINEL;
+        }
+    }
+
+    private static Object objectWithToString(final String string) {
+        return new Object() {
+            @Override
+            public String toString() {
+                return string;
+            }
+        };
+    }
+
+    private String componentTypeName(Class<?> arrayClass) {
+        Class<?> componentType = arrayClass.getComponentType();
+        if (componentType.isArray()) {
+            return componentTypeName(componentType) + "[]";
+        } else {
+            return componentType.getName();
+        }
+    }
+
+    private boolean isArray(Object expected) {
+        return expected != null && expected.getClass().isArray();
+    }
+
+    protected abstract void assertElementsEqual(Object expected, Object actual);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/ExactComparisonCriteria.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/ExactComparisonCriteria.java
new file mode 100644
index 0000000..a267f7f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/ExactComparisonCriteria.java
@@ -0,0 +1,10 @@
+package org.junit.internal;
+
+import org.junit.Assert;
+
+public class ExactComparisonCriteria extends ComparisonCriteria {
+    @Override
+    protected void assertElementsEqual(Object expected, Object actual) {
+        Assert.assertEquals(expected, actual);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/InexactComparisonCriteria.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/InexactComparisonCriteria.java
new file mode 100644
index 0000000..16e804b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/InexactComparisonCriteria.java
@@ -0,0 +1,24 @@
+package org.junit.internal;
+
+import org.junit.Assert;
+
+public class InexactComparisonCriteria extends ComparisonCriteria {
+    public Object fDelta;
+
+    public InexactComparisonCriteria(double delta) {
+        fDelta = delta;
+    }
+
+    public InexactComparisonCriteria(float delta) {
+        fDelta = delta;
+    }
+
+    @Override
+    protected void assertElementsEqual(Object expected, Object actual) {
+        if (expected instanceof Double) {
+            Assert.assertEquals((Double) expected, (Double) actual, (Double) fDelta);
+        } else {
+            Assert.assertEquals((Float) expected, (Float) actual, (Float) fDelta);
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/JUnitSystem.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/JUnitSystem.java
new file mode 100644
index 0000000..cf0f2c0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/JUnitSystem.java
@@ -0,0 +1,14 @@
+package org.junit.internal;
+
+import java.io.PrintStream;
+
+public interface JUnitSystem {
+
+    /**
+     * Will be removed in the next major release
+     */
+    @Deprecated
+    void exit(int code);
+
+    PrintStream out();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/MethodSorter.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/MethodSorter.java
new file mode 100644
index 0000000..d8e661a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/MethodSorter.java
@@ -0,0 +1,72 @@
+package org.junit.internal;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.junit.FixMethodOrder;
+
+public class MethodSorter {
+    /**
+     * DEFAULT sort order
+     */
+    public static final Comparator<Method> DEFAULT = new Comparator<Method>() {
+        public int compare(Method m1, Method m2) {
+            int i1 = m1.getName().hashCode();
+            int i2 = m2.getName().hashCode();
+            if (i1 != i2) {
+                return i1 < i2 ? -1 : 1;
+            }
+            return NAME_ASCENDING.compare(m1, m2);
+        }
+    };
+
+    /**
+     * Method name ascending lexicographic sort order, with {@link Method#toString()} as a tiebreaker
+     */
+    public static final Comparator<Method> NAME_ASCENDING = new Comparator<Method>() {
+        public int compare(Method m1, Method m2) {
+            final int comparison = m1.getName().compareTo(m2.getName());
+            if (comparison != 0) {
+                return comparison;
+            }
+            return m1.toString().compareTo(m2.toString());
+        }
+    };
+
+    /**
+     * Gets declared methods of a class in a predictable order, unless @FixMethodOrder(MethodSorters.JVM) is specified.
+     *
+     * Using the JVM order is unwise since the Java platform does not
+     * specify any particular order, and in fact JDK 7 returns a more or less
+     * random order; well-written test code would not assume any order, but some
+     * does, and a predictable failure is better than a random failure on
+     * certain platforms. By default, uses an unspecified but deterministic order.
+     *
+     * @param clazz a class
+     * @return same as {@link Class#getDeclaredMethods} but sorted
+     * @see <a href="http://bugs.sun.com/view_bug.do?bug_id=7023180">JDK
+     *      (non-)bug #7023180</a>
+     */
+    public static Method[] getDeclaredMethods(Class<?> clazz) {
+        Comparator<Method> comparator = getSorter(clazz.getAnnotation(FixMethodOrder.class));
+
+        Method[] methods = clazz.getDeclaredMethods();
+        if (comparator != null) {
+            Arrays.sort(methods, comparator);
+        }
+
+        return methods;
+    }
+
+    private MethodSorter() {
+    }
+
+    private static Comparator<Method> getSorter(FixMethodOrder fixMethodOrder) {
+        if (fixMethodOrder == null) {
+            return DEFAULT;
+        }
+
+        return fixMethodOrder.value().getComparator();
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/RealSystem.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/RealSystem.java
new file mode 100644
index 0000000..e64e1fe
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/RealSystem.java
@@ -0,0 +1,19 @@
+package org.junit.internal;
+
+import java.io.PrintStream;
+
+public class RealSystem implements JUnitSystem {
+
+    /**
+     * Will be removed in the next major release
+     */
+    @Deprecated
+    public void exit(int code) {
+        System.exit(code);
+    }
+
+    public PrintStream out() {
+        return System.out;
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableMatcherDescription.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableMatcherDescription.java
new file mode 100644
index 0000000..e036557
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableMatcherDescription.java
@@ -0,0 +1,47 @@
+package org.junit.internal;
+
+import java.io.Serializable;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+
+/**
+ * This class exists solely to provide a serializable description of a matcher to be serialized as a field in
+ * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but most
+ * implementations of {@link Matcher} are not. This class works around that limitation as
+ * {@link AssumptionViolatedException} only every uses the description of the {@link Matcher}, while still retaining
+ * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of
+ * previously serialized instances.
+ */
+class SerializableMatcherDescription<T> extends BaseMatcher<T> implements Serializable {
+
+    private final String matcherDescription;
+
+    private SerializableMatcherDescription(Matcher<T> matcher) {
+        matcherDescription = StringDescription.asString(matcher);
+    }
+
+    public boolean matches(Object o) {
+        throw new UnsupportedOperationException("This Matcher implementation only captures the description");
+    }
+
+    public void describeTo(Description description) {
+        description.appendText(matcherDescription);
+    }
+
+    /**
+     * Factory method that checks to see if the matcher is already serializable.
+     * @param matcher the matcher to make serializable
+     * @return The provided matcher if it is null or already serializable,
+     * the SerializableMatcherDescription representation of it if it is not.
+     */
+    static <T> Matcher<T> asSerializableMatcher(Matcher<T> matcher) {
+        if (matcher == null || matcher instanceof Serializable) {
+            return matcher;
+        } else {
+            return new SerializableMatcherDescription<T>(matcher);
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableValueDescription.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableValueDescription.java
new file mode 100644
index 0000000..4d055d7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableValueDescription.java
@@ -0,0 +1,38 @@
+package org.junit.internal;
+
+import java.io.Serializable;
+
+/**
+ * This class exists solely to provide a serializable description of a value to be serialized as a field in
+ * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but a
+ * value of type Object provides no guarantee to be serializable. This class works around that limitation as
+ * {@link AssumptionViolatedException} only every uses the string representation of the value, while still retaining
+ * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of
+ * previously serialized instances.
+ */
+class SerializableValueDescription implements Serializable {
+    private final String value;
+
+    private SerializableValueDescription(Object value) {
+        this.value = String.valueOf(value);
+    }
+
+    /**
+     * Factory method that checks to see if the value is already serializable.
+     * @param value the value to make serializable
+     * @return The provided value if it is null or already serializable,
+     * the SerializableValueDescription representation of it if it is not.
+     */
+    static Object asSerializableValue(Object value) {
+        if (value == null || value instanceof Serializable) {
+            return value;
+        } else {
+            return new SerializableValueDescription(value);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return value;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/TextListener.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/TextListener.java
new file mode 100644
index 0000000..d548aeb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/TextListener.java
@@ -0,0 +1,101 @@
+package org.junit.internal;
+
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class TextListener extends RunListener {
+
+    private final PrintStream writer;
+
+    public TextListener(JUnitSystem system) {
+        this(system.out());
+    }
+
+    public TextListener(PrintStream writer) {
+        this.writer = writer;
+    }
+
+    @Override
+    public void testRunFinished(Result result) {
+        printHeader(result.getRunTime());
+        printFailures(result);
+        printFooter(result);
+    }
+
+    @Override
+    public void testStarted(Description description) {
+        writer.append('.');
+    }
+
+    @Override
+    public void testFailure(Failure failure) {
+        writer.append('E');
+    }
+
+    @Override
+    public void testIgnored(Description description) {
+        writer.append('I');
+    }
+
+    /*
+      * Internal methods
+      */
+
+    private PrintStream getWriter() {
+        return writer;
+    }
+
+    protected void printHeader(long runTime) {
+        getWriter().println();
+        getWriter().println("Time: " + elapsedTimeAsString(runTime));
+    }
+
+    protected void printFailures(Result result) {
+        List<Failure> failures = result.getFailures();
+        if (failures.isEmpty()) {
+            return;
+        }
+        if (failures.size() == 1) {
+            getWriter().println("There was " + failures.size() + " failure:");
+        } else {
+            getWriter().println("There were " + failures.size() + " failures:");
+        }
+        int i = 1;
+        for (Failure each : failures) {
+            printFailure(each, "" + i++);
+        }
+    }
+
+    protected void printFailure(Failure each, String prefix) {
+        getWriter().println(prefix + ") " + each.getTestHeader());
+        getWriter().print(each.getTrimmedTrace());
+    }
+
+    protected void printFooter(Result result) {
+        if (result.wasSuccessful()) {
+            getWriter().println();
+            getWriter().print("OK");
+            getWriter().println(" (" + result.getRunCount() + " test" + (result.getRunCount() == 1 ? "" : "s") + ")");
+
+        } else {
+            getWriter().println();
+            getWriter().println("FAILURES!!!");
+            getWriter().println("Tests run: " + result.getRunCount() + ",  Failures: " + result.getFailureCount());
+        }
+        getWriter().println();
+    }
+
+    /**
+     * Returns the formatted string of the elapsed time. Duplicated from
+     * BaseTestRunner. Fix it.
+     */
+    protected String elapsedTimeAsString(long runTime) {
+        return NumberFormat.getInstance().format((double) runTime / 1000);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/Throwables.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/Throwables.java
new file mode 100644
index 0000000..3f0f7a3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/Throwables.java
@@ -0,0 +1,273 @@
+package org.junit.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Miscellaneous functions dealing with {@code Throwable}.
+ *
+ * @author kcooney@google.com (Kevin Cooney)
+ * @since 4.12
+ */
+public final class Throwables {
+
+    private Throwables() {
+    }
+
+    /**
+     * Rethrows the given {@code Throwable}, allowing the caller to
+     * declare that it throws {@code Exception}. This is useful when
+     * your callers have nothing reasonable they can do when a
+     * {@code Throwable} is thrown. This is declared to return {@code Exception}
+     * so it can be used in a {@code throw} clause:
+     * <pre>
+     * try {
+     *   doSomething();
+     * } catch (Throwable e} {
+     *   throw Throwables.rethrowAsException(e);
+     * }
+     * doSomethingLater();
+     * </pre>
+     *
+     * @param e exception to rethrow
+     * @return does not return anything
+     * @since 4.12
+     */
+    public static Exception rethrowAsException(Throwable e) throws Exception {
+        Throwables.<Exception>rethrow(e);
+        return null; // we never get here
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T extends Throwable> void rethrow(Throwable e) throws T {
+        throw (T) e;
+    }
+
+    /**
+     * Returns the stacktrace of the given Throwable as a String.
+     *
+     * @since 4.13
+     */
+    public static String getStacktrace(Throwable exception) {
+        StringWriter stringWriter = new StringWriter();
+        PrintWriter writer = new PrintWriter(stringWriter);
+        exception.printStackTrace(writer);
+        return stringWriter.toString();
+    }
+
+    /**
+     * Gets a trimmed version of the stack trace of the given exception. Stack trace
+     * elements that are below the test method are filtered out.
+     *
+     * @return a trimmed stack trace, or the original trace if trimming wasn't possible
+     */
+    public static String getTrimmedStackTrace(Throwable exception) {
+        List<String> trimmedStackTraceLines = getTrimmedStackTraceLines(exception);
+        if (trimmedStackTraceLines.isEmpty()) {
+            return getFullStackTrace(exception);
+        }
+
+        StringBuilder result = new StringBuilder(exception.toString());
+        appendStackTraceLines(trimmedStackTraceLines, result);
+        appendStackTraceLines(getCauseStackTraceLines(exception), result);
+        return result.toString();
+    }
+
+    private static List<String> getTrimmedStackTraceLines(Throwable exception) {
+        List<StackTraceElement> stackTraceElements = Arrays.asList(exception.getStackTrace());
+        int linesToInclude = stackTraceElements.size();
+
+        State state = State.PROCESSING_OTHER_CODE;
+        for (StackTraceElement stackTraceElement : asReversedList(stackTraceElements)) {
+            state = state.processStackTraceElement(stackTraceElement);
+            if (state == State.DONE) {
+                List<String> trimmedLines = new ArrayList<String>(linesToInclude + 2);
+                trimmedLines.add("");
+                for (StackTraceElement each : stackTraceElements.subList(0, linesToInclude)) {
+                    trimmedLines.add("\tat " + each);
+                }
+                if (exception.getCause() != null) {
+                    trimmedLines.add("\t... " + (stackTraceElements.size() - trimmedLines.size()) + " trimmed");
+                }
+                return trimmedLines;
+            }
+            linesToInclude--;
+        }
+        return Collections.emptyList();
+    }
+
+    private static final Method getSuppressed = initGetSuppressed();
+
+    private static Method initGetSuppressed() {
+        try {
+            return Throwable.class.getMethod("getSuppressed");
+        } catch (Throwable e) {
+            return null;
+        }
+    }
+
+    private static boolean hasSuppressed(Throwable exception) {
+        if (getSuppressed == null) {
+            return false;
+        }
+        try {
+            Throwable[] suppressed = (Throwable[]) getSuppressed.invoke(exception);
+            return suppressed.length != 0;
+        } catch (Throwable e) {
+            return false;
+        }
+    }
+
+    private static List<String> getCauseStackTraceLines(Throwable exception) {
+        if (exception.getCause() != null || hasSuppressed(exception)) {
+            String fullTrace = getFullStackTrace(exception);
+            BufferedReader reader = new BufferedReader(
+                    new StringReader(fullTrace.substring(exception.toString().length())));
+            List<String> causedByLines = new ArrayList<String>();
+    
+            try {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    if (line.startsWith("Caused by: ") || line.trim().startsWith("Suppressed: ")) {
+                        causedByLines.add(line);
+                        while ((line = reader.readLine()) != null) {
+                            causedByLines.add(line);
+                        }
+                        return causedByLines;
+                    }
+                }
+            } catch (IOException e) {
+                // We should never get here, because we are reading from a StringReader
+            }
+        }
+
+        return Collections.emptyList();
+    }
+
+    private static String getFullStackTrace(Throwable exception) {
+        StringWriter stringWriter = new StringWriter();
+        PrintWriter writer = new PrintWriter(stringWriter);
+        exception.printStackTrace(writer);
+        return stringWriter.toString();
+    }
+
+    private static void appendStackTraceLines(
+            List<String> stackTraceLines, StringBuilder destBuilder) {
+        for (String stackTraceLine : stackTraceLines) {
+            destBuilder.append(String.format("%s%n", stackTraceLine));
+        }
+    }
+
+    private static <T> List<T> asReversedList(final List<T> list) {
+        return new AbstractList<T>() {
+
+            @Override
+            public T get(int index) {
+                return list.get(list.size() - index - 1);
+            }
+
+            @Override
+            public int size() {
+                return list.size();
+            }
+        };
+    }
+
+    private enum State {
+        PROCESSING_OTHER_CODE {
+            @Override public State processLine(String methodName) {
+                if (isTestFrameworkMethod(methodName)) {
+                    return PROCESSING_TEST_FRAMEWORK_CODE;
+                }
+                return this;
+            }
+        },
+        PROCESSING_TEST_FRAMEWORK_CODE {
+            @Override public State processLine(String methodName) {
+                if (isReflectionMethod(methodName)) {
+                    return PROCESSING_REFLECTION_CODE;
+                } else if (isTestFrameworkMethod(methodName)) {
+                    return this;
+                }
+                return PROCESSING_OTHER_CODE;
+            } 
+        },
+        PROCESSING_REFLECTION_CODE {
+            @Override public State processLine(String methodName) {
+                if (isReflectionMethod(methodName)) {
+                    return this;
+                } else if (isTestFrameworkMethod(methodName)) {
+                    // This is here to handle TestCase.runBare() calling TestCase.runTest().
+                    return PROCESSING_TEST_FRAMEWORK_CODE;
+                }
+                return DONE;
+            } 
+        },
+        DONE {
+            @Override public State processLine(String methodName) {
+                return this;
+            } 
+        };
+
+        /** Processes a stack trace element method name, possibly moving to a new state. */
+        protected abstract State processLine(String methodName);
+        
+        /** Processes a stack trace element, possibly moving to a new state. */
+        public final State processStackTraceElement(StackTraceElement element) {
+            return processLine(element.getClassName() + "." + element.getMethodName() + "()");
+        }
+    }
+
+    private static final String[] TEST_FRAMEWORK_METHOD_NAME_PREFIXES = {
+        "org.junit.runner.",
+        "org.junit.runners.",
+        "org.junit.experimental.runners.",
+        "org.junit.internal.",
+        "junit.extensions",
+        "junit.framework",
+        "junit.runner",
+        "junit.textui",
+    };
+
+    private static final String[] TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES = {
+        "org.junit.internal.StackTracesTest",
+    };
+
+    private static boolean isTestFrameworkMethod(String methodName) {
+        return isMatchingMethod(methodName, TEST_FRAMEWORK_METHOD_NAME_PREFIXES) &&
+                !isMatchingMethod(methodName, TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES);
+    }
+    
+    private static final String[] REFLECTION_METHOD_NAME_PREFIXES = {
+        "sun.reflect.",
+        "java.lang.reflect.",
+        "jdk.internal.reflect.",
+        "org.junit.rules.RunRules.<init>(",
+        "org.junit.rules.RunRules.applyAll(", // calls TestRules
+        "org.junit.runners.RuleContainer.apply(", // calls MethodRules & TestRules
+        "junit.framework.TestCase.runBare(", // runBare() directly calls setUp() and tearDown()
+   };
+    
+    private static boolean isReflectionMethod(String methodName) {
+        return isMatchingMethod(methodName, REFLECTION_METHOD_NAME_PREFIXES);
+    }
+
+    private static boolean isMatchingMethod(String methodName, String[] methodNamePrefixes) {
+        for (String methodNamePrefix : methodNamePrefixes) {
+            if (methodName.startsWith(methodNamePrefix)) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java
new file mode 100644
index 0000000..8704a54
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java
@@ -0,0 +1,67 @@
+package org.junit.internal.builders;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class AllDefaultPossibilitiesBuilder extends RunnerBuilder {
+    private final boolean canUseSuiteMethod;
+
+    /**
+     * @since 4.13
+     */
+    public AllDefaultPossibilitiesBuilder() {
+        canUseSuiteMethod = true;
+    }
+
+    /**
+     * @deprecated used {@link #AllDefaultPossibilitiesBuilder()}.
+     */
+    @Deprecated
+    public AllDefaultPossibilitiesBuilder(boolean canUseSuiteMethod) {
+        this.canUseSuiteMethod = canUseSuiteMethod;
+    }
+
+    @Override
+    public Runner runnerForClass(Class<?> testClass) throws Throwable {
+        List<RunnerBuilder> builders = Arrays.asList(
+                ignoredBuilder(),
+                annotatedBuilder(),
+                suiteMethodBuilder(),
+                junit3Builder(),
+                junit4Builder());
+
+        for (RunnerBuilder each : builders) {
+            Runner runner = each.safeRunnerForClass(testClass);
+            if (runner != null) {
+                return runner;
+            }
+        }
+        return null;
+    }
+
+    protected JUnit4Builder junit4Builder() {
+        return new JUnit4Builder();
+    }
+
+    protected JUnit3Builder junit3Builder() {
+        return new JUnit3Builder();
+    }
+
+    protected AnnotatedBuilder annotatedBuilder() {
+        return new AnnotatedBuilder(this);
+    }
+
+    protected IgnoredBuilder ignoredBuilder() {
+        return new IgnoredBuilder();
+    }
+
+    protected RunnerBuilder suiteMethodBuilder() {
+        if (canUseSuiteMethod) {
+            return new SuiteMethodBuilder();
+        }
+        return new NullBuilder();
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AnnotatedBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AnnotatedBuilder.java
new file mode 100644
index 0000000..04d7a68
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AnnotatedBuilder.java
@@ -0,0 +1,116 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+import java.lang.reflect.Modifier;
+
+
+/**
+ * The {@code AnnotatedBuilder} is a strategy for constructing runners for test class that have been annotated with the
+ * {@code @RunWith} annotation. All tests within this class will be executed using the runner that was specified within
+ * the annotation.
+ * <p>
+ * If a runner supports inner member classes, the member classes will inherit the runner from the enclosing class, e.g.:
+ * <pre>
+ * &#064;RunWith(MyRunner.class)
+ * public class MyTest {
+ *     // some tests might go here
+ *
+ *     public class MyMemberClass {
+ *         &#064;Test
+ *         public void thisTestRunsWith_MyRunner() {
+ *             // some test logic
+ *         }
+ *
+ *         // some more tests might go here
+ *     }
+ *
+ *     &#064;RunWith(AnotherRunner.class)
+ *     public class AnotherMemberClass {
+ *         // some tests might go here
+ *
+ *         public class DeepInnerClass {
+ *             &#064;Test
+ *             public void thisTestRunsWith_AnotherRunner() {
+ *                 // some test logic
+ *             }
+ *         }
+ *
+ *         public class DeepInheritedClass extends SuperTest {
+ *             &#064;Test
+ *             public void thisTestRunsWith_SuperRunner() {
+ *                 // some test logic
+ *             }
+ *         }
+ *     }
+ * }
+ *
+ * &#064;RunWith(SuperRunner.class)
+ * public class SuperTest {
+ *     // some tests might go here
+ * }
+ * </pre>
+ * The key points to note here are:
+ * <ul>
+ *     <li>If there is no RunWith annotation, no runner will be created.</li>
+ *     <li>The resolve step is inside-out, e.g. the closest RunWith annotation wins</li>
+ *     <li>RunWith annotations are inherited and work as if the class was annotated itself.</li>
+ *     <li>The default JUnit runner does not support inner member classes,
+ *         so this is only valid for custom runners that support inner member classes.</li>
+ *     <li>Custom runners with support for inner classes may or may not support RunWith annotations for member
+ *         classes. Please refer to the custom runner documentation.</li>
+ * </ul>
+ *
+ * @see org.junit.runners.model.RunnerBuilder
+ * @see org.junit.runner.RunWith
+ * @since 4.0
+ */
+public class AnnotatedBuilder extends RunnerBuilder {
+    private static final String CONSTRUCTOR_ERROR_FORMAT = "Custom runner class %s should have a public constructor with signature %s(Class testClass)";
+
+    private final RunnerBuilder suiteBuilder;
+
+    public AnnotatedBuilder(RunnerBuilder suiteBuilder) {
+        this.suiteBuilder = suiteBuilder;
+    }
+
+    @Override
+    public Runner runnerForClass(Class<?> testClass) throws Exception {
+        for (Class<?> currentTestClass = testClass; currentTestClass != null;
+             currentTestClass = getEnclosingClassForNonStaticMemberClass(currentTestClass)) {
+            RunWith annotation = currentTestClass.getAnnotation(RunWith.class);
+            if (annotation != null) {
+                return buildRunner(annotation.value(), testClass);
+            }
+        }
+
+        return null;
+    }
+
+    private Class<?> getEnclosingClassForNonStaticMemberClass(Class<?> currentTestClass) {
+        if (currentTestClass.isMemberClass() && !Modifier.isStatic(currentTestClass.getModifiers())) {
+            return currentTestClass.getEnclosingClass();
+        } else {
+            return null;
+        }
+    }
+
+    public Runner buildRunner(Class<? extends Runner> runnerClass,
+            Class<?> testClass) throws Exception {
+        try {
+            return runnerClass.getConstructor(Class.class).newInstance(testClass);
+        } catch (NoSuchMethodException e) {
+            try {
+                return runnerClass.getConstructor(Class.class,
+                        RunnerBuilder.class).newInstance(testClass, suiteBuilder);
+            } catch (NoSuchMethodException e2) {
+                String simpleName = runnerClass.getSimpleName();
+                throw new InitializationError(String.format(
+                        CONSTRUCTOR_ERROR_FORMAT, simpleName, simpleName));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredBuilder.java
new file mode 100644
index 0000000..71940c8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredBuilder.java
@@ -0,0 +1,15 @@
+package org.junit.internal.builders;
+
+import org.junit.Ignore;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class IgnoredBuilder extends RunnerBuilder {
+    @Override
+    public Runner runnerForClass(Class<?> testClass) {
+        if (testClass.getAnnotation(Ignore.class) != null) {
+            return new IgnoredClassRunner(testClass);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredClassRunner.java
new file mode 100644
index 0000000..7c8926b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredClassRunner.java
@@ -0,0 +1,23 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+
+public class IgnoredClassRunner extends Runner {
+    private final Class<?> clazz;
+
+    public IgnoredClassRunner(Class<?> testClass) {
+        clazz = testClass;
+    }
+
+    @Override
+    public void run(RunNotifier notifier) {
+        notifier.fireTestIgnored(getDescription());
+    }
+
+    @Override
+    public Description getDescription() {
+        return Description.createSuiteDescription(clazz);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit3Builder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit3Builder.java
new file mode 100644
index 0000000..8b6b371
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit3Builder.java
@@ -0,0 +1,19 @@
+package org.junit.internal.builders;
+
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class JUnit3Builder extends RunnerBuilder {
+    @Override
+    public Runner runnerForClass(Class<?> testClass) throws Throwable {
+        if (isPre4Test(testClass)) {
+            return new JUnit38ClassRunner(testClass);
+        }
+        return null;
+    }
+
+    boolean isPre4Test(Class<?> testClass) {
+        return junit.framework.TestCase.class.isAssignableFrom(testClass);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit4Builder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit4Builder.java
new file mode 100644
index 0000000..7959e75
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit4Builder.java
@@ -0,0 +1,12 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.Runner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.model.RunnerBuilder;
+
+public class JUnit4Builder extends RunnerBuilder {
+    @Override
+    public Runner runnerForClass(Class<?> testClass) throws Throwable {
+        return new JUnit4(testClass);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/NullBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/NullBuilder.java
new file mode 100644
index 0000000..c8d306e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/NullBuilder.java
@@ -0,0 +1,11 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class NullBuilder extends RunnerBuilder {
+    @Override
+    public Runner runnerForClass(Class<?> each) throws Throwable {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/SuiteMethodBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/SuiteMethodBuilder.java
new file mode 100644
index 0000000..953e6cf
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/SuiteMethodBuilder.java
@@ -0,0 +1,24 @@
+package org.junit.internal.builders;
+
+import org.junit.internal.runners.SuiteMethod;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class SuiteMethodBuilder extends RunnerBuilder {
+    @Override
+    public Runner runnerForClass(Class<?> each) throws Throwable {
+        if (hasSuiteMethod(each)) {
+            return new SuiteMethod(each);
+        }
+        return null;
+    }
+
+    public boolean hasSuiteMethod(Class<?> testClass) {
+        try {
+            testClass.getMethod("suite");
+        } catch (NoSuchMethodException e) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeRuntimeMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeRuntimeMXBean.java
new file mode 100644
index 0000000..477b150
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeRuntimeMXBean.java
@@ -0,0 +1,21 @@
+package org.junit.internal.management;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * No-op implementation of RuntimeMXBean when the platform doesn't provide it.
+ */
+class FakeRuntimeMXBean implements RuntimeMXBean {
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>Always returns an empty list.
+   */
+  public List<String> getInputArguments() {
+    return Collections.emptyList();
+  }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeThreadMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeThreadMXBean.java
new file mode 100644
index 0000000..893f2e3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeThreadMXBean.java
@@ -0,0 +1,27 @@
+package org.junit.internal.management;
+
+/**
+ * No-op implementation of ThreadMXBean when the platform doesn't provide it.
+ */
+final class FakeThreadMXBean implements ThreadMXBean {
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>Always throws an {@link UnsupportedOperationException}
+   */
+  public long getThreadCpuTime(long id) {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>Always returns false.
+   */
+  public boolean isThreadCpuTimeSupported() {
+    return false;
+  }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ManagementFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ManagementFactory.java
new file mode 100644
index 0000000..5be1447
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ManagementFactory.java
@@ -0,0 +1,77 @@
+package org.junit.internal.management;
+
+import org.junit.internal.Classes;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Reflective wrapper around {@link java.lang.management.ManagementFactory}
+ */
+public class ManagementFactory {
+  private static final class FactoryHolder {
+    private static final Class<?> MANAGEMENT_FACTORY_CLASS;
+
+    static {
+      Class<?> managementFactoryClass = null;
+      try {
+        managementFactoryClass = Classes.getClass("java.lang.management.ManagementFactory");
+      } catch (ClassNotFoundException e) {
+        // do nothing, managementFactoryClass will be none on failure
+      }
+      MANAGEMENT_FACTORY_CLASS = managementFactoryClass;
+    }
+
+    static Object getBeanObject(String methodName) {
+      if (MANAGEMENT_FACTORY_CLASS != null) {
+        try {
+          return MANAGEMENT_FACTORY_CLASS.getMethod(methodName).invoke(null);
+        } catch (IllegalAccessException e) {
+          // fallthrough
+        } catch (IllegalArgumentException e) {
+          // fallthrough
+        } catch (InvocationTargetException e) {
+          // fallthrough
+        } catch (NoSuchMethodException e) {
+          // fallthrough
+        } catch (SecurityException e) {
+          // fallthrough
+        }
+      }
+      return null;
+    }
+  }
+
+  private static final class RuntimeHolder {
+    private static final RuntimeMXBean RUNTIME_MX_BEAN =
+        getBean(FactoryHolder.getBeanObject("getRuntimeMXBean"));
+
+    private static final RuntimeMXBean getBean(Object runtimeMxBean) {
+      return runtimeMxBean != null
+          ? new ReflectiveRuntimeMXBean(runtimeMxBean) : new FakeRuntimeMXBean();
+    }
+  }
+
+  private static final class ThreadHolder {
+    private static final ThreadMXBean THREAD_MX_BEAN =
+        getBean(FactoryHolder.getBeanObject("getThreadMXBean"));
+
+    private static final ThreadMXBean getBean(Object threadMxBean) {
+      return threadMxBean != null
+          ? new ReflectiveThreadMXBean(threadMxBean) : new FakeThreadMXBean();
+    }
+  }
+
+  /**
+   * @see java.lang.management.ManagementFactory#getRuntimeMXBean()
+   */
+  public static RuntimeMXBean getRuntimeMXBean() {
+    return RuntimeHolder.RUNTIME_MX_BEAN;
+  }
+
+  /**
+   * @see java.lang.management.ManagementFactory#getThreadMXBean()
+   */
+  public static ThreadMXBean getThreadMXBean() {
+    return ThreadHolder.THREAD_MX_BEAN;
+  }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java
new file mode 100644
index 0000000..289587a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java
@@ -0,0 +1,61 @@
+package org.junit.internal.management;
+
+import org.junit.internal.Classes;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Implementation of {@link RuntimeMXBean} using the JVM reflectively.
+ */
+final class ReflectiveRuntimeMXBean implements RuntimeMXBean {
+  private final Object runtimeMxBean;
+
+  private static final class Holder {
+    private static final Method getInputArgumentsMethod;
+    static {
+      Method inputArguments = null;
+      try {
+        Class<?> threadMXBeanClass = Classes.getClass("java.lang.management.RuntimeMXBean");
+        inputArguments = threadMXBeanClass.getMethod("getInputArguments");
+      } catch (ClassNotFoundException e) {
+        // do nothing, input arguments will be null on failure
+      } catch (NoSuchMethodException e) {
+        // do nothing, input arguments will be null on failure
+      } catch (SecurityException e) {
+        // do nothing, input arguments will be null on failure
+      }
+      getInputArgumentsMethod = inputArguments;
+    }
+  }
+
+  ReflectiveRuntimeMXBean(Object runtimeMxBean) {
+    super();
+    this.runtimeMxBean = runtimeMxBean;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @SuppressWarnings("unchecked")
+  public List<String> getInputArguments() {
+    if (Holder.getInputArgumentsMethod != null) {
+      try {
+        return (List<String>) Holder.getInputArgumentsMethod.invoke(runtimeMxBean);
+      } catch (ClassCastException e) { // no multi-catch with source level 6
+        // fallthrough
+      } catch (IllegalAccessException e) {
+        // fallthrough
+      } catch (IllegalArgumentException e) {
+        // fallthrough
+      } catch (InvocationTargetException e) {
+        // fallthrough
+      }
+    }
+    return Collections.emptyList();
+  }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java
new file mode 100644
index 0000000..bc741be
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java
@@ -0,0 +1,92 @@
+package org.junit.internal.management;
+
+import org.junit.internal.Classes;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Implementation of {@link ThreadMXBean} using the JVM reflectively.
+ */
+final class ReflectiveThreadMXBean implements ThreadMXBean {
+  private final Object threadMxBean;
+
+
+  private static final class Holder {
+    static final Method getThreadCpuTimeMethod;
+    static final Method isThreadCpuTimeSupportedMethod;
+
+    private static final String FAILURE_MESSAGE = "Unable to access ThreadMXBean";
+
+    static {
+      Method threadCpuTime = null;
+      Method threadCpuTimeSupported = null;
+      try {
+        Class<?> threadMXBeanClass = Classes.getClass("java.lang.management.ThreadMXBean");
+        threadCpuTime = threadMXBeanClass.getMethod("getThreadCpuTime", long.class);
+        threadCpuTimeSupported = threadMXBeanClass.getMethod("isThreadCpuTimeSupported");
+      } catch (ClassNotFoundException e) {
+        // do nothing, the methods will be null on failure
+      } catch (NoSuchMethodException e) {
+        // do nothing, the methods will be null on failure
+      } catch (SecurityException e) {
+        // do nothing, the methods will be null on failure
+      }
+      getThreadCpuTimeMethod = threadCpuTime;
+      isThreadCpuTimeSupportedMethod = threadCpuTimeSupported;
+    }
+  }
+
+  ReflectiveThreadMXBean(Object threadMxBean) {
+    super();
+    this.threadMxBean = threadMxBean;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public long getThreadCpuTime(long id) {
+    if (Holder.getThreadCpuTimeMethod != null) {
+      Exception error = null;
+      try {
+        return (Long) Holder.getThreadCpuTimeMethod.invoke(threadMxBean, id);
+      } catch (ClassCastException e) {
+        error = e;
+        // fallthrough
+      } catch (IllegalAccessException e) {
+        error = e;
+        // fallthrough
+      } catch (IllegalArgumentException e) {
+        error = e;
+        // fallthrough
+      } catch (InvocationTargetException e) {
+        error = e;
+        // fallthrough
+      }
+      throw new UnsupportedOperationException(Holder.FAILURE_MESSAGE, error);
+    }
+    throw new UnsupportedOperationException(Holder.FAILURE_MESSAGE);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isThreadCpuTimeSupported() {
+    if (Holder.isThreadCpuTimeSupportedMethod != null) {
+      try {
+        return (Boolean) Holder.isThreadCpuTimeSupportedMethod.invoke(threadMxBean);
+      } catch (ClassCastException e) {
+        // fallthrough
+      } catch (IllegalAccessException e) {
+        // fallthrough
+      } catch (IllegalArgumentException e) {
+        // fallthrough
+      } catch (InvocationTargetException e) {
+        // fallthrough
+      }
+    }
+    return false;
+  }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/RuntimeMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/RuntimeMXBean.java
new file mode 100644
index 0000000..84f8861
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/RuntimeMXBean.java
@@ -0,0 +1,14 @@
+package org.junit.internal.management;
+
+import java.util.List;
+
+/**
+ * Wrapper for {@link java.lang.management.RuntimeMXBean}.
+ */
+public interface RuntimeMXBean {
+
+  /**
+   * @see java.lang.management.RuntimeMXBean#getInputArguments()
+   */
+  List<String> getInputArguments();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ThreadMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ThreadMXBean.java
new file mode 100644
index 0000000..f9225c9
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ThreadMXBean.java
@@ -0,0 +1,17 @@
+package org.junit.internal.management;
+
+/**
+ * Wrapper for {@link java.lang.management.ThreadMXBean}.
+ */
+public interface ThreadMXBean {
+  /**
+   * @see java.lang.management.ThreadMXBean#getThreadCpuTime(long)
+   */
+  long getThreadCpuTime(long id);
+
+  /**
+   * @see java.lang.management.ThreadMXBean#isThreadCpuTimeSupported()
+   */
+  boolean isThreadCpuTimeSupported();
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
new file mode 100644
index 0000000..93a6827
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
@@ -0,0 +1,53 @@
+package org.junit.internal.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+
+import org.junit.internal.Throwables;
+
+/**
+ * A matcher that delegates to throwableMatcher and in addition appends the
+ * stacktrace of the actual Throwable in case of a mismatch.
+ */
+public class StacktracePrintingMatcher<T extends Throwable> extends
+        org.hamcrest.TypeSafeMatcher<T> {
+
+    private final Matcher<T> throwableMatcher;
+
+    public StacktracePrintingMatcher(Matcher<T> throwableMatcher) {
+        this.throwableMatcher = throwableMatcher;
+    }
+
+    public void describeTo(Description description) {
+        throwableMatcher.describeTo(description);
+    }
+
+    @Override
+    protected boolean matchesSafely(T item) {
+        return throwableMatcher.matches(item);
+    }
+
+    @Override
+    protected void describeMismatchSafely(T item, Description description) {
+        throwableMatcher.describeMismatch(item, description);
+        description.appendText("\nStacktrace was: ");
+        description.appendText(readStacktrace(item));
+    }
+
+    private String readStacktrace(Throwable throwable) {
+        return Throwables.getStacktrace(throwable);
+    }
+
+    @Factory
+    public static <T extends Throwable> Matcher<T> isThrowable(
+            Matcher<T> throwableMatcher) {
+        return new StacktracePrintingMatcher<T>(throwableMatcher);
+    }
+
+    @Factory
+    public static <T extends Exception> Matcher<T> isException(
+            Matcher<T> exceptionMatcher) {
+        return new StacktracePrintingMatcher<T>(exceptionMatcher);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
new file mode 100644
index 0000000..6e2ff5e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
@@ -0,0 +1,50 @@
+package org.junit.internal.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * A matcher that applies a delegate matcher to the cause of the current Throwable, returning the result of that
+ * match.
+ *
+ * @param <T> the type of the throwable being matched
+ */
+public class ThrowableCauseMatcher<T extends Throwable> extends
+        TypeSafeMatcher<T> {
+
+    private final Matcher<?> causeMatcher;
+
+    public ThrowableCauseMatcher(Matcher<?> causeMatcher) {
+        this.causeMatcher = causeMatcher;
+    }
+
+    public void describeTo(Description description) {
+        description.appendText("exception with cause ");
+        description.appendDescriptionOf(causeMatcher);
+    }
+
+    @Override
+    protected boolean matchesSafely(T item) {
+        return causeMatcher.matches(item.getCause());
+    }
+
+    @Override
+    protected void describeMismatchSafely(T item, Description description) {
+        description.appendText("cause ");
+        causeMatcher.describeMismatch(item.getCause(), description);
+    }
+
+    /**
+     * Returns a matcher that verifies that the outer exception has a cause for which the supplied matcher
+     * evaluates to true.
+     *
+     * @param matcher to apply to the cause of the outer exception
+     * @param <T> type of the outer exception
+     */
+    @Factory
+    public static <T extends Throwable> Matcher<T> hasCause(final Matcher<?> matcher) {
+        return new ThrowableCauseMatcher<T>(matcher);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableMessageMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableMessageMatcher.java
new file mode 100644
index 0000000..74386a8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableMessageMatcher.java
@@ -0,0 +1,37 @@
+package org.junit.internal.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+public class ThrowableMessageMatcher<T extends Throwable> extends
+        TypeSafeMatcher<T> {
+
+    private final Matcher<String> matcher;
+
+    public ThrowableMessageMatcher(Matcher<String> matcher) {
+        this.matcher = matcher;
+    }
+
+    public void describeTo(Description description) {
+        description.appendText("exception with message ");
+        description.appendDescriptionOf(matcher);
+    }
+
+    @Override
+    protected boolean matchesSafely(T item) {
+        return matcher.matches(item.getMessage());
+    }
+
+    @Override
+    protected void describeMismatchSafely(T item, Description description) {
+        description.appendText("message ");
+        matcher.describeMismatch(item.getMessage(), description);
+    }
+
+    @Factory
+    public static <T extends Throwable> Matcher<T> hasMessage(final Matcher<String> matcher) {
+        return new ThrowableMessageMatcher<T>(matcher);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/TypeSafeMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/TypeSafeMatcher.java
new file mode 100644
index 0000000..fb25982
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/TypeSafeMatcher.java
@@ -0,0 +1,63 @@
+package org.junit.internal.matchers;
+
+import java.lang.reflect.Method;
+
+import org.hamcrest.BaseMatcher;
+import org.junit.internal.MethodSorter;
+
+/**
+ * Convenient base class for Matchers that require a non-null value of a specific type.
+ * This simply implements the null check, checks the type and then casts.
+ *
+ * @author Joe Walnes
+ * @deprecated Please use {@link org.hamcrest.TypeSafeMatcher}.
+ */
+@Deprecated
+public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
+
+    private Class<?> expectedType;
+
+    /**
+     * Subclasses should implement this. The item will already have been checked for
+     * the specific type and will never be null.
+     */
+    public abstract boolean matchesSafely(T item);
+
+    protected TypeSafeMatcher() {
+        expectedType = findExpectedType(getClass());
+    }
+
+    private static Class<?> findExpectedType(Class<?> fromClass) {
+        for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
+            for (Method method : MethodSorter.getDeclaredMethods(c)) {
+                if (isMatchesSafelyMethod(method)) {
+                    return method.getParameterTypes()[0];
+                }
+            }
+        }
+
+        throw new Error("Cannot determine correct type for matchesSafely() method.");
+    }
+
+    private static boolean isMatchesSafelyMethod(Method method) {
+        return "matchesSafely".equals(method.getName())
+                && method.getParameterTypes().length == 1
+                && !method.isSynthetic();
+    }
+
+    protected TypeSafeMatcher(Class<T> expectedType) {
+        this.expectedType = expectedType;
+    }
+
+    /**
+     * Method made final to prevent accidental override.
+     * If you need to override this, there's no point on extending TypeSafeMatcher.
+     * Instead, extend the {@link BaseMatcher}.
+     */
+    @SuppressWarnings({"unchecked"})
+    public final boolean matches(Object item) {
+        return item != null
+                && expectedType.isInstance(item)
+                && matchesSafely((T) item);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/ClassRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/ClassRequest.java
new file mode 100644
index 0000000..d60e360
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/ClassRequest.java
@@ -0,0 +1,54 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.internal.builders.SuiteMethodBuilder;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class ClassRequest extends MemoizingRequest {
+    /*
+     * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses
+     * reflection to access this field. See
+     * https://github.com/junit-team/junit4/issues/960
+     */
+    private final Class<?> fTestClass;
+    private final boolean canUseSuiteMethod;
+
+    public ClassRequest(Class<?> testClass, boolean canUseSuiteMethod) {
+        this.fTestClass = testClass;
+        this.canUseSuiteMethod = canUseSuiteMethod;
+    }
+
+    public ClassRequest(Class<?> testClass) {
+        this(testClass, true);
+    }
+
+    @Override
+    protected Runner createRunner() {
+        return new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass);
+    }
+
+    private class CustomAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBuilder {
+
+        @Override
+        protected RunnerBuilder suiteMethodBuilder() {
+            return new CustomSuiteMethodBuilder();
+        }
+    }
+
+    /*
+     * Customization of {@link SuiteMethodBuilder} that prevents use of the
+     * suite method when creating a runner for fTestClass when canUseSuiteMethod
+     * is false.
+     */
+    private class CustomSuiteMethodBuilder extends SuiteMethodBuilder {
+
+        @Override
+        public Runner runnerForClass(Class<?> testClass) throws Throwable {
+            if (testClass == fTestClass && !canUseSuiteMethod) {
+                return null;
+            }
+            return super.runnerForClass(testClass);
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/FilterRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/FilterRequest.java
new file mode 100644
index 0000000..5f00399
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/FilterRequest.java
@@ -0,0 +1,45 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+
+/**
+ * A filtered {@link Request}.
+ */
+public final class FilterRequest extends Request {
+    private final Request request;
+    /*
+     * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses
+     * reflection to access this field. See
+     * https://github.com/junit-team/junit4/issues/960
+     */
+    private final Filter fFilter;
+
+    /**
+     * Creates a filtered Request
+     *
+     * @param request a {@link Request} describing your Tests
+     * @param filter {@link Filter} to apply to the Tests described in
+     * <code>request</code>
+     */
+    public FilterRequest(Request request, Filter filter) {
+        this.request = request;
+        this.fFilter = filter;
+    }
+
+    @Override
+    public Runner getRunner() {
+        try {
+            Runner runner = request.getRunner();
+            fFilter.apply(runner);
+            return runner;
+        } catch (NoTestsRemainException e) {
+            return new ErrorReportingRunner(Filter.class, new Exception(String
+                    .format("No tests found matching %s from %s", fFilter
+                            .describe(), request.toString())));
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/MemoizingRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/MemoizingRequest.java
new file mode 100644
index 0000000..191c230
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/MemoizingRequest.java
@@ -0,0 +1,30 @@
+package org.junit.internal.requests;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+
+abstract class MemoizingRequest extends Request {
+    private final Lock runnerLock = new ReentrantLock();
+    private volatile Runner runner;
+
+    @Override
+    public final Runner getRunner() {
+        if (runner == null) {
+            runnerLock.lock();
+            try {
+                if (runner == null) {
+                    runner = createRunner();
+                }
+            } finally {
+                runnerLock.unlock();
+            }
+        }
+        return runner;
+    }
+
+    /** Creates the {@link Runner} to return from {@link #getRunner()}. Called at most once. */
+    protected abstract Runner createRunner();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/OrderingRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/OrderingRequest.java
new file mode 100644
index 0000000..441e595
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/OrderingRequest.java
@@ -0,0 +1,29 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.Ordering;
+
+/** @since 4.13 */
+public class OrderingRequest extends MemoizingRequest {
+    private final Request request;
+    private final Ordering ordering;
+
+    public OrderingRequest(Request request, Ordering ordering) {
+        this.request = request;
+        this.ordering = ordering;
+    }
+
+    @Override
+    protected Runner createRunner() {
+        Runner runner = request.getRunner();
+        try {
+            ordering.apply(runner);
+        } catch (InvalidOrderingException e) {
+            return new ErrorReportingRunner(ordering.getClass(), e);
+        }
+        return runner;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/SortingRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/SortingRequest.java
new file mode 100644
index 0000000..77061da
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/SortingRequest.java
@@ -0,0 +1,25 @@
+package org.junit.internal.requests;
+
+import java.util.Comparator;
+
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Sorter;
+
+public class SortingRequest extends Request {
+    private final Request request;
+    private final Comparator<Description> comparator;
+
+    public SortingRequest(Request request, Comparator<Description> comparator) {
+        this.request = request;
+        this.comparator = comparator;
+    }
+
+    @Override
+    public Runner getRunner() {
+        Runner runner = request.getRunner();
+        new Sorter(comparator).apply(runner);
+        return runner;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/package-info.java
new file mode 100644
index 0000000..66d2928
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides implementations of {@link org.junit.runner.Request}.
+ *
+ * @since 4.0
+ */
+package org.junit.internal.requests;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ClassRoadie.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ClassRoadie.java
new file mode 100644
index 0000000..df1b453
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ClassRoadie.java
@@ -0,0 +1,81 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class ClassRoadie {
+    private RunNotifier notifier;
+    private TestClass testClass;
+    private Description description;
+    private final Runnable runnable;
+
+    public ClassRoadie(RunNotifier notifier, TestClass testClass,
+            Description description, Runnable runnable) {
+        this.notifier = notifier;
+        this.testClass = testClass;
+        this.description = description;
+        this.runnable = runnable;
+    }
+
+    protected void runUnprotected() {
+        runnable.run();
+    }
+
+    protected void addFailure(Throwable targetException) {
+        notifier.fireTestFailure(new Failure(description, targetException));
+    }
+
+    public void runProtected() {
+        try {
+            runBefores();
+            runUnprotected();
+        } catch (FailedBefore e) {
+        } finally {
+            runAfters();
+        }
+    }
+
+    private void runBefores() throws FailedBefore {
+        try {
+            try {
+                List<Method> befores = testClass.getBefores();
+                for (Method before : befores) {
+                    before.invoke(null);
+                }
+            } catch (InvocationTargetException e) {
+                throw e.getTargetException();
+            }
+        } catch (AssumptionViolatedException e) {
+            throw new FailedBefore();
+        } catch (Throwable e) {
+            addFailure(e);
+            throw new FailedBefore();
+        }
+    }
+
+    private void runAfters() {
+        List<Method> afters = testClass.getAfters();
+        for (Method after : afters) {
+            try {
+                after.invoke(null);
+            } catch (InvocationTargetException e) {
+                addFailure(e.getTargetException());
+            } catch (Throwable e) {
+                addFailure(e); // Untested, but seems impossible
+            }
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ErrorReportingRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ErrorReportingRunner.java
new file mode 100644
index 0000000..f52abab
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ErrorReportingRunner.java
@@ -0,0 +1,92 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InvalidTestClassError;
+import org.junit.runners.model.InitializationError;
+
+import static java.util.Collections.singletonList;
+
+public class ErrorReportingRunner extends Runner {
+    private final List<Throwable> causes;
+
+    private final String classNames;
+
+    public ErrorReportingRunner(Class<?> testClass, Throwable cause) {
+        this(cause, testClass);
+    }
+    
+    public ErrorReportingRunner(Throwable cause, Class<?>... testClasses) {
+        if (testClasses == null || testClasses.length == 0) {
+            throw new NullPointerException("Test classes cannot be null or empty");
+        }
+        for (Class<?> testClass : testClasses) {
+            if (testClass == null) {
+                throw new NullPointerException("Test class cannot be null");
+            }
+        }
+        classNames = getClassNames(testClasses);
+        causes = getCauses(cause);
+    }
+    
+    @Override
+    public Description getDescription() {
+        Description description = Description.createSuiteDescription(classNames);
+        for (Throwable each : causes) {
+            description.addChild(describeCause());
+        }
+        return description;
+    }
+
+    @Override
+    public void run(RunNotifier notifier) {
+        for (Throwable each : causes) {
+            runCause(each, notifier);
+        }
+    }
+
+    private String getClassNames(Class<?>... testClasses) {
+        final StringBuilder builder = new StringBuilder();
+        for (Class<?> testClass : testClasses) {
+            if (builder.length() != 0) {
+                builder.append(", ");
+            }
+            builder.append(testClass.getName());
+        }
+        return builder.toString();
+    }
+
+    @SuppressWarnings("deprecation")
+    private List<Throwable> getCauses(Throwable cause) {
+        if (cause instanceof InvocationTargetException) {
+            return getCauses(cause.getCause());
+        }
+        if (cause instanceof InvalidTestClassError) {
+            return singletonList(cause);
+        }
+        if (cause instanceof InitializationError) {
+            return ((InitializationError) cause).getCauses();
+        }
+        if (cause instanceof org.junit.internal.runners.InitializationError) {
+            return ((org.junit.internal.runners.InitializationError) cause)
+                    .getCauses();
+        }
+        return singletonList(cause);
+    }
+
+    private Description describeCause() {
+        return Description.createTestDescription(classNames, "initializationError");
+    }
+
+    private void runCause(Throwable child, RunNotifier notifier) {
+        Description description = describeCause();
+        notifier.fireTestStarted(description);
+        notifier.fireTestFailure(new Failure(description, child));
+        notifier.fireTestFinished(description);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/FailedBefore.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/FailedBefore.java
new file mode 100644
index 0000000..1036cb6
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/FailedBefore.java
@@ -0,0 +1,13 @@
+package org.junit.internal.runners;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+class FailedBefore extends Exception {
+    private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/InitializationError.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/InitializationError.java
new file mode 100644
index 0000000..484f58d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/InitializationError.java
@@ -0,0 +1,37 @@
+package org.junit.internal.runners;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Use the published version:
+ * {@link org.junit.runners.model.InitializationError}
+ * This may disappear as soon as 1 April 2009
+ */
+@Deprecated
+public class InitializationError extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * We have to use the f prefix until the next major release to ensure
+     * serialization compatibility. 
+     * See https://github.com/junit-team/junit4/issues/976
+     */
+    private final List<Throwable> fErrors;
+
+    public InitializationError(List<Throwable> errors) {
+        this.fErrors = errors;
+    }
+
+    public InitializationError(Throwable... errors) {
+        this(Arrays.asList(errors));
+    }
+
+    public InitializationError(String string) {
+        this(new Exception(string));
+    }
+
+    public List<Throwable> getCauses() {
+        return fErrors;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit38ClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
new file mode 100644
index 0000000..0d51541
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
@@ -0,0 +1,196 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import junit.extensions.TestDecorator;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import org.junit.runner.Describable;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+
+public class JUnit38ClassRunner extends Runner implements Filterable, Orderable {
+    private static final class OldTestClassAdaptingListener implements
+            TestListener {
+        private final RunNotifier notifier;
+
+        private OldTestClassAdaptingListener(RunNotifier notifier) {
+            this.notifier = notifier;
+        }
+
+        public void endTest(Test test) {
+            notifier.fireTestFinished(asDescription(test));
+        }
+
+        public void startTest(Test test) {
+            notifier.fireTestStarted(asDescription(test));
+        }
+
+        // Implement junit.framework.TestListener
+        public void addError(Test test, Throwable e) {
+            Failure failure = new Failure(asDescription(test), e);
+            notifier.fireTestFailure(failure);
+        }
+
+        private Description asDescription(Test test) {
+            if (test instanceof Describable) {
+                Describable facade = (Describable) test;
+                return facade.getDescription();
+            }
+            return Description.createTestDescription(getEffectiveClass(test), getName(test));
+        }
+
+        private Class<? extends Test> getEffectiveClass(Test test) {
+            return test.getClass();
+        }
+
+        private String getName(Test test) {
+            if (test instanceof TestCase) {
+                return ((TestCase) test).getName();
+            } else {
+                return test.toString();
+            }
+        }
+
+        public void addFailure(Test test, AssertionFailedError t) {
+            addError(test, t);
+        }
+    }
+
+    private volatile Test test;
+
+    public JUnit38ClassRunner(Class<?> klass) {
+        this(new TestSuite(klass.asSubclass(TestCase.class)));
+    }
+
+    public JUnit38ClassRunner(Test test) {
+        super();
+        setTest(test);
+    }
+
+    @Override
+    public void run(RunNotifier notifier) {
+        TestResult result = new TestResult();
+        result.addListener(createAdaptingListener(notifier));
+        getTest().run(result);
+    }
+
+    public TestListener createAdaptingListener(final RunNotifier notifier) {
+        return new OldTestClassAdaptingListener(notifier);
+    }
+
+    @Override
+    public Description getDescription() {
+        return makeDescription(getTest());
+    }
+
+    private static Description makeDescription(Test test) {
+        if (test instanceof TestCase) {
+            TestCase tc = (TestCase) test;
+            return Description.createTestDescription(tc.getClass(), tc.getName(),
+                    getAnnotations(tc));
+        } else if (test instanceof TestSuite) {
+            TestSuite ts = (TestSuite) test;
+            String name = ts.getName() == null ? createSuiteDescription(ts) : ts.getName();
+            Description description = Description.createSuiteDescription(name);
+            int n = ts.testCount();
+            for (int i = 0; i < n; i++) {
+                Description made = makeDescription(ts.testAt(i));
+                description.addChild(made);
+            }
+            return description;
+        } else if (test instanceof Describable) {
+            Describable adapter = (Describable) test;
+            return adapter.getDescription();
+        } else if (test instanceof TestDecorator) {
+            TestDecorator decorator = (TestDecorator) test;
+            return makeDescription(decorator.getTest());
+        } else {
+            // This is the best we can do in this case
+            return Description.createSuiteDescription(test.getClass());
+        }
+    }
+
+    /**
+     * Get the annotations associated with given TestCase.
+     * @param test the TestCase.
+     */
+    private static Annotation[] getAnnotations(TestCase test) {
+        try {
+            Method m = test.getClass().getMethod(test.getName());
+            return m.getDeclaredAnnotations();
+        } catch (SecurityException e) {
+        } catch (NoSuchMethodException e) {
+        }
+        return new Annotation[0];
+    }
+
+    private static String createSuiteDescription(TestSuite ts) {
+        int count = ts.countTestCases();
+        String example = count == 0 ? "" : String.format(" [example: %s]", ts.testAt(0));
+        return String.format("TestSuite with %s tests%s", count, example);
+    }
+
+    public void filter(Filter filter) throws NoTestsRemainException {
+        if (getTest() instanceof Filterable) {
+            Filterable adapter = (Filterable) getTest();
+            adapter.filter(filter);
+        } else if (getTest() instanceof TestSuite) {
+            TestSuite suite = (TestSuite) getTest();
+            TestSuite filtered = new TestSuite(suite.getName());
+            int n = suite.testCount();
+            for (int i = 0; i < n; i++) {
+                Test test = suite.testAt(i);
+                if (filter.shouldRun(makeDescription(test))) {
+                    filtered.addTest(test);
+                }
+            }
+            setTest(filtered);
+            if (filtered.testCount() == 0) {
+                throw new NoTestsRemainException();
+            }
+        }
+    }
+
+    public void sort(Sorter sorter) {
+        if (getTest() instanceof Sortable) {
+            Sortable adapter = (Sortable) getTest();
+            adapter.sort(sorter);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 4.13
+     */
+    public void order(Orderer orderer) throws InvalidOrderingException {
+        if (getTest() instanceof Orderable) {
+            Orderable adapter = (Orderable) getTest();
+            adapter.order(orderer);
+        }
+    }
+
+    private void setTest(Test test) {
+        this.test = test;
+    }
+
+    private Test getTest() {
+        return test;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit4ClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit4ClassRunner.java
new file mode 100644
index 0000000..69a23c4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit4ClassRunner.java
@@ -0,0 +1,147 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class JUnit4ClassRunner extends Runner implements Filterable, Sortable {
+    private final List<Method> testMethods;
+    private TestClass testClass;
+
+    public JUnit4ClassRunner(Class<?> klass) throws InitializationError {
+        testClass = new TestClass(klass);
+        testMethods = getTestMethods();
+        validate();
+    }
+
+    protected List<Method> getTestMethods() {
+        return testClass.getTestMethods();
+    }
+
+    protected void validate() throws InitializationError {
+        MethodValidator methodValidator = new MethodValidator(testClass);
+        methodValidator.validateMethodsForDefaultRunner();
+        methodValidator.assertValid();
+    }
+
+    @Override
+    public void run(final RunNotifier notifier) {
+        new ClassRoadie(notifier, testClass, getDescription(), new Runnable() {
+            public void run() {
+                runMethods(notifier);
+            }
+        }).runProtected();
+    }
+
+    protected void runMethods(final RunNotifier notifier) {
+        for (Method method : testMethods) {
+            invokeTestMethod(method, notifier);
+        }
+    }
+
+    @Override
+    public Description getDescription() {
+        Description spec = Description.createSuiteDescription(getName(), classAnnotations());
+        List<Method> testMethods = this.testMethods;
+        for (Method method : testMethods) {
+            spec.addChild(methodDescription(method));
+        }
+        return spec;
+    }
+
+    protected Annotation[] classAnnotations() {
+        return testClass.getJavaClass().getAnnotations();
+    }
+
+    protected String getName() {
+        return getTestClass().getName();
+    }
+
+    protected Object createTest() throws Exception {
+        return getTestClass().getConstructor().newInstance();
+    }
+
+    protected void invokeTestMethod(Method method, RunNotifier notifier) {
+        Description description = methodDescription(method);
+        Object test;
+        try {
+            test = createTest();
+        } catch (InvocationTargetException e) {
+            testAborted(notifier, description, e.getCause());
+            return;
+        } catch (Exception e) {
+            testAborted(notifier, description, e);
+            return;
+        }
+        TestMethod testMethod = wrapMethod(method);
+        new MethodRoadie(test, testMethod, notifier, description).run();
+    }
+
+    private void testAborted(RunNotifier notifier, Description description,
+            Throwable e) {
+        notifier.fireTestStarted(description);
+        notifier.fireTestFailure(new Failure(description, e));
+        notifier.fireTestFinished(description);
+    }
+
+    protected TestMethod wrapMethod(Method method) {
+        return new TestMethod(method, testClass);
+    }
+
+    protected String testName(Method method) {
+        return method.getName();
+    }
+
+    protected Description methodDescription(Method method) {
+        return Description.createTestDescription(getTestClass().getJavaClass(), testName(method), testAnnotations(method));
+    }
+
+    protected Annotation[] testAnnotations(Method method) {
+        return method.getAnnotations();
+    }
+
+    public void filter(Filter filter) throws NoTestsRemainException {
+        for (Iterator<Method> iter = testMethods.iterator(); iter.hasNext(); ) {
+            Method method = iter.next();
+            if (!filter.shouldRun(methodDescription(method))) {
+                iter.remove();
+            }
+        }
+        if (testMethods.isEmpty()) {
+            throw new NoTestsRemainException();
+        }
+    }
+
+    public void sort(final Sorter sorter) {
+        Collections.sort(testMethods, new Comparator<Method>() {
+            public int compare(Method o1, Method o2) {
+                return sorter.compare(methodDescription(o1), methodDescription(o2));
+            }
+        });
+    }
+
+    protected TestClass getTestClass() {
+        return testClass;
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodRoadie.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodRoadie.java
new file mode 100644
index 0000000..01a476b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodRoadie.java
@@ -0,0 +1,163 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.TestTimedOutException;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class MethodRoadie {
+    private final Object test;
+    private final RunNotifier notifier;
+    private final Description description;
+    private TestMethod testMethod;
+
+    public MethodRoadie(Object test, TestMethod method, RunNotifier notifier, Description description) {
+        this.test = test;
+        this.notifier = notifier;
+        this.description = description;
+        testMethod = method;
+    }
+
+    public void run() {
+        if (testMethod.isIgnored()) {
+            notifier.fireTestIgnored(description);
+            return;
+        }
+        notifier.fireTestStarted(description);
+        try {
+            long timeout = testMethod.getTimeout();
+            if (timeout > 0) {
+                runWithTimeout(timeout);
+            } else {
+                runTest();
+            }
+        } finally {
+            notifier.fireTestFinished(description);
+        }
+    }
+
+    private void runWithTimeout(final long timeout) {
+        runBeforesThenTestThenAfters(new Runnable() {
+
+            public void run() {
+                ExecutorService service = Executors.newSingleThreadExecutor();
+                Callable<Object> callable = new Callable<Object>() {
+                    public Object call() throws Exception {
+                        runTestMethod();
+                        return null;
+                    }
+                };
+                Future<Object> result = service.submit(callable);
+                service.shutdown();
+                try {
+                    boolean terminated = service.awaitTermination(timeout,
+                            TimeUnit.MILLISECONDS);
+                    if (!terminated) {
+                        service.shutdownNow();
+                    }
+                    result.get(0, TimeUnit.MILLISECONDS); // throws the exception if one occurred during the invocation
+                } catch (TimeoutException e) {
+                    addFailure(new TestTimedOutException(timeout, TimeUnit.MILLISECONDS));
+                } catch (Exception e) {
+                    addFailure(e);
+                }
+            }
+        });
+    }
+
+    public void runTest() {
+        runBeforesThenTestThenAfters(new Runnable() {
+            public void run() {
+                runTestMethod();
+            }
+        });
+    }
+
+    public void runBeforesThenTestThenAfters(Runnable test) {
+        try {
+            runBefores();
+            test.run();
+        } catch (FailedBefore e) {
+        } catch (Exception e) {
+            throw new RuntimeException("test should never throw an exception to this level");
+        } finally {
+            runAfters();
+        }
+    }
+
+    protected void runTestMethod() {
+        try {
+            testMethod.invoke(test);
+            if (testMethod.expectsException()) {
+                addFailure(new AssertionError("Expected exception: " + testMethod.getExpectedException().getName()));
+            }
+        } catch (InvocationTargetException e) {
+            Throwable actual = e.getTargetException();
+            if (actual instanceof AssumptionViolatedException) {
+                return;
+            } else if (!testMethod.expectsException()) {
+                addFailure(actual);
+            } else if (testMethod.isUnexpected(actual)) {
+                String message = "Unexpected exception, expected<" + testMethod.getExpectedException().getName() + "> but was<"
+                        + actual.getClass().getName() + ">";
+                addFailure(new Exception(message, actual));
+            }
+        } catch (Throwable e) {
+            addFailure(e);
+        }
+    }
+
+    private void runBefores() throws FailedBefore {
+        try {
+            try {
+                List<Method> befores = testMethod.getBefores();
+                for (Method before : befores) {
+                    before.invoke(test);
+                }
+            } catch (InvocationTargetException e) {
+                throw e.getTargetException();
+            }
+        } catch (AssumptionViolatedException e) {
+            throw new FailedBefore();
+        } catch (Throwable e) {
+            addFailure(e);
+            throw new FailedBefore();
+        }
+    }
+
+    private void runAfters() {
+        List<Method> afters = testMethod.getAfters();
+        for (Method after : afters) {
+            try {
+                after.invoke(test);
+            } catch (InvocationTargetException e) {
+                addFailure(e.getTargetException());
+            } catch (Throwable e) {
+                addFailure(e); // Untested, but seems impossible
+            }
+        }
+    }
+
+    protected void addFailure(Throwable e) {
+        notifier.fireTestFailure(new Failure(description, e));
+    }
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodValidator.java
new file mode 100644
index 0000000..e656ee5
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodValidator.java
@@ -0,0 +1,97 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class MethodValidator {
+
+    private final List<Throwable> errors = new ArrayList<Throwable>();
+
+    private TestClass testClass;
+
+    public MethodValidator(TestClass testClass) {
+        this.testClass = testClass;
+    }
+
+    public void validateInstanceMethods() {
+        validateTestMethods(After.class, false);
+        validateTestMethods(Before.class, false);
+        validateTestMethods(Test.class, false);
+
+        List<Method> methods = testClass.getAnnotatedMethods(Test.class);
+        if (methods.size() == 0) {
+            errors.add(new Exception("No runnable methods"));
+        }
+    }
+
+    public void validateStaticMethods() {
+        validateTestMethods(BeforeClass.class, true);
+        validateTestMethods(AfterClass.class, true);
+    }
+
+    public List<Throwable> validateMethodsForDefaultRunner() {
+        validateNoArgConstructor();
+        validateStaticMethods();
+        validateInstanceMethods();
+        return errors;
+    }
+
+    public void assertValid() throws InitializationError {
+        if (!errors.isEmpty()) {
+            throw new InitializationError(errors);
+        }
+    }
+
+    public void validateNoArgConstructor() {
+        try {
+            testClass.getConstructor();
+        } catch (Exception e) {
+            errors.add(new Exception("Test class should have public zero-argument constructor", e));
+        }
+    }
+
+    private void validateTestMethods(Class<? extends Annotation> annotation,
+            boolean isStatic) {
+        List<Method> methods = testClass.getAnnotatedMethods(annotation);
+
+        for (Method each : methods) {
+            if (Modifier.isStatic(each.getModifiers()) != isStatic) {
+                String state = isStatic ? "should" : "should not";
+                errors.add(new Exception("Method " + each.getName() + "() "
+						+ state + " be static"));
+            }
+            if (!Modifier.isPublic(each.getDeclaringClass().getModifiers())) {
+                errors.add(new Exception("Class " + each.getDeclaringClass().getName()
+						+ " should be public"));
+            }
+            if (!Modifier.isPublic(each.getModifiers())) {
+                errors.add(new Exception("Method " + each.getName()
+						+ " should be public"));
+            }
+            if (each.getReturnType() != Void.TYPE) {
+                errors.add(new Exception("Method " + each.getName()
+						+ "should have a return type of void"));
+            }
+            if (each.getParameterTypes().length != 0) {
+                errors.add(new Exception("Method " + each.getName()
+						+ " should have no parameters"));
+            }
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/SuiteMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/SuiteMethod.java
new file mode 100644
index 0000000..e336983
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/SuiteMethod.java
@@ -0,0 +1,41 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import junit.framework.Test;
+
+/**
+ * Runner for use with JUnit 3.8.x-style AllTests classes
+ * (those that only implement a static <code>suite()</code>
+ * method). For example:
+ * <pre>
+ * &#064;RunWith(AllTests.class)
+ * public class ProductTests {
+ *    public static junit.framework.Test suite() {
+ *       ...
+ *    }
+ * }
+ * </pre>
+ */
+public class SuiteMethod extends JUnit38ClassRunner {
+    public SuiteMethod(Class<?> klass) throws Throwable {
+        super(testFromSuiteMethod(klass));
+    }
+
+    public static Test testFromSuiteMethod(Class<?> klass) throws Throwable {
+        Method suiteMethod = null;
+        Test suite = null;
+        try {
+            suiteMethod = klass.getMethod("suite");
+            if (!Modifier.isStatic(suiteMethod.getModifiers())) {
+                throw new Exception(klass.getName() + ".suite() must be static");
+            }
+            suite = (Test) suiteMethod.invoke(null); // static method
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        }
+        return suite;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestClass.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestClass.java
new file mode 100644
index 0000000..6d24f4f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestClass.java
@@ -0,0 +1,109 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.internal.MethodSorter;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class TestClass {
+    private final Class<?> klass;
+
+    public TestClass(Class<?> klass) {
+        this.klass = klass;
+    }
+
+    public List<Method> getTestMethods() {
+        return getAnnotatedMethods(Test.class);
+    }
+
+    List<Method> getBefores() {
+        return getAnnotatedMethods(BeforeClass.class);
+    }
+
+    List<Method> getAfters() {
+        return getAnnotatedMethods(AfterClass.class);
+    }
+
+    public List<Method> getAnnotatedMethods(Class<? extends Annotation> annotationClass) {
+        List<Method> results = new ArrayList<Method>();
+        for (Class<?> eachClass : getSuperClasses(klass)) {
+            Method[] methods = MethodSorter.getDeclaredMethods(eachClass);
+            for (Method eachMethod : methods) {
+                Annotation annotation = eachMethod.getAnnotation(annotationClass);
+                if (annotation != null && !isShadowed(eachMethod, results)) {
+                    results.add(eachMethod);
+                }
+            }
+        }
+        if (runsTopToBottom(annotationClass)) {
+            Collections.reverse(results);
+        }
+        return results;
+    }
+
+    private boolean runsTopToBottom(Class<? extends Annotation> annotation) {
+        return annotation.equals(Before.class) || annotation.equals(BeforeClass.class);
+    }
+
+    private boolean isShadowed(Method method, List<Method> results) {
+        for (Method each : results) {
+            if (isShadowed(method, each)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isShadowed(Method current, Method previous) {
+        if (!previous.getName().equals(current.getName())) {
+            return false;
+        }
+        if (previous.getParameterTypes().length != current.getParameterTypes().length) {
+            return false;
+        }
+        for (int i = 0; i < previous.getParameterTypes().length; i++) {
+            if (!previous.getParameterTypes()[i].equals(current.getParameterTypes()[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private List<Class<?>> getSuperClasses(Class<?> testClass) {
+        List<Class<?>> results = new ArrayList<Class<?>>();
+        Class<?> current = testClass;
+        while (current != null) {
+            results.add(current);
+            current = current.getSuperclass();
+        }
+        return results;
+    }
+
+    public Constructor<?> getConstructor() throws SecurityException, NoSuchMethodException {
+        return klass.getConstructor();
+    }
+
+    public Class<?> getJavaClass() {
+        return klass;
+    }
+
+    public String getName() {
+        return klass.getName();
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestMethod.java
new file mode 100644
index 0000000..821e193
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestMethod.java
@@ -0,0 +1,71 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.Test.None;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ *             removed in the next major release. Please use
+ *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class TestMethod {
+    private final Method method;
+    private TestClass testClass;
+
+    public TestMethod(Method method, TestClass testClass) {
+        this.method = method;
+        this.testClass = testClass;
+    }
+
+    public boolean isIgnored() {
+        return method.getAnnotation(Ignore.class) != null;
+    }
+
+    public long getTimeout() {
+        Test annotation = method.getAnnotation(Test.class);
+        if (annotation == null) {
+            return 0;
+        }
+        long timeout = annotation.timeout();
+        return timeout;
+    }
+
+    protected Class<? extends Throwable> getExpectedException() {
+        Test annotation = method.getAnnotation(Test.class);
+        if (annotation == null || annotation.expected() == None.class) {
+            return null;
+        } else {
+            return annotation.expected();
+        }
+    }
+
+    boolean isUnexpected(Throwable exception) {
+        return !getExpectedException().isAssignableFrom(exception.getClass());
+    }
+
+    boolean expectsException() {
+        return getExpectedException() != null;
+    }
+
+    List<Method> getBefores() {
+        return testClass.getAnnotatedMethods(Before.class);
+    }
+
+    List<Method> getAfters() {
+        return testClass.getAnnotatedMethods(After.class);
+    }
+
+    public void invoke(Object test) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        method.invoke(test);
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/EachTestNotifier.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/EachTestNotifier.java
new file mode 100644
index 0000000..c5a0764
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/EachTestNotifier.java
@@ -0,0 +1,71 @@
+package org.junit.internal.runners.model;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.MultipleFailureException;
+
+public class EachTestNotifier {
+    private final RunNotifier notifier;
+
+    private final Description description;
+
+    public EachTestNotifier(RunNotifier notifier, Description description) {
+        this.notifier = notifier;
+        this.description = description;
+    }
+
+    public void addFailure(Throwable targetException) {
+        if (targetException instanceof MultipleFailureException) {
+            addMultipleFailureException((MultipleFailureException) targetException);
+        } else {
+            notifier.fireTestFailure(new Failure(description, targetException));
+        }
+    }
+
+    private void addMultipleFailureException(MultipleFailureException mfe) {
+        for (Throwable each : mfe.getFailures()) {
+            addFailure(each);
+        }
+    }
+
+    public void addFailedAssumption(AssumptionViolatedException e) {
+        notifier.fireTestAssumptionFailed(new Failure(description, e));
+    }
+
+    public void fireTestFinished() {
+        notifier.fireTestFinished(description);
+    }
+
+    public void fireTestStarted() {
+        notifier.fireTestStarted(description);
+    }
+
+    public void fireTestIgnored() {
+        notifier.fireTestIgnored(description);
+    }
+
+    /**
+     * Calls {@link RunNotifier#fireTestSuiteStarted(Description)}, passing the
+     * {@link Description} that was passed to the {@code EachTestNotifier} constructor.
+     * This should be called when a test suite is about to be started.
+     * @see RunNotifier#fireTestSuiteStarted(Description)
+     * @since 4.13
+     */
+    public void fireTestSuiteStarted() {
+        notifier.fireTestSuiteStarted(description);
+    }
+
+    /**
+     * Calls {@link RunNotifier#fireTestSuiteFinished(Description)}, passing the
+     * {@link Description} that was passed to the {@code EachTestNotifier} constructor.
+     * This should be called when a test suite has finished, whether the test suite succeeds
+     * or fails.
+     * @see RunNotifier#fireTestSuiteFinished(Description)
+     * @since 4.13
+     */
+    public void fireTestSuiteFinished() {
+        notifier.fireTestSuiteFinished(description);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/MultipleFailureException.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/MultipleFailureException.java
new file mode 100644
index 0000000..054f042
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/MultipleFailureException.java
@@ -0,0 +1,12 @@
+package org.junit.internal.runners.model;
+
+import java.util.List;
+
+@Deprecated
+public class MultipleFailureException extends org.junit.runners.model.MultipleFailureException {
+    private static final long serialVersionUID = 1L;
+
+    public MultipleFailureException(List<Throwable> errors) {
+        super(errors);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/ReflectiveCallable.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/ReflectiveCallable.java
new file mode 100644
index 0000000..79d5c05
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/ReflectiveCallable.java
@@ -0,0 +1,19 @@
+package org.junit.internal.runners.model;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * When invoked, throws the exception from the reflected method, rather than
+ * wrapping it in an InvocationTargetException.
+ */
+public abstract class ReflectiveCallable {
+    public Object run() throws Throwable {
+        try {
+            return runReflectiveCall();
+        } catch (InvocationTargetException e) {
+            throw e.getTargetException();
+        }
+    }
+
+    protected abstract Object runReflectiveCall() throws Throwable;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/package-info.java
new file mode 100644
index 0000000..5ab7e7b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides implementations of {@link org.junit.runner.Runner}
+ *
+ * @since 4.0
+ */
+package org.junit.internal.runners;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java
new file mode 100644
index 0000000..36de4f1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java
@@ -0,0 +1,279 @@
+package org.junit.internal.runners.rules;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runners.model.FrameworkMember;
+import org.junit.runners.model.TestClass;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A RuleMemberValidator validates the rule fields/methods of a
+ * {@link org.junit.runners.model.TestClass}. All reasons for rejecting the
+ * {@code TestClass} are written to a list of errors.
+ *
+ * <p>There are four slightly different validators. The {@link #CLASS_RULE_VALIDATOR}
+ * validates fields with a {@link ClassRule} annotation and the
+ * {@link #RULE_VALIDATOR} validates fields with a {@link Rule} annotation.</p>
+ *
+ * <p>The {@link #CLASS_RULE_METHOD_VALIDATOR}
+ * validates methods with a {@link ClassRule} annotation and the
+ * {@link #RULE_METHOD_VALIDATOR} validates methods with a {@link Rule} annotation.</p>
+ */
+public class RuleMemberValidator {
+    /**
+     * Validates fields with a {@link ClassRule} annotation.
+     */
+    public static final RuleMemberValidator CLASS_RULE_VALIDATOR =
+            classRuleValidatorBuilder()
+            .withValidator(new DeclaringClassMustBePublic())
+            .withValidator(new MemberMustBeStatic())
+            .withValidator(new MemberMustBePublic())
+            .withValidator(new FieldMustBeATestRule())
+            .build();
+    /**
+     * Validates fields with a {@link Rule} annotation.
+     */
+    public static final RuleMemberValidator RULE_VALIDATOR =
+            testRuleValidatorBuilder()
+            .withValidator(new MemberMustBeNonStaticOrAlsoClassRule())
+            .withValidator(new MemberMustBePublic())
+            .withValidator(new FieldMustBeARule())
+            .build();
+    /**
+     * Validates methods with a {@link ClassRule} annotation.
+     */
+    public static final RuleMemberValidator CLASS_RULE_METHOD_VALIDATOR =
+            classRuleValidatorBuilder()
+            .forMethods()
+            .withValidator(new DeclaringClassMustBePublic())
+            .withValidator(new MemberMustBeStatic())
+            .withValidator(new MemberMustBePublic())
+            .withValidator(new MethodMustBeATestRule())
+            .build();
+
+    /**
+     * Validates methods with a {@link Rule} annotation.
+     */
+    public static final RuleMemberValidator RULE_METHOD_VALIDATOR =
+            testRuleValidatorBuilder()
+            .forMethods()
+            .withValidator(new MemberMustBeNonStaticOrAlsoClassRule())
+            .withValidator(new MemberMustBePublic())
+            .withValidator(new MethodMustBeARule())
+            .build();
+
+    private final Class<? extends Annotation> annotation;
+    private final boolean methods;
+    private final List<RuleValidator> validatorStrategies;
+
+    RuleMemberValidator(Builder builder) {
+        this.annotation = builder.annotation;
+        this.methods = builder.methods;
+        this.validatorStrategies = builder.validators;
+    }
+
+    /**
+     * Validate the {@link org.junit.runners.model.TestClass} and adds reasons
+     * for rejecting the class to a list of errors.
+     *
+     * @param target the {@code TestClass} to validate.
+     * @param errors the list of errors.
+     */
+    public void validate(TestClass target, List<Throwable> errors) {
+        List<? extends FrameworkMember<?>> members = methods ? target.getAnnotatedMethods(annotation)
+                : target.getAnnotatedFields(annotation);
+
+        for (FrameworkMember<?> each : members) {
+            validateMember(each, errors);
+        }
+    }
+
+    private void validateMember(FrameworkMember<?> member, List<Throwable> errors) {
+        for (RuleValidator strategy : validatorStrategies) {
+            strategy.validate(member, annotation, errors);
+        }
+    }
+
+    private static Builder classRuleValidatorBuilder() {
+        return new Builder(ClassRule.class);
+    }
+
+    private static Builder testRuleValidatorBuilder() {
+        return new Builder(Rule.class);
+    }
+
+    private static class Builder {
+        private final Class<? extends Annotation> annotation;
+        private boolean methods;
+        private final List<RuleValidator> validators;
+
+        private Builder(Class<? extends Annotation> annotation) {
+            this.annotation = annotation;
+            this.methods = false;
+            this.validators = new ArrayList<RuleValidator>();
+        }
+
+        Builder forMethods() {
+            methods = true;
+            return this;
+        }
+
+        Builder withValidator(RuleValidator validator) {
+            validators.add(validator);
+            return this;
+        }
+
+        RuleMemberValidator build() {
+            return new RuleMemberValidator(this);
+        }
+    }
+
+    private static boolean isRuleType(FrameworkMember<?> member) {
+        return isMethodRule(member) || isTestRule(member);
+    }
+
+    private static boolean isTestRule(FrameworkMember<?> member) {
+        return TestRule.class.isAssignableFrom(member.getType());
+    }
+
+    private static boolean isMethodRule(FrameworkMember<?> member) {
+        return MethodRule.class.isAssignableFrom(member.getType());
+    }
+
+    /**
+     * Encapsulates a single piece of validation logic, used to determine if {@link org.junit.Rule} and
+     * {@link org.junit.ClassRule} annotations have been used correctly
+     */
+    interface RuleValidator {
+        /**
+         * Examine the given member and add any violations of the strategy's validation logic to the given list of errors
+         * @param member The member (field or member) to examine
+         * @param annotation The type of rule annotation on the member
+         * @param errors The list of errors to add validation violations to
+         */
+        void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors);
+    }
+
+    /**
+     * Requires the validated member to be non-static
+     */
+    private static final class MemberMustBeNonStaticOrAlsoClassRule implements RuleValidator {
+        public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+            boolean isMethodRuleMember = isMethodRule(member);
+            boolean isClassRuleAnnotated = (member.getAnnotation(ClassRule.class) != null);
+
+            // We disallow:
+            //  - static MethodRule members
+            //  - static @Rule annotated members
+            //    - UNLESS they're also @ClassRule annotated
+            // Note that MethodRule cannot be annotated with @ClassRule
+            if (member.isStatic() && (isMethodRuleMember || !isClassRuleAnnotated)) {
+                String message;
+                if (isMethodRule(member)) {
+                    message = "must not be static.";
+                } else {
+                    message = "must not be static or it must be annotated with @ClassRule.";
+                }
+                errors.add(new ValidationError(member, annotation, message));
+            }
+        }
+    }
+
+    /**
+     * Requires the member to be static
+     */
+    private static final class MemberMustBeStatic implements RuleValidator {
+        public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!member.isStatic()) {
+                errors.add(new ValidationError(member, annotation,
+                        "must be static."));
+            }
+        }
+    }
+
+    /**
+     * Requires the member's declaring class to be public
+     */
+    private static final class DeclaringClassMustBePublic implements RuleValidator {
+        public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!isDeclaringClassPublic(member)) {
+                errors.add(new ValidationError(member, annotation,
+                        "must be declared in a public class."));
+            }
+        }
+
+        private boolean isDeclaringClassPublic(FrameworkMember<?> member) {
+            return Modifier.isPublic(member.getDeclaringClass().getModifiers());
+        }
+    }
+
+    /**
+     * Requires the member to be public
+     */
+    private static final class MemberMustBePublic implements RuleValidator {
+        public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!member.isPublic()) {
+                errors.add(new ValidationError(member, annotation,
+                        "must be public."));
+            }
+        }
+    }
+
+    /**
+     * Requires the member is a field implementing {@link org.junit.rules.MethodRule} or {@link org.junit.rules.TestRule}
+     */
+    private static final class FieldMustBeARule implements RuleValidator {
+        public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!isRuleType(member)) {
+                errors.add(new ValidationError(member, annotation,
+                        "must implement MethodRule or TestRule."));
+            }
+        }
+    }
+
+    /**
+     * Require the member to return an implementation of {@link org.junit.rules.MethodRule} or
+     * {@link org.junit.rules.TestRule}
+     */
+    private static final class MethodMustBeARule implements RuleValidator {
+        public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!isRuleType(member)) {
+                errors.add(new ValidationError(member, annotation,
+                        "must return an implementation of MethodRule or TestRule."));
+            }
+        }
+    }
+    
+    /**
+     * Require the member to return an implementation of {@link org.junit.rules.TestRule}
+     */
+    private static final class MethodMustBeATestRule implements RuleValidator {
+        public void validate(FrameworkMember<?> member,
+                Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!isTestRule(member)) {
+                errors.add(new ValidationError(member, annotation, 
+                        "must return an implementation of TestRule."));
+            }
+        }
+    }
+    
+    /**
+     * Requires the member is a field implementing {@link org.junit.rules.TestRule}
+     */
+    private static final class FieldMustBeATestRule implements RuleValidator {
+
+        public void validate(FrameworkMember<?> member,
+                Class<? extends Annotation> annotation, List<Throwable> errors) {
+            if (!isTestRule(member)) {
+                errors.add(new ValidationError(member, annotation,
+                        "must implement TestRule."));
+            }
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/ValidationError.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/ValidationError.java
new file mode 100644
index 0000000..31bd660
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/ValidationError.java
@@ -0,0 +1,14 @@
+package org.junit.internal.runners.rules;
+
+import org.junit.runners.model.FrameworkMember;
+
+import java.lang.annotation.Annotation;
+
+class ValidationError extends Exception {
+
+    private static final long serialVersionUID = 3176511008672645574L;
+
+    public ValidationError(FrameworkMember<?> member, Class<? extends Annotation> annotation, String suffix) {
+        super(String.format("The @%s '%s' %s", annotation.getSimpleName(), member.getName(), suffix));
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/ExpectException.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/ExpectException.java
new file mode 100644
index 0000000..9a2a952
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/ExpectException.java
@@ -0,0 +1,38 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.Statement;
+
+public class ExpectException extends Statement {
+    private final Statement next;
+    private final Class<? extends Throwable> expected;
+
+    public ExpectException(Statement next, Class<? extends Throwable> expected) {
+        this.next = next;
+        this.expected = expected;
+    }
+
+    @Override
+    public void evaluate() throws Exception {
+        boolean complete = false;
+        try {
+            next.evaluate();
+            complete = true;
+        } catch (AssumptionViolatedException e) {
+            if (!expected.isAssignableFrom(e.getClass())) {
+                throw e;
+            }
+        } catch (Throwable e) {
+            if (!expected.isAssignableFrom(e.getClass())) {
+                String message = "Unexpected exception, expected<"
+                        + expected.getName() + "> but was<"
+                        + e.getClass().getName() + ">";
+                throw new Exception(message, e);
+            }
+        }
+        if (complete) {
+            throw new AssertionError("Expected exception: "
+                    + expected.getName());
+        }
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/Fail.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/Fail.java
new file mode 100644
index 0000000..e55875c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/Fail.java
@@ -0,0 +1,16 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.runners.model.Statement;
+
+public class Fail extends Statement {
+    private final Throwable error;
+
+    public Fail(Throwable e) {
+        error = e;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        throw error;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/FailOnTimeout.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
new file mode 100644
index 0000000..9362cc1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
@@ -0,0 +1,312 @@
+package org.junit.internal.runners.statements;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.internal.management.ManagementFactory;
+import org.junit.internal.management.ThreadMXBean;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestTimedOutException;
+
+public class FailOnTimeout extends Statement {
+    private final Statement originalStatement;
+    private final TimeUnit timeUnit;
+    private final long timeout;
+    private final boolean lookForStuckThread;
+
+    /**
+     * Returns a new builder for building an instance.
+     *
+     * @since 4.12
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Creates an instance wrapping the given statement with the given timeout in milliseconds.
+     *
+     * @param statement the statement to wrap
+     * @param timeoutMillis the timeout in milliseconds
+     * @deprecated use {@link #builder()} instead.
+     */
+    @Deprecated
+    public FailOnTimeout(Statement statement, long timeoutMillis) {
+        this(builder().withTimeout(timeoutMillis, TimeUnit.MILLISECONDS), statement);
+    }
+
+    private FailOnTimeout(Builder builder, Statement statement) {
+        originalStatement = statement;
+        timeout = builder.timeout;
+        timeUnit = builder.unit;
+        lookForStuckThread = builder.lookForStuckThread;
+    }
+
+    /**
+     * Builder for {@link FailOnTimeout}.
+     *
+     * @since 4.12
+     */
+    public static class Builder {
+        private boolean lookForStuckThread = false;
+        private long timeout = 0;
+        private TimeUnit unit = TimeUnit.SECONDS;
+
+        private Builder() {
+        }
+
+        /**
+         * Specifies the time to wait before timing out the test.
+         *
+         * <p>If this is not called, or is called with a {@code timeout} of
+         * {@code 0}, the returned {@code Statement} will wait forever for the
+         * test to complete, however the test will still launch from a separate
+         * thread. This can be useful for disabling timeouts in environments
+         * where they are dynamically set based on some property.
+         *
+         * @param timeout the maximum time to wait
+         * @param unit the time unit of the {@code timeout} argument
+         * @return {@code this} for method chaining.
+         */
+        public Builder withTimeout(long timeout, TimeUnit unit) {
+            if (timeout < 0) {
+                throw new IllegalArgumentException("timeout must be non-negative");
+            }
+            if (unit == null) {
+                throw new NullPointerException("TimeUnit cannot be null");
+            }
+            this.timeout = timeout;
+            this.unit = unit;
+            return this;
+        }
+
+        /**
+         * Specifies whether to look for a stuck thread.  If a timeout occurs and this
+         * feature is enabled, the test will look for a thread that appears to be stuck
+         * and dump its backtrace.  This feature is experimental.  Behavior may change
+         * after the 4.12 release in response to feedback.
+         *
+         * @param enable {@code true} to enable the feature
+         * @return {@code this} for method chaining.
+         */
+        public Builder withLookingForStuckThread(boolean enable) {
+            this.lookForStuckThread = enable;
+            return this;
+        }
+
+        /**
+         * Builds a {@link FailOnTimeout} instance using the values in this builder,
+         * wrapping the given statement.
+         *
+         * @param statement
+         */
+        public FailOnTimeout build(Statement statement) {
+            if (statement == null) {
+                throw new NullPointerException("statement cannot be null");
+            }
+            return new FailOnTimeout(this, statement);
+        }
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        CallableStatement callable = new CallableStatement();
+        FutureTask<Throwable> task = new FutureTask<Throwable>(callable);
+        ThreadGroup threadGroup = threadGroupForNewThread();
+        Thread thread = new Thread(threadGroup, task, "Time-limited test");
+        thread.setDaemon(true);
+        thread.start();
+        callable.awaitStarted();
+        Throwable throwable = getResult(task, thread);
+        if (throwable != null) {
+            throw throwable;
+        }
+    }
+
+    private ThreadGroup threadGroupForNewThread() {
+        if (!lookForStuckThread) {
+            // Use the default ThreadGroup (usually the one from the current
+            // thread).
+            return null;
+        }
+
+        // Create the thread in a new ThreadGroup, so if the time-limited thread
+        // becomes stuck, getStuckThread() can find the thread likely to be the
+        // culprit.
+        ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup");
+        if (!threadGroup.isDaemon()) {
+            // Mark the new ThreadGroup as a daemon thread group, so it will be
+            // destroyed after the time-limited thread completes. By ensuring the
+            // ThreadGroup is destroyed, any data associated with the ThreadGroup
+            // (ex: via java.beans.ThreadGroupContext) is destroyed.
+            try {
+                threadGroup.setDaemon(true);
+            } catch (SecurityException e) {
+                // Swallow the exception to keep the same behavior as in JUnit 4.12.
+            }
+        }
+        return threadGroup;
+    }
+
+    /**
+     * Wait for the test task, returning the exception thrown by the test if the
+     * test failed, an exception indicating a timeout if the test timed out, or
+     * {@code null} if the test passed.
+     */
+    private Throwable getResult(FutureTask<Throwable> task, Thread thread) {
+        try {
+            if (timeout > 0) {
+                return task.get(timeout, timeUnit);
+            } else {
+                return task.get();
+            }
+        } catch (InterruptedException e) {
+            return e; // caller will re-throw; no need to call Thread.interrupt()
+        } catch (ExecutionException e) {
+            // test failed; have caller re-throw the exception thrown by the test
+            return e.getCause();
+        } catch (TimeoutException e) {
+            return createTimeoutException(thread);
+        }
+    }
+
+    private Exception createTimeoutException(Thread thread) {
+        StackTraceElement[] stackTrace = thread.getStackTrace();
+        final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null;
+        Exception currThreadException = new TestTimedOutException(timeout, timeUnit);
+        if (stackTrace != null) {
+            currThreadException.setStackTrace(stackTrace);
+            thread.interrupt();
+        }
+        if (stuckThread != null) {
+            Exception stuckThreadException = 
+                new Exception("Appears to be stuck in thread " +
+                               stuckThread.getName());
+            stuckThreadException.setStackTrace(getStackTrace(stuckThread));
+            return new MultipleFailureException(
+                Arrays.<Throwable>asList(currThreadException, stuckThreadException));
+        } else {
+            return currThreadException;
+        }
+    }
+
+    /**
+     * Retrieves the stack trace for a given thread.
+     * @param thread The thread whose stack is to be retrieved.
+     * @return The stack trace; returns a zero-length array if the thread has 
+     * terminated or the stack cannot be retrieved for some other reason.
+     */
+    private StackTraceElement[] getStackTrace(Thread thread) {
+        try {
+            return thread.getStackTrace();
+        } catch (SecurityException e) {
+            return new StackTraceElement[0];
+        }
+    }
+
+    /**
+     * Determines whether the test appears to be stuck in some thread other than
+     * the "main thread" (the one created to run the test).  This feature is experimental.
+     * Behavior may change after the 4.12 release in response to feedback.
+     * @param mainThread The main thread created by {@code evaluate()}
+     * @return The thread which appears to be causing the problem, if different from
+     * {@code mainThread}, or {@code null} if the main thread appears to be the
+     * problem or if the thread cannot be determined.  The return value is never equal 
+     * to {@code mainThread}.
+     */
+    private Thread getStuckThread(Thread mainThread) {
+        List<Thread> threadsInGroup = getThreadsInGroup(mainThread.getThreadGroup());
+        if (threadsInGroup.isEmpty()) {
+            return null;
+        }
+
+        // Now that we have all the threads in the test's thread group: Assume that
+        // any thread we're "stuck" in is RUNNABLE.  Look for all RUNNABLE threads. 
+        // If just one, we return that (unless it equals threadMain).  If there's more
+        // than one, pick the one that's using the most CPU time, if this feature is
+        // supported.
+        Thread stuckThread = null;
+        long maxCpuTime = 0;
+        for (Thread thread : threadsInGroup) {
+            if (thread.getState() == Thread.State.RUNNABLE) {
+                long threadCpuTime = cpuTime(thread);
+                if (stuckThread == null || threadCpuTime > maxCpuTime) {
+                    stuckThread = thread;
+                    maxCpuTime = threadCpuTime;
+                }
+            }               
+        }
+        return (stuckThread == mainThread) ? null : stuckThread;
+    }
+
+    /**
+     * Returns all active threads belonging to a thread group.  
+     * @param group The thread group.
+     * @return The active threads in the thread group.  The result should be a
+     * complete list of the active threads at some point in time.  Returns an empty list
+     * if this cannot be determined, e.g. because new threads are being created at an
+     * extremely fast rate.
+     */
+    private List<Thread> getThreadsInGroup(ThreadGroup group) {
+        final int activeThreadCount = group.activeCount(); // this is just an estimate
+        int threadArraySize = Math.max(activeThreadCount * 2, 100);
+        for (int loopCount = 0; loopCount < 5; loopCount++) {
+            Thread[] threads = new Thread[threadArraySize];
+            int enumCount = group.enumerate(threads);
+            if (enumCount < threadArraySize) {
+                return Arrays.asList(threads).subList(0, enumCount);
+            }
+            // if there are too many threads to fit into the array, enumerate's result
+            // is >= the array's length; therefore we can't trust that it returned all
+            // the threads.  Try again.
+            threadArraySize += 100;
+        }
+        // threads are proliferating too fast for us.  Bail before we get into 
+        // trouble.
+        return Collections.emptyList();
+    }
+
+    /**
+     * Returns the CPU time used by a thread, if possible.
+     * @param thr The thread to query.
+     * @return The CPU time used by {@code thr}, or 0 if it cannot be determined.
+     */
+    private long cpuTime(Thread thr) {
+        ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
+        if (mxBean.isThreadCpuTimeSupported()) {
+            try {
+                return mxBean.getThreadCpuTime(thr.getId());
+            } catch (UnsupportedOperationException e) {
+            }
+        }
+        return 0;
+    }
+
+    private class CallableStatement implements Callable<Throwable> {
+        private final CountDownLatch startLatch = new CountDownLatch(1);
+
+        public Throwable call() throws Exception {
+            try {
+                startLatch.countDown();
+                originalStatement.evaluate();
+            } catch (Exception e) {
+                throw e;
+            } catch (Throwable e) {
+                return e;
+            }
+            return null;
+        }
+
+        public void awaitStarted() throws InterruptedException {
+            startLatch.await();
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/InvokeMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/InvokeMethod.java
new file mode 100644
index 0000000..68c0545
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/InvokeMethod.java
@@ -0,0 +1,19 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+public class InvokeMethod extends Statement {
+    private final FrameworkMethod testMethod;
+    private final Object target;
+
+    public InvokeMethod(FrameworkMethod testMethod, Object target) {
+        this.testMethod = testMethod;
+        this.target = target;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        testMethod.invokeExplosively(target);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunAfters.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunAfters.java
new file mode 100644
index 0000000..5e56c33
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunAfters.java
@@ -0,0 +1,48 @@
+package org.junit.internal.runners.statements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+public class RunAfters extends Statement {
+    private final Statement next;
+
+    private final Object target;
+
+    private final List<FrameworkMethod> afters;
+
+    public RunAfters(Statement next, List<FrameworkMethod> afters, Object target) {
+        this.next = next;
+        this.afters = afters;
+        this.target = target;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        List<Throwable> errors = new ArrayList<Throwable>();
+        try {
+            next.evaluate();
+        } catch (Throwable e) {
+            errors.add(e);
+        } finally {
+            for (FrameworkMethod each : afters) {
+                try {
+                    invokeMethod(each);
+                } catch (Throwable e) {
+                    errors.add(e);
+                }
+            }
+        }
+        MultipleFailureException.assertEmpty(errors);
+    }
+
+    /**
+     * @since 4.13
+     */
+    protected void invokeMethod(FrameworkMethod method) throws Throwable {
+        method.invokeExplosively(target);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunBefores.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunBefores.java
new file mode 100644
index 0000000..bd835c7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunBefores.java
@@ -0,0 +1,35 @@
+package org.junit.internal.runners.statements;
+
+import java.util.List;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+public class RunBefores extends Statement {
+    private final Statement next;
+
+    private final Object target;
+
+    private final List<FrameworkMethod> befores;
+
+    public RunBefores(Statement next, List<FrameworkMethod> befores, Object target) {
+        this.next = next;
+        this.befores = befores;
+        this.target = target;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        for (FrameworkMethod before : befores) {
+            invokeMethod(before);
+        }
+        next.evaluate();
+    }
+
+    /**
+     * @since 4.13
+     */
+    protected void invokeMethod(FrameworkMethod method) throws Throwable {
+        method.invokeExplosively(target);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/matchers/JUnitMatchers.java b/google3/third_party/java_src/junit/main/java/org/junit/matchers/JUnitMatchers.java
new file mode 100644
index 0000000..13407cc
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/matchers/JUnitMatchers.java
@@ -0,0 +1,113 @@
+package org.junit.matchers;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matcher;
+import org.hamcrest.core.CombinableMatcher.CombinableBothMatcher;
+import org.hamcrest.core.CombinableMatcher.CombinableEitherMatcher;
+import org.junit.internal.matchers.StacktracePrintingMatcher;
+
+/**
+ * Convenience import class: these are useful matchers for use with the assertThat method, but they are
+ * not currently included in the basic CoreMatchers class from hamcrest.
+ *
+ * @since 4.4
+ */
+public class JUnitMatchers {
+    /**
+     * @return A matcher matching any collection containing element
+     * @deprecated Please use {@link CoreMatchers#hasItem(Object)} instead.
+     */
+    @Deprecated
+    public static <T> Matcher<Iterable<? super T>> hasItem(T element) {
+        return CoreMatchers.hasItem(element);
+    }
+
+    /**
+     * @return A matcher matching any collection containing an element matching elementMatcher
+     * @deprecated Please use {@link CoreMatchers#hasItem(Matcher)} instead.
+     */
+    @Deprecated
+    public static <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> elementMatcher) {
+        return CoreMatchers.<T>hasItem(elementMatcher);
+    }
+
+    /**
+     * @return A matcher matching any collection containing every element in elements
+     * @deprecated Please use {@link CoreMatchers#hasItems(Object...)} instead.
+     */
+    @Deprecated
+    public static <T> Matcher<Iterable<T>> hasItems(T... elements) {
+        return CoreMatchers.hasItems(elements);
+    }
+
+    /**
+     * @return A matcher matching any collection containing at least one element that matches
+     *         each matcher in elementMatcher (this may be one element matching all matchers,
+     *         or different elements matching each matcher)
+     * @deprecated Please use {@link CoreMatchers#hasItems(Matcher...)} instead.
+     */
+    @Deprecated
+    public static <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... elementMatchers) {
+        return CoreMatchers.hasItems(elementMatchers);
+    }
+
+    /**
+     * @return A matcher matching any collection in which every element matches elementMatcher
+     * @deprecated Please use {@link CoreMatchers#everyItem(Matcher)} instead.
+     */
+    @Deprecated
+    public static <T> Matcher<Iterable<T>> everyItem(final Matcher<T> elementMatcher) {
+        return CoreMatchers.everyItem(elementMatcher);
+    }
+
+    /**
+     * @return a matcher matching any string that contains substring
+     * @deprecated Please use {@link CoreMatchers#containsString(String)} instead.
+     */
+    @Deprecated
+    public static Matcher<java.lang.String> containsString(java.lang.String substring) {
+        return CoreMatchers.containsString(substring);
+    }
+
+    /**
+     * This is useful for fluently combining matchers that must both pass.  For example:
+     * <pre>
+     *   assertThat(string, both(containsString("a")).and(containsString("b")));
+     * </pre>
+     *
+     * @deprecated Please use {@link CoreMatchers#both(Matcher)} instead.
+     */
+    @Deprecated
+    public static <T> CombinableBothMatcher<T> both(Matcher<? super T> matcher) {
+        return CoreMatchers.both(matcher);
+    }
+
+    /**
+     * This is useful for fluently combining matchers where either may pass, for example:
+     * <pre>
+     *   assertThat(string, either(containsString("a")).or(containsString("b")));
+     * </pre>
+     *
+     * @deprecated Please use {@link CoreMatchers#either(Matcher)} instead.
+     */
+    @Deprecated
+    public static <T> CombinableEitherMatcher<T> either(Matcher<? super T> matcher) {
+        return CoreMatchers.either(matcher);
+    }
+
+    /**
+     * @return A matcher that delegates to throwableMatcher and in addition
+     *         appends the stacktrace of the actual Throwable in case of a mismatch.
+     */
+    public static <T extends Throwable> Matcher<T> isThrowable(Matcher<T> throwableMatcher) {
+        return StacktracePrintingMatcher.isThrowable(throwableMatcher);
+    }
+
+    /**
+     * @return A matcher that delegates to exceptionMatcher and in addition
+     *         appends the stacktrace of the actual Exception in case of a mismatch.
+     */
+    public static <T extends Exception> Matcher<T> isException(Matcher<T> exceptionMatcher) {
+        return StacktracePrintingMatcher.isException(exceptionMatcher);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/matchers/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/matchers/package-info.java
new file mode 100644
index 0000000..71aca34
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/matchers/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * Provides useful additional {@link org.hamcrest.Matcher}s for use with
+ * the {@link org.junit.Assert#assertThat(Object, org.hamcrest.Matcher)}
+ * statement
+ *
+ * @since 4.0
+ * @see org.junit.matchers.JUnitMatchers
+ */
+package org.junit.matchers;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/package-info.java
new file mode 100644
index 0000000..fb12f25
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Provides JUnit core classes and annotations. 
+ *
+ * Corresponds to junit.framework in Junit 3.x.
+ *
+ * @since 4.0
+ */
+package org.junit;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/DisableOnDebug.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/DisableOnDebug.java
new file mode 100644
index 0000000..3bca103
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/DisableOnDebug.java
@@ -0,0 +1,125 @@
+package org.junit.rules;
+
+import java.util.List;
+
+import org.junit.internal.management.ManagementFactory;
+import org.junit.internal.management.RuntimeMXBean;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code DisableOnDebug} Rule allows you to label certain rules to be
+ * disabled when debugging.
+ * <p>
+ * The most illustrative use case is for tests that make use of the
+ * {@link Timeout} rule, when ran in debug mode the test may terminate on
+ * timeout abruptly during debugging. Developers may disable the timeout, or
+ * increase the timeout by making a code change on tests that need debugging and
+ * remember revert the change afterwards or rules such as {@link Timeout} that
+ * may be disabled during debugging may be wrapped in a {@code DisableOnDebug}.
+ * <p>
+ * The important benefit of this feature is that you can disable such rules
+ * without any making any modifications to your test class to remove them during
+ * debugging.
+ * <p>
+ * This does nothing to tackle timeouts or time sensitive code under test when
+ * debugging and may make this less useful in such circumstances.
+ * <p>
+ * Example usage:
+ * 
+ * <pre>
+ * public static class DisableTimeoutOnDebugSampleTest {
+ * 
+ *     &#064;Rule
+ *     public TestRule timeout = new DisableOnDebug(new Timeout(20));
+ * 
+ *     &#064;Test
+ *     public void myTest() {
+ *         int i = 0;
+ *         assertEquals(0, i); // suppose you had a break point here to inspect i
+ *     }
+ * }
+ * </pre>
+ * 
+ * @since 4.12
+ */
+public class DisableOnDebug implements TestRule {
+    private final TestRule rule;
+    private final boolean debugging;
+
+    /**
+     * Create a {@code DisableOnDebug} instance with the timeout specified in
+     * milliseconds.
+     * 
+     * @param rule to disable during debugging
+     */
+    public DisableOnDebug(TestRule rule) {
+        this(rule, ManagementFactory.getRuntimeMXBean()
+                .getInputArguments());
+    }
+
+    /**
+     * Visible for testing purposes only.
+     * 
+     * @param rule the rule to disable during debugging
+     * @param inputArguments
+     *            arguments provided to the Java runtime
+     */
+    DisableOnDebug(TestRule rule, List<String> inputArguments) {
+        this.rule = rule;
+        debugging = isDebugging(inputArguments);
+    }
+
+    /**
+     * @see TestRule#apply(Statement, Description)
+     */
+    public Statement apply(Statement base, Description description) {
+        if (debugging) {
+            return base;
+        } else {
+            return rule.apply(base, description);
+        }
+    }
+
+    /**
+     * Parses arguments passed to the runtime environment for debug flags
+     * <p>
+     * Options specified in:
+     * <ul>
+     * <li>
+     * <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Invocation"
+     * >javase-6</a></li>
+     * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation"
+     * >javase-7</a></li>
+     * <li><a href="http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html#Invocation"
+     * >javase-8</a></li>
+     * 
+     * 
+     * @param arguments
+     *            the arguments passed to the runtime environment, usually this
+     *            will be {@link RuntimeMXBean#getInputArguments()}
+     * @return true if the current JVM was started in debug mode, false
+     *         otherwise.
+     */
+    private static boolean isDebugging(List<String> arguments) {
+        for (final String argument : arguments) {
+            if ("-Xdebug".equals(argument) || argument.startsWith("-agentlib:jdwp")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if the JVM is in debug mode. This method may be used
+     * by test classes to take additional action to disable code paths that
+     * interfere with debugging if required.
+     * 
+     * @return {@code true} if the current JVM is in debug mode, {@code false}
+     *         otherwise
+     */
+    public boolean isDebugging() {
+        return debugging;
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ErrorCollector.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ErrorCollector.java
new file mode 100644
index 0000000..9711e50
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ErrorCollector.java
@@ -0,0 +1,120 @@
+package org.junit.rules;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertThrows;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.junit.function.ThrowingRunnable;
+import org.junit.internal.AssumptionViolatedException;
+import org.hamcrest.Matcher;
+import org.junit.runners.model.MultipleFailureException;
+
+/**
+ * The ErrorCollector rule allows execution of a test to continue after the
+ * first problem is found (for example, to collect _all_ the incorrect rows in a
+ * table, and report them all at once):
+ *
+ * <pre>
+ * public static class UsesErrorCollectorTwice {
+ * 	&#064;Rule
+ * 	public ErrorCollector collector= new ErrorCollector();
+ *
+ * &#064;Test
+ * public void example() {
+ *      collector.addError(new Throwable(&quot;first thing went wrong&quot;));
+ *      collector.addError(new Throwable(&quot;second thing went wrong&quot;));
+ *      collector.checkThat(getResult(), not(containsString(&quot;ERROR!&quot;)));
+ *      // all lines will run, and then a combined failure logged at the end.
+ *     }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public class ErrorCollector extends Verifier {
+    private List<Throwable> errors = new ArrayList<Throwable>();
+
+    @Override
+    protected void verify() throws Throwable {
+        MultipleFailureException.assertEmpty(errors);
+    }
+
+    /**
+     * Adds a Throwable to the table.  Execution continues, but the test will fail at the end.
+     */
+    public void addError(Throwable error) {
+        if (error == null) {
+            throw new NullPointerException("Error cannot be null");
+        }
+        if (error instanceof AssumptionViolatedException) {
+            AssertionError e = new AssertionError(error.getMessage());
+            e.initCause(error);
+            errors.add(e);
+        } else {
+            errors.add(error);
+        }
+    }
+
+    /**
+     * Adds a failure to the table if {@code matcher} does not match {@code value}.
+     * Execution continues, but the test will fail at the end if the match fails.
+     */
+    public <T> void checkThat(final T value, final Matcher<T> matcher) {
+        checkThat("", value, matcher);
+    }
+
+    /**
+     * Adds a failure with the given {@code reason}
+     * to the table if {@code matcher} does not match {@code value}.
+     * Execution continues, but the test will fail at the end if the match fails.
+     */
+    public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
+        checkSucceeds(new Callable<Object>() {
+            public Object call() throws Exception {
+                assertThat(reason, value, matcher);
+                return value;
+            }
+        });
+    }
+
+    /**
+     * Adds to the table the exception, if any, thrown from {@code callable}.
+     * Execution continues, but the test will fail at the end if
+     * {@code callable} threw an exception.
+     */
+    public <T> T checkSucceeds(Callable<T> callable) {
+        try {
+            return callable.call();
+        } catch (AssumptionViolatedException e) {
+            AssertionError error = new AssertionError("Callable threw AssumptionViolatedException");
+            error.initCause(e);
+            addError(error);
+            return null;
+        } catch (Throwable e) {
+            addError(e);
+            return null;
+        }
+    }
+
+    /**
+     * Adds a failure to the table if {@code runnable} does not throw an
+     * exception of type {@code expectedThrowable} when executed.
+     * Execution continues, but the test will fail at the end if the runnable
+     * does not throw an exception, or if it throws a different exception.
+     *
+     * @param expectedThrowable the expected type of the exception
+     * @param runnable       a function that is expected to throw an exception when executed
+     * @since 4.13
+     */
+    public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
+        try {
+            assertThrows(expectedThrowable, runnable);
+        } catch (AssertionError e) {
+            addError(e);
+        }
+    }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedException.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedException.java
new file mode 100644
index 0000000..431ad49
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedException.java
@@ -0,0 +1,285 @@
+package org.junit.rules;
+
+import static java.lang.String.format;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause;
+import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+import org.junit.AssumptionViolatedException;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code ExpectedException} rule allows you to verify that your code
+ * throws a specific exception.
+ *
+ * <h3>Usage</h3>
+ *
+ * <pre> public class SimpleExpectedExceptionTest {
+ *     &#064;Rule
+ *     public ExpectedException thrown = ExpectedException.none();
+ *
+ *     &#064;Test
+ *     public void throwsNothing() {
+ *         // no exception expected, none thrown: passes.
+ *     }
+ *
+ *     &#064;Test
+ *     public void throwsExceptionWithSpecificType() {
+ *         thrown.expect(NullPointerException.class);
+ *         throw new NullPointerException();
+ *     }
+ * }</pre>
+ * 
+ * <p>You have to add the {@code ExpectedException} rule to your test.
+ * This doesn't affect your existing tests (see {@code throwsNothing()}).
+ * After specifying the type of the expected exception your test is
+ * successful when such an exception is thrown and it fails if a
+ * different or no exception is thrown.
+ *
+ * <p>This rule does not perform any special magic to make execution continue
+ * as if the exception had not been thrown. So it is nearly always a mistake
+ * for a test method to have statements after the one that is expected to
+ * throw the exception.
+ *
+ * <p>Instead of specifying the exception's type you can characterize the
+ * expected exception based on other criteria, too:
+ *
+ * <ul>
+ *   <li>The exception's message contains a specific text: {@link #expectMessage(String)}</li>
+ *   <li>The exception's message complies with a Hamcrest matcher: {@link #expectMessage(Matcher)}</li>
+ *   <li>The exception's cause complies with a Hamcrest matcher: {@link #expectCause(Matcher)}</li>
+ *   <li>The exception itself complies with a Hamcrest matcher: {@link #expect(Matcher)}</li>
+ * </ul>
+ *
+ * <p>You can combine any of the presented expect-methods. The test is
+ * successful if all specifications are met.
+ * <pre> &#064;Test
+ * public void throwsException() {
+ *     thrown.expect(NullPointerException.class);
+ *     thrown.expectMessage(&quot;happened&quot;);
+ *     throw new NullPointerException(&quot;What happened?&quot;);
+ * }</pre>
+ *
+ * <p>It is recommended to set the {@link org.junit.Rule#order() order} of the
+ * {@code ExpectedException} to {@code Integer.MAX_VALUE} if it is used together
+ * with another rule that handles exceptions, e.g. {@link ErrorCollector}.
+ * Otherwise failing tests may be successful.
+ * <pre> &#064;Rule(order = Integer.MAX_VALUE)
+ * public ExpectedException thrown = ExpectedException.none();</pre>
+ *
+ * <h3>AssumptionViolatedExceptions</h3>
+ * <p>JUnit uses {@link AssumptionViolatedException}s for indicating that a test
+ * provides no useful information. (See {@link org.junit.Assume} for more
+ * information.) You have to call {@code assume} methods before you set
+ * expectations of the {@code ExpectedException} rule. In this case the rule
+ * will not handle consume the exceptions and it can be handled by the
+ * framework. E.g. the following test is ignored by JUnit's default runner.
+ *
+ * <pre> &#064;Test
+ * public void ignoredBecauseOfFailedAssumption() {
+ *     assumeTrue(false); // throws AssumptionViolatedException
+ *     thrown.expect(NullPointerException.class);
+ * }</pre>
+ *
+ * <h3>AssertionErrors</h3>
+ *
+ * <p>JUnit uses {@link AssertionError}s for indicating that a test is failing. You
+ * have to call {@code assert} methods before you set expectations of the
+ * {@code ExpectedException} rule, if they should be handled by the framework.
+ * E.g. the following test fails because of the {@code assertTrue} statement.
+ *
+ * <pre> &#064;Test
+ * public void throwsUnhandled() {
+ *     assertTrue(false); // throws AssertionError
+ *     thrown.expect(NullPointerException.class);
+ * }</pre>
+ *
+ * <h3>Missing Exceptions</h3>
+ * <p>By default missing exceptions are reported with an error message
+ * like "Expected test to throw an instance of foo". You can configure a different
+ * message by means of {@link #reportMissingExceptionWithMessage(String)}. You
+ * can use a {@code %s} placeholder for the description of the expected
+ * exception. E.g. "Test doesn't throw %s." will fail with the error message
+ * "Test doesn't throw an instance of foo.".
+ *
+ * @since 4.7
+ */
+public class ExpectedException implements TestRule {
+    /**
+     * Returns a {@linkplain TestRule rule} that expects no exception to
+     * be thrown (identical to behavior without this rule).
+     *
+     * @deprecated Since 4.13
+     * {@link org.junit.Assert#assertThrows(Class, org.junit.function.ThrowingRunnable)
+     * Assert.assertThrows} can be used to verify that your code throws a specific
+     * exception.
+     */
+    @Deprecated
+    public static ExpectedException none() {
+        return new ExpectedException();
+    }
+
+    private final ExpectedExceptionMatcherBuilder matcherBuilder = new ExpectedExceptionMatcherBuilder();
+
+    private String missingExceptionMessage= "Expected test to throw %s";
+
+    private ExpectedException() {
+    }
+
+    /**
+     * This method does nothing. Don't use it.
+     * @deprecated AssertionErrors are handled by default since JUnit 4.12. Just
+     *             like in JUnit &lt;= 4.10.
+     */
+    @Deprecated
+    public ExpectedException handleAssertionErrors() {
+        return this;
+    }
+
+    /**
+     * This method does nothing. Don't use it.
+     * @deprecated AssumptionViolatedExceptions are handled by default since
+     *             JUnit 4.12. Just like in JUnit &lt;= 4.10.
+     */
+    @Deprecated
+    public ExpectedException handleAssumptionViolatedExceptions() {
+        return this;
+    }
+
+    /**
+     * Specifies the failure message for tests that are expected to throw 
+     * an exception but do not throw any. You can use a {@code %s} placeholder for
+     * the description of the expected exception. E.g. "Test doesn't throw %s."
+     * will fail with the error message
+     * "Test doesn't throw an instance of foo.".
+     *
+     * @param message exception detail message
+     * @return the rule itself
+     */
+    public ExpectedException reportMissingExceptionWithMessage(String message) {
+        missingExceptionMessage = message;
+        return this;
+    }
+
+    public Statement apply(Statement base,
+            org.junit.runner.Description description) {
+        return new ExpectedExceptionStatement(base);
+    }
+
+    /**
+     * Verify that your code throws an exception that is matched by
+     * a Hamcrest matcher.
+     * <pre> &#064;Test
+     * public void throwsExceptionThatCompliesWithMatcher() {
+     *     NullPointerException e = new NullPointerException();
+     *     thrown.expect(is(e));
+     *     throw e;
+     * }</pre>
+     */
+    public void expect(Matcher<?> matcher) {
+        matcherBuilder.add(matcher);
+    }
+
+    /**
+     * Verify that your code throws an exception that is an
+     * instance of specific {@code type}.
+     * <pre> &#064;Test
+     * public void throwsExceptionWithSpecificType() {
+     *     thrown.expect(NullPointerException.class);
+     *     throw new NullPointerException();
+     * }</pre>
+     */
+    public void expect(Class<? extends Throwable> type) {
+        expect(instanceOf(type));
+    }
+
+    /**
+     * Verify that your code throws an exception whose message contains
+     * a specific text.
+     * <pre> &#064;Test
+     * public void throwsExceptionWhoseMessageContainsSpecificText() {
+     *     thrown.expectMessage(&quot;happened&quot;);
+     *     throw new NullPointerException(&quot;What happened?&quot;);
+     * }</pre>
+     */
+    public void expectMessage(String substring) {
+        expectMessage(containsString(substring));
+    }
+
+    /**
+     * Verify that your code throws an exception whose message is matched 
+     * by a Hamcrest matcher.
+     * <pre> &#064;Test
+     * public void throwsExceptionWhoseMessageCompliesWithMatcher() {
+     *     thrown.expectMessage(startsWith(&quot;What&quot;));
+     *     throw new NullPointerException(&quot;What happened?&quot;);
+     * }</pre>
+     */
+    public void expectMessage(Matcher<String> matcher) {
+        expect(hasMessage(matcher));
+    }
+
+    /**
+     * Verify that your code throws an exception whose cause is matched by 
+     * a Hamcrest matcher.
+     * <pre> &#064;Test
+     * public void throwsExceptionWhoseCauseCompliesWithMatcher() {
+     *     NullPointerException expectedCause = new NullPointerException();
+     *     thrown.expectCause(is(expectedCause));
+     *     throw new IllegalArgumentException(&quot;What happened?&quot;, cause);
+     * }</pre>
+     */
+    public void expectCause(Matcher<?> expectedCause) {
+        expect(hasCause(expectedCause));
+    }
+
+    /**
+     * Check if any Exception is expected.
+     * @since 4.13
+     */
+    public final boolean isAnyExceptionExpected() {
+        return matcherBuilder.expectsThrowable();
+    }
+
+    private class ExpectedExceptionStatement extends Statement {
+        private final Statement next;
+
+        public ExpectedExceptionStatement(Statement base) {
+            next = base;
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            try {
+                next.evaluate();
+            } catch (Throwable e) {
+                handleException(e);
+                return;
+            }
+            if (isAnyExceptionExpected()) {
+                failDueToMissingException();
+            }
+        }
+    }
+
+    private void handleException(Throwable e) throws Throwable {
+        if (isAnyExceptionExpected()) {
+            assertThat(e, matcherBuilder.build());
+        } else {
+            throw e;
+        }
+    }
+
+    private void failDueToMissingException() throws AssertionError {
+        fail(missingExceptionMessage());
+    }
+    
+    private String missingExceptionMessage() {
+        String expectation= StringDescription.toString(matcherBuilder.build());
+        return format(missingExceptionMessage, expectation);
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedExceptionMatcherBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedExceptionMatcherBuilder.java
new file mode 100644
index 0000000..e7d94c4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedExceptionMatcherBuilder.java
@@ -0,0 +1,46 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.junit.matchers.JUnitMatchers.isThrowable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+
+/**
+ * Builds special matcher used by {@link ExpectedException}.
+ */
+class ExpectedExceptionMatcherBuilder {
+
+    private final List<Matcher<?>> matchers = new ArrayList<Matcher<?>>();
+
+    void add(Matcher<?> matcher) {
+        matchers.add(matcher);
+    }
+
+    boolean expectsThrowable() {
+        return !matchers.isEmpty();
+    }
+
+    Matcher<Throwable> build() {
+        return isThrowable(allOfTheMatchers());
+    }
+
+    private Matcher<Throwable> allOfTheMatchers() {
+        if (matchers.size() == 1) {
+            return cast(matchers.get(0));
+        }
+        return allOf(castedMatchers());
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private List<Matcher<? super Throwable>> castedMatchers() {
+        return new ArrayList<Matcher<? super Throwable>>((List) matchers);
+    }
+
+    @SuppressWarnings("unchecked")
+    private Matcher<Throwable> cast(Matcher<?> singleMatcher) {
+        return (Matcher<Throwable>) singleMatcher;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java
new file mode 100644
index 0000000..71fc842
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java
@@ -0,0 +1,84 @@
+package org.junit.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+/**
+ * A base class for Rules (like TemporaryFolder) that set up an external
+ * resource before a test (a file, socket, server, database connection, etc.),
+ * and guarantee to tear it down afterward:
+ *
+ * <pre>
+ * public static class UsesExternalResource {
+ *  Server myServer= new Server();
+ *
+ *  &#064;Rule
+ *  public ExternalResource resource= new ExternalResource() {
+ *      &#064;Override
+ *      protected void before() throws Throwable {
+ *          myServer.connect();
+ *         };
+ *
+ *      &#064;Override
+ *      protected void after() {
+ *          myServer.disconnect();
+ *         };
+ *     };
+ *
+ *  &#064;Test
+ *  public void testFoo() {
+ *      new Client().run(myServer);
+ *     }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public abstract class ExternalResource implements TestRule {
+    public Statement apply(Statement base, Description description) {
+        return statement(base);
+    }
+
+    private Statement statement(final Statement base) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                before();
+
+                List<Throwable> errors = new ArrayList<Throwable>();
+                try {
+                    base.evaluate();
+                } catch (Throwable t) {
+                    errors.add(t);
+                } finally {
+                    try {
+                        after();
+                    } catch (Throwable t) {
+                        errors.add(t);
+                    }
+                }
+                MultipleFailureException.assertEmpty(errors);
+            }
+        };
+    }
+
+    /**
+     * Override to set up your specific external resource.
+     *
+     * @throws Throwable if setup fails (which will disable {@code after}
+     */
+    protected void before() throws Throwable {
+        // do nothing
+    }
+
+    /**
+     * Override to tear down your specific external resource.
+     */
+    protected void after() {
+        // do nothing
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/MethodRule.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/MethodRule.java
new file mode 100644
index 0000000..94608f5
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/MethodRule.java
@@ -0,0 +1,32 @@
+package org.junit.rules;
+
+import org.junit.Rule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * A MethodRule is an alteration in how a test method is run and reported.
+ * Multiple {@link MethodRule}s can be applied to a test method. The
+ * {@link Statement} that executes the method is passed to each annotated
+ * {@link Rule} in turn, and each may return a substitute or modified
+ * {@link Statement}, which is passed to the next {@link Rule}, if any. For
+ * an example of how this can be useful, see {@link TestWatchman}.
+ *
+ * <p>Note that {@link MethodRule} has been replaced by {@link TestRule},
+ * which has the added benefit of supporting class rules.
+ *
+ * @since 4.7
+ */
+public interface MethodRule {
+    /**
+     * Modifies the method-running {@link Statement} to implement an additional
+     * test-running rule.
+     *
+     * @param base The {@link Statement} to be modified
+     * @param method The method to be run
+     * @param target The object on which the method will be run.
+     * @return a new statement, which may be the same as {@code base},
+     *         a wrapper around {@code base}, or a completely new Statement.
+     */
+    Statement apply(Statement base, FrameworkMethod method, Object target);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/RuleChain.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/RuleChain.java
new file mode 100644
index 0000000..bf93aae
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/RuleChain.java
@@ -0,0 +1,113 @@
+package org.junit.rules;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code RuleChain} can be used for creating composite rules. You create a
+ * {@code RuleChain} with {@link #outerRule(TestRule)} and subsequent calls of
+ * {@link #around(TestRule)}:
+ *
+ * <pre>
+ * public abstract class CompositeRules {
+ *   public static TestRule extendedLogging() {
+ *     return RuleChain.outerRule(new LoggingRule("outer rule"))
+ *                     .around(new LoggingRule("middle rule"))
+ *                     .around(new LoggingRule("inner rule"));
+ *   }
+ * }
+ * </pre>
+ *
+ * <pre>
+ * public class UseRuleChain {
+ *   &#064;Rule
+ *   public final TestRule extendedLogging = CompositeRules.extendedLogging();
+ *
+ *   &#064;Test
+ *   public void example() {
+ *     assertTrue(true);
+ *   }
+ * }
+ * </pre>
+ *
+ * writes the log
+ *
+ * <pre>
+ * starting outer rule
+ * starting middle rule
+ * starting inner rule
+ * finished inner rule
+ * finished middle rule
+ * finished outer rule
+ * </pre>
+ *
+ * In older versions of JUnit (before 4.13) {@code RuleChain} was used for
+ * ordering rules. We recommend to not use it for this purpose anymore. You can
+ * use the attribute {@code order} of the annotation {@link Rule#order() Rule}
+ * or {@link org.junit.ClassRule#order() ClassRule} for ordering rules.
+ *
+ * @see org.junit.Rule#order()
+ * @see org.junit.ClassRule#order()
+ * @since 4.10
+ */
+public class RuleChain implements TestRule {
+    private static final RuleChain EMPTY_CHAIN = new RuleChain(
+            Collections.<TestRule>emptyList());
+
+    private List<TestRule> rulesStartingWithInnerMost;
+
+    /**
+     * Returns a {@code RuleChain} without a {@link TestRule}. This method may
+     * be the starting point of a {@code RuleChain}.
+     *
+     * @return a {@code RuleChain} without a {@link TestRule}.
+     */
+    public static RuleChain emptyRuleChain() {
+        return EMPTY_CHAIN;
+    }
+
+    /**
+     * Returns a {@code RuleChain} with a single {@link TestRule}. This method
+     * is the usual starting point of a {@code RuleChain}.
+     *
+     * @param outerRule the outer rule of the {@code RuleChain}.
+     * @return a {@code RuleChain} with a single {@link TestRule}.
+     */
+    public static RuleChain outerRule(TestRule outerRule) {
+        return emptyRuleChain().around(outerRule);
+    }
+
+    private RuleChain(List<TestRule> rules) {
+        this.rulesStartingWithInnerMost = rules;
+    }
+
+    /**
+     * Create a new {@code RuleChain}, which encloses the given {@link TestRule} with
+     * the rules of the current {@code RuleChain}.
+     *
+     * @param enclosedRule the rule to enclose; must not be {@code null}.
+     * @return a new {@code RuleChain}.
+     * @throws NullPointerException if the argument {@code enclosedRule} is {@code null}
+     */
+    public RuleChain around(TestRule enclosedRule) {
+        if (enclosedRule == null) {
+            throw new NullPointerException("The enclosed rule must not be null");
+        }
+        List<TestRule> rulesOfNewChain = new ArrayList<TestRule>();
+        rulesOfNewChain.add(enclosedRule);
+        rulesOfNewChain.addAll(rulesStartingWithInnerMost);
+        return new RuleChain(rulesOfNewChain);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Statement apply(Statement base, Description description) {
+        return new RunRules(base, rulesStartingWithInnerMost, description);
+    }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/RunRules.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/RunRules.java
new file mode 100644
index 0000000..131fc1f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/RunRules.java
@@ -0,0 +1,30 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Runs a collection of rules on a statement.
+ *
+ * @since 4.9
+ */
+public class RunRules extends Statement {
+    private final Statement statement;
+
+    public RunRules(Statement base, Iterable<TestRule> rules, Description description) {
+        statement = applyAll(base, rules, description);
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        statement.evaluate();
+    }
+
+    private static Statement applyAll(Statement result, Iterable<TestRule> rules,
+            Description description) {
+        for (TestRule each : rules) {
+            result = each.apply(result, description);
+        }
+        return result;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/Stopwatch.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/Stopwatch.java
new file mode 100644
index 0000000..6900a48
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/Stopwatch.java
@@ -0,0 +1,183 @@
+package org.junit.rules;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The Stopwatch Rule notifies one of its own protected methods of the time spent by a test.
+ *
+ * <p>Override them to get the time in nanoseconds. For example, this class will keep logging the
+ * time spent by each passed, failed, skipped, and finished test:
+ *
+ * <pre>
+ * public static class StopwatchTest {
+ *     private static final Logger logger = Logger.getLogger(&quot;&quot;);
+ *
+ *     private static void logInfo(Description description, String status, long nanos) {
+ *         String testName = description.getMethodName();
+ *         logger.info(String.format(&quot;Test %s %s, spent %d microseconds&quot;,
+ *                                   testName, status, TimeUnit.NANOSECONDS.toMicros(nanos)));
+ *     }
+ *
+ *     &#064;Rule
+ *     public Stopwatch stopwatch = new Stopwatch() {
+ *         &#064;Override
+ *         protected void succeeded(long nanos, Description description) {
+ *             logInfo(description, &quot;succeeded&quot;, nanos);
+ *         }
+ *
+ *         &#064;Override
+ *         protected void failed(long nanos, Throwable e, Description description) {
+ *             logInfo(description, &quot;failed&quot;, nanos);
+ *         }
+ *
+ *         &#064;Override
+ *         protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
+ *             logInfo(description, &quot;skipped&quot;, nanos);
+ *         }
+ *
+ *         &#064;Override
+ *         protected void finished(long nanos, Description description) {
+ *             logInfo(description, &quot;finished&quot;, nanos);
+ *         }
+ *     };
+ *
+ *     &#064;Test
+ *     public void succeeds() {
+ *     }
+ *
+ *     &#064;Test
+ *     public void fails() {
+ *         fail();
+ *     }
+ *
+ *     &#064;Test
+ *     public void skips() {
+ *         assumeTrue(false);
+ *     }
+ * }
+ * </pre>
+ *
+ * An example to assert runtime:
+ * <pre>
+ * &#064;Test
+ * public void performanceTest() throws InterruptedException {
+ *     long delta = 30;
+ *     Thread.sleep(300L);
+ *     assertEquals(300d, stopwatch.runtime(MILLISECONDS), delta);
+ *     Thread.sleep(500L);
+ *     assertEquals(800d, stopwatch.runtime(MILLISECONDS), delta);
+ * }
+ * </pre>
+ *
+ * @author tibor17
+ * @since 4.12
+ */
+public class Stopwatch implements TestRule {
+    private final Clock clock;
+    private volatile long startNanos;
+    private volatile long endNanos;
+
+    public Stopwatch() {
+        this(new Clock());
+    }
+
+    Stopwatch(Clock clock) {
+        this.clock = clock;
+    }
+
+    /**
+     * Gets the runtime for the test.
+     *
+     * @param unit time unit for returned runtime
+     * @return runtime measured during the test
+     */
+    public long runtime(TimeUnit unit) {
+        return unit.convert(getNanos(), TimeUnit.NANOSECONDS);
+    }
+
+    /**
+     * Invoked when a test succeeds
+     */
+    protected void succeeded(long nanos, Description description) {
+    }
+
+    /**
+     * Invoked when a test fails
+     */
+    protected void failed(long nanos, Throwable e, Description description) {
+    }
+
+    /**
+     * Invoked when a test is skipped due to a failed assumption.
+     */
+    protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
+    }
+
+    /**
+     * Invoked when a test method finishes (whether passing or failing)
+     */
+    protected void finished(long nanos, Description description) {
+    }
+
+    private long getNanos() {
+        if (startNanos == 0) {
+            throw new IllegalStateException("Test has not started");
+        }
+        long currentEndNanos = endNanos; // volatile read happens here
+        if (currentEndNanos == 0) {
+          currentEndNanos = clock.nanoTime();
+        }
+
+        return currentEndNanos - startNanos;
+    }
+
+    private void starting() {
+        startNanos = clock.nanoTime();
+        endNanos = 0;
+    }
+
+    private void stopping() {
+        endNanos = clock.nanoTime();
+    }
+
+    public final Statement apply(Statement base, Description description) {
+        return new InternalWatcher().apply(base, description);
+    }
+
+    private class InternalWatcher extends TestWatcher {
+
+        @Override protected void starting(Description description) {
+            Stopwatch.this.starting();
+        }
+
+        @Override protected void finished(Description description) {
+            Stopwatch.this.finished(getNanos(), description);
+        }
+
+        @Override protected void succeeded(Description description) {
+            Stopwatch.this.stopping();
+            Stopwatch.this.succeeded(getNanos(), description);
+        }
+
+        @Override protected void failed(Throwable e, Description description) {
+            Stopwatch.this.stopping();
+            Stopwatch.this.failed(getNanos(), e, description);
+        }
+
+        @Override protected void skipped(AssumptionViolatedException e, Description description) {
+            Stopwatch.this.stopping();
+            Stopwatch.this.skipped(getNanos(), e, description);
+        }
+    }
+
+    static class Clock {
+
+        public long nanoTime() {
+            return System.nanoTime();
+        }
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TemporaryFolder.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TemporaryFolder.java
new file mode 100644
index 0000000..a726c66
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TemporaryFolder.java
@@ -0,0 +1,351 @@
+package org.junit.rules;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.Rule;
+
+/**
+ * The TemporaryFolder Rule allows creation of files and folders that should
+ * be deleted when the test method finishes (whether it passes or
+ * fails).
+ * By default no exception will be thrown in case the deletion fails.
+ *
+ * <p>Example of usage:
+ * <pre>
+ * public static class HasTempFolder {
+ *  &#064;Rule
+ *  public TemporaryFolder folder= new TemporaryFolder();
+ *
+ *  &#064;Test
+ *  public void testUsingTempFolder() throws IOException {
+ *      File createdFile= folder.newFile(&quot;myfile.txt&quot;);
+ *      File createdFolder= folder.newFolder(&quot;subfolder&quot;);
+ *      // ...
+ *     }
+ * }
+ * </pre>
+ *
+ * <p>TemporaryFolder rule supports assured deletion mode, which
+ * will fail the test in case deletion fails with {@link AssertionError}.
+ *
+ * <p>Creating TemporaryFolder with assured deletion:
+ * <pre>
+ *  &#064;Rule
+ *  public TemporaryFolder folder= TemporaryFolder.builder().assureDeletion().build();
+ * </pre>
+ *
+ * @since 4.7
+ */
+public class TemporaryFolder extends ExternalResource {
+    private final File parentFolder;
+    private final boolean assureDeletion;
+    private File folder;
+
+    private static final int TEMP_DIR_ATTEMPTS = 10000;
+    private static final String TMP_PREFIX = "junit";
+
+    /**
+     * Create a temporary folder which uses system default temporary-file 
+     * directory to create temporary resources.
+     */
+    public TemporaryFolder() {
+        this((File) null);
+    }
+
+    /**
+     * Create a temporary folder which uses the specified directory to create
+     * temporary resources.
+     *
+     * @param parentFolder folder where temporary resources will be created.
+     * If {@code null} then system default temporary-file directory is used.
+     */
+    public TemporaryFolder(File parentFolder) {
+        this.parentFolder = parentFolder;
+        this.assureDeletion = false;
+    }
+
+    /**
+     * Create a {@link TemporaryFolder} initialized with
+     * values from a builder.
+     */
+    protected TemporaryFolder(Builder builder) {
+        this.parentFolder = builder.parentFolder;
+        this.assureDeletion = builder.assureDeletion;
+    }
+
+    /**
+     * Returns a new builder for building an instance of {@link TemporaryFolder}.
+     *
+     * @since 4.13
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builds an instance of {@link TemporaryFolder}.
+     * 
+     * @since 4.13
+     */
+    public static class Builder {
+        private File parentFolder;
+        private boolean assureDeletion;
+
+        protected Builder() {}
+
+        /**
+         * Specifies which folder to use for creating temporary resources.
+         * If {@code null} then system default temporary-file directory is
+         * used.
+         *
+         * @return this
+         */
+        public Builder parentFolder(File parentFolder) {
+            this.parentFolder = parentFolder;
+            return this;
+        }
+
+        /**
+         * Setting this flag assures that no resources are left undeleted. Failure
+         * to fulfill the assurance results in failure of tests with an
+         * {@link AssertionError}.
+         *
+         * @return this
+         */
+        public Builder assureDeletion() {
+            this.assureDeletion = true;
+            return this;
+        }
+
+        /**
+         * Builds a {@link TemporaryFolder} instance using the values in this builder.
+         */
+        public TemporaryFolder build() {
+            return new TemporaryFolder(this);
+        }
+    }
+
+    @Override
+    protected void before() throws Throwable {
+        create();
+    }
+
+    @Override
+    protected void after() {
+        delete();
+    }
+
+    // testing purposes only
+
+    /**
+     * for testing purposes only. Do not use.
+     */
+    public void create() throws IOException {
+        folder = createTemporaryFolderIn(parentFolder);
+    }
+
+    /**
+     * Returns a new fresh file with the given name under the temporary folder.
+     */
+    public File newFile(String fileName) throws IOException {
+        File file = new File(getRoot(), fileName);
+        if (!file.createNewFile()) {
+            throw new IOException(
+                    "a file with the name \'" + fileName + "\' already exists in the test folder");
+        }
+        return file;
+    }
+
+    /**
+     * Returns a new fresh file with a random name under the temporary folder.
+     */
+    public File newFile() throws IOException {
+        return File.createTempFile(TMP_PREFIX, null, getRoot());
+    }
+
+    /**
+     * Returns a new fresh folder with the given path under the temporary
+     * folder.
+     */
+    public File newFolder(String path) throws IOException {
+        return newFolder(new String[]{path});
+    }
+
+    /**
+     * Returns a new fresh folder with the given paths under the temporary
+     * folder. For example, if you pass in the strings {@code "parent"} and {@code "child"}
+     * then a directory named {@code "parent"} will be created under the temporary folder
+     * and a directory named {@code "child"} will be created under the newly-created
+     * {@code "parent"} directory.
+     */
+    public File newFolder(String... paths) throws IOException {
+        if (paths.length == 0) {
+            throw new IllegalArgumentException("must pass at least one path");
+        }
+
+        /*
+         * Before checking if the paths are absolute paths, check if create() was ever called,
+         * and if it wasn't, throw IllegalStateException.
+         */
+        File root = getRoot();
+        for (String path : paths) {
+            if (new File(path).isAbsolute()) {
+                throw new IOException("folder path \'" + path + "\' is not a relative path");
+            }
+        }
+
+        File relativePath = null;
+        File file = root;
+        boolean lastMkdirsCallSuccessful = true;
+        for (String path : paths) {
+            relativePath = new File(relativePath, path);
+            file = new File(root, relativePath.getPath());
+
+            lastMkdirsCallSuccessful = file.mkdirs();
+            if (!lastMkdirsCallSuccessful && !file.isDirectory()) {
+                if (file.exists()) {
+                    throw new IOException(
+                            "a file with the path \'" + relativePath.getPath() + "\' exists");
+                } else {
+                    throw new IOException(
+                            "could not create a folder with the path \'" + relativePath.getPath() + "\'");
+                }
+            }
+        }
+        if (!lastMkdirsCallSuccessful) {
+            throw new IOException(
+                    "a folder with the path \'" + relativePath.getPath() + "\' already exists");
+        }
+        return file;
+    }
+
+    /**
+     * Returns a new fresh folder with a random name under the temporary folder.
+     */
+    public File newFolder() throws IOException {
+        return createTemporaryFolderIn(getRoot());
+    }
+
+    private static File createTemporaryFolderIn(File parentFolder) throws IOException {
+        try {
+            return createTemporaryFolderWithNioApi(parentFolder);
+        } catch (ClassNotFoundException ignore) {
+            // Fallback for Java 5 and 6
+            return createTemporaryFolderWithFileApi(parentFolder);
+        } catch (InvocationTargetException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof IOException) {
+                throw (IOException) cause;
+            }
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            }
+            IOException exception = new IOException("Failed to create temporary folder in " + parentFolder);
+            exception.initCause(cause);
+            throw exception;
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to create temporary folder in " + parentFolder, e);
+        }
+    }
+
+    private static File createTemporaryFolderWithNioApi(File parentFolder) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?> filesClass = Class.forName("java.nio.file.Files");
+        Object fileAttributeArray = Array.newInstance(Class.forName("java.nio.file.attribute.FileAttribute"), 0);
+        Class<?> pathClass = Class.forName("java.nio.file.Path");
+        Object tempDir;
+        if (parentFolder != null) {
+            Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", pathClass, String.class, fileAttributeArray.getClass());
+            Object parentPath = File.class.getDeclaredMethod("toPath").invoke(parentFolder);
+            tempDir = createTempDirectoryMethod.invoke(null, parentPath, TMP_PREFIX, fileAttributeArray);
+        } else {
+            Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", String.class, fileAttributeArray.getClass());
+            tempDir = createTempDirectoryMethod.invoke(null, TMP_PREFIX, fileAttributeArray);
+        }
+        return (File) pathClass.getDeclaredMethod("toFile").invoke(tempDir);
+    }
+
+    private static File createTemporaryFolderWithFileApi(File parentFolder) throws IOException {
+        File createdFolder = null;
+        for (int i = 0; i < TEMP_DIR_ATTEMPTS; ++i) {
+            // Use createTempFile to get a suitable folder name.
+            String suffix = ".tmp";
+            File tmpFile = File.createTempFile(TMP_PREFIX, suffix, parentFolder);
+            String tmpName = tmpFile.toString();
+            // Discard .tmp suffix of tmpName.
+            String folderName = tmpName.substring(0, tmpName.length() - suffix.length());
+            createdFolder = new File(folderName);
+            if (createdFolder.mkdir()) {
+                tmpFile.delete();
+                return createdFolder;
+            }
+            tmpFile.delete();
+        }
+        throw new IOException("Unable to create temporary directory in: "
+            + parentFolder.toString() + ". Tried " + TEMP_DIR_ATTEMPTS + " times. "
+            + "Last attempted to create: " + createdFolder.toString());
+    }
+
+    /**
+     * @return the location of this temporary folder.
+     */
+    public File getRoot() {
+        if (folder == null) {
+            throw new IllegalStateException(
+                    "the temporary folder has not yet been created");
+        }
+        return folder;
+    }
+
+    /**
+     * Delete all files and folders under the temporary folder. Usually not
+     * called directly, since it is automatically applied by the {@link Rule}.
+     *
+     * @throws AssertionError if unable to clean up resources
+     * and deletion of resources is assured.
+     */
+    public void delete() {
+        if (!tryDelete()) {
+            if (assureDeletion) {
+                fail("Unable to clean up temporary folder " + folder);
+            }
+        }
+    }
+
+    /**
+     * Tries to delete all files and folders under the temporary folder and
+     * returns whether deletion was successful or not.
+     *
+     * @return {@code true} if all resources are deleted successfully,
+     *         {@code false} otherwise.
+     */
+    private boolean tryDelete() {
+        if (folder == null) {
+            return true;
+        }
+        
+        return recursiveDelete(folder);
+    }
+
+    private boolean recursiveDelete(File file) {
+        // Try deleting file before assuming file is a directory
+        // to prevent following symbolic links.
+        if (file.delete()) {
+            return true;
+        }
+        File[] files = file.listFiles();
+        if (files != null) {
+            for (File each : files) {
+                if (!recursiveDelete(each)) {
+                    return false;
+                }
+            }
+        }
+        return file.delete();
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestName.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestName.java
new file mode 100644
index 0000000..e2ebc2e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestName.java
@@ -0,0 +1,41 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+
+/**
+ * The TestName Rule makes the current test name available inside test methods:
+ *
+ * <pre>
+ * public class TestNameTest {
+ *  &#064;Rule
+ *  public TestName name= new TestName();
+ *
+ *  &#064;Test
+ *  public void testA() {
+ *      assertEquals(&quot;testA&quot;, name.getMethodName());
+ *     }
+ *
+ *  &#064;Test
+ *  public void testB() {
+ *      assertEquals(&quot;testB&quot;, name.getMethodName());
+ *     }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public class TestName extends TestWatcher {
+    private volatile String name;
+
+    @Override
+    protected void starting(Description d) {
+        name = d.getMethodName();
+    }
+
+    /**
+     * @return the name of the currently-running test method
+     */
+    public String getMethodName() {
+        return name;
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestRule.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestRule.java
new file mode 100644
index 0000000..53e2f70
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestRule.java
@@ -0,0 +1,56 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * A TestRule is an alteration in how a test method, or set of test methods,
+ * is run and reported.  A {@link TestRule} may add additional checks that cause
+ * a test that would otherwise fail to pass, or it may perform necessary setup or
+ * cleanup for tests, or it may observe test execution to report it elsewhere.
+ * {@link TestRule}s can do everything that could be done previously with
+ * methods annotated with {@link org.junit.Before},
+ * {@link org.junit.After}, {@link org.junit.BeforeClass}, or
+ * {@link org.junit.AfterClass}, but they are more powerful, and more easily
+ * shared
+ * between projects and classes.
+ *
+ * The default JUnit test runners for suites and
+ * individual test cases recognize {@link TestRule}s introduced in two different
+ * ways.  {@link org.junit.Rule} annotates method-level
+ * {@link TestRule}s, and {@link org.junit.ClassRule}
+ * annotates class-level {@link TestRule}s.  See Javadoc for those annotations
+ * for more information.
+ *
+ * Multiple {@link TestRule}s can be applied to a test or suite execution. The
+ * {@link Statement} that executes the method or suite is passed to each annotated
+ * {@link org.junit.Rule} in turn, and each may return a substitute or modified
+ * {@link Statement}, which is passed to the next {@link org.junit.Rule}, if any. For
+ * examples of how this can be useful, see these provided TestRules,
+ * or write your own:
+ *
+ * <ul>
+ *   <li>{@link ErrorCollector}: collect multiple errors in one test method</li>
+ *   <li>{@link ExpectedException}: make flexible assertions about thrown exceptions</li>
+ *   <li>{@link ExternalResource}: start and stop a server, for example</li>
+ *   <li>{@link TemporaryFolder}: create fresh files, and delete after test</li>
+ *   <li>{@link TestName}: remember the test name for use during the method</li>
+ *   <li>{@link TestWatcher}: add logic at events during method execution</li>
+ *   <li>{@link Timeout}: cause test to fail after a set time</li>
+ *   <li>{@link Verifier}: fail test if object state ends up incorrect</li>
+ * </ul>
+ *
+ * @since 4.9
+ */
+public interface TestRule {
+    /**
+     * Modifies the method-running {@link Statement} to implement this
+     * test-running rule.
+     *
+     * @param base The {@link Statement} to be modified
+     * @param description A {@link Description} of the test implemented in {@code base}
+     * @return a new statement, which may be the same as {@code base},
+     *         a wrapper around {@code base}, or a completely new Statement.
+     */
+    Statement apply(Statement base, Description description);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java
new file mode 100644
index 0000000..a28514d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java
@@ -0,0 +1,170 @@
+package org.junit.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.Rule;
+import org.junit.runner.Description;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+/**
+ * TestWatcher is a base class for Rules that take note of the testing
+ * action, without modifying it. For example, this class will keep a log of each
+ * passing and failing test:
+ *
+ * <pre>
+ * public static class WatchmanTest {
+ *  private static String watchedLog;
+ *
+ *  &#064;Rule(order = Integer.MIN_VALUE)
+ *  public TestWatcher watchman= new TestWatcher() {
+ *      &#064;Override
+ *      protected void failed(Throwable e, Description description) {
+ *          watchedLog+= description + &quot;\n&quot;;
+ *      }
+ *
+ *      &#064;Override
+ *      protected void succeeded(Description description) {
+ *          watchedLog+= description + &quot; &quot; + &quot;success!\n&quot;;
+ *         }
+ *     };
+ *
+ *  &#064;Test
+ *  public void fails() {
+ *      fail();
+ *  }
+ *
+ *  &#064;Test
+ *  public void succeeds() {
+ *     }
+ * }
+ * </pre>
+ * <p>It is recommended to always set the {@link Rule#order() order} of the
+ * {@code TestWatcher} to {@code Integer.MIN_VALUE} so that it encloses all
+ * other rules. Otherwise it may see failed tests as successful and vice versa
+ * if some rule changes the result of a test (e.g. {@link ErrorCollector} or
+ * {@link ExpectedException}).
+ *
+ * @since 4.9
+ */
+public abstract class TestWatcher implements TestRule {
+    public Statement apply(final Statement base, final Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                List<Throwable> errors = new ArrayList<Throwable>();
+
+                startingQuietly(description, errors);
+                try {
+                    base.evaluate();
+                    succeededQuietly(description, errors);
+                } catch (org.junit.internal.AssumptionViolatedException  e) {
+                    errors.add(e);
+                    skippedQuietly(e, description, errors);
+                } catch (Throwable e) {
+                    errors.add(e);
+                    failedQuietly(e, description, errors);
+                } finally {
+                    finishedQuietly(description, errors);
+                }
+
+                MultipleFailureException.assertEmpty(errors);
+            }
+        };
+    }
+
+    private void succeededQuietly(Description description,
+            List<Throwable> errors) {
+        try {
+            succeeded(description);
+        } catch (Throwable e) {
+            errors.add(e);
+        }
+    }
+
+    private void failedQuietly(Throwable e, Description description,
+            List<Throwable> errors) {
+        try {
+            failed(e, description);
+        } catch (Throwable e1) {
+            errors.add(e1);
+        }
+    }
+
+    private void skippedQuietly(
+            org.junit.internal.AssumptionViolatedException e, Description description,
+            List<Throwable> errors) {
+        try {
+            if (e instanceof AssumptionViolatedException) {
+                skipped((AssumptionViolatedException) e, description);
+            } else {
+                skipped(e, description);
+            }
+        } catch (Throwable e1) {
+            errors.add(e1);
+        }
+    }
+
+    private void startingQuietly(Description description,
+            List<Throwable> errors) {
+        try {
+            starting(description);
+        } catch (Throwable e) {
+            errors.add(e);
+        }
+    }
+
+    private void finishedQuietly(Description description,
+            List<Throwable> errors) {
+        try {
+            finished(description);
+        } catch (Throwable e) {
+            errors.add(e);
+        }
+    }
+
+    /**
+     * Invoked when a test succeeds
+     */
+    protected void succeeded(Description description) {
+    }
+
+    /**
+     * Invoked when a test fails
+     */
+    protected void failed(Throwable e, Description description) {
+    }
+
+    /**
+     * Invoked when a test is skipped due to a failed assumption.
+     */
+    protected void skipped(AssumptionViolatedException e, Description description) {
+        // For backwards compatibility with JUnit 4.11 and earlier, call the legacy version
+        org.junit.internal.AssumptionViolatedException asInternalException = e;
+        skipped(asInternalException, description);
+    }
+
+    /**
+     * Invoked when a test is skipped due to a failed assumption.
+     *
+     * @deprecated use {@link #skipped(AssumptionViolatedException, Description)}
+     */
+    @Deprecated
+    protected void skipped(
+            org.junit.internal.AssumptionViolatedException e, Description description) {
+    }
+
+    /**
+     * Invoked when a test is about to start
+     */
+    protected void starting(Description description) {
+    }
+
+    /**
+     * Invoked when a test method finishes (whether passing or failing)
+     */
+    protected void finished(Description description) {
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatchman.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatchman.java
new file mode 100644
index 0000000..c8d6c71
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatchman.java
@@ -0,0 +1,91 @@
+package org.junit.rules;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * TestWatchman is a base class for Rules that take note of the testing
+ * action, without modifying it. For example, this class will keep a log of each
+ * passing and failing test:
+ *
+ * <pre>
+ * public static class WatchmanTest {
+ *  private static String watchedLog;
+ *
+ *  &#064;Rule
+ *  public MethodRule watchman= new TestWatchman() {
+ *      &#064;Override
+ *      public void failed(Throwable e, FrameworkMethod method) {
+ *          watchedLog+= method.getName() + &quot; &quot; + e.getClass().getSimpleName()
+ *                  + &quot;\n&quot;;
+ *         }
+ *
+ *      &#064;Override
+ *      public void succeeded(FrameworkMethod method) {
+ *          watchedLog+= method.getName() + &quot; &quot; + &quot;success!\n&quot;;
+ *         }
+ *     };
+ *
+ *  &#064;Test
+ *  public void fails() {
+ *      fail();
+ *     }
+ *
+ *  &#064;Test
+ *  public void succeeds() {
+ *     }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ * @deprecated Use {@link TestWatcher} (which implements {@link TestRule}) instead.
+ */
+@Deprecated
+public class TestWatchman implements MethodRule {
+    public Statement apply(final Statement base, final FrameworkMethod method,
+            Object target) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                starting(method);
+                try {
+                    base.evaluate();
+                    succeeded(method);
+                } catch (AssumptionViolatedException e) {
+                    throw e;
+                } catch (Throwable e) {
+                    failed(e, method);
+                    throw e;
+                } finally {
+                    finished(method);
+                }
+            }
+        };
+    }
+
+    /**
+     * Invoked when a test method succeeds
+     */
+    public void succeeded(FrameworkMethod method) {
+    }
+
+    /**
+     * Invoked when a test method fails
+     */
+    public void failed(Throwable e, FrameworkMethod method) {
+    }
+
+    /**
+     * Invoked when a test method is about to start
+     */
+    public void starting(FrameworkMethod method) {
+    }
+
+
+    /**
+     * Invoked when a test method finishes (whether passing or failing)
+     */
+    public void finished(FrameworkMethod method) {
+    }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/Timeout.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/Timeout.java
new file mode 100644
index 0000000..334a923
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/Timeout.java
@@ -0,0 +1,233 @@
+package org.junit.rules;
+
+import org.junit.internal.runners.statements.FailOnTimeout;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The Timeout Rule applies the same timeout to all test methods in a class:
+ * <pre>
+ * public static class HasGlobalLongTimeout {
+ *
+ *  &#064;Rule
+ *  public Timeout globalTimeout = Timeout.millis(20);
+ *
+ *  &#064;Test
+ *  public void run1() throws InterruptedException {
+ *      Thread.sleep(100);
+ *  }
+ *
+ *  &#064;Test
+ *  public void infiniteLoop() {
+ *      while (true) {}
+ *  }
+ * }
+ * </pre>
+ * <p>
+ * Each test is run in a new thread. If the specified timeout elapses before
+ * the test completes, its execution is interrupted via {@link Thread#interrupt()}.
+ * This happens in interruptable I/O and locks, and methods in {@link Object}
+ * and {@link Thread} throwing {@link InterruptedException}.
+ * <p>
+ * A specified timeout of 0 will be interpreted as not set, however tests will
+ * still launch from separate threads. This can be useful for disabling timeouts
+ * in environments where they are dynamically set based on some property.
+ *
+ * @since 4.7
+ */
+public class Timeout implements TestRule {
+    private final long timeout;
+    private final TimeUnit timeUnit;
+    private final boolean lookForStuckThread;
+
+    /**
+     * Returns a new builder for building an instance.
+     *
+     * @since 4.12
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Create a {@code Timeout} instance with the timeout specified
+     * in milliseconds.
+     * <p>
+     * This constructor is deprecated.
+     * <p>
+     * Instead use {@link #Timeout(long, java.util.concurrent.TimeUnit)},
+     * {@link Timeout#millis(long)}, or {@link Timeout#seconds(long)}.
+     *
+     * @param millis the maximum time in milliseconds to allow the
+     * test to run before it should timeout
+     */
+    @Deprecated
+    public Timeout(int millis) {
+        this(millis, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Create a {@code Timeout} instance with the timeout specified
+     * at the timeUnit of granularity of the provided {@code TimeUnit}.
+     *
+     * @param timeout the maximum time to allow the test to run
+     * before it should timeout
+     * @param timeUnit the time unit for the {@code timeout}
+     * @since 4.12
+     */
+    public Timeout(long timeout, TimeUnit timeUnit) {
+        this.timeout = timeout;
+        this.timeUnit = timeUnit;
+        lookForStuckThread = false;
+    }
+
+    /**
+     * Create a {@code Timeout} instance initialized with values from
+     * a builder.
+     *
+     * @since 4.12
+     */
+    protected Timeout(Builder builder) {
+        timeout = builder.getTimeout();
+        timeUnit = builder.getTimeUnit();
+        lookForStuckThread = builder.getLookingForStuckThread();
+    }
+
+    /**
+     * Creates a {@link Timeout} that will timeout a test after the
+     * given duration, in milliseconds.
+     *
+     * @since 4.12
+     */
+    public static Timeout millis(long millis) {
+        return new Timeout(millis, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Creates a {@link Timeout} that will timeout a test after the
+     * given duration, in seconds.
+     *
+     * @since 4.12
+     */
+    public static Timeout seconds(long seconds) {
+        return new Timeout(seconds, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Gets the timeout configured for this rule, in the given units.
+     *
+     * @since 4.12
+     */
+    protected final long getTimeout(TimeUnit unit) {
+        return unit.convert(timeout, timeUnit);
+    }
+
+    /**
+     * Gets whether this {@code Timeout} will look for a stuck thread
+     * when the test times out.
+     *
+     * @since 4.12
+     */
+    protected final boolean getLookingForStuckThread() {
+        return lookForStuckThread;
+    }
+
+    /**
+     * Creates a {@link Statement} that will run the given
+     * {@code statement}, and timeout the operation based
+     * on the values configured in this rule. Subclasses
+     * can override this method for different behavior.
+     *
+     * @since 4.12
+     */
+    protected Statement createFailOnTimeoutStatement(
+            Statement statement) throws Exception {
+        return FailOnTimeout.builder()
+            .withTimeout(timeout, timeUnit)
+            .withLookingForStuckThread(lookForStuckThread)
+            .build(statement);
+    }
+
+    public Statement apply(Statement base, Description description) {
+        try {
+            return createFailOnTimeoutStatement(base);
+        } catch (final Exception e) {
+            return new Statement() {
+                @Override public void evaluate() throws Throwable {
+                    throw new RuntimeException("Invalid parameters for Timeout", e);
+                }
+            };
+        }
+    }
+
+    /**
+     * Builder for {@link Timeout}.
+     *
+     * @since 4.12
+     */
+    public static class Builder {
+        private boolean lookForStuckThread = false;
+        private long timeout = 0;
+        private TimeUnit timeUnit = TimeUnit.SECONDS;
+
+        protected Builder() {
+        }
+
+        /**
+         * Specifies the time to wait before timing out the test.
+         *
+         * <p>If this is not called, or is called with a
+         * {@code timeout} of {@code 0}, the returned {@code Timeout}
+         * rule instance will cause the tests to wait forever to
+         * complete, however the tests will still launch from a
+         * separate thread. This can be useful for disabling timeouts
+         * in environments where they are dynamically set based on
+         * some property.
+         *
+         * @param timeout the maximum time to wait
+         * @param unit the time unit of the {@code timeout} argument
+         * @return {@code this} for method chaining.
+         */