Cloned from commit 2dddbeeac25ace6f53dd3ce6ac588111c239bdf0 by '[] patch'.
Original change by elenairina@elenairina:incompatible-guava5:667:citc on 2016/08/24 08:03:39.

Original change ignored the fact that LinkedListMultimap and ConcurrentHashMap
handle the get operation differently. The first one returns an empty collection when
there is nothing associated with a given key in the data structure, while the
latter simply returns null.


Removing some of GUAVA dependencies from junit.runner.junit4 and -.model

Bazel users that are using a different Guava version than the one in the
junitrunner jar are getting an IncompatibleClassChangeError. Rewriting
parts of junitrunner code so it won't depend on Guava anymore.

Continuing progress on issue #1150.

--
MOS_MIGRATED_REVID=131695499
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java
index 10447a7..1c67697 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java
@@ -14,9 +14,7 @@
 
 package com.google.testing.junit.runner.junit4;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Supplier;
-import com.google.common.io.Files;
 import com.google.testing.junit.junit4.runner.SuiteTrimmingFilter;
 import com.google.testing.junit.runner.internal.Stdout;
 import com.google.testing.junit.runner.model.TestSuiteModel;
@@ -34,6 +32,7 @@
 import org.junit.runner.notification.RunNotifier;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.Set;
@@ -129,8 +128,10 @@
 
   private static void exitFileActive(@Nullable File file) {
     if (file != null) {
-      try {
-        Files.write(new byte[0], file);
+      try (FileOutputStream outputStream = new FileOutputStream(file, false)) {
+        // Overwrite file content.
+        outputStream.write(new byte[0]);
+        outputStream.close();
       } catch (IOException e) {
         throw new RuntimeException("Could not write exit file at " + file, e);
       }
@@ -148,7 +149,7 @@
     }
   }
 
-  @VisibleForTesting
+  // VisibleForTesting
   TestSuiteModel getModel() {
     return modelSupplier.get();
   }
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java
index 74ab90b..af64e3b 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java
@@ -16,15 +16,11 @@
 
 import static com.google.testing.junit.runner.util.TestPropertyExporter.INITIAL_INDEX_FOR_REPEATED_PROPERTY;
 
-import com.google.common.collect.ConcurrentHashMultiset;
-import com.google.common.collect.LinkedListMultimap;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Multiset;
 import com.google.testing.junit.runner.model.TestResult.Status;
 import com.google.testing.junit.runner.util.TestPropertyExporter;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Queue;
@@ -39,10 +35,10 @@
 class TestCaseNode extends TestNode implements TestPropertyExporter.Callback {
   private final TestSuiteNode parent;
   private final Map<String, String> properties = new ConcurrentHashMap<>();
-  private final Multiset<String> repeatedPropertyNames = ConcurrentHashMultiset.create();
+  private final Map<String, Integer> repeatedPropertyNamesToRepetitions = new HashMap<>();
   private final Queue<Throwable> globalFailures = new ConcurrentLinkedQueue<>();
-  private final ListMultimap<Description, Throwable> dynamicTestToFailures =
-      Multimaps.synchronizedListMultimap(LinkedListMultimap.<Description, Throwable>create());
+  private final ConcurrentHashMap<Description, List<Throwable>> dynamicTestToFailures =
+      new ConcurrentHashMap<>();
 
   @Nullable private volatile TestInterval runTimeInterval = null;
   private volatile State state = State.INITIAL;
@@ -117,11 +113,12 @@
   @Override
   public void dynamicTestFailure(Description test, Throwable throwable, long now) {
     compareAndSetState(State.INITIAL, State.FINISHED, now);
-    dynamicTestToFailures.put(test, throwable);
+    addThrowableToDynamicTestToFailures(test, throwable);
   }
 
   private String getRepeatedPropertyName(String name) {
-    int index = repeatedPropertyNames.add(name, 1) + INITIAL_INDEX_FOR_REPEATED_PROPERTY;
+    int index = addNameToRepeatedPropertyNamesAndGetRepetitionsNr(name)
+        + INITIAL_INDEX_FOR_REPEATED_PROPERTY;
     return name + index;
   }
 
@@ -130,6 +127,25 @@
     return true;
   }
 
+  private synchronized void addThrowableToDynamicTestToFailures(
+      Description test, Throwable throwable) {
+    List<Throwable> throwables = dynamicTestToFailures.get(test);
+    if (throwables == null) {
+      throwables = new ArrayList<>();
+      dynamicTestToFailures.put(test, throwables);
+    }
+    throwables.add(throwable);
+  }
+
+  private synchronized int addNameToRepeatedPropertyNamesAndGetRepetitionsNr(String name) {
+    Integer previousRepetitionsNr = repeatedPropertyNamesToRepetitions.get(name);
+    if (previousRepetitionsNr == null) {
+      previousRepetitionsNr = 0;
+    }
+    repeatedPropertyNamesToRepetitions.put(name, previousRepetitionsNr + 1);
+    return previousRepetitionsNr;
+  }
+
   private synchronized boolean compareAndSetState(State fromState, State toState, long now) {
     if (fromState == null || toState == null || state == null) {
       throw new NullPointerException();
@@ -198,6 +214,9 @@
     // The dynamic test fails if the testcase itself fails or there is
     // a dynamic failure specifically for the dynamic test.
     List<Throwable> dynamicFailures = dynamicTestToFailures.get(test);
+    if (dynamicFailures == null) {
+      dynamicFailures = new ArrayList<>();
+    }
     boolean failed = !globalFailures.isEmpty() || !dynamicFailures.isEmpty();
     return new TestResult.Builder()
         .name(test.getDisplayName())
@@ -238,4 +257,4 @@
       return status;
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java
index 08be4ca..c3babe3 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java
@@ -14,13 +14,8 @@
 
 package com.google.testing.junit.runner.model;
 
-import static com.google.common.base.Predicates.notNull;
-import static com.google.common.collect.Maps.filterValues;
-import static com.google.common.collect.Maps.transformValues;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
 import com.google.common.base.Ticker;
 import com.google.testing.junit.junit4.runner.DynamicTestException;
 import com.google.testing.junit.runner.sharding.ShardingEnvironment;
@@ -30,6 +25,7 @@
 import java.io.OutputStream;
 import java.io.StringWriter;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -269,7 +265,9 @@
     }
 
     public TestSuiteModel build(String suiteName, Description... topLevelSuites) {
-      Preconditions.checkState(!buildWasCalled, "Builder.build() was already called");
+      if (buildWasCalled) {
+        throw new IllegalStateException("Builder.build() was already called");
+      }
       buildWasCalled = true;
       if (shardingEnvironment.isShardingEnabled()) {
         shardingFilter = getShardingFilter(topLevelSuites);
@@ -317,7 +315,9 @@
     }
 
     private void addTestCase(TestSuiteNode parentSuite, Description testCaseDesc) {
-      Preconditions.checkArgument(testCaseDesc.isTest());
+      if (!testCaseDesc.isTest()) {
+        throw new IllegalArgumentException();
+      }
       if (!shardingFilter.shouldRun(testCaseDesc)) {
         return;
       }
@@ -327,16 +327,18 @@
     }
   }
 
+  /**
+   * Converts the values of the Map from {@link TestNode} to {@link TestCaseNode} filtering out null
+   * values.
+   */
   private static Map<Description, TestCaseNode> filterTestCases(Map<Description, TestNode> tests) {
-    return filterValues(transformValues(tests, toTestCaseNode()), notNull());
-  }
-
-  private static Function<TestNode, TestCaseNode> toTestCaseNode() {
-    return new Function<TestNode, TestCaseNode>() {
-      @Override
-      public TestCaseNode apply(TestNode test) {
-        return test instanceof TestCaseNode ? (TestCaseNode) test : null;
+    Map<Description, TestCaseNode> filteredAndConvertedTests = new HashMap<>();
+    for (Description key : tests.keySet()) {
+      TestNode testNode = tests.get(key);
+      if (testNode instanceof TestCaseNode) {
+        filteredAndConvertedTests.put(key, (TestCaseNode) testNode);
       }
-    };
+    }
+    return filteredAndConvertedTests;
   }
-}
+}
\ No newline at end of file