Merge "Revert "Upgrade guava to v30.0""
diff --git a/.travis.yml b/.travis.yml
index fac7af9..435138f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,13 +3,14 @@
 language: java
 
 jdk:
-  - openjdk8
+  - oraclejdk8
   - openjdk11
 
+# https://github.com/travis-ci/travis-ci/issues/3259#issuecomment-130860338
 addons:
   apt:
     packages:
-      - openjdk-8-source
+      - oracle-java8-installer
 
 install: mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install -U -DskipTests=true -f $ROOT_POM
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8e54c6f..8acd79c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -42,8 +42,8 @@
 Guidelines for any code contributions:
 
   1. Any significant changes should be accompanied by tests. The project already
-     has good test coverage, so look at some existing tests if you're unsure
-     how to go about it.
+     has good test coverage, so look at some of the existing tests if you're
+     unsure how to go about it.
   2. All contributions must be licensed Apache 2.0 and all files must have a
      copy of the boilerplate license comment (can be copied from an existing
      file).
diff --git a/README.md b/README.md
index f95062c..c063aec 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,10 @@
 [![Latest release](https://img.shields.io/github/release/google/guava.svg)](https://github.com/google/guava/releases/latest)
 [![Build Status](https://travis-ci.org/google/guava.svg?branch=master)](https://travis-ci.org/google/guava)
 
-Guava is a set of core Java libraries from Google that includes new collection types
-(such as multimap and multiset), immutable collections, a graph library, and
-utilities for concurrency, I/O, hashing, caching, primitives, strings, and more! It
-is widely used on most Java projects within Google, and widely used by many
-other companies as well.
+Guava is a set of core libraries that includes new collection types (such as
+multimap and multiset), immutable collections, a graph library, functional
+types, an in-memory cache, and APIs/utilities for concurrency, I/O, hashing,
+primitives, reflection, string processing, and much more!
 
 Guava comes in two flavors.
 
@@ -19,12 +18,12 @@
 
 ## Adding Guava to your build
 
-Guava's Maven group ID is `com.google.guava`, and its artifact ID is `guava`.
+Guava's Maven group ID is `com.google.guava` and its artifact ID is `guava`.
 Guava provides two different "flavors": one for use on a (Java 8+) JRE and one
 for use on Android or Java 7 or by any library that wants to be compatible with
 either of those. These flavors are specified in the Maven version field as
-either `30.0-jre` or `30.0-android`. For more about depending on Guava, see
-[using Guava in your build].
+either `27.1-jre` or `27.1-android`. For more about depending on
+Guava, see [using Guava in your build].
 
 To add a dependency on Guava using Maven, use the following:
 
@@ -32,9 +31,9 @@
 <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
-  <version>30.0-jre</version>
+  <version>27.1-jre</version>
   <!-- or, for Android: -->
-  <version>30.0-android</version>
+  <version>27.1-android</version>
 </dependency>
 ```
 
@@ -42,82 +41,68 @@
 
 ```gradle
 dependencies {
-  // Pick one:
-
-  // 1. Use Guava in your implementation only:
-  implementation("com.google.guava:guava:30.0-jre")
-
-  // 2. Use Guava types in your public API:
-  api("com.google.guava:guava:30.0-jre")
-
-  // 3. Android - Use Guava in your implementation only:
-  implementation("com.google.guava:guava:30.0-android")
-
-  // 4. Android - Use Guava types in your public API:
-  api("com.google.guava:guava:30.0-android")
+  compile 'com.google.guava:guava:27.1-jre'
+  // or, for Android:
+  api 'com.google.guava:guava:27.1-android'
 }
 ```
 
-For more information on when to use `api` and when to use `implementation`,
-consult the
-[Gradle documentation on API and implementation separation](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation).
-
-## Snapshots and Documentation
+## Snapshots
 
 Snapshots of Guava built from the `master` branch are available through Maven
 using version `HEAD-jre-SNAPSHOT`, or `HEAD-android-SNAPSHOT` for the Android
 flavor.
 
--   Snapshot API Docs: [guava][guava-snapshot-api-docs]
--   Snapshot API Diffs: [guava][guava-snapshot-api-diffs]
+- Snapshot API Docs: [guava][guava-snapshot-api-docs]
+- Snapshot API Diffs: [guava][guava-snapshot-api-diffs]
 
 ## Learn about Guava
 
--   Our users' guide, [Guava Explained]
--   [A nice collection](http://www.tfnico.com/presentations/google-guava) of
-    other helpful links
+- Our users' guide, [Guava Explained]
+- [A nice collection](http://www.tfnico.com/presentations/google-guava) of other helpful links
 
 ## Links
 
--   [GitHub project](https://github.com/google/guava)
--   [Issue tracker: Report a defect or feature request](https://github.com/google/guava/issues/new)
--   [StackOverflow: Ask "how-to" and "why-didn't-it-work" questions](https://stackoverflow.com/questions/ask?tags=guava+java)
--   [guava-announce: Announcements of releases and upcoming significant changes](http://groups.google.com/group/guava-announce)
--   [guava-discuss: For open-ended questions and discussion](http://groups.google.com/group/guava-discuss)
+- [GitHub project](https://github.com/google/guava)
+- [Issue tracker: Report a defect or feature request](https://github.com/google/guava/issues/new)
+- [StackOverflow: Ask "how-to" and "why-didn't-it-work" questions](https://stackoverflow.com/questions/ask?tags=guava+java)
+- [guava-discuss: For open-ended questions and discussion](http://groups.google.com/group/guava-discuss)
 
 ## IMPORTANT WARNINGS
 
-1.  APIs marked with the `@Beta` annotation at the class or method level are
-    subject to change. They can be modified in any way, or even removed, at any
-    time. If your code is a library itself (i.e., it is used on the CLASSPATH of
-    users outside your own control), you should not use beta APIs unless you
-    [repackage] them. **If your code is a library, we strongly recommend using
-    the [Guava Beta Checker] to ensure that you do not use any `@Beta` APIs!**
+1. APIs marked with the `@Beta` annotation at the class or method level
+are subject to change. They can be modified in any way, or even
+removed, at any time. If your code is a library itself (i.e. it is
+used on the CLASSPATH of users outside your own control), you should
+not use beta APIs, unless you [repackage] them. **If your
+code is a library, we strongly recommend using the [Guava Beta Checker] to
+ensure that you do not use any `@Beta` APIs!**
 
-2.  APIs without `@Beta` will remain binary-compatible for the indefinite
-    future. (Previously, we sometimes removed such APIs after a deprecation
-    period. The last release to remove non-`@Beta` APIs was Guava 21.0.) Even
-    `@Deprecated` APIs will remain (again, unless they are `@Beta`). We have no
-    plans to start removing things again, but officially, we're leaving our
-    options open in case of surprises (like, say, a serious security problem).
+2. APIs without `@Beta` will remain binary-compatible for the indefinite
+future. (Previously, we sometimes removed such APIs after a deprecation period.
+The last release to remove non-`@Beta` APIs was Guava 21.0.) Even `@Deprecated`
+APIs will remain (again, unless they are `@Beta`). We have no plans to start
+removing things again, but officially, we're leaving our options open in case
+of surprises (like, say, a serious security problem).
 
-3.  Guava has one dependency that is needed at runtime:
-    `com.google.guava:failureaccess:1.0.1`
+3. Guava has one dependency that is needed at runtime:
+`com.google.guava:failureaccess:1.0`
 
-4.  Serialized forms of ALL objects are subject to change unless noted
-    otherwise. Do not persist these and assume they can be read by a future
-    version of the library.
+4. Serialized forms of ALL objects are subject to change unless noted
+otherwise. Do not persist these and assume they can be read by a
+future version of the library.
 
-5.  Our classes are not designed to protect against a malicious caller. You
-    should not use them for communication between trusted and untrusted code.
+5. Our classes are not designed to protect against a malicious caller.
+You should not use them for communication between trusted and
+untrusted code.
 
-6.  For the mainline flavor, we unit-test the libraries using only OpenJDK 1.8
-    on Linux. Some features, especially in `com.google.common.io`, may not work
-    correctly in other environments. For the Android flavor, our unit tests run
-    on API level 15 (Ice Cream Sandwich).
+6. For the mainline flavor, we unit-test the libraries using only OpenJDK 1.8 on
+Linux. Some features, especially in `com.google.common.io`, may not work
+correctly in other environments. For the Android flavor, our unit tests run on
+API level 15 (Ice Cream Sandwich).
 
-[guava-snapshot-api-docs]: https://guava.dev/releases/snapshot-jre/api/docs/
-[guava-snapshot-api-diffs]: https://guava.dev/releases/snapshot-jre/api/diffs/
+[guava-snapshot-api-docs]: https://google.github.io/guava/releases/snapshot-jre/api/docs/
+[guava-snapshot-api-diffs]: https://google.github.io/guava/releases/snapshot-jre/api/diffs/
 [Guava Explained]: https://github.com/google/guava/wiki/Home
 [Guava Beta Checker]: https://github.com/google/guava-beta-checker
 
diff --git a/android/guava-bom/pom.xml b/android/guava-bom/pom.xml
index cbb2fda..7c2bdad 100644
--- a/android/guava-bom/pom.xml
+++ b/android/guava-bom/pom.xml
@@ -8,7 +8,7 @@
 
   <groupId>com.google.guava</groupId>
   <artifactId>guava-bom</artifactId>
-  <version>30.0-android</version>
+  <version>27.1-android</version>
   <packaging>pom</packaging>
   
   <parent>
@@ -29,7 +29,7 @@
 
   <licenses>
     <license>
-      <name>Apache License, Version 2.0</name>
+      <name>The Apache Software License, Version 2.0</name>
       <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
       <distribution>repo</distribution>
     </license>
diff --git a/android/guava-testlib/pom.xml b/android/guava-testlib/pom.xml
index ed18b46..2b0ba53 100644
--- a/android/guava-testlib/pom.xml
+++ b/android/guava-testlib/pom.xml
@@ -5,7 +5,7 @@
   <parent>
     <groupId>com.google.guava</groupId>
     <artifactId>guava-parent</artifactId>
-    <version>30.0-android</version>
+    <version>27.1-android</version>
   </parent>
   <artifactId>guava-testlib</artifactId>
   <name>Guava Testing Library</name>
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java
index cf1ed23..c2d9542 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java
@@ -91,7 +91,8 @@
   }
 
   private static Set<Feature<?>> computeReserializedCollectionFeatures(Set<Feature<?>> features) {
-    Set<Feature<?>> derivedFeatures = new HashSet<>(features);
+    Set<Feature<?>> derivedFeatures = new HashSet<>();
+    derivedFeatures.addAll(features);
     derivedFeatures.remove(SERIALIZABLE);
     derivedFeatures.remove(SERIALIZABLE_INCLUDING_VIEWS);
     return derivedFeatures;
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java b/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java
index 3588e85..af50129 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java
@@ -375,7 +375,8 @@
 
     @Override
     public SortedSet<E> create(Object... elements) {
-      List<?> normalValues = (List<?>) Arrays.asList(elements);
+      @SuppressWarnings("unchecked") // set generators must pass SampleElements values
+      List<E> normalValues = (List) Arrays.asList(elements);
       List<E> extremeValues = new ArrayList<>();
 
       // nulls are usually out of bounds for a subset, so ban them altogether
@@ -398,12 +399,12 @@
       }
 
       // the regular values should be visible after filtering
-      List<Object> allEntries = new ArrayList<>();
+      List<E> allEntries = new ArrayList<>();
       allEntries.addAll(extremeValues);
       allEntries.addAll(normalValues);
-      SortedSet<E> set = delegate.create(allEntries.toArray());
+      SortedSet<E> map = delegate.create(allEntries.toArray());
 
-      return createSubSet(set, firstExclusive, lastExclusive);
+      return createSubSet(map, firstExclusive, lastExclusive);
     }
 
     /** Calls the smallest subSet overload that filters out the extreme values. */
@@ -473,6 +474,8 @@
 
     @Override
     public SortedMap<K, V> create(Object... entries) {
+      @SuppressWarnings("unchecked") // map generators must past entry objects
+      List<Entry<K, V>> normalValues = (List) Arrays.asList(entries);
       List<Entry<K, V>> extremeValues = new ArrayList<>();
 
       // prepare extreme values to be filtered out of view
@@ -488,12 +491,12 @@
       }
 
       // the regular values should be visible after filtering
-      List<Entry<?, ?>> allEntries = new ArrayList<>();
+      List<Entry<K, V>> allEntries = new ArrayList<>();
       allEntries.addAll(extremeValues);
-      for (Object entry : entries) {
-        allEntries.add((Entry<?, ?>) entry);
-      }
-      SortedMap<K, V> map = (SortedMap<K, V>) delegate.create(allEntries.toArray());
+      allEntries.addAll(normalValues);
+      SortedMap<K, V> map =
+          (SortedMap<K, V>)
+              delegate.create((Object[]) allEntries.toArray(new Entry<?, ?>[allEntries.size()]));
 
       return createSubMap(map, firstExclusive, lastExclusive);
     }
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java b/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java
index 8efafc3..5023d39 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/Helpers.java
@@ -169,7 +169,8 @@
   }
 
   public static void assertContainsAllOf(Iterable<?> actual, Object... expected) {
-    List<Object> expectedList = new ArrayList<>(Arrays.asList(expected));
+    List<Object> expectedList = new ArrayList<>();
+    expectedList.addAll(Arrays.asList(expected));
 
     for (Object o : actual) {
       expectedList.remove(o);
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java b/android/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java
index fdc418a..fd1643b 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java
@@ -50,36 +50,6 @@
  * verify() method, which is called <em>after</em> each sequence and is guaranteed to be called
  * using the latest values obtained from {@link IteratorTester#newTargetIterator()}.
  *
- * <p>The value you pass to the parameter {@code steps} should be greater than the length of your
- * iterator, so that this class can check that your iterator behaves correctly when it is exhausted.
- *
- * <p>For example, to test {@link java.util.Collections#unmodifiableList(java.util.List)
- * Collections.unmodifiableList}'s iterator:
- *
- * <pre>{@code
- * List<String> expectedElements =
- *     Arrays.asList("a", "b", "c", "d", "e");
- * List<String> actualElements =
- *     Collections.unmodifiableList(
- *         Arrays.asList("a", "b", "c", "d", "e"));
- * IteratorTester<String> iteratorTester =
- *     new IteratorTester<String>(
- *         6,
- *         IteratorFeature.UNMODIFIABLE,
- *         expectedElements,
- *         IteratorTester.KnownOrder.KNOWN_ORDER) {
- *       @Override
- *       protected Iterator<String> newTargetIterator() {
- *         return actualElements.iterator();
- *       }
- *     };
- * iteratorTester.test();
- * iteratorTester.testForEachRemaining();
- * }</pre>
- *
- * <p><b>Note</b>: It is necessary to use {@code IteratorTester.KnownOrder} as shown above, rather
- * than {@code KnownOrder} directly, because otherwise the code cannot be compiled.
- *
  * @author Kevin Bourrillion
  * @author Chris Povirk
  */
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java
index e010564..144428e 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java
@@ -146,7 +146,8 @@
   }
 
   private static Set<Feature<?>> computeReserializedCollectionFeatures(Set<Feature<?>> features) {
-    Set<Feature<?>> derivedFeatures = new HashSet<>(features);
+    Set<Feature<?>> derivedFeatures = new HashSet<>();
+    derivedFeatures.addAll(features);
     derivedFeatures.remove(SERIALIZABLE);
     derivedFeatures.remove(SERIALIZABLE_INCLUDING_VIEWS);
     return derivedFeatures;
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java b/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java
index b8b5c28..c8053b1 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java
@@ -301,10 +301,10 @@
     }
     assertTrue(map.containsKey(map.keySet().iterator().next()));
     if (allowsNullKeys) {
-      boolean unused = map.containsKey(null);
+      map.containsKey(null);
     } else {
       try {
-        boolean unused2 = map.containsKey(null);
+        map.containsKey(null);
       } catch (NullPointerException optional) {
       }
     }
@@ -323,10 +323,10 @@
     assertFalse(map.containsValue(unmappedValue));
     assertTrue(map.containsValue(map.values().iterator().next()));
     if (allowsNullValues) {
-      boolean unused = map.containsValue(null);
+      map.containsValue(null);
     } else {
       try {
-        boolean unused2 = map.containsKey(null);
+        map.containsKey(null);
       } catch (NullPointerException optional) {
       }
     }
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
index 26a2870..042ba9d 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
@@ -112,7 +112,8 @@
   }
 
   private static Set<Feature<?>> computeReserializedCollectionFeatures(Set<Feature<?>> features) {
-    Set<Feature<?>> derivedFeatures = new HashSet<>(features);
+    Set<Feature<?>> derivedFeatures = new HashSet<>();
+    derivedFeatures.addAll(features);
     derivedFeatures.remove(SERIALIZABLE);
     derivedFeatures.remove(SERIALIZABLE_INCLUDING_VIEWS);
     return derivedFeatures;
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java
index e97b08f..ce01adb 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java
@@ -86,7 +86,8 @@
     final TestSortedSetGenerator<E> delegate =
         (TestSortedSetGenerator<E>) parentBuilder.getSubjectGenerator().getInnerGenerator();
 
-    List<Feature<?>> features = new ArrayList<>(parentBuilder.getFeatures());
+    List<Feature<?>> features = new ArrayList<>();
+    features.addAll(parentBuilder.getFeatures());
     features.remove(CollectionFeature.ALLOWS_NULL_VALUES);
     features.add(CollectionFeature.SUBSET_VIEW);
 
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java
index 266daa4..e60ccf8 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java
@@ -88,7 +88,8 @@
   }
 
   private static Set<Feature<?>> computeEntrySetFeatures(Set<Feature<?>> features) {
-    Set<Feature<?>> derivedFeatures = new HashSet<>(features);
+    Set<Feature<?>> derivedFeatures = new HashSet<>();
+    derivedFeatures.addAll(features);
     derivedFeatures.remove(CollectionFeature.GENERAL_PURPOSE);
     derivedFeatures.remove(CollectionFeature.SUPPORTS_ADD);
     derivedFeatures.remove(CollectionFeature.ALLOWS_NULL_VALUES);
@@ -100,7 +101,8 @@
   }
 
   static Set<Feature<?>> computeElementSetFeatures(Set<Feature<?>> features) {
-    Set<Feature<?>> derivedFeatures = new HashSet<>(features);
+    Set<Feature<?>> derivedFeatures = new HashSet<>();
+    derivedFeatures.addAll(features);
     derivedFeatures.remove(CollectionFeature.GENERAL_PURPOSE);
     derivedFeatures.remove(CollectionFeature.SUPPORTS_ADD);
     if (!derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
@@ -110,7 +112,8 @@
   }
 
   private static Set<Feature<?>> computeReserializedMultisetFeatures(Set<Feature<?>> features) {
-    Set<Feature<?>> derivedFeatures = new HashSet<>(features);
+    Set<Feature<?>> derivedFeatures = new HashSet<>();
+    derivedFeatures.addAll(features);
     derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
     derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
     return derivedFeatures;
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java b/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java
index dafd521..f763dcc 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java
@@ -168,10 +168,10 @@
               public SortedMultiset<E> create(Object... entries) {
                 @SuppressWarnings("unchecked")
                 // we dangerously assume E is a string
-                List<E> extremeValues = (List<E>) getExtremeValues();
+                List<E> extremeValues = (List) getExtremeValues();
                 @SuppressWarnings("unchecked")
                 // map generators must past entry objects
-                List<E> normalValues = (List<E>) Arrays.asList(entries);
+                List<E> normalValues = (List) Arrays.asList(entries);
 
                 // prepare extreme values to be filtered out of view
                 Collections.sort(extremeValues, comparator);
@@ -266,7 +266,8 @@
     final TestMultisetGenerator<E> delegate =
         (TestMultisetGenerator<E>) parentBuilder.getSubjectGenerator();
 
-    Set<Feature<?>> features = new HashSet<>(parentBuilder.getFeatures());
+    Set<Feature<?>> features = new HashSet<>();
+    features.addAll(parentBuilder.getFeatures());
     features.remove(SERIALIZABLE);
     features.remove(SERIALIZABLE_INCLUDING_VIEWS);
 
diff --git a/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java b/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java
index b170497..89e0662 100644
--- a/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java
+++ b/android/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java
@@ -19,11 +19,9 @@
 import static com.google.common.collect.testing.Helpers.mapEntry;
 import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
 import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ITERATOR_REMOVE;
 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static java.util.Arrays.asList;
 
 import com.google.common.annotations.GwtCompatible;
 import com.google.common.collect.testing.AbstractCollectionTester;
@@ -68,17 +66,6 @@
     assertEquals("Different ordered iteration", expected, iteratorElements);
   }
 
-  @CollectionFeature.Require(ALLOWS_NULL_VALUES)
-  @CollectionSize.Require(absent = ZERO)
-  public void testIterator_nullElement() {
-    initCollectionWithNullElement();
-    List<E> iteratorElements = new ArrayList<E>();
-    for (E element : collection) { // uses iterator()
-      iteratorElements.add(element);
-    }
-    Helpers.assertEqualIgnoringOrder(asList(createArrayWithNullElement()), iteratorElements);
-  }
-
   @CollectionFeature.Require(SUPPORTS_ITERATOR_REMOVE)
   @CollectionSize.Require(absent = ZERO)
   public void testIterator_removeAffectsBackingCollection() {
diff --git a/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java b/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java
index 01904d6..906c1c5 100644
--- a/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java
+++ b/android/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java
@@ -123,7 +123,6 @@
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
-import java.util.UUID;
 import java.util.concurrent.BlockingDeque;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
@@ -206,7 +205,6 @@
           .put(Charset.class, Charsets.UTF_8)
           .put(Currency.class, Currency.getInstance(Locale.US))
           .put(Locale.class, Locale.US)
-          .put(UUID.class, UUID.randomUUID())
           // common.base
           .put(CharMatcher.class, CharMatcher.none())
           .put(Joiner.class, Joiner.on(','))
@@ -371,14 +369,7 @@
     constructor.setAccessible(true); // accessibility check is too slow
     try {
       return constructor.newInstance();
-      /*
-       * Do not merge the 2 catch blocks below. javac would infer a type of
-       * ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
-       * Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
-       */
-    } catch (InstantiationException impossible) {
-      throw new AssertionError(impossible);
-    } catch (IllegalAccessException impossible) {
+    } catch (InstantiationException | IllegalAccessException impossible) {
       throw new AssertionError(impossible);
     } catch (InvocationTargetException e) {
       logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause());
diff --git a/android/guava-testlib/src/com/google/common/testing/ClusterException.java b/android/guava-testlib/src/com/google/common/testing/ClusterException.java
index 7665ab1..5f50ff8 100644
--- a/android/guava-testlib/src/com/google/common/testing/ClusterException.java
+++ b/android/guava-testlib/src/com/google/common/testing/ClusterException.java
@@ -67,7 +67,8 @@
     super(
         exceptions.size() + " exceptions were thrown. The first exception is listed as a cause.",
         exceptions.iterator().next());
-    ArrayList<Throwable> temp = new ArrayList<>(exceptions);
+    ArrayList<Throwable> temp = new ArrayList<>();
+    temp.addAll(exceptions);
     this.exceptions = Collections.unmodifiableCollection(temp);
   }
 
diff --git a/android/guava-testlib/src/com/google/common/testing/EqualsTester.java b/android/guava-testlib/src/com/google/common/testing/EqualsTester.java
index 2c8e08b..dc2d197 100644
--- a/android/guava-testlib/src/com/google/common/testing/EqualsTester.java
+++ b/android/guava-testlib/src/com/google/common/testing/EqualsTester.java
@@ -127,11 +127,6 @@
           "the Object#hashCode of " + item + " must be consistent",
           item.hashCode(),
           item.hashCode());
-      if (!(item instanceof String)) {
-        assertTrue(
-            item + " must not be Object#equals to its Object#toString representation",
-            !item.equals(item.toString()));
-      }
     }
   }
 
diff --git a/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java b/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java
index 21e25cb..d6b329d 100644
--- a/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java
+++ b/android/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java
@@ -508,14 +508,7 @@
       @SuppressWarnings("unchecked") // getAvailableCurrencies() returns Set<Currency>.
       Set<Currency> currencies = (Set<Currency>) method.invoke(null);
       return pickInstance(currencies, Currency.getInstance(Locale.US));
-      /*
-       * Do not merge the 2 catch blocks below. javac would infer a type of
-       * ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
-       * Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
-       */
-    } catch (NoSuchMethodException notJava7) {
-      return preJava7FreshCurrency();
-    } catch (InvocationTargetException notJava7) {
+    } catch (NoSuchMethodException | InvocationTargetException notJava7) {
       return preJava7FreshCurrency();
     } catch (IllegalAccessException impossible) {
       throw new AssertionError(impossible);
diff --git a/android/guava-testlib/src/com/google/common/testing/GcFinalization.java b/android/guava-testlib/src/com/google/common/testing/GcFinalization.java
index 015afea..92394f1 100644
--- a/android/guava-testlib/src/com/google/common/testing/GcFinalization.java
+++ b/android/guava-testlib/src/com/google/common/testing/GcFinalization.java
@@ -20,7 +20,6 @@
 
 import com.google.common.annotations.Beta;
 import com.google.common.annotations.GwtIncompatible;
-import com.google.errorprone.annotations.DoNotMock;
 import com.google.j2objc.annotations.J2ObjCIncompatible;
 import java.lang.ref.WeakReference;
 import java.util.Locale;
@@ -242,7 +241,6 @@
    *   <li>enqueuing weak references to unreachable referents in their reference queue
    * </ul>
    */
-  @DoNotMock("Implement with a lambda")
   public interface FinalizationPredicate {
     boolean isDone();
   }
diff --git a/android/guava-testlib/src/com/google/common/testing/TearDownAccepter.java b/android/guava-testlib/src/com/google/common/testing/TearDownAccepter.java
index bad1f19..a1d1f00 100644
--- a/android/guava-testlib/src/com/google/common/testing/TearDownAccepter.java
+++ b/android/guava-testlib/src/com/google/common/testing/TearDownAccepter.java
@@ -17,7 +17,6 @@
 package com.google.common.testing;
 
 import com.google.common.annotations.Beta;
-import com.google.errorprone.annotations.DoNotMock;
 import com.google.common.annotations.GwtCompatible;
 
 /**
@@ -27,7 +26,6 @@
  * @since 10.0
  */
 @Beta
-@DoNotMock("Implement with a lambda")
 @GwtCompatible
 public interface TearDownAccepter {
   /**
diff --git a/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractCheckedFutureTest.java b/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractCheckedFutureTest.java
new file mode 100755
index 0000000..5c2ce32
--- /dev/null
+++ b/android/guava-testlib/src/com/google/common/util/concurrent/testing/AbstractCheckedFutureTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.util.concurrent.testing;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test case to make sure the {@link CheckedFuture#checkedGet()} and {@link
+ * CheckedFuture#checkedGet(long, TimeUnit)} methods work correctly.
+ *
+ * @author Sven Mawson
+ * @since 10.0
+ */
+@Beta
+@GwtIncompatible
+public abstract class AbstractCheckedFutureTest extends AbstractListenableFutureTest {
+
+  /** More specific type for the create method. */
+  protected abstract <V> CheckedFuture<V, ?> createCheckedFuture(
+      V value, Exception except, CountDownLatch waitOn);
+
+  /** Checks that the exception is the correct type of cancellation exception. */
+  protected abstract void checkCancelledException(Exception e);
+
+  /** Checks that the exception is the correct type of execution exception. */
+  protected abstract void checkExecutionException(Exception e);
+
+  /** Checks that the exception is the correct type of interruption exception. */
+  protected abstract void checkInterruptedException(Exception e);
+
+  @Override
+  protected <V> ListenableFuture<V> createListenableFuture(
+      V value, Exception except, CountDownLatch waitOn) {
+    return createCheckedFuture(value, except, waitOn);
+  }
+
+  /**
+   * Tests that the {@link CheckedFuture#checkedGet()} method throws the correct type of
+   * cancellation exception when it is cancelled.
+   */
+  public void testCheckedGetThrowsApplicationExceptionOnCancellation() {
+
+    final CheckedFuture<Boolean, ?> future = createCheckedFuture(Boolean.TRUE, null, latch);
+
+    assertFalse(future.isDone());
+    assertFalse(future.isCancelled());
+
+    new Thread(
+            new Runnable() {
+              @Override
+              public void run() {
+                future.cancel(true);
+              }
+            })
+        .start();
+
+    try {
+      future.checkedGet();
+      fail("RPC Should have been cancelled.");
+    } catch (Exception e) {
+      checkCancelledException(e);
+    }
+
+    assertTrue(future.isDone());
+    assertTrue(future.isCancelled());
+  }
+
+  public void testCheckedGetThrowsApplicationExceptionOnInterruption() throws InterruptedException {
+
+    final CheckedFuture<Boolean, ?> future = createCheckedFuture(Boolean.TRUE, null, latch);
+
+    final CountDownLatch startingGate = new CountDownLatch(1);
+    final CountDownLatch successLatch = new CountDownLatch(1);
+
+    assertFalse(future.isDone());
+    assertFalse(future.isCancelled());
+
+    Thread getThread =
+        new Thread(
+            new Runnable() {
+              @Override
+              public void run() {
+                startingGate.countDown();
+
+                try {
+                  future.checkedGet();
+                } catch (Exception e) {
+                  checkInterruptedException(e);
+
+                  // This only gets hit if the original call throws an exception and
+                  // the check call above passes.
+                  successLatch.countDown();
+                }
+              }
+            });
+    getThread.start();
+
+    assertTrue(startingGate.await(500, TimeUnit.MILLISECONDS));
+    getThread.interrupt();
+
+    assertTrue(successLatch.await(500, TimeUnit.MILLISECONDS));
+
+    assertFalse(future.isDone());
+    assertFalse(future.isCancelled());
+  }
+
+  public void testCheckedGetThrowsApplicationExceptionOnError() {
+    final CheckedFuture<Boolean, ?> future =
+        createCheckedFuture(Boolean.TRUE, new Exception("Error"), latch);
+
+    assertFalse(future.isDone());
+    assertFalse(future.isCancelled());
+
+    new Thread(
+            new Runnable() {
+              @Override
+              public void run() {
+                latch.countDown();
+              }
+            })
+        .start();
+
+    try {
+      future.checkedGet();
+      fail();
+    } catch (Exception e) {
+      checkExecutionException(e);
+    }
+
+    assertTrue(future.isDone());
+    assertFalse(future.isCancelled());
+  }
+}
diff --git a/android/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java b/android/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java
index cb6ba6a..666d726 100644
--- a/android/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java
+++ b/android/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java
@@ -72,7 +72,7 @@
     assertThat(findClassesToTest(ImmutableList.of(Foo.class))).contains(Foo.class);
   }
 
-  public void testFindClassesToTest_ignoreUnderscores() {
+  public void testFindClassesToTeset_ignoreUnderscores() {
     assertThat(findClassesToTest(ImmutableList.of(Foo.class, Foo_Bar.class)))
         .containsExactly(Foo.class, Foo_Bar.class);
     sanityTests.ignoreClasses(AbstractPackageSanityTests.UNDERSCORE_IN_NAME);
diff --git a/android/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java b/android/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java
index b47672f..3664b23 100644
--- a/android/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java
+++ b/android/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java
@@ -109,7 +109,6 @@
 import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
-import java.util.UUID;
 import java.util.concurrent.BlockingDeque;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentMap;
@@ -164,7 +163,6 @@
     assertNotNull(ArbitraryInstances.get(Object.class));
     assertEquals(0, ArbitraryInstances.get(Number.class));
     assertEquals(Charsets.UTF_8, ArbitraryInstances.get(Charset.class));
-    assertNotNull(ArbitraryInstances.get(UUID.class));
   }
 
   public void testGet_collections() {
diff --git a/android/guava-testlib/test/com/google/common/testing/EqualsTesterTest.java b/android/guava-testlib/test/com/google/common/testing/EqualsTesterTest.java
index d615af6..b992f1b 100644
--- a/android/guava-testlib/test/com/google/common/testing/EqualsTesterTest.java
+++ b/android/guava-testlib/test/com/google/common/testing/EqualsTesterTest.java
@@ -272,15 +272,6 @@
         .testEquals();
   }
 
-  public void testEqualityBasedOnToString() {
-    try {
-      new EqualsTester().addEqualityGroup(new EqualsBasedOnToString("foo")).testEquals();
-      fail();
-    } catch (AssertionFailedError e) {
-      assertTrue(e.getMessage().contains("toString representation"));
-    }
-  }
-
   private static void assertErrorMessage(Throwable e, String message) {
     // TODO(kevinb): use a Truth assertion here
     if (!e.getMessage().contains(message)) {
@@ -431,27 +422,4 @@
       return name;
     }
   }
-
-  private static final class EqualsBasedOnToString {
-    private final String s;
-
-    private EqualsBasedOnToString(String s) {
-      this.s = s;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      return obj != null && obj.toString().equals(toString());
-    }
-
-    @Override
-    public int hashCode() {
-      return s.hashCode();
-    }
-
-    @Override
-    public String toString() {
-      return s;
-    }
-  }
 }
diff --git a/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java b/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
index 99f01d6..28cdca2 100644
--- a/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
+++ b/android/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
@@ -339,25 +339,21 @@
     }
 
     /** Two-arg method with no Nullable params. */
-    @SuppressWarnings("GoodTime") // false positive; b/122617528
     public void normalNormal(String first, Integer second) {
       reactToNullParameters(first, second);
     }
 
     /** Two-arg method with the second param Nullable. */
-    @SuppressWarnings("GoodTime") // false positive; b/122617528
     public void normalNullable(String first, @NullableDecl Integer second) {
       reactToNullParameters(first, second);
     }
 
     /** Two-arg method with the first param Nullable. */
-    @SuppressWarnings("GoodTime") // false positive; b/122617528
     public void nullableNormal(@NullableDecl String first, Integer second) {
       reactToNullParameters(first, second);
     }
 
     /** Two-arg method with the both params Nullable. */
-    @SuppressWarnings("GoodTime") // false positive; b/122617528
     public void nullableNullable(@NullableDecl String first, @NullableDecl Integer second) {
       reactToNullParameters(first, second);
     }
diff --git a/android/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java b/android/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java
index 43fc75c..24d75b9 100644
--- a/android/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java
+++ b/android/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java
@@ -35,7 +35,6 @@
   private ReferenceEntry<Object, Object> head;
   private ReferenceEntry<Object, Object> chain;
 
-  @SuppressWarnings("GuardedBy")
   @BeforeExperiment
   void setUp() {
     LocalCache<Object, Object> cache =
@@ -44,8 +43,6 @@
     chain = null;
     for (int i = 0; i < length; i++) {
       Object key = new Object();
-      // TODO(b/145386688): This access should be guarded by 'this.segment', which is not currently
-      // held
       chain = segment.newEntry(key, cache.hash(key), chain);
       if (i == 0) {
         head = chain;
@@ -53,13 +50,10 @@
     }
   }
 
-  @SuppressWarnings("GuardedBy")
   @Benchmark
   int time(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      // TODO(b/145386688): This access should be guarded by 'this.segment', which is not currently
-      // held
       segment.removeEntryFromChain(chain, head);
       dummy += segment.count;
     }
diff --git a/android/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java b/android/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java
index a473d75..5b82f83 100644
--- a/android/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java
+++ b/android/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java
@@ -50,14 +50,11 @@
     checkState(segment.table.length() == capacity);
   }
 
-  @SuppressWarnings("GuardedBy")
   @Benchmark
   int time(int reps) {
     int dummy = 0;
     AtomicReferenceArray<ReferenceEntry<Object, Object>> oldTable = segment.table;
     for (int i = 0; i < reps; i++) {
-      // TODO(b/145386688): This access should be guarded by 'this.segment', which is not currently
-      // held
       segment.expand();
       segment.table = oldTable;
       dummy += segment.count;
diff --git a/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java b/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java
index f10b94e..fb8a26e 100644
--- a/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java
+++ b/android/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java
@@ -26,6 +26,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 
@@ -223,24 +224,12 @@
   }
 
   @Benchmark
-  boolean createPopulateAndRemove(int reps) {
-    boolean dummy = false;
-    for (int i = 1; i < reps; i++) {
-      Map<Element, Element> map = impl.create(values);
-      for (Element value : values) {
-        dummy |= map.remove(value) == null;
-      }
-    }
-    return dummy;
-  }
-
-  @Benchmark
   boolean iterateWithEntrySet(int reps) {
     Map<Element, Element> map = mapToTest;
 
     boolean dummy = false;
     for (int i = 0; i < reps; i++) {
-      for (Map.Entry<Element, Element> entry : map.entrySet()) {
+      for (Entry<Element, Element> entry : map.entrySet()) {
         dummy ^= entry.getKey() != entry.getValue();
       }
     }
diff --git a/android/guava-tests/benchmark/com/google/common/collect/MapsMemoryBenchmark.java b/android/guava-tests/benchmark/com/google/common/collect/MapsMemoryBenchmark.java
index b834846..f13d9b7 100644
--- a/android/guava-tests/benchmark/com/google/common/collect/MapsMemoryBenchmark.java
+++ b/android/guava-tests/benchmark/com/google/common/collect/MapsMemoryBenchmark.java
@@ -45,8 +45,6 @@
     "HashMapImpl",
     "LinkedHashMapImpl",
     "ConcurrentHashMapImpl",
-    "CompactHashMapImpl",
-    "CompactLinkedHashMapImpl",
     "ImmutableMapImpl",
     "TreeMapImpl",
     "ImmutableSortedMapImpl",
diff --git a/android/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java b/android/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java
index be387f7..e8616ee 100644
--- a/android/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java
+++ b/android/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java
@@ -88,14 +88,4 @@
     }
     return tmp;
   }
-
-  @Benchmark
-  long roundToDouble(int reps) {
-    long tmp = 0;
-    for (int i = 0; i < reps; i++) {
-      int j = i & ARRAY_MASK;
-      tmp += Double.doubleToRawLongBits(BigIntegerMath.roundToDouble(nonzero1[j], mode));
-    }
-    return tmp;
-  }
 }
diff --git a/android/guava-tests/pom.xml b/android/guava-tests/pom.xml
index 5191c8e..223fc49 100644
--- a/android/guava-tests/pom.xml
+++ b/android/guava-tests/pom.xml
@@ -5,7 +5,7 @@
   <parent>
     <groupId>com.google.guava</groupId>
     <artifactId>guava-parent</artifactId>
-    <version>30.0-android</version>
+    <version>27.1-android</version>
   </parent>
   <artifactId>guava-tests</artifactId>
   <name>Guava Unit Tests</name>
diff --git a/android/guava-tests/test/com/google/common/base/CharMatcherTest.java b/android/guava-tests/test/com/google/common/base/CharMatcherTest.java
index 5412882..db56260 100644
--- a/android/guava-tests/test/com/google/common/base/CharMatcherTest.java
+++ b/android/guava-tests/test/com/google/common/base/CharMatcherTest.java
@@ -727,9 +727,12 @@
     Set<Character> chars = new HashSet<>(size);
     for (int i = 0; i < size; i++) {
       char c;
-      do {
+      while (true) {
         c = (char) rand.nextInt(Character.MAX_VALUE - Character.MIN_VALUE + 1);
-      } while (chars.contains(c));
+        if (!chars.contains(c)) {
+          break;
+        }
+      }
       chars.add(c);
     }
     char[] retValue = new char[chars.size()];
diff --git a/android/guava-tests/test/com/google/common/base/OptionalTest.java b/android/guava-tests/test/com/google/common/base/OptionalTest.java
index 35de2d4..5bfe3be 100644
--- a/android/guava-tests/test/com/google/common/base/OptionalTest.java
+++ b/android/guava-tests/test/com/google/common/base/OptionalTest.java
@@ -246,7 +246,7 @@
     List<Optional<? extends Number>> optionals =
         ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2));
     Iterable<Number> onlyPresent = Optional.presentInstances(optionals);
-    assertThat(onlyPresent).containsExactly(2);
+    assertThat(onlyPresent).containsExactly(2).inOrder();
   }
 
   private static Optional<Integer> getSomeOptionalInt() {
@@ -288,7 +288,7 @@
     // Sadly, the following is what users will have to do in some circumstances.
 
     @SuppressWarnings("unchecked") // safe covariant cast
-    Optional<Number> first = (Optional<Number>) numbers.first();
+    Optional<Number> first = (Optional) numbers.first();
     Number value = first.or(0.5); // fine
   }
 
diff --git a/android/guava-tests/test/com/google/common/base/SplitterTest.java b/android/guava-tests/test/com/google/common/base/SplitterTest.java
index 46928aa..6b3d861 100644
--- a/android/guava-tests/test/com/google/common/base/SplitterTest.java
+++ b/android/guava-tests/test/com/google/common/base/SplitterTest.java
@@ -758,18 +758,6 @@
     }
   }
 
-  /**
-   * Testing the behavior in https://github.com/google/guava/issues/1900 - this behavior may want to
-   * be changed?
-   */
-  public void testMapSplitter_extraValueDelimiter() {
-    try {
-      COMMA_SPLITTER.withKeyValueSeparator("=").split("a=1,c=2=");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   public void testMapSplitter_orderedResults() {
     Map<String, String> m =
         COMMA_SPLITTER.withKeyValueSeparator(":").split("boy:tom,girl:tina,cat:kitty,dog:tommy");
diff --git a/android/guava-tests/test/com/google/common/base/ThrowablesTest.java b/android/guava-tests/test/com/google/common/base/ThrowablesTest.java
index e4c64aa..076f899 100644
--- a/android/guava-tests/test/com/google/common/base/ThrowablesTest.java
+++ b/android/guava-tests/test/com/google/common/base/ThrowablesTest.java
@@ -575,7 +575,7 @@
       Throwables.getRootCause(cause);
       fail("Should have throw IAE");
     } catch (IllegalArgumentException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(cause);
+      assertThat(expected).hasCauseThat().isSameAs(cause);
     }
   }
 
@@ -675,7 +675,7 @@
       Throwables.getCausalChain(cause);
       fail("Should have throw IAE");
     } catch (IllegalArgumentException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(cause);
+      assertThat(expected).hasCauseThat().isSameAs(cause);
     }
   }
 
@@ -684,15 +684,15 @@
     SomeCheckedException cause = new SomeCheckedException();
     SomeChainingException thrown = new SomeChainingException(cause);
 
-    assertThat(thrown).hasCauseThat().isSameInstanceAs(cause);
-    assertThat(Throwables.getCauseAs(thrown, SomeCheckedException.class)).isSameInstanceAs(cause);
-    assertThat(Throwables.getCauseAs(thrown, Exception.class)).isSameInstanceAs(cause);
+    assertThat(thrown).hasCauseThat().isSameAs(cause);
+    assertThat(Throwables.getCauseAs(thrown, SomeCheckedException.class)).isSameAs(cause);
+    assertThat(Throwables.getCauseAs(thrown, Exception.class)).isSameAs(cause);
 
     try {
       Throwables.getCauseAs(thrown, IllegalStateException.class);
       fail("Should have thrown CCE");
     } catch (ClassCastException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(thrown);
+      assertThat(expected).hasCauseThat().isSameAs(thrown);
     }
   }
 
diff --git a/android/guava-tests/test/com/google/common/cache/AbstractCacheTest.java b/android/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
index 13ef33d..a9dcbfb 100644
--- a/android/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
+++ b/android/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
@@ -146,14 +146,6 @@
     assertEquals(27, stats.evictionCount());
   }
 
-  public void testSimpleStatsOverflow() {
-    StatsCounter counter = new SimpleStatsCounter();
-    counter.recordLoadSuccess(Long.MAX_VALUE);
-    counter.recordLoadSuccess(1);
-    CacheStats stats = counter.snapshot();
-    assertEquals(Long.MAX_VALUE, stats.totalLoadTime());
-  }
-
   public void testSimpleStatsIncrementBy() {
     long totalLoadTime = 0;
 
diff --git a/android/guava-tests/test/com/google/common/cache/CacheLoadingTest.java b/android/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
index ba3e7e9..bc2cbd3 100644
--- a/android/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
+++ b/android/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
@@ -91,7 +91,7 @@
   }
 
   private void checkLoggedCause(Throwable t) {
-    assertThat(popLoggedThrowable()).hasCauseThat().isSameInstanceAs(t);
+    assertThat(popLoggedThrowable()).hasCauseThat().isSameAs(t);
   }
 
   private void checkLoggedInvalidLoad() {
@@ -889,7 +889,7 @@
       cache.get(new Object());
       fail();
     } catch (ExecutionError expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(1, stats.missCount());
@@ -901,7 +901,7 @@
       cache.getUnchecked(new Object());
       fail();
     } catch (ExecutionError expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(2, stats.missCount());
@@ -929,7 +929,7 @@
           });
       fail();
     } catch (ExecutionError expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(callableError);
+      assertThat(expected).hasCauseThat().isSameAs(callableError);
     }
     stats = cache.stats();
     assertEquals(3, stats.missCount());
@@ -941,7 +941,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (ExecutionError expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(4, stats.missCount());
@@ -1122,7 +1122,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (ExecutionError expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(1, stats.missCount());
@@ -1145,7 +1145,7 @@
       cache.get(new Object());
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(1, stats.missCount());
@@ -1157,7 +1157,7 @@
       cache.getUnchecked(new Object());
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(2, stats.missCount());
@@ -1178,7 +1178,7 @@
       cache.get(new Object(), throwing(callableException));
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(callableException);
+      assertThat(expected).hasCauseThat().isSameAs(callableException);
     }
     stats = cache.stats();
     assertEquals(3, stats.missCount());
@@ -1190,7 +1190,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(4, stats.missCount());
@@ -1216,7 +1216,7 @@
       cache.get(new Object());
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     assertTrue(currentThread().interrupted());
     stats = cache.stats();
@@ -1229,7 +1229,7 @@
       cache.getUnchecked(new Object());
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     assertTrue(currentThread().interrupted());
     stats = cache.stats();
@@ -1252,7 +1252,7 @@
       cache.get(new Object(), throwing(callableException));
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(callableException);
+      assertThat(expected).hasCauseThat().isSameAs(callableException);
     }
     assertTrue(currentThread().interrupted());
     stats = cache.stats();
@@ -1265,7 +1265,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     assertTrue(currentThread().interrupted());
     stats = cache.stats();
@@ -1447,7 +1447,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(1, stats.missCount());
@@ -1471,7 +1471,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (ExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     assertTrue(currentThread().interrupted());
     stats = cache.stats();
@@ -1495,7 +1495,7 @@
       cache.get(new Object());
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(1, stats.missCount());
@@ -1507,7 +1507,7 @@
       cache.getUnchecked(new Object());
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(2, stats.missCount());
@@ -1528,7 +1528,7 @@
       cache.get(new Object(), throwing(callableException));
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(callableException);
+      assertThat(expected).hasCauseThat().isSameAs(callableException);
     }
     stats = cache.stats();
     assertEquals(3, stats.missCount());
@@ -1540,7 +1540,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(4, stats.missCount());
@@ -1721,7 +1721,7 @@
       cache.getAll(asList(new Object()));
       fail();
     } catch (UncheckedExecutionException expected) {
-      assertThat(expected).hasCauseThat().isSameInstanceAs(e);
+      assertThat(expected).hasCauseThat().isSameAs(e);
     }
     stats = cache.stats();
     assertEquals(1, stats.missCount());
@@ -1752,7 +1752,7 @@
       cache.getUnchecked(1);
       fail();
     } catch (UncheckedExecutionException ue) {
-      assertThat(ue).hasCauseThat().isSameInstanceAs(e);
+      assertThat(ue).hasCauseThat().isSameAs(e);
     }
 
     assertEquals("1", cache.getUnchecked(1));
@@ -1866,14 +1866,14 @@
     } catch (ExecutionException e) {
       fail();
     } catch (UncheckedExecutionException caughtEe) {
-      assertThat(caughtEe).hasCauseThat().isSameInstanceAs(uee);
+      assertThat(caughtEe).hasCauseThat().isSameAs(uee);
     }
 
     try {
       cacheUnchecked.getUnchecked(new Object());
       fail();
     } catch (UncheckedExecutionException caughtUee) {
-      assertThat(caughtUee).hasCauseThat().isSameInstanceAs(uee);
+      assertThat(caughtUee).hasCauseThat().isSameAs(uee);
     }
 
     cacheUnchecked.refresh(new Object());
@@ -1885,21 +1885,21 @@
     } catch (ExecutionException e) {
       fail();
     } catch (UncheckedExecutionException caughtEe) {
-      assertThat(caughtEe).hasCauseThat().isSameInstanceAs(uee);
+      assertThat(caughtEe).hasCauseThat().isSameAs(uee);
     }
 
     try {
       cacheChecked.get(new Object());
       fail();
     } catch (ExecutionException caughtEe) {
-      assertThat(caughtEe).hasCauseThat().isSameInstanceAs(ee);
+      assertThat(caughtEe).hasCauseThat().isSameAs(ee);
     }
 
     try {
       cacheChecked.getUnchecked(new Object());
       fail();
     } catch (UncheckedExecutionException caughtUee) {
-      assertThat(caughtUee).hasCauseThat().isSameInstanceAs(ee);
+      assertThat(caughtUee).hasCauseThat().isSameAs(ee);
     }
 
     cacheChecked.refresh(new Object());
@@ -1909,7 +1909,7 @@
       cacheChecked.getAll(asList(new Object()));
       fail();
     } catch (ExecutionException caughtEe) {
-      assertThat(caughtEe).hasCauseThat().isSameInstanceAs(ee);
+      assertThat(caughtEe).hasCauseThat().isSameAs(ee);
     }
   }
 
@@ -1929,14 +1929,14 @@
     } catch (ExecutionException e) {
       fail();
     } catch (UncheckedExecutionException caughtEe) {
-      assertThat(caughtEe).hasCauseThat().isSameInstanceAs(uee);
+      assertThat(caughtEe).hasCauseThat().isSameAs(uee);
     }
 
     try {
       cacheChecked.getAll(asList(new Object()));
       fail();
     } catch (ExecutionException caughtEe) {
-      assertThat(caughtEe).hasCauseThat().isSameInstanceAs(ee);
+      assertThat(caughtEe).hasCauseThat().isSameAs(ee);
     }
   }
 
@@ -2057,7 +2057,7 @@
       // doConcurrentGet alternates between calling getUnchecked and calling get, but an unchecked
       // exception thrown by the loader is always wrapped as an UncheckedExecutionException.
       assertThat(result.get(i)).isInstanceOf(UncheckedExecutionException.class);
-      assertThat(((UncheckedExecutionException) result.get(i))).hasCauseThat().isSameInstanceAs(e);
+      assertThat(((UncheckedExecutionException) result.get(i))).hasCauseThat().isSameAs(e);
     }
 
     // subsequent calls should call the loader again, not get the old exception
@@ -2103,10 +2103,10 @@
       int mod = i % 3;
       if (mod == 0 || mod == 2) {
         assertThat(result.get(i)).isInstanceOf(ExecutionException.class);
-        assertThat((ExecutionException) result.get(i)).hasCauseThat().isSameInstanceAs(e);
+        assertThat((ExecutionException) result.get(i)).hasCauseThat().isSameAs(e);
       } else {
         assertThat(result.get(i)).isInstanceOf(UncheckedExecutionException.class);
-        assertThat((UncheckedExecutionException) result.get(i)).hasCauseThat().isSameInstanceAs(e);
+        assertThat((UncheckedExecutionException) result.get(i)).hasCauseThat().isSameAs(e);
       }
     }
 
diff --git a/android/guava-tests/test/com/google/common/cache/CacheStatsTest.java b/android/guava-tests/test/com/google/common/cache/CacheStatsTest.java
index 3e715f1..f029d37 100644
--- a/android/guava-tests/test/com/google/common/cache/CacheStatsTest.java
+++ b/android/guava-tests/test/com/google/common/cache/CacheStatsTest.java
@@ -98,32 +98,4 @@
 
     assertEquals(sum, one.plus(two));
   }
-
-  public void testPlusLarge() {
-    CacheStats maxCacheStats =
-        new CacheStats(
-            Long.MAX_VALUE,
-            Long.MAX_VALUE,
-            Long.MAX_VALUE,
-            Long.MAX_VALUE,
-            Long.MAX_VALUE,
-            Long.MAX_VALUE);
-    CacheStats smallCacheStats = new CacheStats(1, 1, 1, 1, 1, 1);
-
-    CacheStats sum = smallCacheStats.plus(maxCacheStats);
-    assertEquals(Long.MAX_VALUE, sum.requestCount());
-    assertEquals(Long.MAX_VALUE, sum.hitCount());
-    assertEquals(1.0, sum.hitRate());
-    assertEquals(Long.MAX_VALUE, sum.missCount());
-    assertEquals(1.0, sum.missRate());
-    assertEquals(Long.MAX_VALUE, sum.loadSuccessCount());
-    assertEquals(Long.MAX_VALUE, sum.loadExceptionCount());
-    assertEquals(1.0, sum.loadExceptionRate());
-    assertEquals(Long.MAX_VALUE, sum.loadCount());
-    assertEquals(Long.MAX_VALUE, sum.totalLoadTime());
-    assertEquals(1.0, sum.averageLoadPenalty());
-    assertEquals(Long.MAX_VALUE, sum.evictionCount());
-
-    assertEquals(sum, maxCacheStats.plus(smallCacheStats));
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/cache/CacheTesting.java b/android/guava-tests/test/com/google/common/cache/CacheTesting.java
index 255a894..d7a3b4a 100644
--- a/android/guava-tests/test/com/google/common/cache/CacheTesting.java
+++ b/android/guava-tests/test/com/google/common/cache/CacheTesting.java
@@ -393,7 +393,7 @@
 
       ReferenceEntry<?, ?> originalHead = segment.accessQueue.peek();
       @SuppressWarnings("unchecked")
-      ReferenceEntry<Integer, Integer> entry = (ReferenceEntry<Integer, Integer>) originalHead;
+      ReferenceEntry<Integer, Integer> entry = (ReferenceEntry) originalHead;
       operation.accept(entry);
       drainRecencyQueue(segment);
 
diff --git a/android/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java b/android/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java
index 412ff78..127b3c5 100644
--- a/android/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java
+++ b/android/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java
@@ -34,7 +34,7 @@
   private Cache<String, Boolean> forward;
   private Cache<String, Boolean> mock;
 
-  @SuppressWarnings({"unchecked", "DoNotMock"}) // mock
+  @SuppressWarnings("unchecked") // mock
   @Override
   public void setUp() throws Exception {
     super.setUp();
diff --git a/android/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java b/android/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java
index c5681d2..01704ef 100644
--- a/android/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java
+++ b/android/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java
@@ -34,7 +34,7 @@
   private LoadingCache<String, Boolean> forward;
   private LoadingCache<String, Boolean> mock;
 
-  @SuppressWarnings({"unchecked", "DoNotMock"}) // mock
+  @SuppressWarnings("unchecked") // mock
   @Override
   public void setUp() throws Exception {
     super.setUp();
diff --git a/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java b/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java
index 667ea93..da2224e 100644
--- a/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java
+++ b/android/guava-tests/test/com/google/common/cache/LocalCacheTest.java
@@ -2413,7 +2413,7 @@
         ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne);
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) entry;
+        Reference<Object> reference = (Reference) entry;
         reference.enqueue();
 
         map.put(keyTwo, valueTwo);
@@ -2443,7 +2443,7 @@
         ValueReference<Object, Object> valueReference = entry.getValueReference();
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) valueReference;
+        Reference<Object> reference = (Reference) valueReference;
         reference.enqueue();
 
         map.put(keyTwo, valueTwo);
@@ -2471,7 +2471,7 @@
         ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne);
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) entry;
+        Reference<Object> reference = (Reference) entry;
         reference.enqueue();
 
         for (int i = 0; i < SMALL_MAX_SIZE; i++) {
@@ -2502,7 +2502,7 @@
         ValueReference<Object, Object> valueReference = entry.getValueReference();
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) valueReference;
+        Reference<Object> reference = (Reference) valueReference;
         reference.enqueue();
 
         for (int i = 0; i < SMALL_MAX_SIZE; i++) {
diff --git a/android/guava-tests/test/com/google/common/cache/LongAdderTest.java b/android/guava-tests/test/com/google/common/cache/LongAdderTest.java
index 876f907..78f6edc 100644
--- a/android/guava-tests/test/com/google/common/cache/LongAdderTest.java
+++ b/android/guava-tests/test/com/google/common/cache/LongAdderTest.java
@@ -14,27 +14,11 @@
 
 package com.google.common.cache;
 
-import static com.google.common.truth.Truth.assertThat;
-
-import junit.framework.TestCase;
-
-/** Unit tests for {@link LongAdder}. */
-public class LongAdderTest extends TestCase {
-
-  /**
-   * No-op null-pointer test for {@link LongAdder} to override the {@link PackageSanityTests}
-   * version, which checks package-private methods that we don't want to have to annotate as {@code
-   * Nullable} because we don't want diffs from jsr166e.
-   */
+/**
+ * No-op null-pointer test for {@link LongAdder} to override the {@link PackageSanityTests} version,
+ * which checks package-private methods that we don't want to have to annotate as {@code Nullable}
+ * because we don't want diffs from jsr166e.
+ */
+public class LongAdderTest {
   public void testNulls() {}
-
-  public void testOverflows() {
-    LongAdder longAdder = new LongAdder();
-    longAdder.add(Long.MAX_VALUE);
-    assertThat(longAdder.sum()).isEqualTo(Long.MAX_VALUE);
-    longAdder.add(1);
-    // silently overflows; is this a bug?
-    // See https://github.com/google/guava/issues/3503
-    assertThat(longAdder.sum()).isEqualTo(-9223372036854775808L);
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/cache/NullCacheTest.java b/android/guava-tests/test/com/google/common/cache/NullCacheTest.java
index 89dc3fb..e418f6c 100644
--- a/android/guava-tests/test/com/google/common/cache/NullCacheTest.java
+++ b/android/guava-tests/test/com/google/common/cache/NullCacheTest.java
@@ -123,7 +123,7 @@
       map.getUnchecked(new Object());
       fail();
     } catch (UncheckedExecutionException uee) {
-      assertThat(uee).hasCauseThat().isSameInstanceAs(e);
+      assertThat(uee).hasCauseThat().isSameAs(e);
     }
     assertTrue(listener.isEmpty());
     checkEmpty(map);
diff --git a/android/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java b/android/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
index 1e71b63..06f0d27 100644
--- a/android/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
+++ b/android/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
@@ -237,15 +237,21 @@
     }
   }
 
+  @SuppressWarnings("unchecked") // generic array creation
+
   public void testEntrySet_populated() {
     for (LoadingCache<Object, Object> cache : caches()) {
       Set<Entry<Object, Object>> entries = cache.asMap().entrySet();
       List<Entry<Object, Object>> warmed = warmUp(cache, WARMUP_MIN, WARMUP_MAX);
 
       Set<?> expected = Maps.newHashMap(cache.asMap()).entrySet();
-      assertThat(entries).containsExactlyElementsIn(expected);
-      assertThat(entries.toArray()).asList().containsExactlyElementsIn(expected);
-      assertThat(entries.toArray(new Object[0])).asList().containsExactlyElementsIn(expected);
+      assertThat(entries).containsExactlyElementsIn((Collection<Entry<Object, Object>>) expected);
+      assertThat(entries.toArray())
+          .asList()
+          .containsExactlyElementsIn((Collection<Object>) expected);
+      assertThat(entries.toArray(new Entry[0]))
+          .asList()
+          .containsExactlyElementsIn((Collection<Entry>) expected);
 
       new EqualsTester()
           .addEqualityGroup(cache.asMap().entrySet(), entries)
diff --git a/android/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java b/android/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
index e430f0e..55a455b 100644
--- a/android/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
@@ -28,7 +28,6 @@
 
   // The next two tests verify that map entries are not accessed after they're
   // removed, since IdentityHashMap throws an exception when that occurs.
-  @SuppressWarnings("IdentityHashMapBoxing") // explicitly testing IdentityHashMap
   public void testIdentityKeySetIteratorRemove() {
     BiMap<Integer, String> bimap =
         new AbstractBiMap<Integer, String>(
@@ -46,7 +45,6 @@
     assertEquals(1, bimap.inverse().size());
   }
 
-  @SuppressWarnings("IdentityHashMapBoxing") // explicitly testing IdentityHashMap
   public void testIdentityEntrySetIteratorRemove() {
     BiMap<Integer, String> bimap =
         new AbstractBiMap<Integer, String>(
diff --git a/android/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java b/android/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
index 65d2ef6..4d13736 100644
--- a/android/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
+++ b/android/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
@@ -107,7 +107,21 @@
         return ContiguousSet.copyOf(contents);
       }
     },
-    ;
+  //    @GoogleInternal
+  //    CompactHashSetImpl {
+  //      @Override
+  //      public <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+  //        return CompactHashSet.create(contents);
+  //      }
+  //    },
+  //    @GoogleInternal
+  //    CompactLinkedHashSetImpl {
+  //      @Override
+  //      public <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+  //        return CompactLinkedHashSet.create(contents);
+  //      }
+  //    },
+  ;
   }
 
   public enum ListMultimapImpl {
@@ -203,6 +217,24 @@
         return new ConcurrentHashMap<>(map);
       }
     },
+    //    @GoogleInternal
+    //    CompactHashmapImpl {
+    //      @Override
+    //      public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) {
+    //        Map<K, V> result = CompactHashMap.createWithExpectedSize(map.size());
+    //        result.putAll(map);
+    //        return result;
+    //      }
+    //    },
+    //    @GoogleInternal
+    //    CompactLinkedHashmapImpl {
+    //      @Override
+    //      public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) {
+    //        Map<K, V> result = CompactLinkedHashMap.createWithExpectedSize(map.size());
+    //        result.putAll(map);
+    //        return result;
+    //      }
+    //    },
     ImmutableMapImpl {
       @Override
       public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) {
diff --git a/android/guava-tests/test/com/google/common/collect/CompactHashMapTest.java b/android/guava-tests/test/com/google/common/collect/CompactHashMapTest.java
index 52c9bed..33e6015 100644
--- a/android/guava-tests/test/com/google/common/collect/CompactHashMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/CompactHashMapTest.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.google.common.collect;
 
 import static com.google.common.collect.Iterables.getOnlyElement;
@@ -86,35 +85,4 @@
     entry.setValue("one");
     assertThat(map).containsEntry(1, "one");
   }
-
-  public void testAllocArraysDefault() {
-    CompactHashMap<Integer, String> map = CompactHashMap.create();
-    assertThat(map.needsAllocArrays()).isTrue();
-    assertThat(map.entries).isNull();
-    assertThat(map.keys).isNull();
-    assertThat(map.values).isNull();
-
-    map.put(1, "1");
-    assertThat(map.needsAllocArrays()).isFalse();
-    assertThat(map.entries).hasLength(CompactHashing.DEFAULT_SIZE);
-    assertThat(map.keys).hasLength(CompactHashing.DEFAULT_SIZE);
-    assertThat(map.values).hasLength(CompactHashing.DEFAULT_SIZE);
-  }
-
-  public void testAllocArraysExpectedSize() {
-    for (int i = 0; i <= CompactHashing.DEFAULT_SIZE; i++) {
-      CompactHashMap<Integer, String> map = CompactHashMap.createWithExpectedSize(i);
-      assertThat(map.needsAllocArrays()).isTrue();
-      assertThat(map.entries).isNull();
-      assertThat(map.keys).isNull();
-      assertThat(map.values).isNull();
-
-      map.put(1, "1");
-      assertThat(map.needsAllocArrays()).isFalse();
-      int expectedSize = Math.max(1, i);
-      assertThat(map.entries).hasLength(expectedSize);
-      assertThat(map.keys).hasLength(expectedSize);
-      assertThat(map.values).hasLength(expectedSize);
-    }
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/collect/CompactHashSetTest.java b/android/guava-tests/test/com/google/common/collect/CompactHashSetTest.java
index 0f0216f..e5c3a45 100644
--- a/android/guava-tests/test/com/google/common/collect/CompactHashSetTest.java
+++ b/android/guava-tests/test/com/google/common/collect/CompactHashSetTest.java
@@ -16,9 +16,6 @@
 
 package com.google.common.collect;
 
-import static com.google.common.truth.Truth.assertThat;
-import static java.util.stream.Collectors.*;
-
 import com.google.common.annotations.GwtIncompatible;
 import com.google.common.collect.testing.SetTestSuiteBuilder;
 import com.google.common.collect.testing.TestStringSetGenerator;
@@ -86,26 +83,7 @@
     return suite;
   }
 
-  public void testAllocArraysDefault() {
-    CompactHashSet<Integer> set = CompactHashSet.create();
-    assertThat(set.needsAllocArrays()).isTrue();
-    assertThat(set.elements).isNull();
-
-    set.add(1);
-    assertThat(set.needsAllocArrays()).isFalse();
-    assertThat(set.elements).hasLength(CompactHashing.DEFAULT_SIZE);
-  }
-
-  public void testAllocArraysExpectedSize() {
-    for (int i = 0; i <= CompactHashing.DEFAULT_SIZE; i++) {
-      CompactHashSet<Integer> set = CompactHashSet.createWithExpectedSize(i);
-      assertThat(set.needsAllocArrays()).isTrue();
-      assertThat(set.elements).isNull();
-
-      set.add(1);
-      assertThat(set.needsAllocArrays()).isFalse();
-      int expectedSize = Math.max(1, i);
-      assertThat(set.elements).hasLength(expectedSize);
-    }
+  public void testDummyMethod() {
+    // Just make sure the test runner doesn't complain about no test methods.
   }
 }
diff --git a/android/guava-tests/test/com/google/common/collect/CompactLinkedHashMapTest.java b/android/guava-tests/test/com/google/common/collect/CompactLinkedHashMapTest.java
index d1363bc..f7e2857 100644
--- a/android/guava-tests/test/com/google/common/collect/CompactLinkedHashMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/CompactLinkedHashMapTest.java
@@ -11,7 +11,6 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package com.google.common.collect;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -97,8 +96,8 @@
     map.put(4, "b");
     map.put(3, "d");
     map.put(2, "c");
-    map.remove(4);
-    testHasMapEntriesInOrder(map, 1, "a", 3, "d", 2, "c");
+    map.remove(3);
+    testHasMapEntriesInOrder(map, 1, "a", 4, "b", 2, "c");
   }
 
   public void testInsertionOrderAfterRemoveLastEntry() {
@@ -142,39 +141,4 @@
       assertEquals(expectedValue, values.get(i));
     }
   }
-
-  public void testAllocArraysDefault() {
-    CompactLinkedHashMap<Integer, String> map = CompactLinkedHashMap.create();
-    assertThat(map.needsAllocArrays()).isTrue();
-    assertThat(map.entries).isNull();
-    assertThat(map.keys).isNull();
-    assertThat(map.values).isNull();
-    assertThat(map.links).isNull();
-
-    map.put(1, Integer.toString(1));
-    assertThat(map.needsAllocArrays()).isFalse();
-    assertThat(map.entries).hasLength(CompactHashing.DEFAULT_SIZE);
-    assertThat(map.keys).hasLength(CompactHashing.DEFAULT_SIZE);
-    assertThat(map.values).hasLength(CompactHashing.DEFAULT_SIZE);
-    assertThat(map.links).hasLength(CompactHashing.DEFAULT_SIZE);
-  }
-
-  public void testAllocArraysExpectedSize() {
-    for (int i = 0; i <= CompactHashing.DEFAULT_SIZE; i++) {
-      CompactLinkedHashMap<Integer, String> map = CompactLinkedHashMap.createWithExpectedSize(i);
-      assertThat(map.needsAllocArrays()).isTrue();
-      assertThat(map.entries).isNull();
-      assertThat(map.keys).isNull();
-      assertThat(map.values).isNull();
-      assertThat(map.links).isNull();
-
-      map.put(1, Integer.toString(1));
-      assertThat(map.needsAllocArrays()).isFalse();
-      int expectedSize = Math.max(1, i);
-      assertThat(map.entries).hasLength(expectedSize);
-      assertThat(map.keys).hasLength(expectedSize);
-      assertThat(map.values).hasLength(expectedSize);
-      assertThat(map.links).hasLength(expectedSize);
-    }
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/collect/CompactLinkedHashSetTest.java b/android/guava-tests/test/com/google/common/collect/CompactLinkedHashSetTest.java
index 299503e..a95e486 100644
--- a/android/guava-tests/test/com/google/common/collect/CompactLinkedHashSetTest.java
+++ b/android/guava-tests/test/com/google/common/collect/CompactLinkedHashSetTest.java
@@ -16,8 +16,6 @@
 
 package com.google.common.collect;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import com.google.common.annotations.GwtIncompatible;
 import com.google.common.collect.testing.SetTestSuiteBuilder;
 import com.google.common.collect.testing.TestStringSetGenerator;
@@ -67,26 +65,7 @@
     return suite;
   }
 
-  public void testAllocArraysDefault() {
-    CompactHashSet<Integer> set = CompactHashSet.create();
-    assertThat(set.needsAllocArrays()).isTrue();
-    assertThat(set.elements).isNull();
-
-    set.add(1);
-    assertThat(set.needsAllocArrays()).isFalse();
-    assertThat(set.elements).hasLength(CompactHashing.DEFAULT_SIZE);
-  }
-
-  public void testAllocArraysExpectedSize() {
-    for (int i = 0; i <= CompactHashing.DEFAULT_SIZE; i++) {
-      CompactHashSet<Integer> set = CompactHashSet.createWithExpectedSize(i);
-      assertThat(set.needsAllocArrays()).isTrue();
-      assertThat(set.elements).isNull();
-
-      set.add(1);
-      assertThat(set.needsAllocArrays()).isFalse();
-      int expectedSize = Math.max(1, i);
-      assertThat(set.elements).hasLength(expectedSize);
-    }
+  public void testDummyMethod() {
+    // Just make sure the test runner doesn't complain about no test methods.
   }
 }
diff --git a/android/guava-tests/test/com/google/common/collect/ComparatorsTest.java b/android/guava-tests/test/com/google/common/collect/ComparatorsTest.java
index b30cb76..d5f8801 100644
--- a/android/guava-tests/test/com/google/common/collect/ComparatorsTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ComparatorsTest.java
@@ -16,7 +16,6 @@
 
 package com.google.common.collect;
 
-import static com.google.common.truth.Truth.assertThat;
 import static java.util.Arrays.asList;
 
 import com.google.common.annotations.GwtCompatible;
@@ -72,59 +71,4 @@
     assertTrue(Comparators.isInStrictOrder(Collections.singleton(1), Ordering.natural()));
     assertTrue(Comparators.isInStrictOrder(Collections.<Integer>emptyList(), Ordering.natural()));
   }
-
-  public void testMinMaxNatural() {
-    assertThat(Comparators.min(1, 2)).isEqualTo(1);
-    assertThat(Comparators.min(2, 1)).isEqualTo(1);
-    assertThat(Comparators.max(1, 2)).isEqualTo(2);
-    assertThat(Comparators.max(2, 1)).isEqualTo(2);
-  }
-
-  public void testMinMaxNatural_equalInstances() {
-    Foo a = new Foo(1);
-    Foo b = new Foo(1);
-    assertThat(Comparators.min(a, b)).isSameInstanceAs(a);
-    assertThat(Comparators.max(a, b)).isSameInstanceAs(a);
-  }
-
-  public void testMinMaxComparator() {
-    Comparator<Integer> natural = Ordering.natural();
-    Comparator<Integer> reverse = Collections.reverseOrder(natural);
-    assertThat(Comparators.min(1, 2, reverse)).isEqualTo(2);
-    assertThat(Comparators.min(2, 1, reverse)).isEqualTo(2);
-    assertThat(Comparators.max(1, 2, reverse)).isEqualTo(1);
-    assertThat(Comparators.max(2, 1, reverse)).isEqualTo(1);
-  }
-
-  public void testMinMaxComparator_equalInstances() {
-    Comparator<Foo> natural = Ordering.natural();
-    Comparator<Foo> reverse = Collections.reverseOrder(natural);
-    Foo a = new Foo(1);
-    Foo b = new Foo(1);
-    assertThat(Comparators.min(a, b, reverse)).isSameInstanceAs(a);
-    assertThat(Comparators.max(a, b, reverse)).isSameInstanceAs(a);
-  }
-
-  private static class Foo implements Comparable<Foo> {
-    final Integer value;
-
-    Foo(int value) {
-      this.value = value;
-    }
-
-    @Override
-    public int hashCode() {
-      return value.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      return (o instanceof Foo) && ((Foo) o).value.equals(value);
-    }
-
-    @Override
-    public int compareTo(Foo other) {
-      return value.compareTo(other.value);
-    }
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java b/android/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
index 1d38c86..592a1c7 100644
--- a/android/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
@@ -20,8 +20,8 @@
 import static com.google.common.collect.MapMakerInternalMap.Strength.WEAK;
 import static com.google.common.testing.SerializableTester.reserializeAndAssert;
 import static java.util.Arrays.asList;
-import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.isA;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
diff --git a/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java b/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
index cc5d739..6ca5b8c 100644
--- a/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
@@ -17,7 +17,7 @@
 package com.google.common.collect;
 
 import static java.lang.reflect.Modifier.STATIC;
-import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyObject;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -231,10 +231,10 @@
 
     // These are the methods specified by StandardEntrySet
     verify(map, atLeast(0)).clear();
-    verify(map, atLeast(0)).containsKey(any());
-    verify(map, atLeast(0)).get(any());
+    verify(map, atLeast(0)).containsKey(anyObject());
+    verify(map, atLeast(0)).get(anyObject());
     verify(map, atLeast(0)).isEmpty();
-    verify(map, atLeast(0)).remove(any());
+    verify(map, atLeast(0)).remove(anyObject());
     verify(map, atLeast(0)).size();
     verifyNoMoreInteractions(map);
   }
@@ -259,9 +259,9 @@
 
     // These are the methods specified by StandardKeySet
     verify(map, atLeast(0)).clear();
-    verify(map, atLeast(0)).containsKey(any());
+    verify(map, atLeast(0)).containsKey(anyObject());
     verify(map, atLeast(0)).isEmpty();
-    verify(map, atLeast(0)).remove(any());
+    verify(map, atLeast(0)).remove(anyObject());
     verify(map, atLeast(0)).size();
     verify(map, atLeast(0)).entrySet();
     verifyNoMoreInteractions(map);
@@ -287,7 +287,7 @@
 
     // These are the methods specified by StandardValues
     verify(map, atLeast(0)).clear();
-    verify(map, atLeast(0)).containsValue(any());
+    verify(map, atLeast(0)).containsValue(anyObject());
     verify(map, atLeast(0)).isEmpty();
     verify(map, atLeast(0)).size();
     verify(map, atLeast(0)).entrySet();
diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
index cb23f3e..f1f59c5 100644
--- a/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
@@ -575,7 +575,4 @@
       assertEquals(alternatingKeysAndValues[i++], entry.getValue());
     }
   }
-
-  /** No-op test so that the class has at least one method, making Maven's test runner happy. */
-  public void testNoop() {}
 }
diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
index 2cf43ef..e6569b0 100644
--- a/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
@@ -17,7 +17,6 @@
 package com.google.common.collect;
 
 import static com.google.common.testing.SerializableTester.reserialize;
-import static com.google.common.truth.Truth.assertThat;
 
 import com.google.common.annotations.GwtCompatible;
 import com.google.common.annotations.GwtIncompatible;
@@ -46,15 +45,12 @@
 import com.google.common.testing.EqualsTester;
 import com.google.common.testing.NullPointerTester;
 import com.google.common.testing.SerializableTester;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -651,37 +647,6 @@
       assertMapEquals(copy, "one", 1, "two", 2, "three", 3);
       assertSame(copy, ImmutableMap.copyOf(copy));
     }
-
-    public static void hashtableTestHelper(ImmutableList<Integer> sizes) {
-      for (int size : sizes) {
-        Builder<Integer, Integer> builder = ImmutableMap.builderWithExpectedSize(size);
-        for (int i = 0; i < size; i++) {
-          Integer integer = i;
-          builder.put(integer, integer);
-        }
-        ImmutableMap<Integer, Integer> map = builder.build();
-        assertEquals(size, map.size());
-        int entries = 0;
-        for (Integer key : map.keySet()) {
-          assertEquals(entries, key.intValue());
-          assertSame(key, map.get(key));
-          entries++;
-        }
-        assertEquals(size, entries);
-      }
-    }
-
-    public void testByteArrayHashtable() {
-      hashtableTestHelper(ImmutableList.of(2, 89));
-    }
-
-    public void testShortArrayHashtable() {
-      hashtableTestHelper(ImmutableList.of(90, 22937));
-    }
-
-    public void testIntArrayHashtable() {
-      hashtableTestHelper(ImmutableList.of(22938));
-    }
   }
 
   public void testNullGet() {
@@ -772,58 +737,6 @@
     assertTrue(reserializedValues instanceof ImmutableCollection);
   }
 
-  @GwtIncompatible // SerializableTester
-  public void testKeySetIsSerializable_regularImmutableMap() {
-    class NonSerializableClass {}
-
-    Map<String, NonSerializableClass> map =
-        RegularImmutableMap.create(1, new Object[] {"one", new NonSerializableClass()});
-    Set<String> set = map.keySet();
-
-    LenientSerializableTester.reserializeAndAssertLenient(set);
-  }
-
-  @GwtIncompatible // SerializableTester
-  public void testValuesCollectionIsSerializable_regularImmutableMap() {
-    class NonSerializableClass {}
-
-    Map<NonSerializableClass, String> map =
-        RegularImmutableMap.create(1, new Object[] {new NonSerializableClass(), "value"});
-    Collection<String> collection = map.values();
-
-    LenientSerializableTester.reserializeAndAssertElementsEqual(collection);
-  }
-
-  // TODO: Re-enable this test after moving to new serialization format in ImmutableMap.
-  @GwtIncompatible // SerializableTester
-  @SuppressWarnings("unchecked")
-  public void ignore_testSerializationNoDuplication_regularImmutableMap() throws Exception {
-    // Tests that searializing a map, its keySet, and values only writes the underlying data once.
-
-    Object[] entries = new Object[2000];
-    for (int i = 0; i < entries.length; i++) {
-      entries[i] = i;
-    }
-
-    ImmutableMap<Integer, Integer> map = RegularImmutableMap.create(entries.length / 2, entries);
-    Set<Integer> keySet = map.keySet();
-    Collection<Integer> values = map.values();
-
-    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-    ObjectOutputStream oos = new ObjectOutputStream(bytes);
-    oos.writeObject(map);
-    oos.flush();
-
-    int mapSize = bytes.size();
-    oos.writeObject(keySet);
-    oos.writeObject(values);
-    oos.close();
-
-    int finalSize = bytes.size();
-
-    assertThat(finalSize - mapSize).isLessThan(100);
-  }
-
   public void testEquals() {
     new EqualsTester()
         .addEqualityGroup(ImmutableMap.of(), ImmutableMap.builder().build())
diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableSetTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
index 6dc6f22..8a984c9 100644
--- a/android/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
@@ -366,12 +366,4 @@
     builder.add("baz");
     assertTrue(set.elements != builder.contents);
   }
-
-  public void testReuseBuilderReducingHashTableSizeWithPowerOfTwoTotalElements() {
-    ImmutableSet.Builder<Object> builder = ImmutableSet.builderWithExpectedSize(6);
-    builder.add(0);
-    ImmutableSet<Object> unused = builder.build();
-    ImmutableSet<Object> subject = builder.add(1).add(2).add(3).build();
-    assertFalse(subject.contains(4));
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java b/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
index cf2f5aa..520ba65 100644
--- a/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
@@ -1005,44 +1005,6 @@
     }
   }
 
-  public void testFloor_emptySet() {
-    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(new String[] {});
-    assertThat(set.floor("f")).isNull();
-  }
-
-  public void testFloor_elementPresent() {
-    ImmutableSortedSet<String> set =
-        ImmutableSortedSet.copyOf(new String[] {"e", "a", "e", "f", "b", "i", "d", "a", "c", "k"});
-    assertThat(set.floor("f")).isEqualTo("f");
-    assertThat(set.floor("j")).isEqualTo("i");
-    assertThat(set.floor("q")).isEqualTo("k");
-  }
-
-  public void testFloor_elementAbsent() {
-    ImmutableSortedSet<String> set =
-        ImmutableSortedSet.copyOf(new String[] {"e", "e", "f", "b", "i", "d", "c", "k"});
-    assertThat(set.floor("a")).isNull();
-  }
-
-  public void testCeiling_emptySet() {
-    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(new String[] {});
-    assertThat(set.ceiling("f")).isNull();
-  }
-
-  public void testCeiling_elementPresent() {
-    ImmutableSortedSet<String> set =
-        ImmutableSortedSet.copyOf(new String[] {"e", "e", "f", "f", "i", "d", "c", "k", "p", "c"});
-    assertThat(set.ceiling("f")).isEqualTo("f");
-    assertThat(set.ceiling("h")).isEqualTo("i");
-    assertThat(set.ceiling("a")).isEqualTo("c");
-  }
-
-  public void testCeiling_elementAbsent() {
-    ImmutableSortedSet<String> set =
-        ImmutableSortedSet.copyOf(new String[] {"e", "a", "e", "f", "b", "i", "d", "a", "c", "k"});
-    assertThat(set.ceiling("l")).isNull();
-  }
-
   public void testSubSetExclusiveExclusive() {
     String[] strings = NUMBER_NAMES.toArray(new String[0]);
     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
diff --git a/android/guava-tests/test/com/google/common/collect/IteratorsTest.java b/android/guava-tests/test/com/google/common/collect/IteratorsTest.java
index 15f7ccc..afe22b8 100644
--- a/android/guava-tests/test/com/google/common/collect/IteratorsTest.java
+++ b/android/guava-tests/test/com/google/common/collect/IteratorsTest.java
@@ -1279,7 +1279,8 @@
   }
 
   private static Enumeration<Integer> enumerate(Integer... ints) {
-    Vector<Integer> vector = new Vector<>(asList(ints));
+    Vector<Integer> vector = new Vector<>();
+    vector.addAll(asList(ints));
     return vector.elements();
   }
 
diff --git a/android/guava-tests/test/com/google/common/collect/LenientSerializableTester.java b/android/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
index ce3ec9d..03b35e0 100644
--- a/android/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
+++ b/android/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
@@ -24,7 +24,6 @@
 import com.google.common.annotations.GwtIncompatible;
 import com.google.common.testing.SerializableTester;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
-import java.util.Collection;
 import java.util.Set;
 
 /**
@@ -61,14 +60,5 @@
     return copy;
   }
 
-  @CanIgnoreReturnValue
-  @GwtIncompatible // SerializableTester
-  static <E> Collection<E> reserializeAndAssertElementsEqual(Collection<E> original) {
-    Collection<E> copy = reserialize(original);
-    assertTrue(Iterables.elementsEqual(original, copy));
-    assertTrue(copy instanceof ImmutableCollection);
-    return copy;
-  }
-
   private LenientSerializableTester() {}
 }
diff --git a/android/guava-tests/test/com/google/common/collect/ListsImplTest.java b/android/guava-tests/test/com/google/common/collect/ListsImplTest.java
index 2d18f5a..69d19ba 100644
--- a/android/guava-tests/test/com/google/common/collect/ListsImplTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ListsImplTest.java
@@ -17,7 +17,6 @@
 package com.google.common.collect;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import com.google.common.annotations.GwtCompatible;
 import com.google.common.annotations.GwtIncompatible;
@@ -139,7 +138,7 @@
     List<Object> unEqualItems =
         Arrays.asList(outOfOrder, diffValue, diffLength, empty, null, new Object());
     for (Object other : unEqualItems) {
-      assertWithMessage("%s", other).that(Lists.equalsImpl(base, other)).isFalse();
+      assertThat(Lists.equalsImpl(base, other)).named("%s", other).isFalse();
     }
   }
 
@@ -168,11 +167,11 @@
       int index = indexes.get(i);
       Iterable<String> iterableToAdd = toAdd.get(i);
       boolean expectedChanged = iterableToAdd.iterator().hasNext();
-      assertWithMessage(format, iterableToAdd, index)
-          .that(Lists.addAllImpl(toTest, index, iterableToAdd))
+      assertThat(Lists.addAllImpl(toTest, index, iterableToAdd))
+          .named(format, iterableToAdd, index)
           .isEqualTo(expectedChanged);
-      assertWithMessage(format, iterableToAdd, index)
-          .that(toTest)
+      assertThat(toTest)
+          .named(format, iterableToAdd, index)
           .containsExactlyElementsIn(expected.get(i));
     }
   }
@@ -217,7 +216,7 @@
     int index = 0;
     for (Object obj : toTest) {
       String name = "toTest[" + index + "] (" + obj + ")";
-      assertWithMessage(name).that(Lists.indexOfImpl(toTest, obj)).isEqualTo(expected[index]);
+      assertThat(Lists.indexOfImpl(toTest, obj)).named(name).isEqualTo(expected[index]);
       index++;
     }
   }
@@ -226,7 +225,7 @@
     int index = 0;
     for (Object obj : toTest) {
       String name = "toTest[" + index + "] (" + obj + ")";
-      assertWithMessage(name).that(Lists.lastIndexOfImpl(toTest, obj)).isEqualTo(expected[index]);
+      assertThat(Lists.lastIndexOfImpl(toTest, obj)).named(name).isEqualTo(expected[index]);
       index++;
     }
   }
diff --git a/android/guava-tests/test/com/google/common/collect/ListsTest.java b/android/guava-tests/test/com/google/common/collect/ListsTest.java
index ef90e54..0d0e6f2 100644
--- a/android/guava-tests/test/com/google/common/collect/ListsTest.java
+++ b/android/guava-tests/test/com/google/common/collect/ListsTest.java
@@ -629,16 +629,6 @@
     assertEquals(actual.indexOf(list(1, 1, 1)), -1);
   }
 
-  public void testCartesianProduct_lastIndexOf() {
-    List<List<Integer>> actual = Lists.cartesianProduct(list(1, 1), list(2, 3));
-    assertThat(actual.lastIndexOf(list(1, 2))).isEqualTo(2);
-    assertThat(actual.lastIndexOf(list(1, 3))).isEqualTo(3);
-    assertThat(actual.lastIndexOf(list(1, 1))).isEqualTo(-1);
-
-    assertThat(actual.lastIndexOf(list(1))).isEqualTo(-1);
-    assertThat(actual.lastIndexOf(list(1, 1, 1))).isEqualTo(-1);
-  }
-
   @SuppressWarnings("unchecked") // varargs!
   public void testCartesianProduct_unrelatedTypes() {
     List<Integer> x = list(1, 2);
diff --git a/android/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java b/android/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
index 47fc74c..535eed4 100644
--- a/android/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
@@ -604,7 +604,6 @@
     assertNull(segment.get(key, hash));
   }
 
-  @SuppressWarnings("GuardedBy")
   public void testExpand() {
     MapMakerInternalMap<Object, Object, ?, ?> map =
         makeMap(createMapMaker().concurrencyLevel(1).initialCapacity(1));
@@ -630,8 +629,6 @@
 
     for (int i = 1; i <= originalCount * 2; i *= 2) {
       if (i > 1) {
-        // TODO(b/145386688): This access should be guarded by 'segment', which is not currently
-        // held
         segment.expand();
       }
       assertEquals(i, segment.table.length());
@@ -690,7 +687,6 @@
     assertNull(newFirst.getNext());
   }
 
-  @SuppressWarnings("GuardedBy")
   public void testExpand_cleanup() {
     MapMakerInternalMap<Object, Object, ?, ?> map =
         makeMap(createMapMaker().concurrencyLevel(1).initialCapacity(1));
@@ -723,8 +719,6 @@
 
     for (int i = 1; i <= originalCount * 2; i *= 2) {
       if (i > 1) {
-        // TODO(b/145386688): This access should be guarded by 'segment', which is not currently
-        // held
         segment.expand();
       }
       assertEquals(i, segment.table.length());
@@ -851,7 +845,7 @@
         InternalEntry<Object, Object, ?> entry = segment.getEntry(keyOne, hashOne);
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) entry;
+        Reference<Object> reference = (Reference) entry;
         reference.enqueue();
 
         map.put(keyTwo, valueTwo);
@@ -883,7 +877,7 @@
         WeakValueReference<Object, Object, ?> valueReference = entry.getValueReference();
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) valueReference;
+        Reference<Object> reference = (Reference) valueReference;
         reference.enqueue();
 
         map.put(keyTwo, valueTwo);
@@ -911,7 +905,7 @@
         InternalEntry<Object, Object, ?> entry = segment.getEntry(keyOne, hashOne);
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) entry;
+        Reference<Object> reference = (Reference) entry;
         reference.enqueue();
 
         for (int i = 0; i < SMALL_MAX_SIZE; i++) {
@@ -944,7 +938,7 @@
         WeakValueReference<Object, Object, ?> valueReference = entry.getValueReference();
 
         @SuppressWarnings("unchecked")
-        Reference<Object> reference = (Reference<Object>) valueReference;
+        Reference<Object> reference = (Reference) valueReference;
         reference.enqueue();
 
         for (int i = 0; i < SMALL_MAX_SIZE; i++) {
diff --git a/android/guava-tests/test/com/google/common/collect/MapsTest.java b/android/guava-tests/test/com/google/common/collect/MapsTest.java
index 76394c8..8ea3475 100644
--- a/android/guava-tests/test/com/google/common/collect/MapsTest.java
+++ b/android/guava-tests/test/com/google/common/collect/MapsTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.collect.Maps.unmodifiableNavigableMap;
 import static com.google.common.collect.testing.Helpers.mapEntry;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 import static java.util.Arrays.asList;
 
 import com.google.common.annotations.GwtCompatible;
@@ -156,8 +155,8 @@
     for (int i = 1; i < size; i++) {
       map1.put(i, null);
     }
-    assertWithMessage("table size after adding " + size + " elements")
-        .that(bucketsOf(map1))
+    assertThat(bucketsOf(map1))
+        .named("table size after adding " + size + " elements")
         .isEqualTo(initialBuckets);
 
     /*
@@ -165,8 +164,8 @@
      * once; make sure that passes too.
      */
     map2.putAll(map1);
-    assertWithMessage("table size after adding " + size + " elements")
-        .that(bucketsOf(map1))
+    assertThat(bucketsOf(map1))
+        .named("table size after adding " + size + " elements")
         .isEqualTo(initialBuckets);
   }
 
@@ -245,8 +244,6 @@
     assertEquals(original, map);
   }
 
-  // Intentionally using IdentityHashMap to test creation.
-  @SuppressWarnings("IdentityHashMapBoxing")
   public void testIdentityHashMap() {
     IdentityHashMap<Integer, Integer> map = Maps.newIdentityHashMap();
     assertEquals(Collections.emptyMap(), map);
diff --git a/android/guava-tests/test/com/google/common/collect/QueuesTest.java b/android/guava-tests/test/com/google/common/collect/QueuesTest.java
index 66d99fe..e85051b 100644
--- a/android/guava-tests/test/com/google/common/collect/QueuesTest.java
+++ b/android/guava-tests/test/com/google/common/collect/QueuesTest.java
@@ -77,7 +77,7 @@
   @Override
   public void tearDown() throws InterruptedException {
     threadPool.shutdown();
-    assertTrue("Some worker didn't finish in time", threadPool.awaitTermination(10, SECONDS));
+    assertTrue("Some worker didn't finish in time", threadPool.awaitTermination(1, SECONDS));
   }
 
   private static <T> int drain(
diff --git a/android/guava-tests/test/com/google/common/collect/RangeTest.java b/android/guava-tests/test/com/google/common/collect/RangeTest.java
index 9a2cd74..d76b96f 100644
--- a/android/guava-tests/test/com/google/common/collect/RangeTest.java
+++ b/android/guava-tests/test/com/google/common/collect/RangeTest.java
@@ -23,7 +23,6 @@
 import static java.util.Arrays.asList;
 
 import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
 import com.google.common.base.Predicate;
 import com.google.common.collect.testing.Helpers;
 import com.google.common.testing.EqualsTester;
@@ -38,7 +37,7 @@
  *
  * @author Kevin Bourrillion
  */
-@GwtCompatible(emulated = true)
+@GwtCompatible
 public class RangeTest extends TestCase {
   public void testOpen() {
     Range<Integer> range = Range.open(4, 8);
@@ -119,8 +118,6 @@
 
   public void testIsConnected() {
     assertTrue(Range.closed(3, 5).isConnected(Range.open(5, 6)));
-    assertTrue(Range.closed(3, 5).isConnected(Range.closed(5, 6)));
-    assertTrue(Range.closed(5, 6).isConnected(Range.closed(3, 5)));
     assertTrue(Range.closed(3, 5).isConnected(Range.openClosed(5, 5)));
     assertTrue(Range.open(3, 5).isConnected(Range.closed(5, 6)));
     assertTrue(Range.closed(3, 7).isConnected(Range.open(6, 8)));
@@ -474,32 +471,6 @@
     }
   }
 
-  public void testGap_invalidRangesWithInfinity() {
-    try {
-      Range.atLeast(1).gap(Range.atLeast(2));
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      Range.atLeast(2).gap(Range.atLeast(1));
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      Range.atMost(1).gap(Range.atMost(2));
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      Range.atMost(2).gap(Range.atMost(1));
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   public void testGap_connectedAdjacentYieldsEmpty() {
     Range<Integer> range = Range.open(3, 4);
 
@@ -528,8 +499,6 @@
     assertEquals(Range.open(2, 4), closedRange.gap(Range.atMost(2)));
   }
 
-  // TODO(cpovirk): More extensive testing of gap().
-
   public void testSpan_general() {
     Range<Integer> range = Range.closed(4, 8);
 
@@ -599,7 +568,6 @@
         .testEquals();
   }
 
-  @GwtIncompatible // TODO(b/148207871): Restore once Eclipse compiler no longer flakes for this.
   public void testLegacyComparable() {
     Range<LegacyComparable> range = Range.closed(LegacyComparable.X, LegacyComparable.Y);
   }
diff --git a/android/guava-tests/test/com/google/common/collect/SetsTest.java b/android/guava-tests/test/com/google/common/collect/SetsTest.java
index 8aa8d83..1873a14 100644
--- a/android/guava-tests/test/com/google/common/collect/SetsTest.java
+++ b/android/guava-tests/test/com/google/common/collect/SetsTest.java
@@ -24,7 +24,6 @@
 import static com.google.common.collect.Sets.unmodifiableNavigableSet;
 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 import static java.io.ObjectStreamConstants.TC_REFERENCE;
 import static java.io.ObjectStreamConstants.baseWireHandle;
 import static java.util.Collections.emptySet;
@@ -949,13 +948,6 @@
     }
   }
 
-  public void testPowerSetEquals_independentOfOrder() {
-    ImmutableSet<Integer> elements = ImmutableSet.of(1, 2, 3, 4);
-    Set<Set<Integer>> forward = powerSet(elements);
-    Set<Set<Integer>> reverse = powerSet(ImmutableSet.copyOf(elements.asList().reverse()));
-    new EqualsTester().addEqualityGroup(forward, reverse).testEquals();
-  }
-
   /**
    * Test that a hash code miscomputed by "input.hashCode() * tooFarValue / 2" is correct under our
    * {@code hashCode} implementation.
@@ -1040,8 +1032,8 @@
                     return input.size() == size;
                   }
                 });
-        assertWithMessage("Sets.combinations(%s, %s)", sampleSet, k)
-            .that(Sets.combinations(sampleSet, k))
+        assertThat(Sets.combinations(sampleSet, k))
+            .named("Sets.combinations(%s, %s)", sampleSet, k)
             .containsExactlyElementsIn(expected)
             .inOrder();
       }
diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java
index 0a11b27..1c8de93 100644
--- a/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java
+++ b/android/guava-tests/test/com/google/common/collect/SynchronizedDequeTest.java
@@ -263,8 +263,8 @@
     create().add("foo");
     create().addAll(ImmutableList.of("foo"));
     create().clear();
-    boolean unused = create().contains("foo");
-    boolean unused2 = create().containsAll(ImmutableList.of("foo"));
+    create().contains("foo");
+    create().containsAll(ImmutableList.of("foo"));
     create().equals(new ArrayDeque<>(ImmutableList.of("foo")));
     create().hashCode();
     create().isEmpty();
diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java
index 34d1c6f..140720c 100644
--- a/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java
@@ -175,11 +175,11 @@
   }
 
   public void testContainsKey() {
-    boolean unused = create().containsKey(null);
+    create().containsKey(null);
   }
 
   public void testContainsValue() {
-    boolean unused = create().containsValue(null);
+    create().containsValue(null);
   }
 
   public void testGet() {
diff --git a/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java b/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
index 70ff774..a29c00f 100644
--- a/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
+++ b/android/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
@@ -161,8 +161,8 @@
     create().add("foo");
     create().addAll(ImmutableList.of("foo"));
     create().clear();
-    boolean unused = create().contains("foo");
-    boolean unused2 = create().containsAll(ImmutableList.of("foo"));
+    create().contains("foo");
+    create().containsAll(ImmutableList.of("foo"));
     create().equals(new ArrayDeque<>(ImmutableList.of("foo")));
     create().hashCode();
     create().isEmpty();
diff --git a/android/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java b/android/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
index d82633a..213b4fa 100644
--- a/android/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
+++ b/android/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
@@ -489,20 +489,6 @@
     assertEquals(ImmutableMap.of(Range.closedOpen(0, 2), 1), rangeMap.asMapOfRanges());
   }
 
-  public void testPutCoalescingSubmapEmpty() {
-    RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
-    rangeMap.put(Range.closedOpen(0, 1), 1);
-    rangeMap.put(Range.closedOpen(1, 2), 1);
-    assertEquals(
-        ImmutableMap.of(Range.closedOpen(0, 1), 1, Range.closedOpen(1, 2), 1),
-        rangeMap.asMapOfRanges());
-
-    RangeMap<Integer, Integer> subRangeMap = rangeMap.subRangeMap(Range.closedOpen(0, 2));
-    subRangeMap.putCoalescing(Range.closedOpen(1, 1), 1); // empty range coalesces connected ranges
-    assertEquals(ImmutableMap.of(Range.closedOpen(0, 2), 1), subRangeMap.asMapOfRanges());
-    assertEquals(ImmutableMap.of(Range.closedOpen(0, 2), 1), rangeMap.asMapOfRanges());
-  }
-
   public void testPutCoalescingComplex() {
     // {[0..1): 1, [1..3): 1, [3..5): 1, [7..10): 2, [12..15): 2, [18..19): 3}
     RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
diff --git a/android/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java b/android/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
index 498a1a1..d033e24 100644
--- a/android/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
+++ b/android/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
@@ -285,19 +285,6 @@
     }
   }
 
-  public void testSubRangeSetAdd() {
-    TreeRangeSet<Integer> set = TreeRangeSet.create();
-    Range<Integer> range = Range.closedOpen(0, 5);
-    set.subRangeSet(range).add(range);
-  }
-
-  public void testSubRangeSetReplaceAdd() {
-    TreeRangeSet<Integer> set = TreeRangeSet.create();
-    Range<Integer> range = Range.closedOpen(0, 5);
-    set.add(range);
-    set.subRangeSet(range).add(range);
-  }
-
   public void testComplement() {
     for (Range<Integer> range1 : QUERY_RANGES) {
       for (Range<Integer> range2 : QUERY_RANGES) {
diff --git a/android/guava-tests/test/com/google/common/eventbus/EventBusTest.java b/android/guava-tests/test/com/google/common/eventbus/EventBusTest.java
index 249d3b0..647663c 100644
--- a/android/guava-tests/test/com/google/common/eventbus/EventBusTest.java
+++ b/android/guava-tests/test/com/google/common/eventbus/EventBusTest.java
@@ -289,18 +289,6 @@
     assertEquals(1, calls.get());
   }
 
-  public void testPrimitiveSubscribeFails() {
-    class SubscribesToPrimitive {
-      @Subscribe
-      public void toInt(int i) {}
-    }
-    try {
-      bus.register(new SubscribesToPrimitive());
-      fail("should have thrown");
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   /** Records thrown exception information. */
   private static final class RecordingSubscriberExceptionHandler
       implements SubscriberExceptionHandler {
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractDirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/AbstractDirectedGraphTest.java
new file mode 100644
index 0000000..e8b8a43
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/AbstractDirectedGraphTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+/**
+ * Abstract base class for testing implementations of {@link Graph} interface.
+ *
+ * <p>This class is responsible for testing that a directed implementation of {@link Graph} is
+ * correctly handling directed edges. Implementation-dependent test cases are left to subclasses.
+ * Test cases that do not require the graph to be directed are found in superclasses.
+ */
+public abstract class AbstractDirectedGraphTest extends AbstractGraphTest {
+  @Test
+  public void predecessors_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.predecessors(N2)).containsExactly(N1);
+    // Edge direction handled correctly
+    assertThat(graph.predecessors(N1)).isEmpty();
+  }
+
+  @Test
+  public void successors_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.successors(N1)).containsExactly(N2);
+    // Edge direction handled correctly
+    assertThat(graph.successors(N2)).isEmpty();
+  }
+
+  @Test
+  public void incidentEdges_oneEdge() {
+    putEdge(N1, N2);
+    EndpointPair<Integer> expectedEndpoints = EndpointPair.ordered(N1, N2);
+    assertThat(graph.incidentEdges(N1)).containsExactly(expectedEndpoints);
+    assertThat(graph.incidentEdges(N2)).containsExactly(expectedEndpoints);
+  }
+
+  @Test
+  public void inDegree_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.inDegree(N2)).isEqualTo(1);
+    // Edge direction handled correctly
+    assertThat(graph.inDegree(N1)).isEqualTo(0);
+  }
+
+  @Test
+  public void outDegree_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.outDegree(N1)).isEqualTo(1);
+    // Edge direction handled correctly
+    assertThat(graph.outDegree(N2)).isEqualTo(0);
+  }
+
+  @Test
+  public void hasEdgeConnecting_correct() {
+    putEdge(N1, N2);
+    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N1, N2))).isTrue();
+  }
+
+  @Test
+  public void hasEdgeConnecting_backwards() {
+    putEdge(N1, N2);
+    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N2, N1))).isFalse();
+  }
+
+  @Test
+  public void hasEdgeConnecting_mismatch() {
+    putEdge(N1, N2);
+    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N1, N2))).isFalse();
+    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N2, N1))).isFalse();
+  }
+
+  // Element Mutation
+
+  @Test
+  public void putEdge_existingNodes() {
+    // Adding nodes initially for safety (insulating from possible future
+    // modifications to proxy methods)
+    addNode(N1);
+    addNode(N2);
+    assertThat(putEdge(N1, N2)).isTrue();
+  }
+
+  @Test
+  public void putEdge_existingEdgeBetweenSameNodes() {
+    assertThat(putEdge(N1, N2)).isTrue();
+    assertThat(putEdge(N1, N2)).isFalse();
+  }
+
+  @Test
+  public void putEdge_orderMismatch() {
+    EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
+    try {
+      putEdge(endpoints);
+      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
+    }
+  }
+
+  public void removeEdge_antiparallelEdges() {
+    putEdge(N1, N2);
+    putEdge(N2, N1);
+
+    assertThat(graph.removeEdge(N1, N2)).isTrue();
+    assertThat(graph.successors(N1)).isEmpty();
+    assertThat(graph.predecessors(N1)).containsExactly(N2);
+    assertThat(graph.edges()).hasSize(1);
+
+    assertThat(graph.removeEdge(N2, N1)).isTrue();
+    assertThat(graph.successors(N1)).isEmpty();
+    assertThat(graph.predecessors(N1)).isEmpty();
+    assertThat(graph.edges()).isEmpty();
+  }
+
+  @Test
+  public void removeEdge_orderMismatch() {
+    putEdge(N1, N2);
+    EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
+    try {
+      graph.removeEdge(endpoints);
+      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
+    }
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractDirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/AbstractDirectedNetworkTest.java
new file mode 100644
index 0000000..6111f82
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/AbstractDirectedNetworkTest.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
+import static com.google.common.graph.TestUtil.assertEdgeNotInGraphErrorMessage;
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Collections;
+import java.util.Set;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Abstract base class for testing implementations of {@link Network} interface.
+ *
+ * <p>This class is responsible for testing that a directed implementation of {@link Network} is
+ * correctly handling directed edges. Implementation-dependent test cases are left to subclasses.
+ * Test cases that do not require the graph to be directed are found in superclasses.
+ */
+public abstract class AbstractDirectedNetworkTest extends AbstractNetworkTest {
+
+  @After
+  public void validateSourceAndTarget() {
+    for (Integer node : network.nodes()) {
+      for (String inEdge : network.inEdges(node)) {
+        EndpointPair<Integer> endpointPair = network.incidentNodes(inEdge);
+        assertThat(endpointPair.source()).isEqualTo(endpointPair.adjacentNode(node));
+        assertThat(endpointPair.target()).isEqualTo(node);
+      }
+
+      for (String outEdge : network.outEdges(node)) {
+        EndpointPair<Integer> endpointPair = network.incidentNodes(outEdge);
+        assertThat(endpointPair.source()).isEqualTo(node);
+        assertThat(endpointPair.target()).isEqualTo(endpointPair.adjacentNode(node));
+      }
+
+      for (Integer adjacentNode : network.adjacentNodes(node)) {
+        Set<String> edges = network.edgesConnecting(node, adjacentNode);
+        Set<String> antiParallelEdges = network.edgesConnecting(adjacentNode, node);
+        assertThat(node.equals(adjacentNode) || Collections.disjoint(edges, antiParallelEdges))
+            .isTrue();
+      }
+    }
+  }
+
+  @Test
+  public void edges_containsOrderMismatch() {
+    addEdge(N1, N2, E12);
+    EndpointPair<Integer> endpointsN1N2 = EndpointPair.unordered(N1, N2);
+    EndpointPair<Integer> endpointsN2N1 = EndpointPair.unordered(N2, N1);
+    assertThat(network.asGraph().edges()).doesNotContain(endpointsN1N2);
+    assertThat(network.asGraph().edges()).doesNotContain(endpointsN2N1);
+  }
+
+  @Test
+  public void edgesConnecting_orderMismatch() {
+    addEdge(N1, N2, E12);
+    try {
+      Set<String> unused = network.edgesConnecting(EndpointPair.unordered(N1, N2));
+      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
+    }
+  }
+
+  @Test
+  public void edgeConnectingOrNull_orderMismatch() {
+    addEdge(N1, N2, E12);
+    try {
+      String unused = network.edgeConnectingOrNull(EndpointPair.unordered(N1, N2));
+      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
+    }
+  }
+
+  @Override
+  @Test
+  public void incidentNodes_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.incidentNodes(E12).source()).isEqualTo(N1);
+    assertThat(network.incidentNodes(E12).target()).isEqualTo(N2);
+  }
+
+  @Test
+  public void edgesConnecting_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    // Passed nodes should be in the correct edge direction, first is the
+    // source node and the second is the target node
+    assertThat(network.edgesConnecting(N2, N1)).isEmpty();
+  }
+
+  @Test
+  public void inEdges_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.inEdges(N2)).containsExactly(E12);
+    // Edge direction handled correctly
+    assertThat(network.inEdges(N1)).isEmpty();
+  }
+
+  @Test
+  public void outEdges_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.outEdges(N1)).containsExactly(E12);
+    // Edge direction handled correctly
+    assertThat(network.outEdges(N2)).isEmpty();
+  }
+
+  @Test
+  public void predecessors_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.predecessors(N2)).containsExactly(N1);
+    // Edge direction handled correctly
+    assertThat(network.predecessors(N1)).isEmpty();
+  }
+
+  @Test
+  public void successors_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.successors(N1)).containsExactly(N2);
+    // Edge direction handled correctly
+    assertThat(network.successors(N2)).isEmpty();
+  }
+
+  @Test
+  public void source_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.incidentNodes(E12).source()).isEqualTo(N1);
+  }
+
+  @Test
+  public void source_edgeNotInGraph() {
+    try {
+      network.incidentNodes(EDGE_NOT_IN_GRAPH).source();
+      fail(ERROR_EDGE_NOT_IN_GRAPH);
+    } catch (IllegalArgumentException e) {
+      assertEdgeNotInGraphErrorMessage(e);
+    }
+  }
+
+  @Test
+  public void target_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.incidentNodes(E12).target()).isEqualTo(N2);
+  }
+
+  @Test
+  public void target_edgeNotInGraph() {
+    try {
+      network.incidentNodes(EDGE_NOT_IN_GRAPH).target();
+      fail(ERROR_EDGE_NOT_IN_GRAPH);
+    } catch (IllegalArgumentException e) {
+      assertEdgeNotInGraphErrorMessage(e);
+    }
+  }
+
+  @Test
+  public void inDegree_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.inDegree(N2)).isEqualTo(1);
+    // Edge direction handled correctly
+    assertThat(network.inDegree(N1)).isEqualTo(0);
+  }
+
+  @Test
+  public void outDegree_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.outDegree(N1)).isEqualTo(1);
+    // Edge direction handled correctly
+    assertThat(network.outDegree(N2)).isEqualTo(0);
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_existingNodes() {
+    // Adding nodes initially for safety (insulating from possible future
+    // modifications to proxy methods)
+    addNode(N1);
+    addNode(N2);
+    assertThat(addEdge(N1, N2, E12)).isTrue();
+    assertThat(network.edges()).contains(E12);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    // Direction of the added edge is correctly handled
+    assertThat(network.edgesConnecting(N2, N1)).isEmpty();
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenSameNodes() {
+    addEdge(N1, N2, E12);
+    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
+    assertThat(addEdge(N1, N2, E12)).isFalse();
+    assertThat(network.edges()).containsExactlyElementsIn(edges);
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenDifferentNodes() {
+    addEdge(N1, N2, E12);
+    try {
+      // Edge between totally different nodes
+      addEdge(N4, N5, E12);
+      fail(ERROR_ADDED_EXISTING_EDGE);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
+    }
+    try {
+      // Edge between same nodes but in reverse direction
+      addEdge(N2, N1, E12);
+      fail(ERROR_ADDED_EXISTING_EDGE);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
+    }
+  }
+
+  @Test
+  public void addEdge_parallelEdge() {
+    addEdge(N1, N2, E12);
+    try {
+      addEdge(N1, N2, EDGE_NOT_IN_GRAPH);
+      fail(ERROR_ADDED_PARALLEL_EDGE);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE);
+    }
+  }
+
+  @Test
+  public void addEdge_orderMismatch() {
+    EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
+    try {
+      addEdge(endpoints, E12);
+      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
+    }
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractGraphTest.java b/android/guava-tests/test/com/google/common/graph/AbstractGraphTest.java
index 3a489a1..2f81895 100644
--- a/android/guava-tests/test/com/google/common/graph/AbstractGraphTest.java
+++ b/android/guava-tests/test/com/google/common/graph/AbstractGraphTest.java
@@ -21,10 +21,10 @@
 import static com.google.common.graph.TestUtil.assertStronglyEquivalent;
 import static com.google.common.graph.TestUtil.sanityCheckSet;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
 import static org.junit.Assert.fail;
 
 import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import java.util.HashSet;
 import java.util.Set;
 import org.junit.After;
@@ -40,7 +40,7 @@
  * graph. The following test cases are left for the subclasses to handle:
  *
  * <ul>
- *   <li>Test cases related to whether the graph is directed or undirected.
+ *   <li>Test cases related to whether the graph is directed, undirected, mutable, or immutable.
  *   <li>Test cases related to the specific implementation of the {@link Graph} interface.
  * </ul>
  *
@@ -48,15 +48,7 @@
  * TODO(user): Differentiate between directed and undirected edge strings.
  */
 public abstract class AbstractGraphTest {
-
-  Graph<Integer> graph;
-
-  /**
-   * The same reference as {@link #graph}, except as a mutable graph. This field is null in case
-   * {@link #createGraph()} didn't return a mutable graph.
-   */
-  MutableGraph<Integer> graphAsMutableGraph;
-
+  MutableGraph<Integer> graph;
   static final Integer N1 = 1;
   static final Integer N2 = 2;
   static final Integer N3 = 3;
@@ -74,36 +66,57 @@
   static final String ERROR_ADDED_SELF_LOOP = "Should not be allowed to add a self-loop edge.";
 
   /** Creates and returns an instance of the graph to be tested. */
-  abstract Graph<Integer> createGraph();
+  public abstract MutableGraph<Integer> createGraph();
 
   /**
    * A proxy method that adds the node {@code n} to the graph being tested. In case of Immutable
-   * graph implementations, this method should replace {@link #graph} with a new graph that includes
-   * this node.
+   * graph implementations, this method should add {@code n} to the graph builder and build a new
+   * graph with the current builder state.
+   *
+   * @return {@code true} iff the graph was modified as a result of this call
    */
-  abstract void addNode(Integer n);
+  @CanIgnoreReturnValue
+  protected boolean addNode(Integer n) {
+    return graph.addNode(n);
+  }
 
   /**
    * A proxy method that adds the edge {@code e} to the graph being tested. In case of Immutable
-   * graph implementations, this method should replace {@link #graph} with a new graph that includes
-   * this edge.
+   * graph implementations, this method should add {@code e} to the graph builder and build a new
+   * graph with the current builder state.
+   *
+   * <p>This method should be used in tests of specific implementations if you want to ensure
+   * uniform behavior (including side effects) with how edges are added elsewhere in the tests. For
+   * example, the existing implementations of this method explicitly add the supplied nodes to the
+   * graph, and then call {@code graph.addEdge()} to connect the edge to the nodes; this is not part
+   * of the contract of {@code graph.addEdge()} and is done for convenience. In cases where you want
+   * to avoid such side effects (e.g., if you're testing what happens in your implementation if you
+   * add an edge whose end-points don't already exist in the graph), you should <b>not</b> use this
+   * method.
+   *
+   * @return {@code true} iff the graph was modified as a result of this call
    */
-  abstract void putEdge(Integer n1, Integer n2);
+  @CanIgnoreReturnValue
+  protected boolean putEdge(Integer n1, Integer n2) {
+    graph.addNode(n1);
+    graph.addNode(n2);
+    return graph.putEdge(n1, n2);
+  }
 
-  final boolean graphIsMutable() {
-    return graphAsMutableGraph != null;
+  @CanIgnoreReturnValue
+  protected boolean putEdge(EndpointPair<Integer> endpoints) {
+    graph.addNode(endpoints.nodeU());
+    graph.addNode(endpoints.nodeV());
+    return graph.putEdge(endpoints);
   }
 
   @Before
-  public final void init() {
+  public void init() {
     graph = createGraph();
-    if (graph instanceof MutableGraph) {
-      graphAsMutableGraph = (MutableGraph<Integer>) graph;
-    }
   }
 
   @After
-  public final void validateGraphState() {
+  public void validateGraphState() {
     validateGraph(graph);
   }
 
@@ -348,30 +361,24 @@
 
   @Test
   public void addNode_newNode() {
-    assume().that(graphIsMutable()).isTrue();
-
-    assertThat(graphAsMutableGraph.addNode(N1)).isTrue();
+    assertThat(addNode(N1)).isTrue();
     assertThat(graph.nodes()).contains(N1);
   }
 
   @Test
   public void addNode_existingNode() {
-    assume().that(graphIsMutable()).isTrue();
-
     addNode(N1);
     ImmutableSet<Integer> nodes = ImmutableSet.copyOf(graph.nodes());
-    assertThat(graphAsMutableGraph.addNode(N1)).isFalse();
+    assertThat(addNode(N1)).isFalse();
     assertThat(graph.nodes()).containsExactlyElementsIn(nodes);
   }
 
   @Test
   public void removeNode_existingNode() {
-    assume().that(graphIsMutable()).isTrue();
-
     putEdge(N1, N2);
     putEdge(N4, N1);
-    assertThat(graphAsMutableGraph.removeNode(N1)).isTrue();
-    assertThat(graphAsMutableGraph.removeNode(N1)).isFalse();
+    assertThat(graph.removeNode(N1)).isTrue();
+    assertThat(graph.removeNode(N1)).isFalse();
     assertThat(graph.nodes()).containsExactly(N2, N4);
     assertThat(graph.adjacentNodes(N2)).isEmpty();
     assertThat(graph.adjacentNodes(N4)).isEmpty();
@@ -379,38 +386,32 @@
 
   @Test
   public void removeNode_antiparallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-
     putEdge(N1, N2);
     putEdge(N2, N1);
 
-    assertThat(graphAsMutableGraph.removeNode(N1)).isTrue();
+    assertThat(graph.removeNode(N1)).isTrue();
     assertThat(graph.nodes()).containsExactly(N2);
     assertThat(graph.edges()).isEmpty();
 
-    assertThat(graphAsMutableGraph.removeNode(N2)).isTrue();
+    assertThat(graph.removeNode(N2)).isTrue();
     assertThat(graph.nodes()).isEmpty();
     assertThat(graph.edges()).isEmpty();
   }
 
   @Test
   public void removeNode_nodeNotPresent() {
-    assume().that(graphIsMutable()).isTrue();
-
     addNode(N1);
     ImmutableSet<Integer> nodes = ImmutableSet.copyOf(graph.nodes());
-    assertThat(graphAsMutableGraph.removeNode(NODE_NOT_IN_GRAPH)).isFalse();
+    assertThat(graph.removeNode(NODE_NOT_IN_GRAPH)).isFalse();
     assertThat(graph.nodes()).containsExactlyElementsIn(nodes);
   }
 
   @Test
   public void removeNode_queryAfterRemoval() {
-    assume().that(graphIsMutable()).isTrue();
-
     addNode(N1);
     @SuppressWarnings("unused")
     Set<Integer> unused = graph.adjacentNodes(N1); // ensure cache (if any) is populated
-    assertThat(graphAsMutableGraph.removeNode(N1)).isTrue();
+    assertThat(graph.removeNode(N1)).isTrue();
     try {
       graph.adjacentNodes(N1);
       fail(ERROR_NODE_NOT_IN_GRAPH);
@@ -421,45 +422,36 @@
 
   @Test
   public void removeEdge_existingEdge() {
-    assume().that(graphIsMutable()).isTrue();
-
     putEdge(N1, N2);
     assertThat(graph.successors(N1)).containsExactly(N2);
     assertThat(graph.predecessors(N2)).containsExactly(N1);
-    assertThat(graphAsMutableGraph.removeEdge(N1, N2)).isTrue();
-    assertThat(graphAsMutableGraph.removeEdge(N1, N2)).isFalse();
+    assertThat(graph.removeEdge(N1, N2)).isTrue();
+    assertThat(graph.removeEdge(N1, N2)).isFalse();
     assertThat(graph.successors(N1)).isEmpty();
     assertThat(graph.predecessors(N2)).isEmpty();
   }
 
   @Test
   public void removeEdge_oneOfMany() {
-    assume().that(graphIsMutable()).isTrue();
-
     putEdge(N1, N2);
     putEdge(N1, N3);
     putEdge(N1, N4);
-    assertThat(graphAsMutableGraph.removeEdge(N1, N3)).isTrue();
+    assertThat(graph.removeEdge(N1, N3)).isTrue();
     assertThat(graph.adjacentNodes(N1)).containsExactly(N2, N4);
   }
 
   @Test
   public void removeEdge_nodeNotPresent() {
-    assume().that(graphIsMutable()).isTrue();
-
     putEdge(N1, N2);
-    assertThat(graphAsMutableGraph.removeEdge(N1, NODE_NOT_IN_GRAPH)).isFalse();
+    assertThat(graph.removeEdge(N1, NODE_NOT_IN_GRAPH)).isFalse();
     assertThat(graph.successors(N1)).contains(N2);
   }
 
   @Test
   public void removeEdge_edgeNotPresent() {
-    assume().that(graphIsMutable()).isTrue();
-
     putEdge(N1, N2);
     addNode(N3);
-
-    assertThat(graphAsMutableGraph.removeEdge(N1, N3)).isFalse();
+    assertThat(graph.removeEdge(N1, N3)).isFalse();
     assertThat(graph.successors(N1)).contains(N2);
   }
 }
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractNetworkTest.java b/android/guava-tests/test/com/google/common/graph/AbstractNetworkTest.java
index e386252..9154a73 100644
--- a/android/guava-tests/test/com/google/common/graph/AbstractNetworkTest.java
+++ b/android/guava-tests/test/com/google/common/graph/AbstractNetworkTest.java
@@ -22,20 +22,14 @@
 import static com.google.common.graph.TestUtil.assertStronglyEquivalent;
 import static com.google.common.graph.TestUtil.sanityCheckSet;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
-import static java.util.concurrent.Executors.newFixedThreadPool;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -57,15 +51,7 @@
  * TODO(user): Differentiate between directed and undirected edge strings.
  */
 public abstract class AbstractNetworkTest {
-
-  Network<Integer, String> network;
-
-  /**
-   * The same reference as {@link #network}, except as a mutable network. This field is null in case
-   * {@link #createGraph()} didn't return a mutable network.
-   */
-  MutableNetwork<Integer, String> networkAsMutableNetwork;
-
+  MutableNetwork<Integer, String> network;
   static final Integer N1 = 1;
   static final Integer N2 = 2;
   static final Integer N3 = 3;
@@ -106,32 +92,54 @@
       "Reusing an existing edge to connect different nodes succeeded";
 
   /** Creates and returns an instance of the graph to be tested. */
-  abstract Network<Integer, String> createGraph();
+  public abstract MutableNetwork<Integer, String> createGraph();
 
   /**
    * A proxy method that adds the node {@code n} to the graph being tested. In case of Immutable
-   * graph implementations, this method should replace {@link #network} with a new graph that
-   * includes this node.
+   * graph implementations, this method should add {@code n} to the graph builder and build a new
+   * graph with the current builder state.
+   *
+   * @return {@code true} iff the graph was modified as a result of this call
    */
-  abstract void addNode(Integer n);
+  @CanIgnoreReturnValue
+  protected boolean addNode(Integer n) {
+    return network.addNode(n);
+  }
 
   /**
    * A proxy method that adds the edge {@code e} to the graph being tested. In case of Immutable
-   * graph implementations, this method should replace {@link #network} with a new graph that
-   * includes this edge.
+   * graph implementations, this method should add {@code e} to the graph builder and build a new
+   * graph with the current builder state.
+   *
+   * <p>This method should be used in tests of specific implementations if you want to ensure
+   * uniform behavior (including side effects) with how edges are added elsewhere in the tests. For
+   * example, the existing implementations of this method explicitly add the supplied nodes to the
+   * graph, and then call {@code graph.addEdge()} to connect the edge to the nodes; this is not part
+   * of the contract of {@code graph.addEdge()} and is done for convenience. In cases where you want
+   * to avoid such side effects (e.g., if you're testing what happens in your implementation if you
+   * add an edge whose end-points don't already exist in the graph), you should <b>not</b> use this
+   * method.
+   *
+   * <p>TODO(user): remove the addNode() calls, that's now contractually guaranteed
+   *
+   * @return {@code true} iff the graph was modified as a result of this call
    */
-  abstract void addEdge(Integer n1, Integer n2, String e);
+  @CanIgnoreReturnValue
+  protected boolean addEdge(Integer n1, Integer n2, String e) {
+    network.addNode(n1);
+    network.addNode(n2);
+    return network.addEdge(n1, n2, e);
+  }
 
-  final boolean graphIsMutable() {
-    return networkAsMutableNetwork != null;
+  protected boolean addEdge(EndpointPair<Integer> endpoints, String e) {
+    network.addNode(endpoints.nodeU());
+    network.addNode(endpoints.nodeV());
+    return network.addEdge(endpoints, e);
   }
 
   @Before
   public void init() {
     network = createGraph();
-    if (network instanceof MutableNetwork) {
-      networkAsMutableNetwork = (MutableNetwork<Integer, String>) network;
-    }
   }
 
   @After
@@ -489,18 +497,6 @@
   }
 
   @Test
-  public void adjacentEdges_parallelEdges() {
-    assume().that(network.allowsParallelEdges()).isTrue();
-
-    addEdge(N1, N2, E12);
-    addEdge(N1, N2, E12_A);
-    addEdge(N1, N2, E12_B);
-    addEdge(N3, N4, E34);
-
-    assertThat(network.adjacentEdges(E12)).containsExactly(E12_A, E12_B);
-  }
-
-  @Test
   public void edgesConnecting_disconnectedNodes() {
     addNode(N1);
     addNode(N2);
@@ -532,60 +528,6 @@
   }
 
   @Test
-  public void edgesConnecting_parallelEdges_directed() {
-    assume().that(network.allowsParallelEdges()).isTrue();
-    assume().that(network.isDirected()).isTrue();
-
-    addEdge(N1, N2, E12);
-    addEdge(N1, N2, E12_A);
-
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A);
-    // Passed nodes should be in the correct edge direction, first is the
-    // source node and the second is the target node
-    assertThat(network.edgesConnecting(N2, N1)).isEmpty();
-  }
-
-  @Test
-  public void edgesConnecting_parallelEdges_undirected() {
-    assume().that(network.allowsParallelEdges()).isTrue();
-    assume().that(network.isDirected()).isFalse();
-
-    addEdge(N1, N2, E12);
-    addEdge(N1, N2, E12_A);
-    addEdge(N2, N1, E21);
-
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A, E21);
-    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12, E12_A, E21);
-  }
-
-  @Test
-  public void edgesConnecting_parallelSelfLoopEdges() {
-    assume().that(network.allowsParallelEdges()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    addEdge(N1, N1, E11_A);
-
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
-  }
-
-  @Test
-  public void hasEdgeConnecting_disconnectedNodes() {
-    addNode(N1);
-    addNode(N2);
-    assertThat(network.hasEdgeConnecting(N1, N2)).isFalse();
-  }
-
-  @Test
-  public void hasEdgesConnecting_nodesNotInGraph() {
-    addNode(N1);
-    addNode(N2);
-    assertThat(network.hasEdgeConnecting(N1, NODE_NOT_IN_GRAPH)).isFalse();
-    assertThat(network.hasEdgeConnecting(NODE_NOT_IN_GRAPH, N2)).isFalse();
-    assertThat(network.hasEdgeConnecting(NODE_NOT_IN_GRAPH, NODE_NOT_IN_GRAPH)).isFalse();
-  }
-
-  @Test
   public void inEdges_noInEdges() {
     addNode(N1);
     assertThat(network.inEdges(N1)).isEmpty();
@@ -651,56 +593,45 @@
 
   @Test
   public void addNode_newNode() {
-    assume().that(graphIsMutable()).isTrue();
-
-    assertTrue(networkAsMutableNetwork.addNode(N1));
-    assertThat(networkAsMutableNetwork.nodes()).contains(N1);
+    assertTrue(addNode(N1));
+    assertThat(network.nodes()).contains(N1);
   }
 
   @Test
   public void addNode_existingNode() {
-    assume().that(graphIsMutable()).isTrue();
-
     addNode(N1);
-    ImmutableSet<Integer> nodes = ImmutableSet.copyOf(networkAsMutableNetwork.nodes());
-    assertFalse(networkAsMutableNetwork.addNode(N1));
-    assertThat(networkAsMutableNetwork.nodes()).containsExactlyElementsIn(nodes);
+    ImmutableSet<Integer> nodes = ImmutableSet.copyOf(network.nodes());
+    assertFalse(addNode(N1));
+    assertThat(network.nodes()).containsExactlyElementsIn(nodes);
   }
 
   @Test
   public void removeNode_existingNode() {
-    assume().that(graphIsMutable()).isTrue();
-
     addEdge(N1, N2, E12);
     addEdge(N4, N1, E41);
-    assertTrue(networkAsMutableNetwork.removeNode(N1));
-    assertFalse(networkAsMutableNetwork.removeNode(N1));
-    assertThat(networkAsMutableNetwork.nodes()).containsExactly(N2, N4);
-    assertThat(networkAsMutableNetwork.edges()).doesNotContain(E12);
-    assertThat(networkAsMutableNetwork.edges()).doesNotContain(E41);
+    assertTrue(network.removeNode(N1));
+    assertFalse(network.removeNode(N1));
+    assertThat(network.nodes()).containsExactly(N2, N4);
+    assertThat(network.edges()).doesNotContain(E12);
+    assertThat(network.edges()).doesNotContain(E41);
   }
 
   @Test
   public void removeNode_nodeNotPresent() {
-    assume().that(graphIsMutable()).isTrue();
-
     addNode(N1);
-    ImmutableSet<Integer> nodes = ImmutableSet.copyOf(networkAsMutableNetwork.nodes());
-    assertFalse(networkAsMutableNetwork.removeNode(NODE_NOT_IN_GRAPH));
-    assertThat(networkAsMutableNetwork.nodes()).containsExactlyElementsIn(nodes);
+    ImmutableSet<Integer> nodes = ImmutableSet.copyOf(network.nodes());
+    assertFalse(network.removeNode(NODE_NOT_IN_GRAPH));
+    assertThat(network.nodes()).containsExactlyElementsIn(nodes);
   }
 
   @Test
   public void removeNode_queryAfterRemoval() {
-    assume().that(graphIsMutable()).isTrue();
-
     addNode(N1);
     @SuppressWarnings("unused")
-    Set<Integer> unused =
-        networkAsMutableNetwork.adjacentNodes(N1); // ensure cache (if any) is populated
-    assertTrue(networkAsMutableNetwork.removeNode(N1));
+    Set<Integer> unused = network.adjacentNodes(N1); // ensure cache (if any) is populated
+    assertTrue(network.removeNode(N1));
     try {
-      networkAsMutableNetwork.adjacentNodes(N1);
+      network.adjacentNodes(N1);
       fail(ERROR_NODE_NOT_IN_GRAPH);
     } catch (IllegalArgumentException e) {
       assertNodeNotInGraphErrorMessage(e);
@@ -709,139 +640,42 @@
 
   @Test
   public void removeEdge_existingEdge() {
-    assume().that(graphIsMutable()).isTrue();
-
     addEdge(N1, N2, E12);
-    assertTrue(networkAsMutableNetwork.removeEdge(E12));
-    assertFalse(networkAsMutableNetwork.removeEdge(E12));
-    assertThat(networkAsMutableNetwork.edges()).doesNotContain(E12);
-    assertThat(networkAsMutableNetwork.edgesConnecting(N1, N2)).isEmpty();
+    assertTrue(network.removeEdge(E12));
+    assertFalse(network.removeEdge(E12));
+    assertThat(network.edges()).doesNotContain(E12);
+    assertThat(network.edgesConnecting(N1, N2)).isEmpty();
   }
 
   @Test
   public void removeEdge_oneOfMany() {
-    assume().that(graphIsMutable()).isTrue();
-
     addEdge(N1, N2, E12);
     addEdge(N1, N3, E13);
     addEdge(N1, N4, E14);
-    assertThat(networkAsMutableNetwork.edges()).containsExactly(E12, E13, E14);
-    assertTrue(networkAsMutableNetwork.removeEdge(E13));
-    assertThat(networkAsMutableNetwork.edges()).containsExactly(E12, E14);
+    assertThat(network.edges()).containsExactly(E12, E13, E14);
+    assertTrue(network.removeEdge(E13));
+    assertThat(network.edges()).containsExactly(E12, E14);
   }
 
   @Test
   public void removeEdge_edgeNotPresent() {
-    assume().that(graphIsMutable()).isTrue();
-
     addEdge(N1, N2, E12);
-    ImmutableSet<String> edges = ImmutableSet.copyOf(networkAsMutableNetwork.edges());
-    assertFalse(networkAsMutableNetwork.removeEdge(EDGE_NOT_IN_GRAPH));
-    assertThat(networkAsMutableNetwork.edges()).containsExactlyElementsIn(edges);
+    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
+    assertFalse(network.removeEdge(EDGE_NOT_IN_GRAPH));
+    assertThat(network.edges()).containsExactlyElementsIn(edges);
   }
 
   @Test
   public void removeEdge_queryAfterRemoval() {
-    assume().that(graphIsMutable()).isTrue();
-
     addEdge(N1, N2, E12);
     @SuppressWarnings("unused")
-    EndpointPair<Integer> unused =
-        networkAsMutableNetwork.incidentNodes(E12); // ensure cache (if any) is populated
-    assertTrue(networkAsMutableNetwork.removeEdge(E12));
+    EndpointPair<Integer> unused = network.incidentNodes(E12); // ensure cache (if any) is populated
+    assertTrue(network.removeEdge(E12));
     try {
-      networkAsMutableNetwork.incidentNodes(E12);
+      network.incidentNodes(E12);
       fail(ERROR_EDGE_NOT_IN_GRAPH);
     } catch (IllegalArgumentException e) {
       assertEdgeNotInGraphErrorMessage(e);
     }
   }
-
-  @Test
-  public void removeEdge_parallelEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsParallelEdges()).isTrue();
-
-    addEdge(N1, N2, E12);
-    addEdge(N1, N2, E12_A);
-    assertTrue(networkAsMutableNetwork.removeEdge(E12_A));
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-  }
-
-  @Test
-  public void removeEdge_parallelSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsParallelEdges()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    addEdge(N1, N1, E11_A);
-    addEdge(N1, N2, E12);
-    assertTrue(networkAsMutableNetwork.removeEdge(E11_A));
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    assertTrue(networkAsMutableNetwork.removeEdge(E11));
-    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-  }
-
-  @Test
-  public void concurrentIteration() throws Exception {
-    addEdge(1, 2, "foo");
-    addEdge(3, 4, "bar");
-    addEdge(5, 6, "baz");
-
-    int threadCount = 20;
-    ExecutorService executor = newFixedThreadPool(threadCount);
-    final CyclicBarrier barrier = new CyclicBarrier(threadCount);
-    ImmutableList.Builder<Future<?>> futures = ImmutableList.builder();
-    for (int i = 0; i < threadCount; i++) {
-      futures.add(
-          executor.submit(
-              new Callable<Object>() {
-                @Override
-                public Object call() throws Exception {
-                  barrier.await();
-                  Integer first = network.nodes().iterator().next();
-                  for (Integer node : network.nodes()) {
-                    Set<Integer> unused = network.successors(node);
-                  }
-                  /*
-                   * Also look up an earlier node so that, if the graph is using MapRetrievalCache,
-                   * we read one of the fields declared in that class.
-                   */
-                  Set<Integer> unused = network.successors(first);
-                  return null;
-                }
-              }));
-    }
-
-    /*
-     * It's unlikely that any operations would fail by throwing an exception, but let's check them
-     * just to be safe.
-     *
-     * The real purpose of this test is to produce a TSAN failure if MapIteratorCache is unsafe for
-     * reads from multiple threads -- unsafe, in fact, even in the absence of a concurrent write.
-     * The specific problem we had was unsafe reads of lastEntryReturnedBySomeIterator. (To fix the
-     * problem, we've since marked that field as volatile.)
-     *
-     * When MapIteratorCache is used from Immutable* classes, the TSAN failure doesn't indicate a
-     * real problem: The Entry objects are ImmutableMap entries, whose fields are all final and thus
-     * safe to read even when the Entry object is unsafely published. But with a mutable graph, the
-     * Entry object is likely to have a non-final value field, which is not safe to read when
-     * unsafely published. (The Entry object might even be newly created by each iterator.next()
-     * call, so we can't assume that writes to the Entry have been safely published by some other
-     * synchronization actions.)
-     *
-     * All that said: I haven't actually managed to make this particular test produce a TSAN error
-     * for the field accesses in MapIteratorCache. This teset *has* found other TSAN errors,
-     * including in MapRetrievalCache, so I'm not sure why this one is different. I did at least
-     * confirm that my change to MapIteratorCache fixes the TSAN error in the (larger) test it was
-     * originally reported in.
-     */
-    for (Future<?> future : futures.build()) {
-      future.get();
-    }
-    executor.shutdown();
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractStandardDirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/AbstractStandardDirectedGraphTest.java
deleted file mode 100644
index c50a7da..0000000
--- a/android/guava-tests/test/com/google/common/graph/AbstractStandardDirectedGraphTest.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Set;
-import org.junit.Test;
-
-/**
- * Abstract base class for testing directed {@link Graph} implementations defined in this package.
- */
-public abstract class AbstractStandardDirectedGraphTest extends AbstractGraphTest {
-
-  @Override
-  @Test
-  public void nodes_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    Set<Integer> nodes = graph.nodes();
-    try {
-      nodes.add(N2);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      addNode(N1);
-      assertThat(graph.nodes()).containsExactlyElementsIn(nodes);
-    }
-  }
-
-  @Override
-  @Test
-  public void adjacentNodes_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<Integer> adjacentNodes = graph.adjacentNodes(N1);
-    try {
-      adjacentNodes.add(N2);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(graph.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
-    }
-  }
-
-  @Override
-  @Test
-  public void predecessors_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N2);
-    Set<Integer> predecessors = graph.predecessors(N2);
-    try {
-      predecessors.add(N1);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(graph.predecessors(N2)).containsExactlyElementsIn(predecessors);
-    }
-  }
-
-  @Override
-  @Test
-  public void successors_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<Integer> successors = graph.successors(N1);
-    try {
-      successors.add(N2);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(successors).containsExactlyElementsIn(graph.successors(N1));
-    }
-  }
-
-  @Override
-  @Test
-  public void incidentEdges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<EndpointPair<Integer>> incidentEdges = graph.incidentEdges(N1);
-    try {
-      incidentEdges.add(EndpointPair.ordered(N1, N2));
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(incidentEdges).containsExactlyElementsIn(graph.incidentEdges(N1));
-    }
-  }
-
-  @Test
-  public void predecessors_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.predecessors(N2)).containsExactly(N1);
-    // Edge direction handled correctly
-    assertThat(graph.predecessors(N1)).isEmpty();
-  }
-
-  @Test
-  public void successors_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.successors(N1)).containsExactly(N2);
-    // Edge direction handled correctly
-    assertThat(graph.successors(N2)).isEmpty();
-  }
-
-  @Test
-  public void incidentEdges_oneEdge() {
-    putEdge(N1, N2);
-    EndpointPair<Integer> expectedEndpoints = EndpointPair.ordered(N1, N2);
-    assertThat(graph.incidentEdges(N1)).containsExactly(expectedEndpoints);
-    assertThat(graph.incidentEdges(N2)).containsExactly(expectedEndpoints);
-  }
-
-  @Test
-  public void inDegree_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.inDegree(N2)).isEqualTo(1);
-    // Edge direction handled correctly
-    assertThat(graph.inDegree(N1)).isEqualTo(0);
-  }
-
-  @Test
-  public void outDegree_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.outDegree(N1)).isEqualTo(1);
-    // Edge direction handled correctly
-    assertThat(graph.outDegree(N2)).isEqualTo(0);
-  }
-
-  @Test
-  public void hasEdgeConnecting_correct() {
-    putEdge(N1, N2);
-    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N1, N2))).isTrue();
-  }
-
-  @Test
-  public void hasEdgeConnecting_backwards() {
-    putEdge(N1, N2);
-    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N2, N1))).isFalse();
-  }
-
-  @Test
-  public void hasEdgeConnecting_mismatch() {
-    putEdge(N1, N2);
-    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N1, N2))).isFalse();
-    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N2, N1))).isFalse();
-  }
-
-  @Test
-  public void adjacentNodes_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    putEdge(N1, N2);
-    assertThat(graph.adjacentNodes(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void predecessors_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.predecessors(N1)).containsExactly(N1);
-    putEdge(N4, N1);
-    assertThat(graph.predecessors(N1)).containsExactly(N1, N4);
-  }
-
-  @Test
-  public void successors_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.successors(N1)).containsExactly(N1);
-    putEdge(N1, N2);
-    assertThat(graph.successors(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void incidentEdges_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.incidentEdges(N1)).containsExactly(EndpointPair.ordered(N1, N1));
-    putEdge(N1, N2);
-    assertThat(graph.incidentEdges(N1))
-        .containsExactly(EndpointPair.ordered(N1, N1), EndpointPair.ordered(N1, N2));
-  }
-
-  @Test
-  public void degree_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.degree(N1)).isEqualTo(2);
-    putEdge(N1, N2);
-    assertThat(graph.degree(N1)).isEqualTo(3);
-  }
-
-  @Test
-  public void inDegree_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.inDegree(N1)).isEqualTo(1);
-    putEdge(N4, N1);
-    assertThat(graph.inDegree(N1)).isEqualTo(2);
-  }
-
-  @Test
-  public void outDegree_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.outDegree(N1)).isEqualTo(1);
-    putEdge(N1, N2);
-    assertThat(graph.outDegree(N1)).isEqualTo(2);
-  }
-
-  // Stable order tests
-
-  // Note: Stable order means that the ordering doesn't change between iterations and versions.
-  // Ideally, the ordering in test should never be updated.
-  @Test
-  public void stableIncidentEdgeOrder_edges_returnsInStableOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateStarShapedGraph();
-
-    assertThat(graph.edges())
-        .containsExactly(
-            EndpointPair.ordered(2, 1),
-            EndpointPair.ordered(1, 4),
-            EndpointPair.ordered(1, 3),
-            EndpointPair.ordered(1, 2),
-            EndpointPair.ordered(3, 1),
-            EndpointPair.ordered(5, 1))
-        .inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_adjacentNodes_returnsInConnectingEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateStarShapedGraph();
-
-    assertThat(graph.adjacentNodes(1)).containsExactly(2, 4, 3, 5).inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_predecessors_returnsInConnectingEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateStarShapedGraph();
-
-    assertThat(graph.predecessors(1)).containsExactly(2, 5, 3).inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_successors_returnsInConnectingEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateStarShapedGraph();
-
-    assertThat(graph.successors(1)).containsExactly(4, 3, 2).inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_incidentEdges_returnsInEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateStarShapedGraph();
-
-    assertThat(graph.incidentEdges(1))
-        .containsExactly(
-            EndpointPair.ordered(2, 1),
-            EndpointPair.ordered(1, 4),
-            EndpointPair.ordered(1, 3),
-            EndpointPair.ordered(5, 1),
-            EndpointPair.ordered(1, 2),
-            EndpointPair.ordered(3, 1))
-        .inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_incidentEdges_withSelfLoop_returnsInEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(2, 1);
-    putEdge(1, 1);
-    putEdge(1, 3);
-    putEdge(1, 2);
-
-    assertThat(graph.incidentEdges(1))
-        .containsExactly(
-            EndpointPair.ordered(2, 1),
-            EndpointPair.ordered(1, 1),
-            EndpointPair.ordered(1, 3),
-            EndpointPair.ordered(1, 2))
-        .inOrder();
-  }
-
-  /**
-   * Populates the graph with nodes and edges in a star shape with node `1` in the middle.
-   *
-   * <p>Note that the edges are added in a shuffled order to properly test the effect of the
-   * insertion order.
-   */
-  private void populateStarShapedGraph() {
-    putEdge(2, 1);
-    putEdge(1, 4);
-    putEdge(1, 3);
-    putEdge(5, 1);
-    putEdge(1, 2);
-    putEdge(3, 1);
-  }
-
-  // Element Mutation
-
-  @Test
-  public void putEdge_existingNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    // Adding nodes initially for safety (insulating from possible future
-    // modifications to proxy methods)
-    addNode(N1);
-    addNode(N2);
-
-    assertThat(graphAsMutableGraph.putEdge(N1, N2)).isTrue();
-  }
-
-  @Test
-  public void putEdge_existingEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    assertThat(graphAsMutableGraph.putEdge(N1, N2)).isTrue();
-    assertThat(graphAsMutableGraph.putEdge(N1, N2)).isFalse();
-  }
-
-  @Test
-  public void putEdge_orderMismatch() {
-    assume().that(graphIsMutable()).isTrue();
-
-    EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
-    try {
-      graphAsMutableGraph.putEdge(endpoints);
-      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
-    }
-  }
-
-  /**
-   * Tests that the method {@code putEdge} will silently add the missing nodes to the graph, then
-   * add the edge connecting them. We are not using the proxy methods here as we want to test {@code
-   * putEdge} when the end-points are not elements of the graph.
-   */
-  @Test
-  public void putEdge_nodesNotInGraph() {
-    assume().that(graphIsMutable()).isTrue();
-
-    graphAsMutableGraph.addNode(N1);
-    assertTrue(graphAsMutableGraph.putEdge(N1, N5));
-    assertTrue(graphAsMutableGraph.putEdge(N4, N1));
-    assertTrue(graphAsMutableGraph.putEdge(N2, N3));
-    assertThat(graph.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder();
-    assertThat(graph.successors(N1)).containsExactly(N5);
-    assertThat(graph.successors(N2)).containsExactly(N3);
-    assertThat(graph.successors(N3)).isEmpty();
-    assertThat(graph.successors(N4)).containsExactly(N1);
-    assertThat(graph.successors(N5)).isEmpty();
-  }
-
-  @Test
-  public void putEdge_doesntAllowSelfLoops() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isFalse();
-
-    try {
-      graphAsMutableGraph.putEdge(N1, N1);
-      fail(ERROR_ADDED_SELF_LOOP);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
-    }
-  }
-
-  @Test
-  public void putEdge_allowsSelfLoops() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    assertThat(graphAsMutableGraph.putEdge(N1, N1)).isTrue();
-    assertThat(graph.successors(N1)).containsExactly(N1);
-    assertThat(graph.predecessors(N1)).containsExactly(N1);
-  }
-
-  @Test
-  public void putEdge_existingSelfLoopEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    graphAsMutableGraph.putEdge(N1, N1);
-    assertThat(graphAsMutableGraph.putEdge(N1, N1)).isFalse();
-  }
-
-  @Test
-  public void removeEdge_antiparallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-
-    putEdge(N1, N2);
-    putEdge(N2, N1);
-
-    assertThat(graphAsMutableGraph.removeEdge(N1, N2)).isTrue();
-    assertThat(graph.successors(N1)).isEmpty();
-    assertThat(graph.predecessors(N1)).containsExactly(N2);
-    assertThat(graph.edges()).hasSize(1);
-
-    assertThat(graphAsMutableGraph.removeEdge(N2, N1)).isTrue();
-    assertThat(graph.successors(N1)).isEmpty();
-    assertThat(graph.predecessors(N1)).isEmpty();
-    assertThat(graph.edges()).isEmpty();
-  }
-
-  @Test
-  public void removeEdge_orderMismatch() {
-    assume().that(graphIsMutable()).isTrue();
-
-    putEdge(N1, N2);
-    EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
-    try {
-      graphAsMutableGraph.removeEdge(endpoints);
-      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
-    }
-  }
-
-  @Test
-  public void removeNode_existingNodeWithSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    addNode(N1);
-    putEdge(N1, N1);
-    assertThat(graphAsMutableGraph.removeNode(N1)).isTrue();
-    assertThat(graph.nodes()).isEmpty();
-  }
-
-  @Test
-  public void removeEdge_existingSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graphAsMutableGraph.removeEdge(N1, N1)).isTrue();
-    assertThat(graph.nodes()).containsExactly(N1);
-    assertThat(graph.successors(N1)).isEmpty();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractStandardDirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/AbstractStandardDirectedNetworkTest.java
deleted file mode 100644
index 98bc2fd..0000000
--- a/android/guava-tests/test/com/google/common/graph/AbstractStandardDirectedNetworkTest.java
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
-import static com.google.common.graph.TestUtil.assertEdgeNotInGraphErrorMessage;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
-import java.util.Set;
-import org.junit.After;
-import org.junit.Test;
-
-/**
- * Abstract base class for testing directed {@link Network} implementations defined in this package.
- */
-public abstract class AbstractStandardDirectedNetworkTest extends AbstractNetworkTest {
-
-  @After
-  public void validateSourceAndTarget() {
-    for (Integer node : network.nodes()) {
-      for (String inEdge : network.inEdges(node)) {
-        EndpointPair<Integer> endpointPair = network.incidentNodes(inEdge);
-        assertThat(endpointPair.source()).isEqualTo(endpointPair.adjacentNode(node));
-        assertThat(endpointPair.target()).isEqualTo(node);
-      }
-
-      for (String outEdge : network.outEdges(node)) {
-        EndpointPair<Integer> endpointPair = network.incidentNodes(outEdge);
-        assertThat(endpointPair.source()).isEqualTo(node);
-        assertThat(endpointPair.target()).isEqualTo(endpointPair.adjacentNode(node));
-      }
-
-      for (Integer adjacentNode : network.adjacentNodes(node)) {
-        Set<String> edges = network.edgesConnecting(node, adjacentNode);
-        Set<String> antiParallelEdges = network.edgesConnecting(adjacentNode, node);
-        assertThat(node.equals(adjacentNode) || Collections.disjoint(edges, antiParallelEdges))
-            .isTrue();
-      }
-    }
-  }
-
-  @Override
-  @Test
-  public void nodes_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    Set<Integer> nodes = network.nodes();
-    try {
-      nodes.add(N2);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addNode(N1);
-      assertThat(network.nodes()).containsExactlyElementsIn(nodes);
-    }
-  }
-
-  @Override
-  @Test
-  public void edges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    Set<String> edges = network.edges();
-    try {
-      edges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.edges()).containsExactlyElementsIn(edges);
-    }
-  }
-
-  @Override
-  @Test
-  public void incidentEdges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<String> incidentEdges = network.incidentEdges(N1);
-    try {
-      incidentEdges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.incidentEdges(N1)).containsExactlyElementsIn(incidentEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void adjacentNodes_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<Integer> adjacentNodes = network.adjacentNodes(N1);
-    try {
-      adjacentNodes.add(N2);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
-    }
-  }
-
-  @Override
-  public void adjacentEdges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addEdge(N1, N2, E12);
-    Set<String> adjacentEdges = network.adjacentEdges(E12);
-    try {
-      adjacentEdges.add(E23);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N2, N3, E23);
-      assertThat(network.adjacentEdges(E12)).containsExactlyElementsIn(adjacentEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void edgesConnecting_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    addNode(N2);
-    Set<String> edgesConnecting = network.edgesConnecting(N1, N2);
-    try {
-      edgesConnecting.add(E23);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting);
-    }
-  }
-
-  @Override
-  @Test
-  public void inEdges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N2);
-    Set<String> inEdges = network.inEdges(N2);
-    try {
-      inEdges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.inEdges(N2)).containsExactlyElementsIn(inEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void outEdges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<String> outEdges = network.outEdges(N1);
-    try {
-      outEdges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.outEdges(N1)).containsExactlyElementsIn(outEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void predecessors_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N2);
-    Set<Integer> predecessors = network.predecessors(N2);
-    try {
-      predecessors.add(N1);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.predecessors(N2)).containsExactlyElementsIn(predecessors);
-    }
-  }
-
-  @Override
-  @Test
-  public void successors_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<Integer> successors = network.successors(N1);
-    try {
-      successors.add(N2);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(successors).containsExactlyElementsIn(network.successors(N1));
-    }
-  }
-
-  @Test
-  public void edges_containsOrderMismatch() {
-    addEdge(N1, N2, E12);
-    EndpointPair<Integer> endpointsN1N2 = EndpointPair.unordered(N1, N2);
-    EndpointPair<Integer> endpointsN2N1 = EndpointPair.unordered(N2, N1);
-    assertThat(network.asGraph().edges()).doesNotContain(endpointsN1N2);
-    assertThat(network.asGraph().edges()).doesNotContain(endpointsN2N1);
-  }
-
-  @Test
-  public void edgesConnecting_orderMismatch() {
-    addEdge(N1, N2, E12);
-    try {
-      Set<String> unused = network.edgesConnecting(EndpointPair.unordered(N1, N2));
-      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
-    }
-  }
-
-  @Test
-  public void edgeConnectingOrNull_orderMismatch() {
-    addEdge(N1, N2, E12);
-    try {
-      String unused = network.edgeConnectingOrNull(EndpointPair.unordered(N1, N2));
-      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
-    }
-  }
-
-  @Override
-  @Test
-  public void incidentNodes_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.incidentNodes(E12).source()).isEqualTo(N1);
-    assertThat(network.incidentNodes(E12).target()).isEqualTo(N2);
-  }
-
-  @Test
-  public void edgesConnecting_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    // Passed nodes should be in the correct edge direction, first is the
-    // source node and the second is the target node
-    assertThat(network.edgesConnecting(N2, N1)).isEmpty();
-  }
-
-  @Test
-  public void inEdges_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.inEdges(N2)).containsExactly(E12);
-    // Edge direction handled correctly
-    assertThat(network.inEdges(N1)).isEmpty();
-  }
-
-  @Test
-  public void outEdges_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.outEdges(N1)).containsExactly(E12);
-    // Edge direction handled correctly
-    assertThat(network.outEdges(N2)).isEmpty();
-  }
-
-  @Test
-  public void predecessors_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.predecessors(N2)).containsExactly(N1);
-    // Edge direction handled correctly
-    assertThat(network.predecessors(N1)).isEmpty();
-  }
-
-  @Test
-  public void successors_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.successors(N1)).containsExactly(N2);
-    // Edge direction handled correctly
-    assertThat(network.successors(N2)).isEmpty();
-  }
-
-  @Test
-  public void source_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.incidentNodes(E12).source()).isEqualTo(N1);
-  }
-
-  @Test
-  public void source_edgeNotInGraph() {
-    try {
-      network.incidentNodes(EDGE_NOT_IN_GRAPH).source();
-      fail(ERROR_EDGE_NOT_IN_GRAPH);
-    } catch (IllegalArgumentException e) {
-      assertEdgeNotInGraphErrorMessage(e);
-    }
-  }
-
-  @Test
-  public void target_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.incidentNodes(E12).target()).isEqualTo(N2);
-  }
-
-  @Test
-  public void target_edgeNotInGraph() {
-    try {
-      network.incidentNodes(EDGE_NOT_IN_GRAPH).target();
-      fail(ERROR_EDGE_NOT_IN_GRAPH);
-    } catch (IllegalArgumentException e) {
-      assertEdgeNotInGraphErrorMessage(e);
-    }
-  }
-
-  @Test
-  public void inDegree_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.inDegree(N2)).isEqualTo(1);
-    // Edge direction handled correctly
-    assertThat(network.inDegree(N1)).isEqualTo(0);
-  }
-
-  @Test
-  public void outDegree_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.outDegree(N1)).isEqualTo(1);
-    // Edge direction handled correctly
-    assertThat(network.outDegree(N2)).isEqualTo(0);
-  }
-
-  @Test
-  public void edges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.edges()).containsExactly(E11);
-  }
-
-  @Test
-  public void incidentEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.incidentEdges(N1)).containsExactly(E11);
-  }
-
-  @Test
-  public void incidentNodes_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.incidentNodes(E11).source()).isEqualTo(N1);
-    assertThat(network.incidentNodes(E11).target()).isEqualTo(N1);
-  }
-
-  @Test
-  public void adjacentNodes_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.adjacentNodes(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void adjacentEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.adjacentEdges(E11)).containsExactly(E12);
-  }
-
-  @Test
-  public void edgesConnecting_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-  }
-
-  @Test
-  public void inEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.inEdges(N1)).containsExactly(E11);
-    addEdge(N4, N1, E41);
-    assertThat(network.inEdges(N1)).containsExactly(E11, E41);
-  }
-
-  @Test
-  public void outEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.outEdges(N1)).containsExactly(E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.outEdges(N1)).containsExactly(E11, E12);
-  }
-
-  @Test
-  public void predecessors_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.predecessors(N1)).containsExactly(N1);
-    addEdge(N4, N1, E41);
-    assertThat(network.predecessors(N1)).containsExactly(N1, N4);
-  }
-
-  @Test
-  public void successors_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.successors(N1)).containsExactly(N1);
-    addEdge(N1, N2, E12);
-    assertThat(network.successors(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void source_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.incidentNodes(E11).source()).isEqualTo(N1);
-  }
-
-  @Test
-  public void target_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.incidentNodes(E11).target()).isEqualTo(N1);
-  }
-
-  @Test
-  public void degree_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.degree(N1)).isEqualTo(2);
-    addEdge(N1, N2, E12);
-    assertThat(network.degree(N1)).isEqualTo(3);
-  }
-
-  @Test
-  public void inDegree_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.inDegree(N1)).isEqualTo(1);
-    addEdge(N4, N1, E41);
-    assertThat(network.inDegree(N1)).isEqualTo(2);
-  }
-
-  @Test
-  public void outDegree_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.outDegree(N1)).isEqualTo(1);
-    addEdge(N1, N2, E12);
-    assertThat(network.outDegree(N1)).isEqualTo(2);
-  }
-
-  // Element Mutation
-
-  @Test
-  public void addEdge_existingNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    // Adding nodes initially for safety (insulating from possible future
-    // modifications to proxy methods)
-    addNode(N1);
-    addNode(N2);
-    assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isTrue();
-    assertThat(network.edges()).contains(E12);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    // Direction of the added edge is correctly handled
-    assertThat(network.edgesConnecting(N2, N1)).isEmpty();
-  }
-
-  @Test
-  public void addEdge_existingEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addEdge(N1, N2, E12);
-    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
-    assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isFalse();
-    assertThat(network.edges()).containsExactlyElementsIn(edges);
-  }
-
-  @Test
-  public void addEdge_existingEdgeBetweenDifferentNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addEdge(N1, N2, E12);
-    try {
-      // Edge between totally different nodes
-      networkAsMutableNetwork.addEdge(N4, N5, E12);
-      fail(ERROR_ADDED_EXISTING_EDGE);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
-    }
-    try {
-      // Edge between same nodes but in reverse direction
-      addEdge(N2, N1, E12);
-      fail(ERROR_ADDED_EXISTING_EDGE);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelEdge_notAllowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsParallelEdges()).isFalse();
-
-    addEdge(N1, N2, E12);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N2, EDGE_NOT_IN_GRAPH);
-      fail(ERROR_ADDED_PARALLEL_EDGE);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelEdge_allowsParallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsParallelEdges()).isTrue();
-
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N2, E12));
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N2, E12_A));
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A);
-  }
-
-  @Test
-  public void addEdge_orderMismatch() {
-    assume().that(graphIsMutable()).isTrue();
-
-    EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
-    try {
-      networkAsMutableNetwork.addEdge(endpoints, E12);
-      fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
-    }
-  }
-
-  @Test
-  public void addEdge_selfLoop_notAllowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isFalse();
-
-    try {
-      networkAsMutableNetwork.addEdge(N1, N1, E11);
-      fail(ERROR_ADDED_SELF_LOOP);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
-    }
-  }
-
-  /**
-   * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
-   * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
-   * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
-   * elements of the graph.
-   */
-  @Test
-  public void addEdge_nodesNotInGraph() {
-    assume().that(graphIsMutable()).isTrue();
-
-    networkAsMutableNetwork.addNode(N1);
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N5, E15));
-    assertTrue(networkAsMutableNetwork.addEdge(N4, N1, E41));
-    assertTrue(networkAsMutableNetwork.addEdge(N2, N3, E23));
-    assertThat(network.nodes()).containsExactly(N1, N5, N4, N2, N3);
-    assertThat(network.edges()).containsExactly(E15, E41, E23);
-    assertThat(network.edgesConnecting(N1, N5)).containsExactly(E15);
-    assertThat(network.edgesConnecting(N4, N1)).containsExactly(E41);
-    assertThat(network.edgesConnecting(N2, N3)).containsExactly(E23);
-    // Direction of the added edge is correctly handled
-    assertThat(network.edgesConnecting(N3, N2)).isEmpty();
-  }
-
-  @Test
-  public void addEdge_selfLoop_allowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    assertThat(networkAsMutableNetwork.addEdge(N1, N1, E11)).isTrue();
-    assertThat(network.edges()).contains(E11);
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-  }
-
-  @Test
-  public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
-    assertThat(networkAsMutableNetwork.addEdge(N1, N1, E11)).isFalse();
-    assertThat(network.edges()).containsExactlyElementsIn(edges);
-  }
-
-  @Test
-  public void addEdge_existingEdgeBetweenDifferentNodes_selfLoops() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N2, E11);
-      fail("Reusing an existing self-loop edge to connect different nodes succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-    try {
-      networkAsMutableNetwork.addEdge(N2, N2, E11);
-      fail("Reusing an existing self-loop edge to make a different self-loop edge succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-    addEdge(N1, N2, E12);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N1, E12);
-      fail("Reusing an existing edge to add a self-loop edge between different nodes succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelSelfLoopEdge_notAllowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-    assume().that(network.allowsParallelEdges()).isFalse();
-
-    addEdge(N1, N1, E11);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N1, EDGE_NOT_IN_GRAPH);
-      fail("Adding a parallel self-loop edge succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelSelfLoopEdge_allowsParallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-    assume().that(network.allowsParallelEdges()).isTrue();
-
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N1, E11));
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N1, E11_A));
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
-  }
-
-  @Test
-  public void removeNode_existingNodeWithSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addNode(N1);
-    addEdge(N1, N1, E11);
-    assertThat(networkAsMutableNetwork.removeNode(N1)).isTrue();
-    assertThat(network.nodes()).isEmpty();
-    assertThat(network.edges()).doesNotContain(E11);
-  }
-
-  @Test
-  public void removeEdge_existingSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(networkAsMutableNetwork.removeEdge(E11)).isTrue();
-    assertThat(network.edges()).doesNotContain(E11);
-    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractStandardUndirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/AbstractStandardUndirectedGraphTest.java
deleted file mode 100644
index a483f42..0000000
--- a/android/guava-tests/test/com/google/common/graph/AbstractStandardUndirectedGraphTest.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.testing.EqualsTester;
-import java.util.Set;
-import org.junit.After;
-import org.junit.Test;
-
-/**
- * Abstract base class for testing undirected {@link Graph} implementations defined in this package.
- */
-public abstract class AbstractStandardUndirectedGraphTest extends AbstractGraphTest {
-
-  @After
-  public void validateUndirectedEdges() {
-    for (Integer node : graph.nodes()) {
-      new EqualsTester()
-          .addEqualityGroup(
-              graph.predecessors(node), graph.successors(node), graph.adjacentNodes(node))
-          .testEquals();
-    }
-  }
-
-  @Override
-  @Test
-  public void nodes_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    Set<Integer> nodes = graph.nodes();
-    try {
-      nodes.add(N2);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      addNode(N1);
-      assertThat(graph.nodes()).containsExactlyElementsIn(nodes);
-    }
-  }
-
-  @Override
-  @Test
-  public void adjacentNodes_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<Integer> adjacentNodes = graph.adjacentNodes(N1);
-    try {
-      adjacentNodes.add(N2);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(graph.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
-    }
-  }
-
-  @Override
-  @Test
-  public void predecessors_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N2);
-    Set<Integer> predecessors = graph.predecessors(N2);
-    try {
-      predecessors.add(N1);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(graph.predecessors(N2)).containsExactlyElementsIn(predecessors);
-    }
-  }
-
-  @Override
-  @Test
-  public void successors_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<Integer> successors = graph.successors(N1);
-    try {
-      successors.add(N2);
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(graph.successors(N1)).containsExactlyElementsIn(successors);
-    }
-  }
-
-  @Override
-  @Test
-  public void incidentEdges_checkReturnedSetMutability() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addNode(N1);
-    Set<EndpointPair<Integer>> incidentEdges = graph.incidentEdges(N1);
-    try {
-      incidentEdges.add(EndpointPair.unordered(N1, N2));
-      fail(ERROR_MODIFIABLE_SET);
-    } catch (UnsupportedOperationException e) {
-      putEdge(N1, N2);
-      assertThat(incidentEdges).containsExactlyElementsIn(graph.incidentEdges(N1));
-    }
-  }
-
-  @Test
-  public void predecessors_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.predecessors(N2)).containsExactly(N1);
-    assertThat(graph.predecessors(N1)).containsExactly(N2);
-  }
-
-  @Test
-  public void successors_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.successors(N1)).containsExactly(N2);
-    assertThat(graph.successors(N2)).containsExactly(N1);
-  }
-
-  @Test
-  public void incidentEdges_oneEdge() {
-    putEdge(N1, N2);
-    EndpointPair<Integer> expectedEndpoints = EndpointPair.unordered(N1, N2);
-    assertThat(graph.incidentEdges(N1)).containsExactly(expectedEndpoints);
-    assertThat(graph.incidentEdges(N2)).containsExactly(expectedEndpoints);
-  }
-
-  @Test
-  public void inDegree_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.inDegree(N2)).isEqualTo(1);
-    assertThat(graph.inDegree(N1)).isEqualTo(1);
-  }
-
-  @Test
-  public void outDegree_oneEdge() {
-    putEdge(N1, N2);
-    assertThat(graph.outDegree(N1)).isEqualTo(1);
-    assertThat(graph.outDegree(N2)).isEqualTo(1);
-  }
-
-  @Test
-  public void hasEdgeConnecting_correct() {
-    putEdge(N1, N2);
-    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N1, N2))).isTrue();
-    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N2, N1))).isTrue();
-  }
-
-  @Test
-  public void hasEdgeConnecting_mismatch() {
-    putEdge(N1, N2);
-    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N1, N2))).isTrue();
-    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N2, N1))).isTrue();
-  }
-
-  @Test
-  public void adjacentNodes_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    putEdge(N1, N2);
-    assertThat(graph.adjacentNodes(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void predecessors_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.predecessors(N1)).containsExactly(N1);
-    putEdge(N1, N2);
-    assertThat(graph.predecessors(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void successors_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.successors(N1)).containsExactly(N1);
-    putEdge(N2, N1);
-    assertThat(graph.successors(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void incidentEdges_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.incidentEdges(N1)).containsExactly(EndpointPair.unordered(N1, N1));
-    putEdge(N1, N2);
-    assertThat(graph.incidentEdges(N1))
-        .containsExactly(EndpointPair.unordered(N1, N1), EndpointPair.unordered(N1, N2));
-  }
-
-  @Test
-  public void degree_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.degree(N1)).isEqualTo(2);
-    putEdge(N1, N2);
-    assertThat(graph.degree(N1)).isEqualTo(3);
-  }
-
-  @Test
-  public void inDegree_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.inDegree(N1)).isEqualTo(2);
-    putEdge(N1, N2);
-    assertThat(graph.inDegree(N1)).isEqualTo(3);
-  }
-
-  @Test
-  public void outDegree_selfLoop() {
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graph.outDegree(N1)).isEqualTo(2);
-    putEdge(N2, N1);
-    assertThat(graph.outDegree(N1)).isEqualTo(3);
-  }
-
-  // Stable order tests
-
-  // Note: Stable order means that the ordering doesn't change between iterations and versions.
-  // Ideally, the ordering in test should never be updated.
-  @Test
-  public void stableIncidentEdgeOrder_edges_returnsInStableOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateTShapedGraph();
-
-    assertThat(graph.edges())
-        .containsExactly(
-            EndpointPair.unordered(1, 2),
-            EndpointPair.unordered(1, 4),
-            EndpointPair.unordered(1, 3),
-            EndpointPair.unordered(4, 5))
-        .inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_adjacentNodes_returnsInConnectingEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateTShapedGraph();
-
-    assertThat(graph.adjacentNodes(1)).containsExactly(2, 4, 3).inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_predecessors_returnsInConnectingEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateTShapedGraph();
-
-    assertThat(graph.adjacentNodes(1)).containsExactly(2, 4, 3).inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_successors_returnsInConnectingEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateTShapedGraph();
-
-    assertThat(graph.adjacentNodes(1)).containsExactly(2, 4, 3).inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_incidentEdges_returnsInEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-
-    populateTShapedGraph();
-
-    assertThat(graph.incidentEdges(1))
-        .containsExactly(
-            EndpointPair.unordered(1, 2),
-            EndpointPair.unordered(1, 4),
-            EndpointPair.unordered(1, 3))
-        .inOrder();
-  }
-
-  @Test
-  public void stableIncidentEdgeOrder_incidentEdges_withSelfLoop_returnsInEdgeInsertionOrder() {
-    assume().that(graph.incidentEdgeOrder().type()).isEqualTo(ElementOrder.Type.STABLE);
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(2, 1);
-    putEdge(1, 1);
-    putEdge(1, 3);
-
-    assertThat(graph.incidentEdges(1))
-        .containsExactly(
-            EndpointPair.unordered(2, 1),
-            EndpointPair.unordered(1, 1),
-            EndpointPair.unordered(1, 3))
-        .inOrder();
-  }
-
-  /**
-   * Populates the graph with nodes and edges in a star shape with node `1` in the middle.
-   *
-   * <p>Note that the edges are added in a shuffled order to properly test the effect of the
-   * insertion order.
-   */
-  private void populateTShapedGraph() {
-    putEdge(2, 1);
-    putEdge(1, 4);
-    putEdge(1, 3);
-    putEdge(1, 2); // Duplicate
-    putEdge(4, 5);
-  }
-
-  // Element Mutation
-
-  @Test
-  public void putEdge_existingNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    // Adding nodes initially for safety (insulating from possible future
-    // modifications to proxy methods)
-    addNode(N1);
-    addNode(N2);
-
-    assertThat(graphAsMutableGraph.putEdge(N1, N2)).isTrue();
-  }
-
-  @Test
-  public void putEdge_existingEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    putEdge(N1, N2);
-
-    assertThat(graphAsMutableGraph.putEdge(N2, N1)).isFalse();
-  }
-
-  /**
-   * Tests that the method {@code putEdge} will silently add the missing nodes to the graph, then
-   * add the edge connecting them. We are not using the proxy methods here as we want to test {@code
-   * putEdge} when the end-points are not elements of the graph.
-   */
-  @Test
-  public void putEdge_nodesNotInGraph() {
-    assume().that(graphIsMutable()).isTrue();
-
-    graphAsMutableGraph.addNode(N1);
-    assertTrue(graphAsMutableGraph.putEdge(N1, N5));
-    assertTrue(graphAsMutableGraph.putEdge(N4, N1));
-    assertTrue(graphAsMutableGraph.putEdge(N2, N3));
-    assertThat(graph.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder();
-    assertThat(graph.adjacentNodes(N1)).containsExactly(N4, N5);
-    assertThat(graph.adjacentNodes(N2)).containsExactly(N3);
-    assertThat(graph.adjacentNodes(N3)).containsExactly(N2);
-    assertThat(graph.adjacentNodes(N4)).containsExactly(N1);
-    assertThat(graph.adjacentNodes(N5)).containsExactly(N1);
-  }
-
-  @Test
-  public void putEdge_doesntAllowSelfLoops() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isFalse();
-
-    try {
-      putEdge(N1, N1);
-      fail(ERROR_ADDED_SELF_LOOP);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
-    }
-  }
-
-  @Test
-  public void putEdge_allowsSelfLoops() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    assertThat(graphAsMutableGraph.putEdge(N1, N1)).isTrue();
-    assertThat(graph.adjacentNodes(N1)).containsExactly(N1);
-  }
-
-  @Test
-  public void putEdge_existingSelfLoopEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graphAsMutableGraph.putEdge(N1, N1)).isFalse();
-  }
-
-  @Test
-  public void removeEdge_antiparallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-
-    putEdge(N1, N2);
-    putEdge(N2, N1); // no-op
-
-    assertThat(graphAsMutableGraph.removeEdge(N1, N2)).isTrue();
-    assertThat(graph.adjacentNodes(N1)).isEmpty();
-    assertThat(graph.edges()).isEmpty();
-    assertThat(graphAsMutableGraph.removeEdge(N2, N1)).isFalse();
-  }
-
-  @Test
-  public void removeNode_existingNodeWithSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    addNode(N1);
-    putEdge(N1, N1);
-    assertThat(graphAsMutableGraph.removeNode(N1)).isTrue();
-    assertThat(graph.nodes()).isEmpty();
-  }
-
-  @Test
-  public void removeEdge_existingSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(graph.allowsSelfLoops()).isTrue();
-
-    putEdge(N1, N1);
-    assertThat(graphAsMutableGraph.removeEdge(N1, N1)).isTrue();
-    assertThat(graph.nodes()).containsExactly(N1);
-    assertThat(graph.adjacentNodes(N1)).isEmpty();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractStandardUndirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/AbstractStandardUndirectedNetworkTest.java
deleted file mode 100644
index 5cda1c1..0000000
--- a/android/guava-tests/test/com/google/common/graph/AbstractStandardUndirectedNetworkTest.java
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.TruthJUnit.assume;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.testing.EqualsTester;
-import java.util.Set;
-import org.junit.After;
-import org.junit.Test;
-
-/**
- * Abstract base class for testing undirected {@link Network} implementations defined in this
- * package.
- */
-public abstract class AbstractStandardUndirectedNetworkTest extends AbstractNetworkTest {
-  private static final EndpointPair<Integer> ENDPOINTS_N1N2 = EndpointPair.ordered(N1, N2);
-  private static final EndpointPair<Integer> ENDPOINTS_N2N1 = EndpointPair.ordered(N2, N1);
-
-  @After
-  public void validateUndirectedEdges() {
-    for (Integer node : network.nodes()) {
-      new EqualsTester()
-          .addEqualityGroup(
-              network.inEdges(node), network.outEdges(node), network.incidentEdges(node))
-          .testEquals();
-      new EqualsTester()
-          .addEqualityGroup(
-              network.predecessors(node), network.successors(node), network.adjacentNodes(node))
-          .testEquals();
-
-      for (Integer adjacentNode : network.adjacentNodes(node)) {
-        assertThat(network.edgesConnecting(node, adjacentNode))
-            .containsExactlyElementsIn(network.edgesConnecting(adjacentNode, node));
-      }
-    }
-  }
-
-  @Override
-  @Test
-  public void nodes_checkReturnedSetMutability() {
-    Set<Integer> nodes = network.nodes();
-    try {
-      nodes.add(N2);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addNode(N1);
-      assertThat(network.nodes()).containsExactlyElementsIn(nodes);
-    }
-  }
-
-  @Override
-  @Test
-  public void edges_checkReturnedSetMutability() {
-    Set<String> edges = network.edges();
-    try {
-      edges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.edges()).containsExactlyElementsIn(edges);
-    }
-  }
-
-  @Override
-  @Test
-  public void incidentEdges_checkReturnedSetMutability() {
-    addNode(N1);
-    Set<String> incidentEdges = network.incidentEdges(N1);
-    try {
-      incidentEdges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.incidentEdges(N1)).containsExactlyElementsIn(incidentEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void adjacentNodes_checkReturnedSetMutability() {
-    addNode(N1);
-    Set<Integer> adjacentNodes = network.adjacentNodes(N1);
-    try {
-      adjacentNodes.add(N2);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
-    }
-  }
-
-  @Override
-  public void adjacentEdges_checkReturnedSetMutability() {
-    addEdge(N1, N2, E12);
-    Set<String> adjacentEdges = network.adjacentEdges(E12);
-    try {
-      adjacentEdges.add(E23);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N2, N3, E23);
-      assertThat(network.adjacentEdges(E12)).containsExactlyElementsIn(adjacentEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void edgesConnecting_checkReturnedSetMutability() {
-    addNode(N1);
-    addNode(N2);
-    Set<String> edgesConnecting = network.edgesConnecting(N1, N2);
-    try {
-      edgesConnecting.add(E23);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting);
-    }
-  }
-
-  @Override
-  @Test
-  public void inEdges_checkReturnedSetMutability() {
-    addNode(N2);
-    Set<String> inEdges = network.inEdges(N2);
-    try {
-      inEdges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.inEdges(N2)).containsExactlyElementsIn(inEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void outEdges_checkReturnedSetMutability() {
-    addNode(N1);
-    Set<String> outEdges = network.outEdges(N1);
-    try {
-      outEdges.add(E12);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.outEdges(N1)).containsExactlyElementsIn(outEdges);
-    }
-  }
-
-  @Override
-  @Test
-  public void predecessors_checkReturnedSetMutability() {
-    addNode(N2);
-    Set<Integer> predecessors = network.predecessors(N2);
-    try {
-      predecessors.add(N1);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.predecessors(N2)).containsExactlyElementsIn(predecessors);
-    }
-  }
-
-  @Override
-  @Test
-  public void successors_checkReturnedSetMutability() {
-    addNode(N1);
-    Set<Integer> successors = network.successors(N1);
-    try {
-      successors.add(N2);
-      fail(ERROR_MODIFIABLE_COLLECTION);
-    } catch (UnsupportedOperationException e) {
-      addEdge(N1, N2, E12);
-      assertThat(network.successors(N1)).containsExactlyElementsIn(successors);
-    }
-  }
-
-  @Test
-  public void edges_containsOrderMismatch() {
-    addEdge(N1, N2, E12);
-    assertThat(network.asGraph().edges()).contains(ENDPOINTS_N2N1);
-    assertThat(network.asGraph().edges()).contains(ENDPOINTS_N1N2);
-  }
-
-  @Test
-  public void edgeConnectingOrNull_orderMismatch() {
-    addEdge(N1, N2, E12);
-    assertThat(network.edgeConnectingOrNull(ENDPOINTS_N2N1)).isEqualTo(E12);
-    assertThat(network.edgeConnectingOrNull(ENDPOINTS_N1N2)).isEqualTo(E12);
-  }
-
-  @Test
-  public void edgesConnecting_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
-  }
-
-  @Test
-  public void inEdges_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.inEdges(N2)).containsExactly(E12);
-    assertThat(network.inEdges(N1)).containsExactly(E12);
-  }
-
-  @Test
-  public void outEdges_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.outEdges(N2)).containsExactly(E12);
-    assertThat(network.outEdges(N1)).containsExactly(E12);
-  }
-
-  @Test
-  public void predecessors_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.predecessors(N2)).containsExactly(N1);
-    assertThat(network.predecessors(N1)).containsExactly(N2);
-  }
-
-  @Test
-  public void successors_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.successors(N1)).containsExactly(N2);
-    assertThat(network.successors(N2)).containsExactly(N1);
-  }
-
-  @Test
-  public void inDegree_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.inDegree(N2)).isEqualTo(1);
-    assertThat(network.inDegree(N1)).isEqualTo(1);
-  }
-
-  @Test
-  public void outDegree_oneEdge() {
-    addEdge(N1, N2, E12);
-    assertThat(network.outDegree(N1)).isEqualTo(1);
-    assertThat(network.outDegree(N2)).isEqualTo(1);
-  }
-
-  @Test
-  public void edges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.edges()).containsExactly(E11);
-  }
-
-  @Test
-  public void incidentEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.incidentEdges(N1)).containsExactly(E11);
-  }
-
-  @Test
-  public void incidentNodes_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.incidentNodes(E11).nodeU()).isEqualTo(N1);
-    assertThat(network.incidentNodes(E11).nodeV()).isEqualTo(N1);
-  }
-
-  @Test
-  public void adjacentNodes_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.adjacentNodes(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void adjacentEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.adjacentEdges(E11)).containsExactly(E12);
-  }
-
-  @Test
-  public void edgesConnecting_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-  }
-
-  @Test
-  public void inEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.inEdges(N1)).containsExactly(E11);
-    addEdge(N1, N2, E12);
-    assertThat(network.inEdges(N1)).containsExactly(E11, E12);
-  }
-
-  @Test
-  public void outEdges_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.outEdges(N1)).containsExactly(E11);
-    addEdge(N2, N1, E12);
-    assertThat(network.outEdges(N1)).containsExactly(E11, E12);
-  }
-
-  @Test
-  public void predecessors_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.predecessors(N1)).containsExactly(N1);
-    addEdge(N1, N2, E12);
-    assertThat(network.predecessors(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void successors_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.successors(N1)).containsExactly(N1);
-    addEdge(N2, N1, E12);
-    assertThat(network.successors(N1)).containsExactly(N1, N2);
-  }
-
-  @Test
-  public void degree_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.degree(N1)).isEqualTo(2);
-    addEdge(N1, N2, E12);
-    assertThat(network.degree(N1)).isEqualTo(3);
-  }
-
-  @Test
-  public void inDegree_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.inDegree(N1)).isEqualTo(2);
-    addEdge(N1, N2, E12);
-    assertThat(network.inDegree(N1)).isEqualTo(3);
-  }
-
-  @Test
-  public void outDegree_selfLoop() {
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(network.outDegree(N1)).isEqualTo(2);
-    addEdge(N2, N1, E12);
-    assertThat(network.outDegree(N1)).isEqualTo(3);
-  }
-
-  // Element Mutation
-
-  @Test
-  public void addEdge_existingNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    // Adding nodes initially for safety (insulating from possible future
-    // modifications to proxy methods)
-    addNode(N1);
-    addNode(N2);
-    assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isTrue();
-    assertThat(network.edges()).contains(E12);
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
-    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
-  }
-
-  @Test
-  public void addEdge_existingEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isTrue();
-    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
-    assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isFalse();
-    assertThat(network.edges()).containsExactlyElementsIn(edges);
-    assertThat(networkAsMutableNetwork.addEdge(N2, N1, E12)).isFalse();
-    assertThat(network.edges()).containsExactlyElementsIn(edges);
-  }
-
-  @Test
-  public void addEdge_existingEdgeBetweenDifferentNodes() {
-    assume().that(graphIsMutable()).isTrue();
-
-    addEdge(N1, N2, E12);
-    try {
-      // Edge between totally different nodes
-      networkAsMutableNetwork.addEdge(N4, N5, E12);
-      fail(ERROR_ADDED_EXISTING_EDGE);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelEdge_notAllowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsParallelEdges()).isFalse();
-
-    addEdge(N1, N2, E12);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N2, EDGE_NOT_IN_GRAPH);
-      fail(ERROR_ADDED_PARALLEL_EDGE);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
-    }
-    try {
-      networkAsMutableNetwork.addEdge(N2, N1, EDGE_NOT_IN_GRAPH);
-      fail(ERROR_ADDED_PARALLEL_EDGE);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelEdge_allowsParallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsParallelEdges()).isTrue();
-
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N2, E12));
-    assertTrue(networkAsMutableNetwork.addEdge(N2, N1, E21));
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N2, E12_A));
-    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A, E21);
-  }
-
-  @Test
-  public void addEdge_orderMismatch() {
-    assume().that(graphIsMutable()).isTrue();
-
-    EndpointPair<Integer> endpoints = EndpointPair.ordered(N1, N2);
-    assertThat(networkAsMutableNetwork.addEdge(endpoints, E12)).isTrue();
-  }
-
-  @Test
-  public void addEdge_selfLoop_notAllowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isFalse();
-
-    try {
-      networkAsMutableNetwork.addEdge(N1, N1, E11);
-      fail(ERROR_ADDED_SELF_LOOP);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
-    }
-  }
-
-  /**
-   * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
-   * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
-   * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
-   * elements of the graph.
-   */
-  @Test
-  public void addEdge_nodesNotInGraph() {
-    assume().that(graphIsMutable()).isTrue();
-
-    networkAsMutableNetwork.addNode(N1);
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N5, E15));
-    assertTrue(networkAsMutableNetwork.addEdge(N4, N1, E41));
-    assertTrue(networkAsMutableNetwork.addEdge(N2, N3, E23));
-    assertThat(network.nodes()).containsExactly(N1, N5, N4, N2, N3);
-    assertThat(network.edges()).containsExactly(E15, E41, E23);
-    assertThat(network.edgesConnecting(N1, N5)).containsExactly(E15);
-    assertThat(network.edgesConnecting(N4, N1)).containsExactly(E41);
-    assertThat(network.edgesConnecting(N2, N3)).containsExactly(E23);
-    assertThat(network.edgesConnecting(N3, N2)).containsExactly(E23);
-  }
-
-  @Test
-  public void addEdge_selfLoop() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    assertThat(networkAsMutableNetwork.addEdge(N1, N1, E11)).isTrue();
-    assertThat(network.edges()).contains(E11);
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
-  }
-
-  @Test
-  public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
-    assertThat(networkAsMutableNetwork.addEdge(N1, N1, E11)).isFalse();
-    assertThat(network.edges()).containsExactlyElementsIn(edges);
-  }
-
-  @Test
-  public void addEdge_existingEdgeBetweenDifferentNodes_selfLoops() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N2, E11);
-      fail("Reusing an existing self-loop edge to connect different nodes succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-    try {
-      networkAsMutableNetwork.addEdge(N2, N2, E11);
-      fail("Reusing an existing self-loop edge to make a different self-loop edge succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-    addEdge(N1, N2, E12);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N1, E12);
-      fail("Reusing an existing edge to add a self-loop edge between different nodes succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelSelfLoopEdge_notAllowed() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-    assume().that(network.allowsParallelEdges()).isFalse();
-
-    addEdge(N1, N1, E11);
-    try {
-      networkAsMutableNetwork.addEdge(N1, N1, EDGE_NOT_IN_GRAPH);
-      fail("Adding a parallel self-loop edge succeeded");
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
-    }
-  }
-
-  @Test
-  public void addEdge_parallelSelfLoopEdge_allowsParallelEdges() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-    assume().that(network.allowsParallelEdges()).isTrue();
-
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N1, E11));
-    assertTrue(networkAsMutableNetwork.addEdge(N1, N1, E11_A));
-    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
-  }
-
-  @Test
-  public void removeNode_existingNodeWithSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addNode(N1);
-    addEdge(N1, N1, E11);
-    assertThat(networkAsMutableNetwork.removeNode(N1)).isTrue();
-    assertThat(network.nodes()).isEmpty();
-    assertThat(network.edges()).doesNotContain(E11);
-  }
-
-  @Test
-  public void removeEdge_existingSelfLoopEdge() {
-    assume().that(graphIsMutable()).isTrue();
-    assume().that(network.allowsSelfLoops()).isTrue();
-
-    addEdge(N1, N1, E11);
-    assertThat(networkAsMutableNetwork.removeEdge(E11)).isTrue();
-    assertThat(network.edges()).doesNotContain(E11);
-    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractUndirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/AbstractUndirectedGraphTest.java
new file mode 100644
index 0000000..4996a6a
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/AbstractUndirectedGraphTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Abstract base class for testing undirected implementations of the {@link Graph} interface.
+ *
+ * <p>This class is responsible for testing that an undirected implementation of {@link Graph} is
+ * correctly handling undirected edges. Implementation-dependent test cases are left to subclasses.
+ * Test cases that do not require the graph to be undirected are found in superclasses.
+ */
+public abstract class AbstractUndirectedGraphTest extends AbstractGraphTest {
+
+  @After
+  public void validateUndirectedEdges() {
+    for (Integer node : graph.nodes()) {
+      new EqualsTester()
+          .addEqualityGroup(
+              graph.predecessors(node), graph.successors(node), graph.adjacentNodes(node))
+          .testEquals();
+    }
+  }
+
+  @Test
+  public void predecessors_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.predecessors(N2)).containsExactly(N1);
+    assertThat(graph.predecessors(N1)).containsExactly(N2);
+  }
+
+  @Test
+  public void successors_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.successors(N1)).containsExactly(N2);
+    assertThat(graph.successors(N2)).containsExactly(N1);
+  }
+
+  @Test
+  public void incidentEdges_oneEdge() {
+    putEdge(N1, N2);
+    EndpointPair<Integer> expectedEndpoints = EndpointPair.unordered(N1, N2);
+    assertThat(graph.incidentEdges(N1)).containsExactly(expectedEndpoints);
+    assertThat(graph.incidentEdges(N2)).containsExactly(expectedEndpoints);
+  }
+
+  @Test
+  public void inDegree_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.inDegree(N2)).isEqualTo(1);
+    assertThat(graph.inDegree(N1)).isEqualTo(1);
+  }
+
+  @Test
+  public void outDegree_oneEdge() {
+    putEdge(N1, N2);
+    assertThat(graph.outDegree(N1)).isEqualTo(1);
+    assertThat(graph.outDegree(N2)).isEqualTo(1);
+  }
+
+  @Test
+  public void hasEdgeConnecting_correct() {
+    putEdge(N1, N2);
+    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N1, N2))).isTrue();
+    assertThat(graph.hasEdgeConnecting(EndpointPair.unordered(N2, N1))).isTrue();
+  }
+
+  @Test
+  public void hasEdgeConnecting_mismatch() {
+    putEdge(N1, N2);
+    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N1, N2))).isTrue();
+    assertThat(graph.hasEdgeConnecting(EndpointPair.ordered(N2, N1))).isTrue();
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_existingNodes() {
+    // Adding nodes initially for safety (insulating from possible future
+    // modifications to proxy methods)
+    addNode(N1);
+    addNode(N2);
+    assertThat(putEdge(N1, N2)).isTrue();
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenSameNodes() {
+    putEdge(N1, N2);
+    assertThat(putEdge(N2, N1)).isFalse();
+  }
+
+  @Test
+  public void removeEdge_antiparallelEdges() {
+    putEdge(N1, N2);
+    putEdge(N2, N1); // no-op
+
+    assertThat(graph.removeEdge(N1, N2)).isTrue();
+    assertThat(graph.adjacentNodes(N1)).isEmpty();
+    assertThat(graph.edges()).isEmpty();
+    assertThat(graph.removeEdge(N2, N1)).isFalse();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/AbstractUndirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/AbstractUndirectedNetworkTest.java
new file mode 100644
index 0000000..630ec02
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/AbstractUndirectedNetworkTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Abstract base class for testing undirected implementations of the {@link Network} interface.
+ *
+ * <p>This class is responsible for testing that an undirected implementation of {@link Network} is
+ * correctly handling undirected edges. Implementation-dependent test cases are left to subclasses.
+ * Test cases that do not require the graph to be undirected are found in superclasses.
+ */
+public abstract class AbstractUndirectedNetworkTest extends AbstractNetworkTest {
+  private static final EndpointPair<Integer> ENDPOINTS_N1N2 = EndpointPair.ordered(N1, N2);
+  private static final EndpointPair<Integer> ENDPOINTS_N2N1 = EndpointPair.ordered(N2, N1);
+
+  @After
+  public void validateUndirectedEdges() {
+    for (Integer node : network.nodes()) {
+      new EqualsTester()
+          .addEqualityGroup(
+              network.inEdges(node), network.outEdges(node), network.incidentEdges(node))
+          .testEquals();
+      new EqualsTester()
+          .addEqualityGroup(
+              network.predecessors(node), network.successors(node), network.adjacentNodes(node))
+          .testEquals();
+
+      for (Integer adjacentNode : network.adjacentNodes(node)) {
+        assertThat(network.edgesConnecting(node, adjacentNode))
+            .containsExactlyElementsIn(network.edgesConnecting(adjacentNode, node));
+      }
+    }
+  }
+
+  @Test
+  public void edges_containsOrderMismatch() {
+    addEdge(N1, N2, E12);
+    assertThat(network.asGraph().edges()).contains(ENDPOINTS_N2N1);
+    assertThat(network.asGraph().edges()).contains(ENDPOINTS_N1N2);
+  }
+
+  @Test
+  public void edgesConnecting_orderMismatch() {
+    addEdge(N1, N2, E12);
+    assertThat(network.edgesConnecting(ENDPOINTS_N2N1)).containsExactly(E12);
+    assertThat(network.edgesConnecting(ENDPOINTS_N1N2)).containsExactly(E12);
+  }
+
+  @Test
+  public void edgeConnectingOrNull_orderMismatch() {
+    addEdge(N1, N2, E12);
+    assertThat(network.edgeConnectingOrNull(ENDPOINTS_N2N1)).isEqualTo(E12);
+    assertThat(network.edgeConnectingOrNull(ENDPOINTS_N1N2)).isEqualTo(E12);
+  }
+
+  @Test
+  public void edgesConnecting_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
+  }
+
+  @Test
+  public void inEdges_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.inEdges(N2)).containsExactly(E12);
+    assertThat(network.inEdges(N1)).containsExactly(E12);
+  }
+
+  @Test
+  public void outEdges_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.outEdges(N2)).containsExactly(E12);
+    assertThat(network.outEdges(N1)).containsExactly(E12);
+  }
+
+  @Test
+  public void predecessors_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.predecessors(N2)).containsExactly(N1);
+    assertThat(network.predecessors(N1)).containsExactly(N2);
+  }
+
+  @Test
+  public void successors_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.successors(N1)).containsExactly(N2);
+    assertThat(network.successors(N2)).containsExactly(N1);
+  }
+
+  @Test
+  public void inDegree_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.inDegree(N2)).isEqualTo(1);
+    assertThat(network.inDegree(N1)).isEqualTo(1);
+  }
+
+  @Test
+  public void outDegree_oneEdge() {
+    addEdge(N1, N2, E12);
+    assertThat(network.outDegree(N1)).isEqualTo(1);
+    assertThat(network.outDegree(N2)).isEqualTo(1);
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_existingNodes() {
+    // Adding nodes initially for safety (insulating from possible future
+    // modifications to proxy methods)
+    addNode(N1);
+    addNode(N2);
+    assertThat(addEdge(N1, N2, E12)).isTrue();
+    assertThat(network.edges()).contains(E12);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenSameNodes() {
+    assertThat(addEdge(N1, N2, E12)).isTrue();
+    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
+    assertThat(addEdge(N1, N2, E12)).isFalse();
+    assertThat(network.edges()).containsExactlyElementsIn(edges);
+    assertThat(addEdge(N2, N1, E12)).isFalse();
+    assertThat(network.edges()).containsExactlyElementsIn(edges);
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenDifferentNodes() {
+    addEdge(N1, N2, E12);
+    try {
+      // Edge between totally different nodes
+      addEdge(N4, N5, E12);
+      fail(ERROR_ADDED_EXISTING_EDGE);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+  }
+
+  @Test
+  public void addEdge_parallelEdge() {
+    addEdge(N1, N2, E12);
+    try {
+      addEdge(N1, N2, EDGE_NOT_IN_GRAPH);
+      fail(ERROR_ADDED_PARALLEL_EDGE);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
+    }
+    try {
+      addEdge(N2, N1, EDGE_NOT_IN_GRAPH);
+      fail(ERROR_ADDED_PARALLEL_EDGE);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
+    }
+  }
+
+  @Test
+  public void addEdge_orderMismatch() {
+    EndpointPair<Integer> endpoints = EndpointPair.ordered(N1, N2);
+    assertThat(addEdge(endpoints, E12)).isTrue();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedGraphTest.java
new file mode 100644
index 0000000..ed998eb
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedGraphTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for a directed {@link ConfigurableMutableGraph} allowing self-loops. */
+@RunWith(JUnit4.class)
+public class ConfigurableDirectedGraphTest extends ConfigurableSimpleDirectedGraphTest {
+
+  @Override
+  public MutableGraph<Integer> createGraph() {
+    return GraphBuilder.directed().allowsSelfLoops(true).build();
+  }
+
+  @Test
+  public void adjacentNodes_selfLoop() {
+    putEdge(N1, N1);
+    putEdge(N1, N2);
+    assertThat(graph.adjacentNodes(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void predecessors_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.predecessors(N1)).containsExactly(N1);
+    putEdge(N4, N1);
+    assertThat(graph.predecessors(N1)).containsExactly(N1, N4);
+  }
+
+  @Test
+  public void successors_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.successors(N1)).containsExactly(N1);
+    putEdge(N1, N2);
+    assertThat(graph.successors(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void incidentEdges_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.incidentEdges(N1)).containsExactly(EndpointPair.ordered(N1, N1));
+    putEdge(N1, N2);
+    assertThat(graph.incidentEdges(N1))
+        .containsExactly(EndpointPair.ordered(N1, N1), EndpointPair.ordered(N1, N2));
+  }
+
+  @Test
+  public void degree_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.degree(N1)).isEqualTo(2);
+    putEdge(N1, N2);
+    assertThat(graph.degree(N1)).isEqualTo(3);
+  }
+
+  @Test
+  public void inDegree_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.inDegree(N1)).isEqualTo(1);
+    putEdge(N4, N1);
+    assertThat(graph.inDegree(N1)).isEqualTo(2);
+  }
+
+  @Test
+  public void outDegree_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.outDegree(N1)).isEqualTo(1);
+    putEdge(N1, N2);
+    assertThat(graph.outDegree(N1)).isEqualTo(2);
+  }
+
+  @Override
+  @Test
+  public void addEdge_selfLoop() {
+    assertThat(putEdge(N1, N1)).isTrue();
+    assertThat(graph.successors(N1)).containsExactly(N1);
+    assertThat(graph.predecessors(N1)).containsExactly(N1);
+  }
+
+  @Test
+  public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
+    putEdge(N1, N1);
+    assertThat(putEdge(N1, N1)).isFalse();
+  }
+
+  @Test
+  public void removeNode_existingNodeWithSelfLoopEdge() {
+    addNode(N1);
+    putEdge(N1, N1);
+    assertThat(graph.removeNode(N1)).isTrue();
+    assertThat(graph.nodes()).isEmpty();
+  }
+
+  @Test
+  public void removeEdge_existingSelfLoopEdge() {
+    putEdge(N1, N1);
+    assertThat(graph.removeEdge(N1, N1)).isTrue();
+    assertThat(graph.nodes()).containsExactly(N1);
+    assertThat(graph.successors(N1)).isEmpty();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedMultiNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedMultiNetworkTest.java
new file mode 100644
index 0000000..3a49e2d
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedMultiNetworkTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for a directed {@link ConfigurableMutableNetwork} allowing parallel edges and self-loops.
+ */
+@RunWith(JUnit4.class)
+public class ConfigurableDirectedMultiNetworkTest extends ConfigurableDirectedNetworkTest {
+  @Override
+  public MutableNetwork<Integer, String> createGraph() {
+    return NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build();
+  }
+
+  @Test
+  public void adjacentEdges_parallelEdges() {
+    addEdge(N1, N2, E12);
+    addEdge(N1, N2, E12_A);
+    addEdge(N1, N2, E12_B);
+    addEdge(N3, N4, E34);
+    assertThat(network.adjacentEdges(E12)).containsExactly(E12_A, E12_B);
+  }
+
+  @Test
+  public void edgesConnecting_parallelEdges() {
+    assertTrue(addEdge(N1, N2, E12));
+    assertTrue(addEdge(N1, N2, E12_A));
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A);
+    // Passed nodes should be in the correct edge direction, first is the
+    // source node and the second is the target node
+    assertThat(network.edgesConnecting(N2, N1)).isEmpty();
+  }
+
+  @Test
+  public void edgesConnecting_parallelSelfLoopEdges() {
+    assertTrue(addEdge(N1, N1, E11));
+    assertTrue(addEdge(N1, N1, E11_A));
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
+  }
+
+  @Override
+  @Test
+  public void addEdge_parallelEdge() {
+    assertTrue(addEdge(N1, N2, E12));
+    assertTrue(addEdge(N1, N2, E12_A));
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A);
+  }
+
+  @Override
+  @Test
+  public void addEdge_parallelSelfLoopEdge() {
+    assertTrue(addEdge(N1, N1, E11));
+    assertTrue(addEdge(N1, N1, E11_A));
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
+  }
+
+  @Test
+  public void removeEdge_parallelEdge() {
+    addEdge(N1, N2, E12);
+    addEdge(N1, N2, E12_A);
+    assertTrue(network.removeEdge(E12_A));
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+  }
+
+  @Test
+  public void removeEdge_parallelSelfLoopEdge() {
+    addEdge(N1, N1, E11);
+    addEdge(N1, N1, E11_A);
+    addEdge(N1, N2, E12);
+    assertTrue(network.removeEdge(E11_A));
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    assertTrue(network.removeEdge(E11));
+    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedNetworkTest.java
new file mode 100644
index 0000000..671b1e8
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableDirectedNetworkTest.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for a directed {@link ConfigurableMutableNetwork} allowing self-loops. */
+@RunWith(JUnit4.class)
+public class ConfigurableDirectedNetworkTest extends ConfigurableSimpleDirectedNetworkTest {
+
+  @Override
+  public MutableNetwork<Integer, String> createGraph() {
+    return NetworkBuilder.directed().allowsSelfLoops(true).build();
+  }
+
+  @Test
+  public void edges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.edges()).containsExactly(E11);
+  }
+
+  @Test
+  public void incidentEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.incidentEdges(N1)).containsExactly(E11);
+  }
+
+  @Test
+  public void incidentNodes_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.incidentNodes(E11).source()).isEqualTo(N1);
+    assertThat(network.incidentNodes(E11).target()).isEqualTo(N1);
+  }
+
+  @Test
+  public void adjacentNodes_selfLoop() {
+    addEdge(N1, N1, E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.adjacentNodes(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void adjacentEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.adjacentEdges(E11)).containsExactly(E12);
+  }
+
+  @Test
+  public void edgesConnecting_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+  }
+
+  @Test
+  public void inEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.inEdges(N1)).containsExactly(E11);
+    addEdge(N4, N1, E41);
+    assertThat(network.inEdges(N1)).containsExactly(E11, E41);
+  }
+
+  @Test
+  public void outEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.outEdges(N1)).containsExactly(E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.outEdges(N1)).containsExactly(E11, E12);
+  }
+
+  @Test
+  public void predecessors_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.predecessors(N1)).containsExactly(N1);
+    addEdge(N4, N1, E41);
+    assertThat(network.predecessors(N1)).containsExactly(N1, N4);
+  }
+
+  @Test
+  public void successors_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.successors(N1)).containsExactly(N1);
+    addEdge(N1, N2, E12);
+    assertThat(network.successors(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void source_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.incidentNodes(E11).source()).isEqualTo(N1);
+  }
+
+  @Test
+  public void target_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.incidentNodes(E11).target()).isEqualTo(N1);
+  }
+
+  @Test
+  public void degree_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.degree(N1)).isEqualTo(2);
+    addEdge(N1, N2, E12);
+    assertThat(network.degree(N1)).isEqualTo(3);
+  }
+
+  @Test
+  public void inDegree_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.inDegree(N1)).isEqualTo(1);
+    addEdge(N4, N1, E41);
+    assertThat(network.inDegree(N1)).isEqualTo(2);
+  }
+
+  @Test
+  public void outDegree_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.outDegree(N1)).isEqualTo(1);
+    addEdge(N1, N2, E12);
+    assertThat(network.outDegree(N1)).isEqualTo(2);
+  }
+
+  @Override
+  @Test
+  public void addEdge_selfLoop() {
+    assertThat(addEdge(N1, N1, E11)).isTrue();
+    assertThat(network.edges()).contains(E11);
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+  }
+
+  @Test
+  public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
+    addEdge(N1, N1, E11);
+    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
+    assertThat(addEdge(N1, N1, E11)).isFalse();
+    assertThat(network.edges()).containsExactlyElementsIn(edges);
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenDifferentNodes_selfLoops() {
+    addEdge(N1, N1, E11);
+    try {
+      addEdge(N1, N2, E11);
+      fail("Reusing an existing self-loop edge to connect different nodes succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+    try {
+      addEdge(N2, N2, E11);
+      fail("Reusing an existing self-loop edge to make a different self-loop edge succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+    addEdge(N1, N2, E12);
+    try {
+      addEdge(N1, N1, E12);
+      fail("Reusing an existing edge to add a self-loop edge between different nodes succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+  }
+
+  @Test
+  public void addEdge_parallelSelfLoopEdge() {
+    addEdge(N1, N1, E11);
+    try {
+      addEdge(N1, N1, EDGE_NOT_IN_GRAPH);
+      fail("Adding a parallel self-loop edge succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
+    }
+  }
+
+  @Test
+  public void removeNode_existingNodeWithSelfLoopEdge() {
+    addNode(N1);
+    addEdge(N1, N1, E11);
+    assertThat(network.removeNode(N1)).isTrue();
+    assertThat(network.nodes()).isEmpty();
+    assertThat(network.edges()).doesNotContain(E11);
+  }
+
+  @Test
+  public void removeEdge_existingSelfLoopEdge() {
+    addEdge(N1, N1, E11);
+    assertThat(network.removeEdge(E11)).isTrue();
+    assertThat(network.edges()).doesNotContain(E11);
+    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleDirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleDirectedGraphTest.java
new file mode 100644
index 0000000..888cf9a
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleDirectedGraphTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for a directed {@link ConfigurableMutableGraph}, creating a simple directed graph
+ * (self-loop edges are not allowed).
+ */
+@RunWith(JUnit4.class)
+public class ConfigurableSimpleDirectedGraphTest extends AbstractDirectedGraphTest {
+
+  @Override
+  public MutableGraph<Integer> createGraph() {
+    return GraphBuilder.directed().allowsSelfLoops(false).build();
+  }
+
+  @Override
+  @Test
+  public void nodes_checkReturnedSetMutability() {
+    Set<Integer> nodes = graph.nodes();
+    try {
+      nodes.add(N2);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      addNode(N1);
+      assertThat(graph.nodes()).containsExactlyElementsIn(nodes);
+    }
+  }
+
+  @Override
+  @Test
+  public void adjacentNodes_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> adjacentNodes = graph.adjacentNodes(N1);
+    try {
+      adjacentNodes.add(N2);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(graph.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
+    }
+  }
+
+  @Override
+  @Test
+  public void predecessors_checkReturnedSetMutability() {
+    addNode(N2);
+    Set<Integer> predecessors = graph.predecessors(N2);
+    try {
+      predecessors.add(N1);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(graph.predecessors(N2)).containsExactlyElementsIn(predecessors);
+    }
+  }
+
+  @Override
+  @Test
+  public void successors_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> successors = graph.successors(N1);
+    try {
+      successors.add(N2);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(successors).containsExactlyElementsIn(graph.successors(N1));
+    }
+  }
+
+  @Override
+  @Test
+  public void incidentEdges_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<EndpointPair<Integer>> incidentEdges = graph.incidentEdges(N1);
+    try {
+      incidentEdges.add(EndpointPair.ordered(N1, N2));
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(incidentEdges).containsExactlyElementsIn(graph.incidentEdges(N1));
+    }
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_selfLoop() {
+    try {
+      putEdge(N1, N1);
+      fail(ERROR_ADDED_SELF_LOOP);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_SELF_LOOP);
+    }
+  }
+
+  /**
+   * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
+   * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
+   * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
+   * elements of the graph.
+   */
+  @Test
+  public void addEdge_nodesNotInGraph() {
+    graph.addNode(N1);
+    assertTrue(graph.putEdge(N1, N5));
+    assertTrue(graph.putEdge(N4, N1));
+    assertTrue(graph.putEdge(N2, N3));
+    assertThat(graph.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder();
+    assertThat(graph.successors(N1)).containsExactly(N5);
+    assertThat(graph.successors(N2)).containsExactly(N3);
+    assertThat(graph.successors(N3)).isEmpty();
+    assertThat(graph.successors(N4)).containsExactly(N1);
+    assertThat(graph.successors(N5)).isEmpty();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleDirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleDirectedNetworkTest.java
new file mode 100644
index 0000000..a8645b4
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleDirectedNetworkTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for a directed {@link ConfigurableMutableNetwork}, creating a simple directed graph
+ * (parallel and self-loop edges are not allowed).
+ */
+@RunWith(JUnit4.class)
+public class ConfigurableSimpleDirectedNetworkTest extends AbstractDirectedNetworkTest {
+
+  @Override
+  public MutableNetwork<Integer, String> createGraph() {
+    return NetworkBuilder.directed().allowsParallelEdges(false).allowsSelfLoops(false).build();
+  }
+
+  @Override
+  @Test
+  public void nodes_checkReturnedSetMutability() {
+    Set<Integer> nodes = network.nodes();
+    try {
+      nodes.add(N2);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addNode(N1);
+      assertThat(network.nodes()).containsExactlyElementsIn(nodes);
+    }
+  }
+
+  @Override
+  @Test
+  public void edges_checkReturnedSetMutability() {
+    Set<String> edges = network.edges();
+    try {
+      edges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.edges()).containsExactlyElementsIn(edges);
+    }
+  }
+
+  @Override
+  @Test
+  public void incidentEdges_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<String> incidentEdges = network.incidentEdges(N1);
+    try {
+      incidentEdges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.incidentEdges(N1)).containsExactlyElementsIn(incidentEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void adjacentNodes_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> adjacentNodes = network.adjacentNodes(N1);
+    try {
+      adjacentNodes.add(N2);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
+    }
+  }
+
+  @Override
+  public void adjacentEdges_checkReturnedSetMutability() {
+    addEdge(N1, N2, E12);
+    Set<String> adjacentEdges = network.adjacentEdges(E12);
+    try {
+      adjacentEdges.add(E23);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N2, N3, E23);
+      assertThat(network.adjacentEdges(E12)).containsExactlyElementsIn(adjacentEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void edgesConnecting_checkReturnedSetMutability() {
+    addNode(N1);
+    addNode(N2);
+    Set<String> edgesConnecting = network.edgesConnecting(N1, N2);
+    try {
+      edgesConnecting.add(E23);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting);
+    }
+  }
+
+  @Override
+  @Test
+  public void inEdges_checkReturnedSetMutability() {
+    addNode(N2);
+    Set<String> inEdges = network.inEdges(N2);
+    try {
+      inEdges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.inEdges(N2)).containsExactlyElementsIn(inEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void outEdges_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<String> outEdges = network.outEdges(N1);
+    try {
+      outEdges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.outEdges(N1)).containsExactlyElementsIn(outEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void predecessors_checkReturnedSetMutability() {
+    addNode(N2);
+    Set<Integer> predecessors = network.predecessors(N2);
+    try {
+      predecessors.add(N1);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.predecessors(N2)).containsExactlyElementsIn(predecessors);
+    }
+  }
+
+  @Override
+  @Test
+  public void successors_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> successors = network.successors(N1);
+    try {
+      successors.add(N2);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(successors).containsExactlyElementsIn(network.successors(N1));
+    }
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_selfLoop() {
+    try {
+      addEdge(N1, N1, E11);
+      fail(ERROR_ADDED_SELF_LOOP);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_SELF_LOOP);
+    }
+  }
+
+  /**
+   * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
+   * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
+   * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
+   * elements of the graph.
+   */
+  @Test
+  public void addEdge_nodesNotInGraph() {
+    network.addNode(N1);
+    assertTrue(network.addEdge(N1, N5, E15));
+    assertTrue(network.addEdge(N4, N1, E41));
+    assertTrue(network.addEdge(N2, N3, E23));
+    assertThat(network.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder();
+    assertThat(network.edges()).containsExactly(E15, E41, E23).inOrder();
+    assertThat(network.edgesConnecting(N1, N5)).containsExactly(E15);
+    assertThat(network.edgesConnecting(N4, N1)).containsExactly(E41);
+    assertThat(network.edgesConnecting(N2, N3)).containsExactly(E23);
+    // Direction of the added edge is correctly handled
+    assertThat(network.edgesConnecting(N3, N2)).isEmpty();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleUndirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleUndirectedGraphTest.java
new file mode 100644
index 0000000..97693d1
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleUndirectedGraphTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for an undirected {@link ConfigurableMutableGraph}, creating a simple undirected graph
+ * (self-loop edges are not allowed).
+ */
+@RunWith(JUnit4.class)
+public class ConfigurableSimpleUndirectedGraphTest extends AbstractUndirectedGraphTest {
+
+  @Override
+  public MutableGraph<Integer> createGraph() {
+    return GraphBuilder.undirected().allowsSelfLoops(false).build();
+  }
+
+  @Override
+  @Test
+  public void nodes_checkReturnedSetMutability() {
+    Set<Integer> nodes = graph.nodes();
+    try {
+      nodes.add(N2);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      addNode(N1);
+      assertThat(graph.nodes()).containsExactlyElementsIn(nodes);
+    }
+  }
+
+  @Override
+  @Test
+  public void adjacentNodes_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> adjacentNodes = graph.adjacentNodes(N1);
+    try {
+      adjacentNodes.add(N2);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(graph.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
+    }
+  }
+
+  @Override
+  @Test
+  public void predecessors_checkReturnedSetMutability() {
+    addNode(N2);
+    Set<Integer> predecessors = graph.predecessors(N2);
+    try {
+      predecessors.add(N1);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(graph.predecessors(N2)).containsExactlyElementsIn(predecessors);
+    }
+  }
+
+  @Override
+  @Test
+  public void successors_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> successors = graph.successors(N1);
+    try {
+      successors.add(N2);
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(graph.successors(N1)).containsExactlyElementsIn(successors);
+    }
+  }
+
+  @Override
+  @Test
+  public void incidentEdges_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<EndpointPair<Integer>> incidentEdges = graph.incidentEdges(N1);
+    try {
+      incidentEdges.add(EndpointPair.unordered(N1, N2));
+      fail(ERROR_MODIFIABLE_SET);
+    } catch (UnsupportedOperationException e) {
+      putEdge(N1, N2);
+      assertThat(incidentEdges).containsExactlyElementsIn(graph.incidentEdges(N1));
+    }
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_selfLoop() {
+    try {
+      putEdge(N1, N1);
+      fail(ERROR_ADDED_SELF_LOOP);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_SELF_LOOP);
+    }
+  }
+
+  /**
+   * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
+   * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
+   * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
+   * elements of the graph.
+   */
+  @Test
+  public void addEdge_nodesNotInGraph() {
+    graph.addNode(N1);
+    assertTrue(graph.putEdge(N1, N5));
+    assertTrue(graph.putEdge(N4, N1));
+    assertTrue(graph.putEdge(N2, N3));
+    assertThat(graph.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder();
+    assertThat(graph.adjacentNodes(N1)).containsExactly(N4, N5);
+    assertThat(graph.adjacentNodes(N2)).containsExactly(N3);
+    assertThat(graph.adjacentNodes(N3)).containsExactly(N2);
+    assertThat(graph.adjacentNodes(N4)).containsExactly(N1);
+    assertThat(graph.adjacentNodes(N5)).containsExactly(N1);
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleUndirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleUndirectedNetworkTest.java
new file mode 100644
index 0000000..d1c4411
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableSimpleUndirectedNetworkTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for an undirected {@link ConfigurableMutableNetwork}, creating a simple undirected graph
+ * (parallel and self-loop edges are not allowed).
+ */
+@RunWith(JUnit4.class)
+public class ConfigurableSimpleUndirectedNetworkTest extends AbstractUndirectedNetworkTest {
+
+  @Override
+  public MutableNetwork<Integer, String> createGraph() {
+    return NetworkBuilder.undirected().allowsParallelEdges(false).allowsSelfLoops(false).build();
+  }
+
+  @Override
+  @Test
+  public void nodes_checkReturnedSetMutability() {
+    Set<Integer> nodes = network.nodes();
+    try {
+      nodes.add(N2);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addNode(N1);
+      assertThat(network.nodes()).containsExactlyElementsIn(nodes);
+    }
+  }
+
+  @Override
+  @Test
+  public void edges_checkReturnedSetMutability() {
+    Set<String> edges = network.edges();
+    try {
+      edges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.edges()).containsExactlyElementsIn(edges);
+    }
+  }
+
+  @Override
+  @Test
+  public void incidentEdges_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<String> incidentEdges = network.incidentEdges(N1);
+    try {
+      incidentEdges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.incidentEdges(N1)).containsExactlyElementsIn(incidentEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void adjacentNodes_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> adjacentNodes = network.adjacentNodes(N1);
+    try {
+      adjacentNodes.add(N2);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
+    }
+  }
+
+  @Override
+  public void adjacentEdges_checkReturnedSetMutability() {
+    addEdge(N1, N2, E12);
+    Set<String> adjacentEdges = network.adjacentEdges(E12);
+    try {
+      adjacentEdges.add(E23);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N2, N3, E23);
+      assertThat(network.adjacentEdges(E12)).containsExactlyElementsIn(adjacentEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void edgesConnecting_checkReturnedSetMutability() {
+    addNode(N1);
+    addNode(N2);
+    Set<String> edgesConnecting = network.edgesConnecting(N1, N2);
+    try {
+      edgesConnecting.add(E23);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting);
+    }
+  }
+
+  @Override
+  @Test
+  public void inEdges_checkReturnedSetMutability() {
+    addNode(N2);
+    Set<String> inEdges = network.inEdges(N2);
+    try {
+      inEdges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.inEdges(N2)).containsExactlyElementsIn(inEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void outEdges_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<String> outEdges = network.outEdges(N1);
+    try {
+      outEdges.add(E12);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.outEdges(N1)).containsExactlyElementsIn(outEdges);
+    }
+  }
+
+  @Override
+  @Test
+  public void predecessors_checkReturnedSetMutability() {
+    addNode(N2);
+    Set<Integer> predecessors = network.predecessors(N2);
+    try {
+      predecessors.add(N1);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.predecessors(N2)).containsExactlyElementsIn(predecessors);
+    }
+  }
+
+  @Override
+  @Test
+  public void successors_checkReturnedSetMutability() {
+    addNode(N1);
+    Set<Integer> successors = network.successors(N1);
+    try {
+      successors.add(N2);
+      fail(ERROR_MODIFIABLE_COLLECTION);
+    } catch (UnsupportedOperationException e) {
+      addEdge(N1, N2, E12);
+      assertThat(network.successors(N1)).containsExactlyElementsIn(successors);
+    }
+  }
+
+  // Element Mutation
+
+  @Test
+  public void addEdge_selfLoop() {
+    try {
+      addEdge(N1, N1, E11);
+      fail(ERROR_ADDED_SELF_LOOP);
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_SELF_LOOP);
+    }
+  }
+
+  /**
+   * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
+   * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
+   * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
+   * elements of the graph.
+   */
+  @Test
+  public void addEdge_nodesNotInGraph() {
+    network.addNode(N1);
+    assertTrue(network.addEdge(N1, N5, E15));
+    assertTrue(network.addEdge(N4, N1, E41));
+    assertTrue(network.addEdge(N2, N3, E23));
+    assertThat(network.nodes()).containsExactly(N1, N5, N4, N2, N3).inOrder();
+    assertThat(network.edges()).containsExactly(E15, E41, E23).inOrder();
+    assertThat(network.edgesConnecting(N1, N5)).containsExactly(E15);
+    assertThat(network.edgesConnecting(N4, N1)).containsExactly(E41);
+    assertThat(network.edgesConnecting(N2, N3)).containsExactly(E23);
+    assertThat(network.edgesConnecting(N3, N2)).containsExactly(E23);
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedGraphTest.java
new file mode 100644
index 0000000..3bdfd74
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedGraphTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for an undirected {@link ConfigurableMutableGraph} allowing self-loops. */
+@RunWith(JUnit4.class)
+public class ConfigurableUndirectedGraphTest extends ConfigurableSimpleUndirectedGraphTest {
+
+  @Override
+  public MutableGraph<Integer> createGraph() {
+    return GraphBuilder.undirected().allowsSelfLoops(true).build();
+  }
+
+  @Test
+  public void adjacentNodes_selfLoop() {
+    putEdge(N1, N1);
+    putEdge(N1, N2);
+    assertThat(graph.adjacentNodes(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void predecessors_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.predecessors(N1)).containsExactly(N1);
+    putEdge(N1, N2);
+    assertThat(graph.predecessors(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void successors_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.successors(N1)).containsExactly(N1);
+    putEdge(N2, N1);
+    assertThat(graph.successors(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void incidentEdges_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.incidentEdges(N1)).containsExactly(EndpointPair.unordered(N1, N1));
+    putEdge(N1, N2);
+    assertThat(graph.incidentEdges(N1))
+        .containsExactly(EndpointPair.unordered(N1, N1), EndpointPair.unordered(N1, N2));
+  }
+
+  @Test
+  public void degree_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.degree(N1)).isEqualTo(2);
+    putEdge(N1, N2);
+    assertThat(graph.degree(N1)).isEqualTo(3);
+  }
+
+  @Test
+  public void inDegree_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.inDegree(N1)).isEqualTo(2);
+    putEdge(N1, N2);
+    assertThat(graph.inDegree(N1)).isEqualTo(3);
+  }
+
+  @Test
+  public void outDegree_selfLoop() {
+    putEdge(N1, N1);
+    assertThat(graph.outDegree(N1)).isEqualTo(2);
+    putEdge(N2, N1);
+    assertThat(graph.outDegree(N1)).isEqualTo(3);
+  }
+
+  @Override
+  @Test
+  public void addEdge_selfLoop() {
+    assertThat(putEdge(N1, N1)).isTrue();
+    assertThat(graph.adjacentNodes(N1)).containsExactly(N1);
+  }
+
+  @Test
+  public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
+    putEdge(N1, N1);
+    assertThat(putEdge(N1, N1)).isFalse();
+  }
+
+  @Test
+  public void removeNode_existingNodeWithSelfLoopEdge() {
+    addNode(N1);
+    putEdge(N1, N1);
+    assertThat(graph.removeNode(N1)).isTrue();
+    assertThat(graph.nodes()).isEmpty();
+  }
+
+  @Test
+  public void removeEdge_existingSelfLoopEdge() {
+    putEdge(N1, N1);
+    assertThat(graph.removeEdge(N1, N1)).isTrue();
+    assertThat(graph.nodes()).containsExactly(N1);
+    assertThat(graph.adjacentNodes(N1)).isEmpty();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedMultiNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedMultiNetworkTest.java
new file mode 100644
index 0000000..d239e22
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedMultiNetworkTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for an undirected {@link ConfigurableMutableNetwork} allowing parallel edges and
+ * self-loops.
+ */
+@RunWith(JUnit4.class)
+public class ConfigurableUndirectedMultiNetworkTest extends ConfigurableUndirectedNetworkTest {
+  @Override
+  public MutableNetwork<Integer, String> createGraph() {
+    return NetworkBuilder.undirected().allowsParallelEdges(true).allowsSelfLoops(true).build();
+  }
+
+  @Test
+  public void adjacentEdges_parallelEdges() {
+    addEdge(N1, N2, E12);
+    addEdge(N1, N2, E12_A);
+    addEdge(N1, N2, E12_B);
+    addEdge(N3, N4, E34);
+    assertThat(network.adjacentEdges(E12)).containsExactly(E12_A, E12_B);
+  }
+
+  @Test
+  public void edgesConnecting_parallelEdges() {
+    assertTrue(addEdge(N1, N2, E12));
+    assertTrue(addEdge(N1, N2, E12_A));
+    assertTrue(addEdge(N2, N1, E21));
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A, E21);
+    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12, E12_A, E21);
+  }
+
+  @Test
+  public void edgesConnecting_parallelSelfLoopEdges() {
+    assertTrue(addEdge(N1, N1, E11));
+    assertTrue(addEdge(N1, N1, E11_A));
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
+  }
+
+  @Override
+  @Test
+  public void addEdge_parallelEdge() {
+    assertTrue(addEdge(N1, N2, E12));
+    assertTrue(addEdge(N1, N2, E12_A));
+    assertTrue(addEdge(N2, N1, E21));
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A, E21);
+  }
+
+  @Override
+  @Test
+  public void addEdge_parallelSelfLoopEdge() {
+    assertTrue(addEdge(N1, N1, E11));
+    assertTrue(addEdge(N1, N1, E11_A));
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
+  }
+
+  @Test
+  public void removeEdge_parallelEdge() {
+    addEdge(N1, N2, E12);
+    addEdge(N1, N2, E12_A);
+    addEdge(N2, N1, E21);
+    assertTrue(network.removeEdge(E12_A));
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E21);
+  }
+
+  @Test
+  public void removeEdge_parallelSelfLoopEdge() {
+    addEdge(N1, N1, E11);
+    addEdge(N1, N1, E11_A);
+    addEdge(N1, N2, E12);
+    assertTrue(network.removeEdge(E11_A));
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    assertTrue(network.removeEdge(E11));
+    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedNetworkTest.java
new file mode 100644
index 0000000..28cd3e5
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ConfigurableUndirectedNetworkTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for an undirected {@link ConfigurableMutableNetwork} allowing self-loops. */
+@RunWith(JUnit4.class)
+public class ConfigurableUndirectedNetworkTest extends ConfigurableSimpleUndirectedNetworkTest {
+
+  @Override
+  public MutableNetwork<Integer, String> createGraph() {
+    return NetworkBuilder.undirected().allowsSelfLoops(true).build();
+  }
+
+  @Test
+  public void edges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.edges()).containsExactly(E11);
+  }
+
+  @Test
+  public void incidentEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.incidentEdges(N1)).containsExactly(E11);
+  }
+
+  @Test
+  public void incidentNodes_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.incidentNodes(E11).nodeU()).isEqualTo(N1);
+    assertThat(network.incidentNodes(E11).nodeV()).isEqualTo(N1);
+  }
+
+  @Test
+  public void adjacentNodes_selfLoop() {
+    addEdge(N1, N1, E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.adjacentNodes(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void adjacentEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.adjacentEdges(E11)).containsExactly(E12);
+  }
+
+  @Test
+  public void edgesConnecting_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
+    assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+  }
+
+  @Test
+  public void inEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.inEdges(N1)).containsExactly(E11);
+    addEdge(N1, N2, E12);
+    assertThat(network.inEdges(N1)).containsExactly(E11, E12);
+  }
+
+  @Test
+  public void outEdges_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.outEdges(N1)).containsExactly(E11);
+    addEdge(N2, N1, E12);
+    assertThat(network.outEdges(N1)).containsExactly(E11, E12);
+  }
+
+  @Test
+  public void predecessors_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.predecessors(N1)).containsExactly(N1);
+    addEdge(N1, N2, E12);
+    assertThat(network.predecessors(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void successors_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.successors(N1)).containsExactly(N1);
+    addEdge(N2, N1, E12);
+    assertThat(network.successors(N1)).containsExactly(N1, N2);
+  }
+
+  @Test
+  public void degree_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.degree(N1)).isEqualTo(2);
+    addEdge(N1, N2, E12);
+    assertThat(network.degree(N1)).isEqualTo(3);
+  }
+
+  @Test
+  public void inDegree_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.inDegree(N1)).isEqualTo(2);
+    addEdge(N1, N2, E12);
+    assertThat(network.inDegree(N1)).isEqualTo(3);
+  }
+
+  @Test
+  public void outDegree_selfLoop() {
+    addEdge(N1, N1, E11);
+    assertThat(network.outDegree(N1)).isEqualTo(2);
+    addEdge(N2, N1, E12);
+    assertThat(network.outDegree(N1)).isEqualTo(3);
+  }
+
+  @Override
+  @Test
+  public void addEdge_selfLoop() {
+    assertThat(addEdge(N1, N1, E11)).isTrue();
+    assertThat(network.edges()).contains(E11);
+    assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
+  }
+
+  @Test
+  public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
+    addEdge(N1, N1, E11);
+    ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
+    assertThat(addEdge(N1, N1, E11)).isFalse();
+    assertThat(network.edges()).containsExactlyElementsIn(edges);
+  }
+
+  @Test
+  public void addEdge_existingEdgeBetweenDifferentNodes_selfLoops() {
+    addEdge(N1, N1, E11);
+    try {
+      addEdge(N1, N2, E11);
+      fail("Reusing an existing self-loop edge to connect different nodes succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+    try {
+      addEdge(N2, N2, E11);
+      fail("Reusing an existing self-loop edge to make a different self-loop edge succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+    addEdge(N1, N2, E12);
+    try {
+      addEdge(N1, N1, E12);
+      fail("Reusing an existing edge to add a self-loop edge between different nodes succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_REUSE_EDGE);
+    }
+  }
+
+  @Test
+  public void addEdge_parallelSelfLoopEdge() {
+    addEdge(N1, N1, E11);
+    try {
+      addEdge(N1, N1, EDGE_NOT_IN_GRAPH);
+      fail("Adding a parallel self-loop edge succeeded");
+    } catch (IllegalArgumentException e) {
+      assertThat(e.getMessage()).contains(ERROR_PARALLEL_EDGE);
+    }
+  }
+
+  @Test
+  public void removeNode_existingNodeWithSelfLoopEdge() {
+    addNode(N1);
+    addEdge(N1, N1, E11);
+    assertThat(network.removeNode(N1)).isTrue();
+    assertThat(network.nodes()).isEmpty();
+    assertThat(network.edges()).doesNotContain(E11);
+  }
+
+  @Test
+  public void removeEdge_existingSelfLoopEdge() {
+    addEdge(N1, N1, E11);
+    assertThat(network.removeEdge(E11)).isTrue();
+    assertThat(network.edges()).doesNotContain(E11);
+    assertThat(network.edgesConnecting(N1, N1)).isEmpty();
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/GraphsTest.java b/android/guava-tests/test/com/google/common/graph/GraphsTest.java
index a07def0..ce892ad 100644
--- a/android/guava-tests/test/com/google/common/graph/GraphsTest.java
+++ b/android/guava-tests/test/com/google/common/graph/GraphsTest.java
@@ -206,7 +206,7 @@
     MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().build();
     undirectedGraph.putEdge(N1, N2);
 
-    assertThat(transpose(undirectedGraph)).isSameInstanceAs(undirectedGraph);
+    assertThat(transpose(undirectedGraph)).isSameAs(undirectedGraph);
   }
 
   @Test
@@ -227,12 +227,12 @@
 
     Graph<Integer> transpose = transpose(directedGraph);
     assertThat(transpose).isEqualTo(expectedTranspose);
-    assertThat(transpose(transpose)).isSameInstanceAs(directedGraph);
+    assertThat(transpose(transpose)).isSameAs(directedGraph);
     AbstractGraphTest.validateGraph(transpose);
 
     for (Integer node : directedGraph.nodes()) {
-      assertThat(directedGraph.inDegree(node)).isSameInstanceAs(transpose.outDegree(node));
-      assertThat(directedGraph.outDegree(node)).isSameInstanceAs(transpose.inDegree(node));
+      assertThat(directedGraph.inDegree(node)).isSameAs(transpose.outDegree(node));
+      assertThat(directedGraph.outDegree(node)).isSameAs(transpose.inDegree(node));
     }
 
     assertThat(transpose.successors(N1)).doesNotContain(N2);
@@ -247,7 +247,7 @@
     MutableValueGraph<Integer, String> undirectedGraph = ValueGraphBuilder.undirected().build();
     undirectedGraph.putEdgeValue(N1, N2, E12);
 
-    assertThat(transpose(undirectedGraph)).isSameInstanceAs(undirectedGraph);
+    assertThat(transpose(undirectedGraph)).isSameAs(undirectedGraph);
   }
 
   @Test
@@ -270,13 +270,13 @@
 
     ValueGraph<Integer, String> transpose = transpose(directedGraph);
     assertThat(transpose).isEqualTo(expectedTranspose);
-    assertThat(transpose(transpose)).isSameInstanceAs(directedGraph);
+    assertThat(transpose(transpose)).isSameAs(directedGraph);
     AbstractGraphTest.validateGraph(transpose.asGraph());
 
     assertThat(transpose.edgeValueOrDefault(N1, N2, null)).isNull();
     for (Integer node : directedGraph.nodes()) {
-      assertThat(directedGraph.inDegree(node)).isSameInstanceAs(transpose.outDegree(node));
-      assertThat(directedGraph.outDegree(node)).isSameInstanceAs(transpose.inDegree(node));
+      assertThat(directedGraph.inDegree(node)).isSameAs(transpose.outDegree(node));
+      assertThat(directedGraph.outDegree(node)).isSameAs(transpose.inDegree(node));
     }
 
     directedGraph.putEdgeValue(N2, N1, E21);
@@ -290,7 +290,7 @@
     MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().build();
     undirectedGraph.addEdge(N1, N2, E12);
 
-    assertThat(transpose(undirectedGraph)).isSameInstanceAs(undirectedGraph);
+    assertThat(transpose(undirectedGraph)).isSameAs(undirectedGraph);
   }
 
   @Test
@@ -315,15 +315,15 @@
 
     Network<Integer, String> transpose = transpose(directedGraph);
     assertThat(transpose).isEqualTo(expectedTranspose);
-    assertThat(transpose(transpose)).isSameInstanceAs(directedGraph);
+    assertThat(transpose(transpose)).isSameAs(directedGraph);
     AbstractNetworkTest.validateNetwork(transpose);
 
     assertThat(transpose.edgesConnecting(N1, N2)).isEmpty();
     assertThat(transpose.edgeConnectingOrNull(N1, N2)).isNull();
 
     for (Integer node : directedGraph.nodes()) {
-      assertThat(directedGraph.inDegree(node)).isSameInstanceAs(transpose.outDegree(node));
-      assertThat(directedGraph.outDegree(node)).isSameInstanceAs(transpose.inDegree(node));
+      assertThat(directedGraph.inDegree(node)).isSameAs(transpose.outDegree(node));
+      assertThat(directedGraph.outDegree(node)).isSameAs(transpose.inDegree(node));
     }
 
     directedGraph.addEdge(N2, N1, E21);
@@ -487,7 +487,7 @@
       directedGraph.addEdge(N1, N1, E11);
       fail(ERROR_ADDED_SELF_LOOP);
     } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
+      assertThat(e.getMessage()).contains(ERROR_SELF_LOOP);
     }
   }
 
@@ -519,7 +519,7 @@
       undirectedGraph.addEdge(N1, N1, E11);
       fail(ERROR_ADDED_SELF_LOOP);
     } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
+      assertThat(e.getMessage()).contains(ERROR_SELF_LOOP);
     }
   }
 
diff --git a/android/guava-tests/test/com/google/common/graph/ImmutableGraphTest.java b/android/guava-tests/test/com/google/common/graph/ImmutableGraphTest.java
new file mode 100644
index 0000000..1a60836
--- /dev/null
+++ b/android/guava-tests/test/com/google/common/graph/ImmutableGraphTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link ImmutableGraph} and {@link ImmutableValueGraph} . */
+@RunWith(JUnit4.class)
+public class ImmutableGraphTest {
+
+  @Test
+  public void immutableGraph() {
+    MutableGraph<String> mutableGraph = GraphBuilder.directed().build();
+    mutableGraph.addNode("A");
+    ImmutableGraph<String> immutableGraph = ImmutableGraph.copyOf(mutableGraph);
+
+    assertThat(immutableGraph).isNotInstanceOf(MutableValueGraph.class);
+    assertThat(immutableGraph).isEqualTo(mutableGraph);
+
+    mutableGraph.addNode("B");
+    assertThat(immutableGraph).isNotEqualTo(mutableGraph);
+  }
+
+  @Test
+  public void immutableValueGraph() {
+    MutableValueGraph<String, Integer> mutableValueGraph = ValueGraphBuilder.directed().build();
+    mutableValueGraph.addNode("A");
+    ImmutableValueGraph<String, Integer> immutableValueGraph =
+        ImmutableValueGraph.copyOf(mutableValueGraph);
+
+    assertThat(immutableValueGraph.asGraph()).isInstanceOf(ImmutableGraph.class);
+    assertThat(immutableValueGraph).isNotInstanceOf(MutableValueGraph.class);
+    assertThat(immutableValueGraph).isEqualTo(mutableValueGraph);
+
+    mutableValueGraph.addNode("B");
+    assertThat(immutableValueGraph).isNotEqualTo(mutableValueGraph);
+  }
+
+  @Test
+  public void copyOfImmutableGraph_optimized() {
+    Graph<String> graph1 = ImmutableGraph.copyOf(GraphBuilder.directed().<String>build());
+    Graph<String> graph2 = ImmutableGraph.copyOf(graph1);
+
+    assertThat(graph2).isSameAs(graph1);
+  }
+
+  @Test
+  public void copyOfImmutableValueGraph_optimized() {
+    ValueGraph<String, Integer> graph1 =
+        ImmutableValueGraph.copyOf(ValueGraphBuilder.directed().<String, Integer>build());
+    ValueGraph<String, Integer> graph2 = ImmutableValueGraph.copyOf(graph1);
+
+    assertThat(graph2).isSameAs(graph1);
+  }
+}
diff --git a/android/guava-tests/test/com/google/common/graph/ImmutableNetworkTest.java b/android/guava-tests/test/com/google/common/graph/ImmutableNetworkTest.java
index 5de3cf7..e138656 100644
--- a/android/guava-tests/test/com/google/common/graph/ImmutableNetworkTest.java
+++ b/android/guava-tests/test/com/google/common/graph/ImmutableNetworkTest.java
@@ -46,7 +46,7 @@
         ImmutableNetwork.copyOf(NetworkBuilder.directed().<String, String>build());
     Network<String, String> network2 = ImmutableNetwork.copyOf(network1);
 
-    assertThat(network2).isSameInstanceAs(network1);
+    assertThat(network2).isSameAs(network1);
   }
 
   @Test
@@ -74,74 +74,4 @@
     assertThat(network.edgesConnecting("A", "B")).containsExactly("AB");
     assertThat(network.edgesConnecting("B", "A")).containsExactly("AB");
   }
-
-  @Test
-  public void immutableNetworkBuilder_appliesNetworkBuilderConfig() {
-    ImmutableNetwork<String, Integer> emptyNetwork =
-        NetworkBuilder.directed()
-            .allowsSelfLoops(true)
-            .nodeOrder(ElementOrder.<String>natural())
-            .<String, Integer>immutable()
-            .build();
-
-    assertThat(emptyNetwork.isDirected()).isTrue();
-    assertThat(emptyNetwork.allowsSelfLoops()).isTrue();
-    assertThat(emptyNetwork.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
-  }
-
-  /**
-   * Tests that the ImmutableNetwork.Builder doesn't change when the creating NetworkBuilder
-   * changes.
-   */
-  @Test
-  @SuppressWarnings("CheckReturnValue")
-  public void immutableNetworkBuilder_copiesNetworkBuilder() {
-    NetworkBuilder<String, Object> networkBuilder =
-        NetworkBuilder.directed()
-            .allowsSelfLoops(true)
-            .<String>nodeOrder(ElementOrder.<String>natural());
-    ImmutableNetwork.Builder<String, Integer> immutableNetworkBuilder =
-        networkBuilder.<String, Integer>immutable();
-
-    // Update NetworkBuilder, but this shouldn't impact immutableNetworkBuilder
-    networkBuilder.allowsSelfLoops(false).nodeOrder(ElementOrder.<String>unordered());
-
-    ImmutableNetwork<String, Integer> emptyNetwork = immutableNetworkBuilder.build();
-
-    assertThat(emptyNetwork.isDirected()).isTrue();
-    assertThat(emptyNetwork.allowsSelfLoops()).isTrue();
-    assertThat(emptyNetwork.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
-  }
-
-  @Test
-  public void immutableNetworkBuilder_addNode() {
-    ImmutableNetwork<String, Integer> network =
-        NetworkBuilder.directed().<String, Integer>immutable().addNode("A").build();
-
-    assertThat(network.nodes()).containsExactly("A");
-    assertThat(network.edges()).isEmpty();
-  }
-
-  @Test
-  public void immutableNetworkBuilder_putEdgeFromNodes() {
-    ImmutableNetwork<String, Integer> network =
-        NetworkBuilder.directed().<String, Integer>immutable().addEdge("A", "B", 10).build();
-
-    assertThat(network.nodes()).containsExactly("A", "B");
-    assertThat(network.edges()).containsExactly(10);
-    assertThat(network.incidentNodes(10)).isEqualTo(EndpointPair.ordered("A", "B"));
-  }
-
-  @Test
-  public void immutableNetworkBuilder_putEdgeFromEndpointPair() {
-    ImmutableNetwork<String, Integer> network =
-        NetworkBuilder.directed()
-            .<String, Integer>immutable()
-            .addEdge(EndpointPair.ordered("A", "B"), 10)
-            .build();
-
-    assertThat(network.nodes()).containsExactly("A", "B");
-    assertThat(network.edges()).containsExactly(10);
-    assertThat(network.incidentNodes(10)).isEqualTo(EndpointPair.ordered("A", "B"));
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/graph/ImmutableValueGraphTest.java b/android/guava-tests/test/com/google/common/graph/ImmutableValueGraphTest.java
deleted file mode 100644
index 8e5e67f..0000000
--- a/android/guava-tests/test/com/google/common/graph/ImmutableValueGraphTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2019 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link ImmutableValueGraph} . */
-@RunWith(JUnit4.class)
-public class ImmutableValueGraphTest {
-
-  @Test
-  public void immutableValueGraph() {
-    MutableValueGraph<String, Integer> mutableValueGraph = ValueGraphBuilder.directed().build();
-    mutableValueGraph.addNode("A");
-    ImmutableValueGraph<String, Integer> immutableValueGraph =
-        ImmutableValueGraph.copyOf(mutableValueGraph);
-
-    assertThat(immutableValueGraph.asGraph()).isInstanceOf(ImmutableGraph.class);
-    assertThat(immutableValueGraph).isNotInstanceOf(MutableValueGraph.class);
-    assertThat(immutableValueGraph).isEqualTo(mutableValueGraph);
-
-    mutableValueGraph.addNode("B");
-    assertThat(immutableValueGraph).isNotEqualTo(mutableValueGraph);
-  }
-
-  @Test
-  public void copyOfImmutableValueGraph_optimized() {
-    ValueGraph<String, Integer> graph1 =
-        ImmutableValueGraph.copyOf(ValueGraphBuilder.directed().<String, Integer>build());
-    ValueGraph<String, Integer> graph2 = ImmutableValueGraph.copyOf(graph1);
-
-    assertThat(graph2).isSameInstanceAs(graph1);
-  }
-
-  @Test
-  public void incidentEdgeOrder_stable() {
-    ImmutableValueGraph<String, Integer> immutableValueGraph =
-        ImmutableValueGraph.copyOf(ValueGraphBuilder.directed().<String, Integer>build());
-
-    assertThat(immutableValueGraph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-
-  @Test
-  public void incidentEdgeOrder_fromUnorderedGraph_stable() {
-    ImmutableValueGraph<String, Integer> immutableValueGraph =
-        ImmutableValueGraph.copyOf(
-            ValueGraphBuilder.directed()
-                .incidentEdgeOrder(ElementOrder.unordered())
-                .<String, Integer>build());
-
-    assertThat(immutableValueGraph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_appliesGraphBuilderConfig() {
-    ImmutableValueGraph<String, Integer> emptyGraph =
-        ValueGraphBuilder.directed()
-            .allowsSelfLoops(true)
-            .nodeOrder(ElementOrder.<String>natural())
-            .<String, Integer>immutable()
-            .build();
-
-    assertThat(emptyGraph.isDirected()).isTrue();
-    assertThat(emptyGraph.allowsSelfLoops()).isTrue();
-    assertThat(emptyGraph.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
-  }
-
-  /**
-   * Tests that the ImmutableValueGraph.Builder doesn't change when the creating ValueGraphBuilder
-   * changes.
-   */
-  @Test
-  @SuppressWarnings("CheckReturnValue")
-  public void immutableValueGraphBuilder_copiesGraphBuilder() {
-    ValueGraphBuilder<String, Object> graphBuilder =
-        ValueGraphBuilder.directed()
-            .allowsSelfLoops(true)
-            .<String>nodeOrder(ElementOrder.<String>natural());
-    ImmutableValueGraph.Builder<String, Integer> immutableValueGraphBuilder =
-        graphBuilder.<String, Integer>immutable();
-
-    // Update ValueGraphBuilder, but this shouldn't impact immutableValueGraphBuilder
-    graphBuilder.allowsSelfLoops(false).nodeOrder(ElementOrder.<String>unordered());
-
-    ImmutableValueGraph<String, Integer> emptyGraph = immutableValueGraphBuilder.build();
-
-    assertThat(emptyGraph.isDirected()).isTrue();
-    assertThat(emptyGraph.allowsSelfLoops()).isTrue();
-    assertThat(emptyGraph.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_addNode() {
-    ImmutableValueGraph<String, Integer> graph =
-        ValueGraphBuilder.directed().<String, Integer>immutable().addNode("A").build();
-
-    assertThat(graph.nodes()).containsExactly("A");
-    assertThat(graph.edges()).isEmpty();
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_putEdgeFromNodes() {
-    ImmutableValueGraph<String, Integer> graph =
-        ValueGraphBuilder.directed()
-            .<String, Integer>immutable()
-            .putEdgeValue("A", "B", 10)
-            .build();
-
-    assertThat(graph.nodes()).containsExactly("A", "B");
-    assertThat(graph.edges()).containsExactly(EndpointPair.ordered("A", "B"));
-    assertThat(graph.edgeValueOrDefault("A", "B", null)).isEqualTo(10);
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_putEdgeFromEndpointPair() {
-    ImmutableValueGraph<String, Integer> graph =
-        ValueGraphBuilder.directed()
-            .<String, Integer>immutable()
-            .putEdgeValue(EndpointPair.ordered("A", "B"), 10)
-            .build();
-
-    assertThat(graph.nodes()).containsExactly("A", "B");
-    assertThat(graph.edges()).containsExactly(EndpointPair.ordered("A", "B"));
-    assertThat(graph.edgeValueOrDefault("A", "B", null)).isEqualTo(10);
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_incidentEdges_preservesIncidentEdgesOrder() {
-    ImmutableValueGraph<Integer, String> graph =
-        ValueGraphBuilder.directed()
-            .<Integer, String>immutable()
-            .putEdgeValue(2, 1, "2-1")
-            .putEdgeValue(2, 3, "2-3")
-            .putEdgeValue(1, 2, "1-2")
-            .build();
-
-    assertThat(graph.incidentEdges(2))
-        .containsExactly(
-            EndpointPair.ordered(2, 1), EndpointPair.ordered(2, 3), EndpointPair.ordered(1, 2))
-        .inOrder();
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_incidentEdgeOrder_stable() {
-    ImmutableValueGraph<Integer, String> graph =
-        ValueGraphBuilder.directed().<Integer, String>immutable().build();
-
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-
-  @Test
-  public void immutableValueGraphBuilder_fromUnorderedBuilder_incidentEdgeOrder_stable() {
-    ImmutableValueGraph<Integer, String> graph =
-        ValueGraphBuilder.directed()
-            .incidentEdgeOrder(ElementOrder.unordered())
-            .<Integer, String>immutable()
-            .build();
-
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/MapCacheTest.java b/android/guava-tests/test/com/google/common/graph/MapCacheTest.java
index f66b19b..564032a 100644
--- a/android/guava-tests/test/com/google/common/graph/MapCacheTest.java
+++ b/android/guava-tests/test/com/google/common/graph/MapCacheTest.java
@@ -83,7 +83,7 @@
   public void testRemoveEqualKeyWithDifferentReference() {
     String fooReference1 = new String("foo");
     String fooReference2 = new String("foo");
-    assertThat(fooReference1).isNotSameInstanceAs(fooReference2);
+    assertThat(fooReference1).isNotSameAs(fooReference2);
 
     assertThat(mapCache.put(fooReference1, "bar")).isNull();
     assertThat(mapCache.get(fooReference1)).isEqualTo("bar"); // ensure first reference is cached
diff --git a/android/guava-tests/test/com/google/common/graph/PackageSanityTests.java b/android/guava-tests/test/com/google/common/graph/PackageSanityTests.java
index f1526c2..2022952 100644
--- a/android/guava-tests/test/com/google/common/graph/PackageSanityTests.java
+++ b/android/guava-tests/test/com/google/common/graph/PackageSanityTests.java
@@ -35,20 +35,16 @@
   private static final AbstractGraphBuilder<?> GRAPH_BUILDER_B =
       ValueGraphBuilder.directed().allowsSelfLoops(true).expectedNodeCount(16);
 
-  private static final ImmutableGraph<String> IMMUTABLE_GRAPH_A =
-      GraphBuilder.directed().<String>immutable().addNode("A").build();
-  private static final ImmutableGraph<String> IMMUTABLE_GRAPH_B =
-      GraphBuilder.directed().<String>immutable().addNode("B").build();
+  private static final ImmutableGraph<String> IMMUTABLE_GRAPH_A = graphWithNode("A");
+  private static final ImmutableGraph<String> IMMUTABLE_GRAPH_B = graphWithNode("B");
 
   private static final NetworkBuilder<?, ?> NETWORK_BUILDER_A =
       NetworkBuilder.directed().allowsParallelEdges(true).expectedNodeCount(10);
   private static final NetworkBuilder<?, ?> NETWORK_BUILDER_B =
       NetworkBuilder.directed().allowsSelfLoops(true).expectedNodeCount(16);
 
-  private static final ImmutableNetwork<String, String> IMMUTABLE_NETWORK_A =
-      NetworkBuilder.directed().<String, String>immutable().addNode("A").build();
-  private static final ImmutableNetwork<String, String> IMMUTABLE_NETWORK_B =
-      NetworkBuilder.directed().<String, String>immutable().addNode("B").build();
+  private static final ImmutableNetwork<String, String> IMMUTABLE_NETWORK_A = networkWithNode("A");
+  private static final ImmutableNetwork<String, String> IMMUTABLE_NETWORK_B = networkWithNode("B");
 
   public PackageSanityTests() {
     setDistinctValues(AbstractGraphBuilder.class, GRAPH_BUILDER_A, GRAPH_BUILDER_B);
@@ -70,4 +66,16 @@
           .contains(ERROR_ELEMENT_NOT_IN_GRAPH);
     }
   }
+
+  private static <N> ImmutableGraph<N> graphWithNode(N node) {
+    MutableGraph<N> graph = GraphBuilder.directed().build();
+    graph.addNode(node);
+    return ImmutableGraph.copyOf(graph);
+  }
+
+  private static <N> ImmutableNetwork<N, N> networkWithNode(N node) {
+    MutableNetwork<N, N> network = NetworkBuilder.directed().build();
+    network.addNode(node);
+    return ImmutableNetwork.copyOf(network);
+  }
 }
diff --git a/android/guava-tests/test/com/google/common/graph/StandardImmutableDirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/StandardImmutableDirectedGraphTest.java
deleted file mode 100644
index d89baa0..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardImmutableDirectedGraphTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for a directed {@link StandardMutableGraph}. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public final class StandardImmutableDirectedGraphTest extends AbstractStandardDirectedGraphTest {
-
-  @Parameters(name = "allowsSelfLoops={0}")
-  public static Collection<Object[]> parameters() {
-    return Arrays.asList(new Object[][] {{false}, {true}});
-  }
-
-  private final boolean allowsSelfLoops;
-  private ImmutableGraph.Builder<Integer> graphBuilder;
-
-  public StandardImmutableDirectedGraphTest(boolean allowsSelfLoops) {
-    this.allowsSelfLoops = allowsSelfLoops;
-  }
-
-  @Override
-  public Graph<Integer> createGraph() {
-    graphBuilder = GraphBuilder.directed().allowsSelfLoops(allowsSelfLoops).immutable();
-    return graphBuilder.build();
-  }
-
-  @Override
-  final void addNode(Integer n) {
-    graphBuilder.addNode(n);
-    graph = graphBuilder.build();
-  }
-
-  @Override
-  final void putEdge(Integer n1, Integer n2) {
-    graphBuilder.putEdge(n1, n2);
-    graph = graphBuilder.build();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardImmutableDirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/StandardImmutableDirectedNetworkTest.java
deleted file mode 100644
index b237ff9..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardImmutableDirectedNetworkTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import com.google.common.collect.Ordering;
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for a directed {@link ImmutableNetwork}. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public class StandardImmutableDirectedNetworkTest extends AbstractStandardDirectedNetworkTest {
-
-  @Parameters(name = "allowsSelfLoops={0}, allowsParallelEdges={1}, nodeOrder={2}, edgeOrder={3}")
-  public static Collection<Object[]> parameters() {
-    ElementOrder<?> naturalElementOrder = ElementOrder.sorted(Ordering.natural());
-
-    return Arrays.asList(
-        new Object[][] {
-          {false, false, ElementOrder.insertion(), ElementOrder.insertion()},
-          {true, false, ElementOrder.insertion(), ElementOrder.insertion()},
-          {false, false, naturalElementOrder, naturalElementOrder},
-          {true, true, ElementOrder.insertion(), ElementOrder.insertion()},
-        });
-  }
-
-  private final boolean allowsSelfLoops;
-  private final boolean allowsParallelEdges;
-  private final ElementOrder<Integer> nodeOrder;
-  private final ElementOrder<String> edgeOrder;
-
-  private ImmutableNetwork.Builder<Integer, String> networkBuilder;
-
-  public StandardImmutableDirectedNetworkTest(
-      boolean allowsSelfLoops,
-      boolean allowsParallelEdges,
-      ElementOrder<Integer> nodeOrder,
-      ElementOrder<String> edgeOrder) {
-    this.allowsSelfLoops = allowsSelfLoops;
-    this.allowsParallelEdges = allowsParallelEdges;
-    this.nodeOrder = nodeOrder;
-    this.edgeOrder = edgeOrder;
-  }
-
-  @Override
-  Network<Integer, String> createGraph() {
-    networkBuilder =
-        NetworkBuilder.directed()
-            .allowsSelfLoops(allowsSelfLoops)
-            .allowsParallelEdges(allowsParallelEdges)
-            .nodeOrder(nodeOrder)
-            .edgeOrder(edgeOrder)
-            .immutable();
-
-    return networkBuilder.build();
-  }
-
-  @Override
-  void addNode(Integer n) {
-    networkBuilder.addNode(n);
-    network = networkBuilder.build();
-  }
-
-  @Override
-  void addEdge(Integer n1, Integer n2, String e) {
-    networkBuilder.addEdge(n1, n2, e);
-    network = networkBuilder.build();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardImmutableGraphAdditionalTest.java b/android/guava-tests/test/com/google/common/graph/StandardImmutableGraphAdditionalTest.java
deleted file mode 100644
index 47cd6a0..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardImmutableGraphAdditionalTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for {@link ImmutableGraph} and {@link ImmutableGraph.Builder} that are not ready covered by
- * {@link StandardImmutableDirectedGraphTest}.
- */
-@RunWith(JUnit4.class)
-public class StandardImmutableGraphAdditionalTest {
-
-  @Test
-  public void immutableGraph() {
-    MutableGraph<String> mutableGraph = GraphBuilder.directed().build();
-    mutableGraph.addNode("A");
-    ImmutableGraph<String> immutableGraph = ImmutableGraph.copyOf(mutableGraph);
-
-    assertThat(immutableGraph).isNotInstanceOf(MutableValueGraph.class);
-    assertThat(immutableGraph).isEqualTo(mutableGraph);
-
-    mutableGraph.addNode("B");
-    assertThat(immutableGraph).isNotEqualTo(mutableGraph);
-  }
-
-  @Test
-  public void copyOfImmutableGraph_optimized() {
-    Graph<String> graph1 = ImmutableGraph.copyOf(GraphBuilder.directed().<String>build());
-    Graph<String> graph2 = ImmutableGraph.copyOf(graph1);
-
-    assertThat(graph2).isSameInstanceAs(graph1);
-  }
-
-  @Test
-  public void immutableGraphBuilder_appliesGraphBuilderConfig() {
-    ImmutableGraph<String> emptyGraph =
-        GraphBuilder.directed()
-            .allowsSelfLoops(true)
-            .nodeOrder(ElementOrder.<String>natural())
-            .immutable()
-            .build();
-
-    assertThat(emptyGraph.isDirected()).isTrue();
-    assertThat(emptyGraph.allowsSelfLoops()).isTrue();
-    assertThat(emptyGraph.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
-  }
-
-  /**
-   * Tests that the ImmutableGraph.Builder doesn't change when the creating GraphBuilder changes.
-   */
-  @Test
-  @SuppressWarnings("CheckReturnValue")
-  public void immutableGraphBuilder_copiesGraphBuilder() {
-    GraphBuilder<String> graphBuilder =
-        GraphBuilder.directed()
-            .allowsSelfLoops(true)
-            .<String>nodeOrder(ElementOrder.<String>natural());
-    ImmutableGraph.Builder<String> immutableGraphBuilder = graphBuilder.immutable();
-
-    // Update GraphBuilder, but this shouldn't impact immutableGraphBuilder
-    graphBuilder.allowsSelfLoops(false).nodeOrder(ElementOrder.<String>unordered());
-
-    ImmutableGraph<String> emptyGraph = immutableGraphBuilder.build();
-
-    assertThat(emptyGraph.isDirected()).isTrue();
-    assertThat(emptyGraph.allowsSelfLoops()).isTrue();
-    assertThat(emptyGraph.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
-  }
-
-  @Test
-  public void copyOf_incidentEdgeOrder() {
-    ImmutableGraph<Object> graph = ImmutableGraph.copyOf(GraphBuilder.undirected().build());
-
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-
-  @Test
-  public void copyOf_fromUnorderedGraph_incidentEdgeOrder() {
-    ImmutableGraph<Object> graph =
-        ImmutableGraph.copyOf(
-            GraphBuilder.undirected().incidentEdgeOrder(ElementOrder.unordered()).build());
-
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-
-  @Test
-  public void immutableGraphBuilder_addNode() {
-    ImmutableGraph<String> graph = GraphBuilder.directed().<String>immutable().addNode("A").build();
-
-    assertThat(graph.nodes()).containsExactly("A");
-    assertThat(graph.edges()).isEmpty();
-  }
-
-  @Test
-  public void immutableGraphBuilder_putEdgeFromNodes() {
-    ImmutableGraph<String> graph =
-        GraphBuilder.directed().<String>immutable().putEdge("A", "B").build();
-
-    assertThat(graph.nodes()).containsExactly("A", "B");
-    assertThat(graph.edges()).containsExactly(EndpointPair.ordered("A", "B"));
-  }
-
-  @Test
-  public void immutableGraphBuilder_putEdgeFromEndpointPair() {
-    ImmutableGraph<String> graph =
-        GraphBuilder.directed().<String>immutable().putEdge(EndpointPair.ordered("A", "B")).build();
-
-    assertThat(graph.nodes()).containsExactly("A", "B");
-    assertThat(graph.edges()).containsExactly(EndpointPair.ordered("A", "B"));
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardImmutableUndirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/StandardImmutableUndirectedGraphTest.java
deleted file mode 100644
index 7f580a6..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardImmutableUndirectedGraphTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for an undirected {@link StandardMutableGraph}. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public final class StandardImmutableUndirectedGraphTest
-    extends AbstractStandardUndirectedGraphTest {
-
-  @Parameters(name = "allowsSelfLoops={0}")
-  public static Collection<Object[]> parameters() {
-    return Arrays.asList(new Object[][] {{false}, {true}});
-  }
-
-  private final boolean allowsSelfLoops;
-  private ImmutableGraph.Builder<Integer> graphBuilder;
-
-  public StandardImmutableUndirectedGraphTest(boolean allowsSelfLoops) {
-    this.allowsSelfLoops = allowsSelfLoops;
-  }
-
-  @Override
-  public Graph<Integer> createGraph() {
-    graphBuilder = GraphBuilder.undirected().allowsSelfLoops(allowsSelfLoops).immutable();
-    return graphBuilder.build();
-  }
-
-  @Override
-  final void addNode(Integer n) {
-    graphBuilder.addNode(n);
-    graph = graphBuilder.build();
-  }
-
-  @Override
-  final void putEdge(Integer n1, Integer n2) {
-    graphBuilder.putEdge(n1, n2);
-    graph = graphBuilder.build();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardMutableDirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/StandardMutableDirectedGraphTest.java
deleted file mode 100644
index 191010e..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardMutableDirectedGraphTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for a directed {@link StandardMutableGraph}. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public final class StandardMutableDirectedGraphTest extends AbstractStandardDirectedGraphTest {
-
-  @Parameters(name = "allowsSelfLoops={0}, incidentEdgeOrder={1}")
-  public static Collection<Object[]> parameters() {
-    return Arrays.asList(
-        new Object[][] {
-          {false, ElementOrder.unordered()},
-          {true, ElementOrder.unordered()},
-          {false, ElementOrder.stable()},
-          {true, ElementOrder.stable()},
-        });
-  }
-
-  private final boolean allowsSelfLoops;
-  private final ElementOrder<Integer> incidentEdgeOrder;
-
-  public StandardMutableDirectedGraphTest(
-      boolean allowsSelfLoops, ElementOrder<Integer> incidentEdgeOrder) {
-    this.allowsSelfLoops = allowsSelfLoops;
-    this.incidentEdgeOrder = incidentEdgeOrder;
-  }
-
-  @Override
-  public MutableGraph<Integer> createGraph() {
-    return GraphBuilder.directed()
-        .allowsSelfLoops(allowsSelfLoops)
-        .incidentEdgeOrder(incidentEdgeOrder)
-        .build();
-  }
-
-  @Override
-  final void addNode(Integer n) {
-    graphAsMutableGraph.addNode(n);
-  }
-
-  @Override
-  final void putEdge(Integer n1, Integer n2) {
-    graphAsMutableGraph.putEdge(n1, n2);
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardMutableDirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/StandardMutableDirectedNetworkTest.java
deleted file mode 100644
index fb8be1d..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardMutableDirectedNetworkTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import com.google.common.collect.Ordering;
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for a directed {@link StandardMutableNetwork} allowing self-loops. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public class StandardMutableDirectedNetworkTest extends AbstractStandardDirectedNetworkTest {
-
-  @Parameters(name = "allowsSelfLoops={0}, allowsParallelEdges={1}, nodeOrder={2}, edgeOrder={3}")
-  public static Collection<Object[]> parameters() {
-    ElementOrder<?> naturalElementOrder = ElementOrder.sorted(Ordering.natural());
-
-    return Arrays.asList(
-        new Object[][] {
-          {false, false, ElementOrder.insertion(), ElementOrder.insertion()},
-          {true, false, ElementOrder.insertion(), ElementOrder.insertion()},
-          {false, false, naturalElementOrder, naturalElementOrder},
-          {true, true, ElementOrder.insertion(), ElementOrder.insertion()},
-        });
-  }
-
-  private final boolean allowsSelfLoops;
-  private final boolean allowsParallelEdges;
-  private final ElementOrder<Integer> nodeOrder;
-  private final ElementOrder<String> edgeOrder;
-
-  public StandardMutableDirectedNetworkTest(
-      boolean allowsSelfLoops,
-      boolean allowsParallelEdges,
-      ElementOrder<Integer> nodeOrder,
-      ElementOrder<String> edgeOrder) {
-    this.allowsSelfLoops = allowsSelfLoops;
-    this.allowsParallelEdges = allowsParallelEdges;
-    this.nodeOrder = nodeOrder;
-    this.edgeOrder = edgeOrder;
-  }
-
-  @Override
-  MutableNetwork<Integer, String> createGraph() {
-    return NetworkBuilder.directed()
-        .allowsSelfLoops(allowsSelfLoops)
-        .allowsParallelEdges(allowsParallelEdges)
-        .nodeOrder(nodeOrder)
-        .edgeOrder(edgeOrder)
-        .build();
-  }
-
-  @Override
-  void addNode(Integer n) {
-    networkAsMutableNetwork.addNode(n);
-  }
-
-  @Override
-  void addEdge(Integer n1, Integer n2, String e) {
-    networkAsMutableNetwork.addEdge(n1, n2, e);
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardMutableUndirectedGraphTest.java b/android/guava-tests/test/com/google/common/graph/StandardMutableUndirectedGraphTest.java
deleted file mode 100644
index aa0372a..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardMutableUndirectedGraphTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for an undirected {@link StandardMutableGraph}. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public class StandardMutableUndirectedGraphTest extends AbstractStandardUndirectedGraphTest {
-
-  @Parameters(name = "allowsSelfLoops={0}, incidentEdgeOrder={1}")
-  public static Collection<Object[]> parameters() {
-    return Arrays.asList(
-        new Object[][] {
-          {false, ElementOrder.unordered()},
-          {true, ElementOrder.unordered()},
-          {false, ElementOrder.stable()},
-          {true, ElementOrder.stable()},
-        });
-  }
-
-  private final boolean allowsSelfLoops;
-  private final ElementOrder<Integer> incidentEdgeOrder;
-
-  public StandardMutableUndirectedGraphTest(
-      boolean allowsSelfLoops, ElementOrder<Integer> incidentEdgeOrder) {
-    this.allowsSelfLoops = allowsSelfLoops;
-    this.incidentEdgeOrder = incidentEdgeOrder;
-  }
-
-  @Override
-  public MutableGraph<Integer> createGraph() {
-    return GraphBuilder.undirected()
-        .allowsSelfLoops(allowsSelfLoops)
-        .incidentEdgeOrder(incidentEdgeOrder)
-        .build();
-  }
-
-  @Override
-  final void addNode(Integer n) {
-    graphAsMutableGraph.addNode(n);
-  }
-
-  @Override
-  final void putEdge(Integer n1, Integer n2) {
-    graphAsMutableGraph.putEdge(n1, n2);
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/StandardMutableUndirectedNetworkTest.java b/android/guava-tests/test/com/google/common/graph/StandardMutableUndirectedNetworkTest.java
deleted file mode 100644
index c021b5d..0000000
--- a/android/guava-tests/test/com/google/common/graph/StandardMutableUndirectedNetworkTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.graph;
-
-import com.google.common.collect.Ordering;
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/** Tests for an undirected {@link StandardMutableNetwork}. */
-@AndroidIncompatible
-@RunWith(Parameterized.class)
-public final class StandardMutableUndirectedNetworkTest
-    extends AbstractStandardUndirectedNetworkTest {
-
-  @Parameters(name = "allowsSelfLoops={0}, allowsParallelEdges={1}, nodeOrder={2}, edgeOrder={3}")
-  public static Collection<Object[]> parameters() {
-    ElementOrder<?> naturalElementOrder = ElementOrder.sorted(Ordering.natural());
-
-    return Arrays.asList(
-        new Object[][] {
-          {false, false, ElementOrder.insertion(), ElementOrder.insertion()},
-          {true, false, ElementOrder.insertion(), ElementOrder.insertion()},
-          {false, false, naturalElementOrder, naturalElementOrder},
-          {true, true, ElementOrder.insertion(), ElementOrder.insertion()},
-        });
-  }
-
-  private final boolean allowsSelfLoops;
-  private final boolean allowsParallelEdges;
-  private final ElementOrder<Integer> nodeOrder;
-  private final ElementOrder<String> edgeOrder;
-
-  public StandardMutableUndirectedNetworkTest(
-      boolean allowsSelfLoops,
-      boolean allowsParallelEdges,
-      ElementOrder<Integer> nodeOrder,
-      ElementOrder<String> edgeOrder) {
-    this.allowsSelfLoops = allowsSelfLoops;
-    this.allowsParallelEdges = allowsParallelEdges;
-    this.nodeOrder = nodeOrder;
-    this.edgeOrder = edgeOrder;
-  }
-
-  @Override
-  MutableNetwork<Integer, String> createGraph() {
-    return NetworkBuilder.undirected()
-        .allowsSelfLoops(allowsSelfLoops)
-        .allowsParallelEdges(allowsParallelEdges)
-        .nodeOrder(nodeOrder)
-        .edgeOrder(edgeOrder)
-        .build();
-  }
-
-  @Override
-  void addNode(Integer n) {
-    networkAsMutableNetwork.addNode(n);
-  }
-
-  @Override
-  void addEdge(Integer n1, Integer n2, String e) {
-    networkAsMutableNetwork.addEdge(n1, n2, e);
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/graph/TraverserTest.java b/android/guava-tests/test/com/google/common/graph/TraverserTest.java
index d4c8cf7..f1db943 100644
--- a/android/guava-tests/test/com/google/common/graph/TraverserTest.java
+++ b/android/guava-tests/test/com/google/common/graph/TraverserTest.java
@@ -185,13 +185,6 @@
   }
 
   @Test
-  public void forGraph_breadthFirst_infinite() {
-    Iterable<Integer> result =
-        Traverser.forGraph(fixedSuccessors(Iterables.cycle(1, 2, 3))).breadthFirst(0);
-    assertThat(Iterables.limit(result, 4)).containsExactly(0, 1, 2, 3).inOrder();
-  }
-
-  @Test
   public void forGraph_breadthFirst_diamond() {
     Traverser<Character> traverser = Traverser.forGraph(DIAMOND_GRAPH);
     assertEqualCharNodes(traverser.breadthFirst('a'), "abcd");
@@ -381,13 +374,6 @@
   }
 
   @Test
-  public void forGraph_depthFirstPreOrder_infinite() {
-    Iterable<Integer> result =
-        Traverser.forGraph(fixedSuccessors(Iterables.cycle(1, 2, 3))).depthFirstPreOrder(0);
-    assertThat(Iterables.limit(result, 3)).containsExactly(0, 1, 2).inOrder();
-  }
-
-  @Test
   public void forGraph_depthFirstPreOrder_diamond() {
     Traverser<Character> traverser = Traverser.forGraph(DIAMOND_GRAPH);
     assertEqualCharNodes(traverser.depthFirstPreOrder('a'), "abdc");
@@ -533,11 +519,11 @@
     Iterable<Character> result = Traverser.forGraph(graph).depthFirstPreOrder('a');
 
     assertEqualCharNodes(Iterables.limit(result, 2), "ab");
-    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'b');
+    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'b', 'd');
 
     // Iterate again to see if calculation is done again
     assertEqualCharNodes(Iterables.limit(result, 2), "ab");
-    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'a', 'b', 'b');
+    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'a', 'b', 'b', 'd', 'd');
   }
 
   @Test
@@ -546,11 +532,11 @@
     Iterable<Character> result = Traverser.forGraph(graph).depthFirstPreOrder(charactersOf("ac"));
 
     assertEqualCharNodes(Iterables.limit(result, 2), "ab");
-    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'b', 'c');
+    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'b', 'c', 'd');
 
     // Iterate again to see if calculation is done again
     assertEqualCharNodes(Iterables.limit(result, 2), "ab");
-    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'a', 'b', 'b', 'c');
+    assertThat(graph.requestedNodes).containsExactly('a', 'a', 'a', 'b', 'b', 'c', 'd', 'd');
   }
 
   @Test
@@ -799,13 +785,6 @@
   }
 
   @Test
-  public void forTree_breadthFirst_infinite() {
-    Iterable<Integer> result =
-        Traverser.forTree(fixedSuccessors(Iterables.cycle(1, 2, 3))).breadthFirst(0);
-    assertThat(Iterables.limit(result, 8)).containsExactly(0, 1, 2, 3, 1, 2, 3, 1).inOrder();
-  }
-
-  @Test
   public void forTree_breadthFirst_tree() throws Exception {
     Traverser<Character> traverser = Traverser.forTree(TREE);
 
@@ -934,13 +913,6 @@
   }
 
   @Test
-  public void forTree_depthFirstPreOrder_infinite() {
-    Iterable<Integer> result =
-        Traverser.forTree(fixedSuccessors(Iterables.cycle(1, 2, 3))).depthFirstPreOrder(0);
-    assertThat(Iterables.limit(result, 3)).containsExactly(0, 1, 1).inOrder();
-  }
-
-  @Test
   public void forTree_depthFirstPreOrderIterable_tree() throws Exception {
     Traverser<Character> traverser = Traverser.forTree(TREE);
 
@@ -1050,11 +1022,11 @@
     Iterable<Character> result = Traverser.forGraph(graph).depthFirstPreOrder('h');
 
     assertEqualCharNodes(Iterables.limit(result, 2), "hd");
-    assertThat(graph.requestedNodes).containsExactly('h', 'h', 'd');
+    assertThat(graph.requestedNodes).containsExactly('h', 'h', 'd', 'a');
 
     // Iterate again to see if calculation is done again
     assertEqualCharNodes(Iterables.limit(result, 2), "hd");
-    assertThat(graph.requestedNodes).containsExactly('h', 'h', 'h', 'd', 'd');
+    assertThat(graph.requestedNodes).containsExactly('h', 'h', 'h', 'd', 'd', 'a', 'a');
   }
 
   @Test
@@ -1266,13 +1238,4 @@
       return delegate.successors(node);
     }
   }
-
-  private static <N> SuccessorsFunction<N> fixedSuccessors(final Iterable<N> successors) {
-    return new SuccessorsFunction<N>() {
-      @Override
-      public Iterable<N> successors(N n) {
-        return successors;
-      }
-    };
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/graph/ValueGraphTest.java b/android/guava-tests/test/com/google/common/graph/ValueGraphTest.java
index a3f4814..a295692 100644
--- a/android/guava-tests/test/com/google/common/graph/ValueGraphTest.java
+++ b/android/guava-tests/test/com/google/common/graph/ValueGraphTest.java
@@ -19,21 +19,14 @@
 import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
 import static com.google.common.graph.TestUtil.assertStronglyEquivalent;
 import static com.google.common.truth.Truth.assertThat;
-import static java.util.concurrent.Executors.newFixedThreadPool;
 import static org.junit.Assert.fail;
 
-import com.google.common.collect.ImmutableList;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
 import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-/** Tests for {@link StandardMutableValueGraph} and related functionality. */
+/** Tests for {@link ConfigurableMutableValueGraph} and related functionality. */
 // TODO(user): Expand coverage and move to proper test suite.
 @RunWith(JUnit4.class)
 public final class ValueGraphTest {
@@ -51,7 +44,6 @@
     assertThat(graph.nodes()).isEqualTo(asGraph.nodes());
     assertThat(graph.edges()).isEqualTo(asGraph.edges());
     assertThat(graph.nodeOrder()).isEqualTo(asGraph.nodeOrder());
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(asGraph.incidentEdgeOrder());
     assertThat(graph.isDirected()).isEqualTo(asGraph.isDirected());
     assertThat(graph.allowsSelfLoops()).isEqualTo(asGraph.allowsSelfLoops());
 
@@ -122,18 +114,6 @@
   }
 
   @Test
-  public void incidentEdgeOrder_unordered() {
-    graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.unordered()).build();
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.unordered());
-  }
-
-  @Test
-  public void incidentEdgeOrder_stable() {
-    graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.stable()).build();
-    assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
-  }
-
-  @Test
   public void hasEdgeConnecting_directed_correct() {
     graph = ValueGraphBuilder.directed().build();
     graph.putEdgeValue(1, 2, "A");
@@ -350,72 +330,4 @@
     otherGraph.putEdgeValue(1, 2, "valueB");
     assertThat(graph).isNotEqualTo(otherGraph); // values differ
   }
-
-  @Test
-  public void incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_directed() {
-    graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.stable()).build();
-    graph.putEdgeValue(2, 1, "2-1");
-    graph.putEdgeValue(2, 3, "2-3");
-    graph.putEdgeValue(1, 2, "1-2");
-
-    assertThat(graph.incidentEdges(2))
-        .containsExactly(
-            EndpointPair.ordered(2, 1), EndpointPair.ordered(2, 3), EndpointPair.ordered(1, 2))
-        .inOrder();
-  }
-
-  @Test
-  public void incidentEdges_stableIncidentEdgeOrder_preservesIncidentEdgesOrder_undirected() {
-    graph = ValueGraphBuilder.undirected().incidentEdgeOrder(ElementOrder.stable()).build();
-    graph.putEdgeValue(2, 3, "2-3");
-    graph.putEdgeValue(2, 1, "2-1");
-    graph.putEdgeValue(2, 4, "2-4");
-    graph.putEdgeValue(1, 2, "1-2"); // Duplicate nodes, different value
-
-    assertThat(graph.incidentEdges(2))
-        .containsExactly(
-            EndpointPair.unordered(2, 3),
-            EndpointPair.unordered(1, 2),
-            EndpointPair.unordered(2, 4))
-        .inOrder();
-  }
-
-  @Test
-  public void concurrentIteration() throws Exception {
-    graph = ValueGraphBuilder.directed().build();
-    graph.putEdgeValue(1, 2, "A");
-    graph.putEdgeValue(3, 4, "B");
-    graph.putEdgeValue(5, 6, "C");
-
-    int threadCount = 20;
-    ExecutorService executor = newFixedThreadPool(threadCount);
-    final CyclicBarrier barrier = new CyclicBarrier(threadCount);
-    ImmutableList.Builder<Future<?>> futures = ImmutableList.builder();
-    for (int i = 0; i < threadCount; i++) {
-      futures.add(
-          executor.submit(
-              new Callable<Object>() {
-                @Override
-                public Object call() throws Exception {
-                  barrier.await();
-                  Integer first = graph.nodes().iterator().next();
-                  for (Integer node : graph.nodes()) {
-                    Set<Integer> unused = graph.successors(node);
-                  }
-                  /*
-                   * Also look up an earlier node so that, if the graph is using MapRetrievalCache,
-                   * we read one of the fields declared in that class.
-                   */
-                  Set<Integer> unused = graph.successors(first);
-                  return null;
-                }
-              }));
-    }
-
-    // For more about this test, see the equivalent in AbstractNetworkTest.
-    for (Future<?> future : futures.build()) {
-      future.get();
-    }
-    executor.shutdown();
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java b/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java
index 4d64f98..d1cf3fd 100644
--- a/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java
+++ b/android/guava-tests/test/com/google/common/hash/BloomFilterTest.java
@@ -304,7 +304,7 @@
   public void testLargeNumberOfInsertions() {
     // We use horrible FPPs here to keep Java from OOM'ing
     BloomFilter<String> unused =
-        BloomFilter.create(Funnels.unencodedCharsFunnel(), Integer.MAX_VALUE / 2, 0.30);
+        BloomFilter.create(Funnels.unencodedCharsFunnel(), Integer.MAX_VALUE / 2, 0.29);
     unused = BloomFilter.create(Funnels.unencodedCharsFunnel(), 45L * Integer.MAX_VALUE, 0.99);
   }
 
diff --git a/android/guava-tests/test/com/google/common/hash/FunnelsTest.java b/android/guava-tests/test/com/google/common/hash/FunnelsTest.java
index 6b0c758..922bc5d 100644
--- a/android/guava-tests/test/com/google/common/hash/FunnelsTest.java
+++ b/android/guava-tests/test/com/google/common/hash/FunnelsTest.java
@@ -93,7 +93,7 @@
   }
 
   public void testSequential() {
-    @SuppressWarnings({"unchecked", "DoNotMock"})
+    @SuppressWarnings("unchecked")
     Funnel<Object> elementFunnel = mock(Funnel.class);
     PrimitiveSink primitiveSink = mock(PrimitiveSink.class);
     Funnel<Iterable<?>> sequential = Funnels.sequentialFunnel(elementFunnel);
diff --git a/android/guava-tests/test/com/google/common/hash/HashTestUtils.java b/android/guava-tests/test/com/google/common/hash/HashTestUtils.java
index 8dfbdb0..f2b8971 100644
--- a/android/guava-tests/test/com/google/common/hash/HashTestUtils.java
+++ b/android/guava-tests/test/com/google/common/hash/HashTestUtils.java
@@ -509,9 +509,9 @@
     rng.nextBytes(bytes);
     ByteBuffer littleEndian = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
     ByteBuffer bigEndian = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
-    assertEquals(hashFunction.hashBytes(littleEndian), hashFunction.hashBytes(bigEndian));
+    assertEquals(hashFunction.hashBytes(littleEndian), hashFunction.hashBytes(littleEndian));
     assertEquals(ByteOrder.LITTLE_ENDIAN, littleEndian.order());
-    assertEquals(ByteOrder.BIG_ENDIAN, bigEndian.order());
+    assertEquals(ByteOrder.BIG_ENDIAN, littleEndian.order());
   }
 
   static void assertHasherByteBufferPreservesByteOrder(HashFunction hashFunction) {
@@ -522,9 +522,9 @@
     ByteBuffer bigEndian = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
     assertEquals(
         hashFunction.newHasher().putBytes(littleEndian).hash(),
-        hashFunction.newHasher().putBytes(bigEndian).hash());
+        hashFunction.newHasher().putBytes(littleEndian).hash());
     assertEquals(ByteOrder.LITTLE_ENDIAN, littleEndian.order());
-    assertEquals(ByteOrder.BIG_ENDIAN, bigEndian.order());
+    assertEquals(ByteOrder.BIG_ENDIAN, littleEndian.order());
   }
 
   static void assertHashBytesThrowsCorrectExceptions(HashFunction hashFunction) {
diff --git a/android/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java b/android/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java
index 05351d9..58ed689 100644
--- a/android/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java
+++ b/android/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java
@@ -35,7 +35,6 @@
   private static final byte[] testBytes = new byte[] {'y', 'a', 'm', 's'};
   private ByteArrayInputStream buffer;
 
-  @SuppressWarnings("DoNotMock")
   @Override
   protected void setUp() throws Exception {
     super.setUp();
diff --git a/android/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java b/android/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java
index 55e8fbf..fd8f340 100644
--- a/android/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java
+++ b/android/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java
@@ -33,7 +33,6 @@
   private HashFunction hashFunction;
   private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 
-  @SuppressWarnings("DoNotMock")
   @Override
   protected void setUp() throws Exception {
     super.setUp();
diff --git a/android/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java b/android/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java
index ded4447..c76ec76 100644
--- a/android/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java
+++ b/android/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java
@@ -34,7 +34,7 @@
   private static final HashFunction SIP_WITHOUT_KEY = Hashing.sipHash24();
 
   // These constants were originally ported from https://www.131002.net/siphash/siphash24.c. See:
-  // https://github.com/nahi/siphash-java-inline/blob/master/src/test/java/org/jruby/util/SipHashInlineTest.java
+  // https://github.com/nahi/siphash-java-inline/blob/master/src/test/java/SipHashInlineTest.java
   private static final long[] EXPECTED =
       new long[] {
         0x726fdb47dd0e0e31L,
diff --git a/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java b/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java
index 832fb07..17bc325 100644
--- a/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java
+++ b/android/guava-tests/test/com/google/common/io/BaseEncodingTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.io.BaseEncoding.base32;
 import static com.google.common.io.BaseEncoding.base32Hex;
 import static com.google.common.io.BaseEncoding.base64;
-import static com.google.common.io.BaseEncoding.base64Url;
 import static com.google.common.truth.Truth.assertThat;
 
 import com.google.common.annotations.GwtCompatible;
@@ -32,7 +31,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
 import junit.framework.TestCase;
@@ -192,16 +190,6 @@
     testEncodesWithOffset(base64(), "foobar", 4, 0, "");
   }
 
-  public void testBase64Url() {
-    testDecodesByBytes(base64Url(), "_zzz", new byte[] {-1, 60, -13});
-    testDecodesByBytes(base64Url(), "-zzz", new byte[] {-5, 60, -13});
-  }
-
-  public void testBase64UrlInvalidDecodings() {
-    assertFailsToDecode(base64Url(), "+zzz", "Unrecognized character: +");
-    assertFailsToDecode(base64Url(), "/zzz", "Unrecognized character: /");
-  }
-
   public void testBase32() {
     // The following test vectors are specified in RFC 4648 itself
     testEncodingWithCasing(base32(), "", "");
@@ -395,86 +383,29 @@
     assertThat(encoding.decode(encoded)).isEqualTo(decoded.getBytes(UTF_8));
   }
 
-  private static void testDecodesByBytes(BaseEncoding encoding, String encoded, byte[] decoded) {
-    assertTrue(encoding.canDecode(encoded));
-    assertThat(encoding.decode(encoded)).isEqualTo(decoded);
-  }
-
   private static void assertFailsToDecode(BaseEncoding encoding, String cannotDecode) {
     assertFailsToDecode(encoding, cannotDecode, null);
   }
 
   private static void assertFailsToDecode(
       BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) {
-    // We use this somewhat weird pattern with an enum for each assertion we want to make as a way
-    // of dealing with the fact that one of the assertions is @GwtIncompatible but we don't want to
-    // have to have duplicate @GwtIncompatible test methods just to make that assertion.
-    for (AssertFailsToDecodeStrategy strategy : AssertFailsToDecodeStrategy.values()) {
-      strategy.assertFailsToDecode(encoding, cannotDecode, expectedMessage);
+    assertFalse(encoding.canDecode(cannotDecode));
+    try {
+      encoding.decode(cannotDecode);
+      fail("Expected IllegalArgumentException");
+    } catch (IllegalArgumentException expected) {
+      if (expectedMessage != null) {
+        assertThat(expected).hasCauseThat().hasMessageThat().isEqualTo(expectedMessage);
+      }
     }
-  }
-
-  enum AssertFailsToDecodeStrategy {
-    @GwtIncompatible // decodingStream(Reader)
-    DECODING_STREAM {
-      @Override
-      void assertFailsToDecode(
-          BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) {
-        // Regression test for case where DecodingException was swallowed by default implementation
-        // of
-        // InputStream.read(byte[], int, int)
-        // See https://github.com/google/guava/issues/3542
-        Reader reader = new StringReader(cannotDecode);
-        InputStream decodingStream = encoding.decodingStream(reader);
-        try {
-          ByteStreams.exhaust(decodingStream);
-          fail("Expected DecodingException");
-        } catch (DecodingException expected) {
-          // Don't assert on the expectedMessage; the messages for exceptions thrown from the
-          // decoding stream may differ from the messages for the decode methods.
-        } catch (IOException e) {
-          fail("Expected DecodingException but got: " + e);
-        }
+    try {
+      encoding.decodeChecked(cannotDecode);
+      fail("Expected DecodingException");
+    } catch (DecodingException expected) {
+      if (expectedMessage != null) {
+        assertThat(expected).hasMessageThat().isEqualTo(expectedMessage);
       }
-    },
-    CAN_DECODE {
-      @Override
-      void assertFailsToDecode(
-          BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) {
-        assertFalse(encoding.canDecode(cannotDecode));
-      }
-    },
-    DECODE {
-      @Override
-      void assertFailsToDecode(
-          BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) {
-        try {
-          encoding.decode(cannotDecode);
-          fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-          if (expectedMessage != null) {
-            assertThat(expected).hasCauseThat().hasMessageThat().isEqualTo(expectedMessage);
-          }
-        }
-      }
-    },
-    DECODE_CHECKED {
-      @Override
-      void assertFailsToDecode(
-          BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage) {
-        try {
-          encoding.decodeChecked(cannotDecode);
-          fail("Expected DecodingException");
-        } catch (DecodingException expected) {
-          if (expectedMessage != null) {
-            assertThat(expected).hasMessageThat().isEqualTo(expectedMessage);
-          }
-        }
-      }
-    };
-
-    abstract void assertFailsToDecode(
-        BaseEncoding encoding, String cannotDecode, @NullableDecl String expectedMessage);
+    }
   }
 
   @GwtIncompatible // Reader/Writer
diff --git a/android/guava-tests/test/com/google/common/io/ByteSourceTest.java b/android/guava-tests/test/com/google/common/io/ByteSourceTest.java
index f0ba829..0f5b3d9 100644
--- a/android/guava-tests/test/com/google/common/io/ByteSourceTest.java
+++ b/android/guava-tests/test/com/google/common/io/ByteSourceTest.java
@@ -454,10 +454,6 @@
     }
   }
 
-  public void testSlice_returnEmptySource() {
-    assertEquals(ByteSource.empty(), source.slice(0, 3).slice(4, 3));
-  }
-
   private static int getAndResetRecords(TestLogHandler logHandler) {
     int records = logHandler.getStoredLogRecords().size();
     logHandler.clear();
diff --git a/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java b/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java
index f715303..981238a 100644
--- a/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java
+++ b/android/guava-tests/test/com/google/common/io/ByteStreamsTest.java
@@ -48,7 +48,7 @@
 
     ReadableByteChannel inChannel = Channels.newChannel(new ByteArrayInputStream(expected));
     ByteStreams.copy(inChannel, outChannel);
-    assertThat(out.toByteArray()).isEqualTo(expected);
+    assertEquals(expected, out.toByteArray());
   }
 
   public void testCopyFileChannel() throws IOException {
@@ -57,18 +57,24 @@
     WritableByteChannel outChannel = Channels.newChannel(out);
 
     File testFile = createTempFile();
+    FileOutputStream fos = new FileOutputStream(testFile);
     byte[] dummyData = newPreFilledByteArray(chunkSize);
-    try (FileOutputStream fos = new FileOutputStream(testFile)) {
+    try {
       for (int i = 0; i < 500; i++) {
         fos.write(dummyData);
       }
+    } finally {
+      fos.close();
     }
-    try (ReadableByteChannel inChannel = new RandomAccessFile(testFile, "r").getChannel()) {
+    ReadableByteChannel inChannel = new RandomAccessFile(testFile, "r").getChannel();
+    try {
       ByteStreams.copy(inChannel, outChannel);
+    } finally {
+      inChannel.close();
     }
     byte[] actual = out.toByteArray();
     for (int i = 0; i < 500 * chunkSize; i += chunkSize) {
-      assertThat(Arrays.copyOfRange(actual, i, i + chunkSize)).isEqualTo(dummyData);
+      assertEquals(dummyData, Arrays.copyOfRange(actual, i, i + chunkSize));
     }
   }
 
@@ -78,56 +84,56 @@
     try {
       ByteStreams.readFully(newTestStream(10), null, 0, 10);
       fail("expected exception");
-    } catch (NullPointerException expected) {
+    } catch (NullPointerException e) {
     }
 
     try {
       ByteStreams.readFully(null, b, 0, 10);
       fail("expected exception");
-    } catch (NullPointerException expected) {
+    } catch (NullPointerException e) {
     }
 
     try {
       ByteStreams.readFully(newTestStream(10), b, -1, 10);
       fail("expected exception");
-    } catch (IndexOutOfBoundsException expected) {
+    } catch (IndexOutOfBoundsException e) {
     }
 
     try {
       ByteStreams.readFully(newTestStream(10), b, 0, -1);
       fail("expected exception");
-    } catch (IndexOutOfBoundsException expected) {
+    } catch (IndexOutOfBoundsException e) {
     }
 
     try {
       ByteStreams.readFully(newTestStream(10), b, 0, -1);
       fail("expected exception");
-    } catch (IndexOutOfBoundsException expected) {
+    } catch (IndexOutOfBoundsException e) {
     }
 
     try {
       ByteStreams.readFully(newTestStream(10), b, 2, 10);
       fail("expected exception");
-    } catch (IndexOutOfBoundsException expected) {
+    } catch (IndexOutOfBoundsException e) {
     }
 
     try {
       ByteStreams.readFully(newTestStream(5), b, 0, 10);
       fail("expected exception");
-    } catch (EOFException expected) {
+    } catch (EOFException e) {
     }
 
     Arrays.fill(b, (byte) 0);
     ByteStreams.readFully(newTestStream(10), b, 0, 0);
-    assertThat(b).isEqualTo(new byte[10]);
+    assertEquals(new byte[10], b);
 
     Arrays.fill(b, (byte) 0);
     ByteStreams.readFully(newTestStream(10), b, 0, 10);
-    assertThat(b).isEqualTo(newPreFilledByteArray(10));
+    assertEquals(newPreFilledByteArray(10), b);
 
     Arrays.fill(b, (byte) 0);
     ByteStreams.readFully(newTestStream(10), b, 0, 5);
-    assertThat(b).isEqualTo(new byte[] {0, 1, 2, 3, 4, 0, 0, 0, 0, 0});
+    assertEquals(new byte[] {0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b);
   }
 
   public void testSkipFully() throws IOException {
@@ -140,7 +146,7 @@
     try {
       skipHelper(101, 0, new ByteArrayInputStream(bytes));
       fail("expected exception");
-    } catch (EOFException expected) {
+    } catch (EOFException e) {
     }
   }
 
@@ -177,7 +183,7 @@
     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
     byte[] actual = new byte[bytes.length];
     in.readFully(actual);
-    assertThat(actual).isEqualTo(bytes);
+    assertEquals(bytes, actual);
   }
 
   public void testNewDataInput_readFullyAndThenSome() {
@@ -262,27 +268,27 @@
 
   public void testNewDataInput_readByte() {
     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
-    for (byte aByte : bytes) {
-      assertEquals(aByte, in.readByte());
+    for (int i = 0; i < bytes.length; i++) {
+      assertEquals(bytes[i], in.readByte());
     }
     try {
       in.readByte();
       fail("expected exception");
-    } catch (IllegalStateException expected) {
-      assertThat(expected).hasCauseThat().isInstanceOf(EOFException.class);
+    } catch (IllegalStateException ex) {
+      assertThat(ex).hasCauseThat().isInstanceOf(EOFException.class);
     }
   }
 
   public void testNewDataInput_readUnsignedByte() {
     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
-    for (byte aByte : bytes) {
-      assertEquals(aByte, in.readUnsignedByte());
+    for (int i = 0; i < bytes.length; i++) {
+      assertEquals(bytes[i], in.readUnsignedByte());
     }
     try {
       in.readUnsignedByte();
       fail("expected exception");
-    } catch (IllegalStateException expected) {
-      assertThat(expected).hasCauseThat().isInstanceOf(EOFException.class);
+    } catch (IllegalStateException ex) {
+      assertThat(ex).hasCauseThat().isInstanceOf(EOFException.class);
     }
   }
 
@@ -317,40 +323,40 @@
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.writeInt(0x12345678);
     out.writeInt(0x76543210);
-    assertThat(out.toByteArray()).isEqualTo(bytes);
+    assertEquals(bytes, out.toByteArray());
   }
 
   public void testNewDataOutput_sized() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput(4);
     out.writeInt(0x12345678);
     out.writeInt(0x76543210);
-    assertThat(out.toByteArray()).isEqualTo(bytes);
+    assertEquals(bytes, out.toByteArray());
   }
 
   public void testNewDataOutput_writeLong() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.writeLong(0x1234567876543210L);
-    assertThat(out.toByteArray()).isEqualTo(bytes);
+    assertEquals(bytes, out.toByteArray());
   }
 
   public void testNewDataOutput_writeByteArray() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.write(bytes);
-    assertThat(out.toByteArray()).isEqualTo(bytes);
+    assertEquals(bytes, out.toByteArray());
   }
 
   public void testNewDataOutput_writeByte() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.write(0x12);
     out.writeByte(0x34);
-    assertThat(out.toByteArray()).isEqualTo(new byte[] {0x12, 0x34});
+    assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
   }
 
   public void testNewDataOutput_writeByteOffset() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.write(bytes, 4, 2);
     byte[] expected = {bytes[4], bytes[5]};
-    assertThat(out.toByteArray()).isEqualTo(expected);
+    assertEquals(expected, out.toByteArray());
   }
 
   public void testNewDataOutput_writeBoolean() {
@@ -358,13 +364,13 @@
     out.writeBoolean(true);
     out.writeBoolean(false);
     byte[] expected = {(byte) 1, (byte) 0};
-    assertThat(out.toByteArray()).isEqualTo(expected);
+    assertEquals(expected, out.toByteArray());
   }
 
   public void testNewDataOutput_writeChar() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.writeChar('a');
-    assertThat(out.toByteArray()).isEqualTo(new byte[] {0, 97});
+    assertEquals(new byte[] {0, 97}, out.toByteArray());
   }
 
   // Hardcoded because of Android problems. See testUtf16Expected.
@@ -376,14 +382,14 @@
     out.writeChars("r\u00C9sum\u00C9");
     // need to remove byte order mark before comparing
     byte[] expected = Arrays.copyOfRange(utf16ExpectedWithBom, 2, 14);
-    assertThat(out.toByteArray()).isEqualTo(expected);
+    assertEquals(expected, out.toByteArray());
   }
 
   @AndroidIncompatible // https://code.google.com/p/android/issues/detail?id=196848
   public void testUtf16Expected() {
     byte[] hardcodedExpected = utf16ExpectedWithBom;
     byte[] computedExpected = "r\u00C9sum\u00C9".getBytes(Charsets.UTF_16);
-    assertThat(computedExpected).isEqualTo(hardcodedExpected);
+    assertEquals(hardcodedExpected, computedExpected);
   }
 
   public void testNewDataOutput_writeUTF() {
@@ -394,26 +400,26 @@
     // writeUTF writes the length of the string in 2 bytes
     assertEquals(0, actual[0]);
     assertEquals(expected.length, actual[1]);
-    assertThat(Arrays.copyOfRange(actual, 2, actual.length)).isEqualTo(expected);
+    assertEquals(expected, Arrays.copyOfRange(actual, 2, actual.length));
   }
 
   public void testNewDataOutput_writeShort() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.writeShort(0x1234);
-    assertThat(out.toByteArray()).isEqualTo(new byte[] {0x12, 0x34});
+    assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
   }
 
   public void testNewDataOutput_writeDouble() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.writeDouble(Double.longBitsToDouble(0x1234567876543210L));
-    assertThat(out.toByteArray()).isEqualTo(bytes);
+    assertEquals(bytes, out.toByteArray());
   }
 
   public void testNewDataOutput_writeFloat() {
     ByteArrayDataOutput out = ByteStreams.newDataOutput();
     out.writeFloat(Float.intBitsToFloat(0x12345678));
     out.writeFloat(Float.intBitsToFloat(0x76543210));
-    assertThat(out.toByteArray()).isEqualTo(bytes);
+    assertEquals(bytes, out.toByteArray());
   }
 
   public void testNewDataOutput_BAOS() {
@@ -421,7 +427,7 @@
     ByteArrayDataOutput out = ByteStreams.newDataOutput(baos);
     out.writeInt(0x12345678);
     assertEquals(4, baos.size());
-    assertThat(baos.toByteArray()).isEqualTo(new byte[] {0x12, 0x34, 0x56, 0x78});
+    assertEquals(new byte[] {0x12, 0x34, 0x56, 0x78}, baos.toByteArray());
   }
 
   private static final byte[] PRE_FILLED_100 = newPreFilledByteArray(100);
@@ -429,13 +435,13 @@
   public void testToByteArray() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     byte[] b = ByteStreams.toByteArray(in);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testToByteArray_emptyStream() throws IOException {
     InputStream in = newTestStream(0);
     byte[] b = ByteStreams.toByteArray(in);
-    assertThat(b).isEqualTo(new byte[0]);
+    assertEquals(new byte[0], b);
   }
 
   public void testToByteArray_largeStream() throws IOException {
@@ -443,44 +449,44 @@
     byte[] expected = newPreFilledByteArray(10000000);
     InputStream in = new ByteArrayInputStream(expected);
     byte[] b = ByteStreams.toByteArray(in);
-    assertThat(b).isEqualTo(expected);
+    assertEquals(expected, b);
   }
 
   public void testToByteArray_withSize_givenCorrectSize() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     byte[] b = ByteStreams.toByteArray(in, 100);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testToByteArray_withSize_givenSmallerSize() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     byte[] b = ByteStreams.toByteArray(in, 80);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testToByteArray_withSize_givenLargerSize() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     byte[] b = ByteStreams.toByteArray(in, 120);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testToByteArray_withSize_givenSizeZero() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     byte[] b = ByteStreams.toByteArray(in, 0);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testToByteArray_withSize_givenSizeOneSmallerThanActual() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     // this results in toByteArrayInternal being called when the stream is actually exhausted
     byte[] b = ByteStreams.toByteArray(in, 99);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testToByteArray_withSize_givenSizeTwoSmallerThanActual() throws IOException {
     InputStream in = new ByteArrayInputStream(PRE_FILLED_100);
     byte[] b = ByteStreams.toByteArray(in, 98);
-    assertThat(b).isEqualTo(PRE_FILLED_100);
+    assertEquals(PRE_FILLED_100, b);
   }
 
   public void testExhaust() throws IOException {
@@ -502,7 +508,7 @@
   private static class SlowSkipper extends FilterInputStream {
     private final long max;
 
-    SlowSkipper(InputStream in, long max) {
+    public SlowSkipper(InputStream in, long max) {
       super(in);
       this.max = max;
     }
@@ -515,15 +521,15 @@
 
   public void testReadBytes() throws IOException {
     final byte[] array = newPreFilledByteArray(1000);
-    assertThat(ByteStreams.readBytes(new ByteArrayInputStream(array), new TestByteProcessor()))
-        .isEqualTo(array);
+    assertEquals(
+        array, ByteStreams.readBytes(new ByteArrayInputStream(array), new TestByteProcessor()));
   }
 
-  private static class TestByteProcessor implements ByteProcessor<byte[]> {
+  private class TestByteProcessor implements ByteProcessor<byte[]> {
     private final ByteArrayOutputStream out = new ByteArrayOutputStream();
 
     @Override
-    public boolean processBytes(byte[] buf, int off, int len) {
+    public boolean processBytes(byte[] buf, int off, int len) throws IOException {
       out.write(buf, off, len);
       return true;
     }
@@ -543,8 +549,7 @@
             new ByteProcessor<Integer>() {
               @Override
               public boolean processBytes(byte[] buf, int off, int len) {
-                assertThat(newPreFilledByteArray(8192))
-                    .isEqualTo(Arrays.copyOfRange(buf, off, off + len));
+                assertEquals(copyOfRange(buf, off, off + len), newPreFilledByteArray(8192));
                 return false;
               }
 
@@ -671,4 +676,17 @@
       return false;
     }
   }
+
+  private static byte[] copyOfRange(byte[] in, int from, int to) {
+    byte[] out = new byte[to - from];
+    for (int i = 0; i < to - from; i++) {
+      out[i] = in[from + i];
+    }
+    return out;
+  }
+
+  // TODO(cpovirk): Inline this.
+  private static void assertEquals(byte[] expected, byte[] actual) {
+    assertThat(actual).isEqualTo(expected);
+  }
 }
diff --git a/android/guava-tests/test/com/google/common/io/CharStreamsTest.java b/android/guava-tests/test/com/google/common/io/CharStreamsTest.java
index 9b2c24e..3007f09 100644
--- a/android/guava-tests/test/com/google/common/io/CharStreamsTest.java
+++ b/android/guava-tests/test/com/google/common/io/CharStreamsTest.java
@@ -267,21 +267,6 @@
     String test = "Test string for NullWriter";
     nullWriter.write(test);
     nullWriter.write(test, 2, 10);
-    nullWriter.append(null);
-    nullWriter.append(null, 0, 4);
-
-    try {
-      nullWriter.append(null, -1, 4);
-      fail();
-    } catch (IndexOutOfBoundsException expected) {
-    }
-
-    try {
-      nullWriter.append(null, 0, 5);
-      fail();
-    } catch (IndexOutOfBoundsException expected) {
-    }
-
     // nothing really to assert?
     assertSame(CharStreams.nullWriter(), CharStreams.nullWriter());
   }
diff --git a/android/guava-tests/test/com/google/common/math/BigDecimalMathTest.java b/android/guava-tests/test/com/google/common/math/BigDecimalMathTest.java
deleted file mode 100644
index ff86fd5..0000000
--- a/android/guava-tests/test/com/google/common/math/BigDecimalMathTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2020 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-import static java.math.RoundingMode.CEILING;
-import static java.math.RoundingMode.DOWN;
-import static java.math.RoundingMode.FLOOR;
-import static java.math.RoundingMode.HALF_DOWN;
-import static java.math.RoundingMode.HALF_EVEN;
-import static java.math.RoundingMode.HALF_UP;
-import static java.math.RoundingMode.UNNECESSARY;
-import static java.math.RoundingMode.UP;
-import static java.math.RoundingMode.values;
-
-import com.google.common.annotations.GwtIncompatible;
-import java.math.BigDecimal;
-import java.math.MathContext;
-import java.math.RoundingMode;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Map;
-import junit.framework.TestCase;
-
-@GwtIncompatible
-public class BigDecimalMathTest extends TestCase {
-  private static final class RoundToDoubleTester {
-    private final BigDecimal input;
-    private final Map<RoundingMode, Double> expectedValues = new EnumMap<>(RoundingMode.class);
-    private boolean unnecessaryShouldThrow = false;
-
-    RoundToDoubleTester(BigDecimal input) {
-      this.input = input;
-    }
-
-    RoundToDoubleTester setExpectation(double expectedValue, RoundingMode... modes) {
-      for (RoundingMode mode : modes) {
-        Double previous = expectedValues.put(mode, expectedValue);
-        if (previous != null) {
-          throw new AssertionError();
-        }
-      }
-      return this;
-    }
-
-    public RoundToDoubleTester roundUnnecessaryShouldThrow() {
-      unnecessaryShouldThrow = true;
-      return this;
-    }
-
-    public void test() {
-      assertThat(expectedValues.keySet())
-          .containsAtLeastElementsIn(EnumSet.complementOf(EnumSet.of(UNNECESSARY)));
-      for (Map.Entry<RoundingMode, Double> entry : expectedValues.entrySet()) {
-        RoundingMode mode = entry.getKey();
-        Double expectation = entry.getValue();
-        assertWithMessage("roundToDouble(" + input + ", " + mode + ")")
-            .that(BigDecimalMath.roundToDouble(input, mode))
-            .isEqualTo(expectation);
-      }
-
-      if (!expectedValues.containsKey(UNNECESSARY)) {
-        assertWithMessage("Expected roundUnnecessaryShouldThrow call")
-            .that(unnecessaryShouldThrow)
-            .isTrue();
-        try {
-          BigDecimalMath.roundToDouble(input, UNNECESSARY);
-          fail("Expected ArithmeticException for roundToDouble(" + input + ", UNNECESSARY)");
-        } catch (ArithmeticException expected) {
-          // expected
-        }
-      }
-    }
-  }
-
-  public void testRoundToDouble_zero() {
-    new RoundToDoubleTester(BigDecimal.ZERO).setExpectation(0.0, values()).test();
-  }
-
-  public void testRoundToDouble_oneThird() {
-    new RoundToDoubleTester(
-            BigDecimal.ONE.divide(BigDecimal.valueOf(3), new MathContext(50, HALF_EVEN)))
-        .roundUnnecessaryShouldThrow()
-        .setExpectation(0.33333333333333337, UP, CEILING)
-        .setExpectation(0.3333333333333333, HALF_EVEN, FLOOR, DOWN, HALF_UP, HALF_DOWN)
-        .test();
-  }
-
-  public void testRoundToDouble_halfMinDouble() {
-    BigDecimal minDouble = new BigDecimal(Double.MIN_VALUE);
-    BigDecimal halfMinDouble = minDouble.divide(BigDecimal.valueOf(2));
-    new RoundToDoubleTester(halfMinDouble)
-        .roundUnnecessaryShouldThrow()
-        .setExpectation(Double.MIN_VALUE, UP, CEILING, HALF_UP)
-        .setExpectation(0.0, HALF_EVEN, FLOOR, DOWN, HALF_DOWN)
-        .test();
-  }
-
-  public void testRoundToDouble_halfNegativeMinDouble() {
-    BigDecimal minDouble = new BigDecimal(-Double.MIN_VALUE);
-    BigDecimal halfMinDouble = minDouble.divide(BigDecimal.valueOf(2));
-    new RoundToDoubleTester(halfMinDouble)
-        .roundUnnecessaryShouldThrow()
-        .setExpectation(-Double.MIN_VALUE, UP, FLOOR, HALF_UP)
-        .setExpectation(-0.0, HALF_EVEN, CEILING, DOWN, HALF_DOWN)
-        .test();
-  }
-
-  public void testRoundToDouble_smallPositive() {
-    new RoundToDoubleTester(BigDecimal.valueOf(16)).setExpectation(16.0, values()).test();
-  }
-
-  public void testRoundToDouble_maxPreciselyRepresentable() {
-    new RoundToDoubleTester(BigDecimal.valueOf(1L << 53))
-        .setExpectation(Math.pow(2, 53), values())
-        .test();
-  }
-
-  public void testRoundToDouble_maxPreciselyRepresentablePlusOne() {
-    double twoToThe53 = Math.pow(2, 53);
-    // the representable doubles are 2^53 and 2^53 + 2.
-    // 2^53+1 is halfway between, so HALF_UP will go up and HALF_DOWN will go down.
-    new RoundToDoubleTester(BigDecimal.valueOf((1L << 53) + 1))
-        .setExpectation(twoToThe53, DOWN, FLOOR, HALF_DOWN, HALF_EVEN)
-        .setExpectation(Math.nextUp(twoToThe53), CEILING, UP, HALF_UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_twoToThe54PlusOne() {
-    double twoToThe54 = Math.pow(2, 54);
-    // the representable doubles are 2^54 and 2^54 + 4
-    // 2^54+1 is less than halfway between, so HALF_DOWN and HALF_UP will both go down.
-    new RoundToDoubleTester(BigDecimal.valueOf((1L << 54) + 1))
-        .setExpectation(twoToThe54, DOWN, FLOOR, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .setExpectation(Math.nextUp(twoToThe54), CEILING, UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_twoToThe54PlusOneHalf() {
-    double twoToThe54 = Math.pow(2, 54);
-    // the representable doubles are 2^54 and 2^54 + 4
-    // 2^54+1 is less than halfway between, so HALF_DOWN and HALF_UP will both go down.
-    new RoundToDoubleTester(BigDecimal.valueOf(1L << 54).add(new BigDecimal(0.5)))
-        .setExpectation(twoToThe54, DOWN, FLOOR, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .setExpectation(Math.nextUp(twoToThe54), CEILING, UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_twoToThe54PlusThree() {
-    double twoToThe54 = Math.pow(2, 54);
-    // the representable doubles are 2^54 and 2^54 + 4
-    // 2^54+3 is more than halfway between, so HALF_DOWN and HALF_UP will both go up.
-    new RoundToDoubleTester(BigDecimal.valueOf((1L << 54) + 3))
-        .setExpectation(twoToThe54, DOWN, FLOOR)
-        .setExpectation(Math.nextUp(twoToThe54), CEILING, UP, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_twoToThe54PlusFour() {
-    new RoundToDoubleTester(BigDecimal.valueOf((1L << 54) + 4))
-        .setExpectation(Math.pow(2, 54) + 4, values())
-        .test();
-  }
-
-  public void testRoundToDouble_maxDouble() {
-    BigDecimal maxDoubleAsBD = new BigDecimal(Double.MAX_VALUE);
-    new RoundToDoubleTester(maxDoubleAsBD).setExpectation(Double.MAX_VALUE, values()).test();
-  }
-
-  public void testRoundToDouble_maxDoublePlusOne() {
-    BigDecimal maxDoubleAsBD = new BigDecimal(Double.MAX_VALUE).add(BigDecimal.ONE);
-    new RoundToDoubleTester(maxDoubleAsBD)
-        .setExpectation(Double.MAX_VALUE, DOWN, FLOOR, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.POSITIVE_INFINITY, UP, CEILING)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_wayTooBig() {
-    BigDecimal bi = BigDecimal.valueOf(2).pow(2 * Double.MAX_EXPONENT);
-    new RoundToDoubleTester(bi)
-        .setExpectation(Double.MAX_VALUE, DOWN, FLOOR, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.POSITIVE_INFINITY, UP, CEILING)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_smallNegative() {
-    new RoundToDoubleTester(BigDecimal.valueOf(-16)).setExpectation(-16.0, values()).test();
-  }
-
-  public void testRoundToDouble_minPreciselyRepresentable() {
-    new RoundToDoubleTester(BigDecimal.valueOf(-1L << 53))
-        .setExpectation(-Math.pow(2, 53), values())
-        .test();
-  }
-
-  public void testRoundToDouble_minPreciselyRepresentableMinusOne() {
-    // the representable doubles are -2^53 and -2^53 - 2.
-    // -2^53-1 is halfway between, so HALF_UP will go up and HALF_DOWN will go down.
-    new RoundToDoubleTester(BigDecimal.valueOf((-1L << 53) - 1))
-        .setExpectation(-Math.pow(2, 53), DOWN, CEILING, HALF_DOWN, HALF_EVEN)
-        .setExpectation(DoubleUtils.nextDown(-Math.pow(2, 53)), FLOOR, UP, HALF_UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_negativeTwoToThe54MinusOne() {
-    new RoundToDoubleTester(BigDecimal.valueOf((-1L << 54) - 1))
-        .setExpectation(-Math.pow(2, 54), DOWN, CEILING, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .setExpectation(DoubleUtils.nextDown(-Math.pow(2, 54)), FLOOR, UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_negativeTwoToThe54MinusThree() {
-    new RoundToDoubleTester(BigDecimal.valueOf((-1L << 54) - 3))
-        .setExpectation(-Math.pow(2, 54), DOWN, CEILING)
-        .setExpectation(
-            DoubleUtils.nextDown(-Math.pow(2, 54)), FLOOR, UP, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_negativeTwoToThe54MinusFour() {
-    new RoundToDoubleTester(BigDecimal.valueOf((-1L << 54) - 4))
-        .setExpectation(-Math.pow(2, 54) - 4, values())
-        .test();
-  }
-
-  public void testRoundToDouble_minDouble() {
-    BigDecimal minDoubleAsBD = new BigDecimal(-Double.MAX_VALUE);
-    new RoundToDoubleTester(minDoubleAsBD).setExpectation(-Double.MAX_VALUE, values()).test();
-  }
-
-  public void testRoundToDouble_minDoubleMinusOne() {
-    BigDecimal minDoubleAsBD = new BigDecimal(-Double.MAX_VALUE).subtract(BigDecimal.ONE);
-    new RoundToDoubleTester(minDoubleAsBD)
-        .setExpectation(-Double.MAX_VALUE, DOWN, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.NEGATIVE_INFINITY, UP, FLOOR)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  public void testRoundToDouble_negativeWayTooBig() {
-    BigDecimal bi = BigDecimal.valueOf(2).pow(2 * Double.MAX_EXPONENT).negate();
-    new RoundToDoubleTester(bi)
-        .setExpectation(-Double.MAX_VALUE, DOWN, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.NEGATIVE_INFINITY, UP, FLOOR)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-}
diff --git a/android/guava-tests/test/com/google/common/math/BigIntegerMathTest.java b/android/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
index 8a9b4fc..33f3bcf 100644
--- a/android/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
+++ b/android/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
@@ -22,8 +22,6 @@
 import static com.google.common.math.MathTesting.NEGATIVE_BIGINTEGER_CANDIDATES;
 import static com.google.common.math.MathTesting.NONZERO_BIGINTEGER_CANDIDATES;
 import static com.google.common.math.MathTesting.POSITIVE_BIGINTEGER_CANDIDATES;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 import static java.math.BigInteger.ONE;
 import static java.math.BigInteger.TEN;
 import static java.math.BigInteger.ZERO;
@@ -35,7 +33,6 @@
 import static java.math.RoundingMode.HALF_UP;
 import static java.math.RoundingMode.UNNECESSARY;
 import static java.math.RoundingMode.UP;
-import static java.math.RoundingMode.values;
 import static java.util.Arrays.asList;
 
 import com.google.common.annotations.GwtCompatible;
@@ -44,9 +41,6 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Map;
 import junit.framework.TestCase;
 
 /**
@@ -548,219 +542,6 @@
     }
   }
 
-  @GwtIncompatible
-  private static final class RoundToDoubleTester {
-    private final BigInteger input;
-    private final Map<RoundingMode, Double> expectedValues = new EnumMap<>(RoundingMode.class);
-    private boolean unnecessaryShouldThrow = false;
-
-    RoundToDoubleTester(BigInteger input) {
-      this.input = input;
-    }
-
-    RoundToDoubleTester setExpectation(double expectedValue, RoundingMode... modes) {
-      for (RoundingMode mode : modes) {
-        Double previous = expectedValues.put(mode, expectedValue);
-        if (previous != null) {
-          throw new AssertionError();
-        }
-      }
-      return this;
-    }
-
-    public RoundToDoubleTester roundUnnecessaryShouldThrow() {
-      unnecessaryShouldThrow = true;
-      return this;
-    }
-
-    public void test() {
-      assertThat(expectedValues.keySet())
-          .containsAtLeastElementsIn(EnumSet.complementOf(EnumSet.of(UNNECESSARY)));
-      for (Map.Entry<RoundingMode, Double> entry : expectedValues.entrySet()) {
-        RoundingMode mode = entry.getKey();
-        Double expectation = entry.getValue();
-        assertWithMessage("roundToDouble(" + input + ", " + mode + ")")
-            .that(BigIntegerMath.roundToDouble(input, mode))
-            .isEqualTo(expectation);
-      }
-
-      if (!expectedValues.containsKey(UNNECESSARY)) {
-        assertWithMessage("Expected roundUnnecessaryShouldThrow call")
-            .that(unnecessaryShouldThrow)
-            .isTrue();
-        try {
-          BigIntegerMath.roundToDouble(input, UNNECESSARY);
-          fail("Expected ArithmeticException for roundToDouble(" + input + ", UNNECESSARY)");
-        } catch (ArithmeticException expected) {
-          // expected
-        }
-      }
-    }
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_Zero() {
-    new RoundToDoubleTester(BigInteger.ZERO).setExpectation(0.0, values()).test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_smallPositive() {
-    new RoundToDoubleTester(BigInteger.valueOf(16)).setExpectation(16.0, values()).test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_maxPreciselyRepresentable() {
-    new RoundToDoubleTester(BigInteger.valueOf(1L << 53))
-        .setExpectation(Math.pow(2, 53), values())
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_maxPreciselyRepresentablePlusOne() {
-    double twoToThe53 = Math.pow(2, 53);
-    // the representable doubles are 2^53 and 2^53 + 2.
-    // 2^53+1 is halfway between, so HALF_UP will go up and HALF_DOWN will go down.
-    new RoundToDoubleTester(BigInteger.valueOf((1L << 53) + 1))
-        .setExpectation(twoToThe53, DOWN, FLOOR, HALF_DOWN, HALF_EVEN)
-        .setExpectation(Math.nextUp(twoToThe53), CEILING, UP, HALF_UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_twoToThe54PlusOne() {
-    double twoToThe54 = Math.pow(2, 54);
-    // the representable doubles are 2^54 and 2^54 + 4
-    // 2^54+1 is less than halfway between, so HALF_DOWN and HALF_UP will both go down.
-    new RoundToDoubleTester(BigInteger.valueOf((1L << 54) + 1))
-        .setExpectation(twoToThe54, DOWN, FLOOR, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .setExpectation(Math.nextUp(twoToThe54), CEILING, UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_twoToThe54PlusThree() {
-    double twoToThe54 = Math.pow(2, 54);
-    // the representable doubles are 2^54 and 2^54 + 4
-    // 2^54+3 is more than halfway between, so HALF_DOWN and HALF_UP will both go up.
-    new RoundToDoubleTester(BigInteger.valueOf((1L << 54) + 3))
-        .setExpectation(twoToThe54, DOWN, FLOOR)
-        .setExpectation(Math.nextUp(twoToThe54), CEILING, UP, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_twoToThe54PlusFour() {
-    new RoundToDoubleTester(BigInteger.valueOf((1L << 54) + 4))
-        .setExpectation(Math.pow(2, 54) + 4, values())
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_maxDouble() {
-    BigInteger maxDoubleAsBI = DoubleMath.roundToBigInteger(Double.MAX_VALUE, UNNECESSARY);
-    new RoundToDoubleTester(maxDoubleAsBI).setExpectation(Double.MAX_VALUE, values()).test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_maxDoublePlusOne() {
-    BigInteger maxDoubleAsBI =
-        DoubleMath.roundToBigInteger(Double.MAX_VALUE, UNNECESSARY).add(BigInteger.ONE);
-    new RoundToDoubleTester(maxDoubleAsBI)
-        .setExpectation(Double.MAX_VALUE, DOWN, FLOOR, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.POSITIVE_INFINITY, UP, CEILING)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_wayTooBig() {
-    BigInteger bi = BigInteger.ONE.shiftLeft(2 * Double.MAX_EXPONENT);
-    new RoundToDoubleTester(bi)
-        .setExpectation(Double.MAX_VALUE, DOWN, FLOOR, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.POSITIVE_INFINITY, UP, CEILING)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_smallNegative() {
-    new RoundToDoubleTester(BigInteger.valueOf(-16)).setExpectation(-16.0, values()).test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_minPreciselyRepresentable() {
-    new RoundToDoubleTester(BigInteger.valueOf(-1L << 53))
-        .setExpectation(-Math.pow(2, 53), values())
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_minPreciselyRepresentableMinusOne() {
-    // the representable doubles are -2^53 and -2^53 - 2.
-    // -2^53-1 is halfway between, so HALF_UP will go up and HALF_DOWN will go down.
-    new RoundToDoubleTester(BigInteger.valueOf((-1L << 53) - 1))
-        .setExpectation(-Math.pow(2, 53), DOWN, CEILING, HALF_DOWN, HALF_EVEN)
-        .setExpectation(DoubleUtils.nextDown(-Math.pow(2, 53)), FLOOR, UP, HALF_UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_negativeTwoToThe54MinusOne() {
-    new RoundToDoubleTester(BigInteger.valueOf((-1L << 54) - 1))
-        .setExpectation(-Math.pow(2, 54), DOWN, CEILING, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .setExpectation(DoubleUtils.nextDown(-Math.pow(2, 54)), FLOOR, UP)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_negativeTwoToThe54MinusThree() {
-    new RoundToDoubleTester(BigInteger.valueOf((-1L << 54) - 3))
-        .setExpectation(-Math.pow(2, 54), DOWN, CEILING)
-        .setExpectation(
-            DoubleUtils.nextDown(-Math.pow(2, 54)), FLOOR, UP, HALF_DOWN, HALF_UP, HALF_EVEN)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_negativeTwoToThe54MinusFour() {
-    new RoundToDoubleTester(BigInteger.valueOf((-1L << 54) - 4))
-        .setExpectation(-Math.pow(2, 54) - 4, values())
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_minDouble() {
-    BigInteger minDoubleAsBI = DoubleMath.roundToBigInteger(-Double.MAX_VALUE, UNNECESSARY);
-    new RoundToDoubleTester(minDoubleAsBI).setExpectation(-Double.MAX_VALUE, values()).test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_minDoubleMinusOne() {
-    BigInteger minDoubleAsBI =
-        DoubleMath.roundToBigInteger(-Double.MAX_VALUE, UNNECESSARY).subtract(BigInteger.ONE);
-    new RoundToDoubleTester(minDoubleAsBI)
-        .setExpectation(-Double.MAX_VALUE, DOWN, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.NEGATIVE_INFINITY, UP, FLOOR)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
-  @GwtIncompatible
-  public void testRoundToDouble_negativeWayTooBig() {
-    BigInteger bi = BigInteger.ONE.shiftLeft(2 * Double.MAX_EXPONENT).negate();
-    new RoundToDoubleTester(bi)
-        .setExpectation(-Double.MAX_VALUE, DOWN, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN)
-        .setExpectation(Double.NEGATIVE_INFINITY, UP, FLOOR)
-        .roundUnnecessaryShouldThrow()
-        .test();
-  }
-
   @GwtIncompatible // NullPointerTester
   public void testNullPointers() {
     NullPointerTester tester = new NullPointerTester();
diff --git a/android/guava-tests/test/com/google/common/math/LongMathTest.java b/android/guava-tests/test/com/google/common/math/LongMathTest.java
index 2284668..1387e00 100644
--- a/android/guava-tests/test/com/google/common/math/LongMathTest.java
+++ b/android/guava-tests/test/com/google/common/math/LongMathTest.java
@@ -25,8 +25,7 @@
 import static com.google.common.math.MathTesting.NONZERO_LONG_CANDIDATES;
 import static com.google.common.math.MathTesting.POSITIVE_INTEGER_CANDIDATES;
 import static com.google.common.math.MathTesting.POSITIVE_LONG_CANDIDATES;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.Truth.assert_;
 import static java.math.BigInteger.valueOf;
 import static java.math.RoundingMode.FLOOR;
 import static java.math.RoundingMode.UNNECESSARY;
@@ -37,7 +36,6 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
-import java.util.EnumSet;
 import java.util.Random;
 import junit.framework.TestCase;
 
@@ -951,76 +949,7 @@
     }
   }
 
-  private static final long[] roundToDoubleTestCandidates = {
-    0,
-    16,
-    1L << 53,
-    (1L << 53) + 1,
-    (1L << 53) + 2,
-    (1L << 53) + 3,
-    (1L << 53) + 4,
-    1L << 54,
-    (1L << 54) + 1,
-    (1L << 54) + 2,
-    (1L << 54) + 3,
-    (1L << 54) + 4,
-    0x7ffffffffffffe00L, // halfway between 2^63 and next-lower double
-    0x7ffffffffffffe01L, // above + 1
-    0x7ffffffffffffdffL, // above - 1
-    Long.MAX_VALUE - (1L << 11) + 1,
-    Long.MAX_VALUE - 2,
-    Long.MAX_VALUE - 1,
-    Long.MAX_VALUE,
-    -16,
-    -1L << 53,
-    -(1L << 53) - 1,
-    -(1L << 53) - 2,
-    -(1L << 53) - 3,
-    -(1L << 53) - 4,
-    -1L << 54,
-    -(1L << 54) - 1,
-    -(1L << 54) - 2,
-    -(1L << 54) - 3,
-    -(1L << 54) - 4,
-    Long.MIN_VALUE + 2,
-    Long.MIN_VALUE + 1,
-    Long.MIN_VALUE
-  };
-
-  @GwtIncompatible
-  public void testRoundToDoubleAgainstBigInteger() {
-    for (RoundingMode roundingMode : EnumSet.complementOf(EnumSet.of(UNNECESSARY))) {
-      for (long candidate : roundToDoubleTestCandidates) {
-        assertThat(LongMath.roundToDouble(candidate, roundingMode))
-            .isEqualTo(BigIntegerMath.roundToDouble(BigInteger.valueOf(candidate), roundingMode));
-      }
-    }
-  }
-
-  @GwtIncompatible
-  public void testRoundToDoubleAgainstBigIntegerUnnecessary() {
-    for (long candidate : roundToDoubleTestCandidates) {
-      Double expectedDouble = null;
-      try {
-        expectedDouble = BigIntegerMath.roundToDouble(BigInteger.valueOf(candidate), UNNECESSARY);
-      } catch (ArithmeticException expected) {
-        // do nothing
-      }
-
-      if (expectedDouble != null) {
-        assertThat(LongMath.roundToDouble(candidate, UNNECESSARY)).isEqualTo(expectedDouble);
-      } else {
-        try {
-          LongMath.roundToDouble(candidate, UNNECESSARY);
-          fail("Expected ArithmeticException on roundToDouble(" + candidate + ", UNNECESSARY)");
-        } catch (ArithmeticException expected) {
-          // success
-        }
-      }
-    }
-  }
-
   private static void failFormat(String template, Object... args) {
-    assertWithMessage(template, args).fail();
+    assert_().fail(template, args);
   }
 }
diff --git a/android/guava-tests/test/com/google/common/math/PairedStatsAccumulatorTest.java b/android/guava-tests/test/com/google/common/math/PairedStatsAccumulatorTest.java
index 34f82e9..0a21790 100644
--- a/android/guava-tests/test/com/google/common/math/PairedStatsAccumulatorTest.java
+++ b/android/guava-tests/test/com/google/common/math/PairedStatsAccumulatorTest.java
@@ -43,7 +43,6 @@
 import static com.google.common.math.StatsTesting.createFilledPairedStatsAccumulator;
 import static com.google.common.math.StatsTesting.createPartitionedFilledPairedStatsAccumulator;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import com.google.common.math.StatsTesting.ManyValues;
 import java.util.Collections;
@@ -211,17 +210,17 @@
       double populationCovarianceByAddAllPartitionedPairedStats =
           accumulatorByAddAllPartitionedPairedStats.populationCovariance();
       if (values.hasAnyNonFinite()) {
-        assertWithMessage("population covariance of " + values).that(populationCovariance).isNaN();
-        assertWithMessage("population covariance by addAll(PairedStats) of " + values)
-            .that(populationCovarianceByAddAllPartitionedPairedStats)
+        assertThat(populationCovariance).named("population covariance of " + values).isNaN();
+        assertThat(populationCovarianceByAddAllPartitionedPairedStats)
+            .named("population covariance by addAll(PairedStats) of " + values)
             .isNaN();
       } else {
-        assertWithMessage("population covariance of " + values)
-            .that(populationCovariance)
+        assertThat(populationCovariance)
+            .named("population covariance of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
-        assertWithMessage("population covariance by addAll(PairedStats) of " + values)
-            .that(populationCovarianceByAddAllPartitionedPairedStats)
+        assertThat(populationCovarianceByAddAllPartitionedPairedStats)
+            .named("population covariance by addAll(PairedStats) of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
       }
@@ -341,22 +340,22 @@
       double pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats =
           accumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
       if (values.hasAnyNonFinite()) {
-        assertWithMessage("Pearson's correlation coefficient of " + values)
-            .that(pearsonsCorrelationCoefficient)
+        assertThat(pearsonsCorrelationCoefficient)
+            .named("Pearson's correlation coefficient of " + values)
             .isNaN();
-        assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
-            .that(pearsonsCorrelationCoefficient)
+        assertThat(pearsonsCorrelationCoefficient)
+            .named("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
             .isNaN();
       } else {
-        assertWithMessage("Pearson's correlation coefficient of " + values)
-            .that(pearsonsCorrelationCoefficient)
+        assertThat(pearsonsCorrelationCoefficient)
+            .named("Pearson's correlation coefficient of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(
                 accumulator.populationCovariance()
                     / (accumulator.xStats().populationStandardDeviation()
                         * accumulator.yStats().populationStandardDeviation()));
-        assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
-            .that(pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats)
+        assertThat(pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats)
+            .named("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(
                 accumulatorByAddAllPartitionedPairedStats.populationCovariance()
diff --git a/android/guava-tests/test/com/google/common/math/PairedStatsTest.java b/android/guava-tests/test/com/google/common/math/PairedStatsTest.java
index 7dd9e94..f427ae6 100644
--- a/android/guava-tests/test/com/google/common/math/PairedStatsTest.java
+++ b/android/guava-tests/test/com/google/common/math/PairedStatsTest.java
@@ -47,7 +47,6 @@
 import static com.google.common.math.StatsTesting.assertVerticalLinearTransformation;
 import static com.google.common.math.StatsTesting.createPairedStatsOf;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.math.StatsTesting.ManyValues;
@@ -105,10 +104,10 @@
       PairedStats stats = createPairedStatsOf(values.asIterable(), OTHER_MANY_VALUES);
       double populationCovariance = stats.populationCovariance();
       if (values.hasAnyNonFinite()) {
-        assertWithMessage("population covariance of " + values).that(populationCovariance).isNaN();
+        assertThat(populationCovariance).named("population covariance of " + values).isNaN();
       } else {
-        assertWithMessage("population covariance of " + values)
-            .that(populationCovariance)
+        assertThat(populationCovariance)
+            .named("population covariance of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
       }
@@ -170,12 +169,12 @@
       PairedStats stats = createPairedStatsOf(MANY_VALUES, values.asIterable());
       double pearsonsCorrelationCoefficient = stats.pearsonsCorrelationCoefficient();
       if (values.hasAnyNonFinite()) {
-        assertWithMessage("Pearson's correlation coefficient of " + values)
-            .that(pearsonsCorrelationCoefficient)
+        assertThat(pearsonsCorrelationCoefficient)
+            .named("Pearson's correlation coefficient of " + values)
             .isNaN();
       } else {
-        assertWithMessage("Pearson's correlation coefficient of " + values)
-            .that(pearsonsCorrelationCoefficient)
+        assertThat(pearsonsCorrelationCoefficient)
+            .named("Pearson's correlation coefficient of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(
                 stats.populationCovariance()
diff --git a/android/guava-tests/test/com/google/common/math/QuantilesTest.java b/android/guava-tests/test/com/google/common/math/QuantilesTest.java
index 5ac5f6e..bdd3521 100644
--- a/android/guava-tests/test/com/google/common/math/QuantilesTest.java
+++ b/android/guava-tests/test/com/google/common/math/QuantilesTest.java
@@ -20,7 +20,6 @@
 import static com.google.common.math.Quantiles.percentiles;
 import static com.google.common.math.Quantiles.quartiles;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 import static java.lang.Double.NEGATIVE_INFINITY;
 import static java.lang.Double.NaN;
 import static java.lang.Double.POSITIVE_INFINITY;
@@ -36,7 +35,6 @@
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Longs;
 import com.google.common.truth.Correspondence;
-import com.google.common.truth.Correspondence.BinaryPredicate;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -89,17 +87,20 @@
    * each other or identical non-finite values.
    */
   private static final Correspondence<Double, Double> QUANTILE_CORRESPONDENCE =
-      Correspondence.from(
-          new BinaryPredicate<Double, Double>() {
-            @Override
-            public boolean apply(@NullableDecl Double actual, @NullableDecl Double expected) {
-              // Test for equality to allow non-finite values to match; otherwise, use the finite
-              // test.
-              return actual.equals(expected)
-                  || FINITE_QUANTILE_CORRESPONDENCE.compare(actual, expected);
-            }
-          },
-          "is identical to or " + FINITE_QUANTILE_CORRESPONDENCE);
+      new Correspondence<Double, Double>() {
+
+        @Override
+        public boolean compare(@NullableDecl Double actual, @NullableDecl Double expected) {
+          // Test for equality to allow non-finite values to match; otherwise, use the finite test.
+          return actual.equals(expected)
+              || FINITE_QUANTILE_CORRESPONDENCE.compare(actual, expected);
+        }
+
+        @Override
+        public String toString() {
+          return "is identical to or " + FINITE_QUANTILE_CORRESPONDENCE;
+        }
+      };
 
   // 1. Tests on a hardcoded dataset for chains starting with median(), quartiles(), and scale(10):
 
@@ -290,18 +291,6 @@
             8, SIXTEEN_SQUARES_DECILE_8);
   }
 
-  public void testScale_indexes_varargs_compute_indexOrderIsMaintained() {
-    assertThat(Quantiles.scale(10).indexes(0, 10, 5, 1, 8, 1).compute(SIXTEEN_SQUARES_INTEGERS))
-        .comparingValuesUsing(QUANTILE_CORRESPONDENCE)
-        .containsExactly(
-            0, SIXTEEN_SQUARES_MIN,
-            10, SIXTEEN_SQUARES_MAX,
-            5, SIXTEEN_SQUARES_MEDIAN,
-            1, SIXTEEN_SQUARES_DECILE_1,
-            8, SIXTEEN_SQUARES_DECILE_8)
-        .inOrder();
-  }
-
   public void testScale_indexes_varargs_compute_doubleVarargs() {
     double[] dataset = Doubles.toArray(SIXTEEN_SQUARES_DOUBLES);
     assertThat(Quantiles.scale(10).indexes(0, 10, 5, 1, 8, 1).compute(dataset))
@@ -520,8 +509,8 @@
 
   public void testPercentiles_index_compute_doubleCollection() {
     for (int index = 0; index <= 100; index++) {
-      assertWithMessage("quantile at index " + index)
-          .that(percentiles().index(index).compute(PSEUDORANDOM_DATASET))
+      assertThat(percentiles().index(index).compute(PSEUDORANDOM_DATASET))
+          .named("quantile at index " + index)
           .isWithin(ALLOWED_ERROR)
           .of(expectedLargeDatasetPercentile(index));
     }
@@ -532,8 +521,8 @@
     // Assert that the computation gives the correct result for all possible percentiles.
     for (int index = 0; index <= 100; index++) {
       double[] dataset = Doubles.toArray(PSEUDORANDOM_DATASET);
-      assertWithMessage("quantile at index " + index)
-          .that(percentiles().index(index).computeInPlace(dataset))
+      assertThat(percentiles().index(index).computeInPlace(dataset))
+          .named("quantile at index " + index)
           .isWithin(ALLOWED_ERROR)
           .of(expectedLargeDatasetPercentile(index));
     }
@@ -756,13 +745,4 @@
     } catch (IllegalArgumentException expected) {
     }
   }
-
-  public void testScale_indexes_indexes_computeInPlace_empty() {
-    int[] emptyIndexes = {};
-    try {
-      Quantiles.ScaleAndIndexes unused = Quantiles.scale(10).indexes(emptyIndexes);
-      fail("Expected IllegalArgumentException");
-    } catch (IllegalArgumentException expected) {
-    }
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/math/StatsAccumulatorTest.java b/android/guava-tests/test/com/google/common/math/StatsAccumulatorTest.java
index 6926a69..a38c803 100644
--- a/android/guava-tests/test/com/google/common/math/StatsAccumulatorTest.java
+++ b/android/guava-tests/test/com/google/common/math/StatsAccumulatorTest.java
@@ -44,7 +44,6 @@
 import static com.google.common.math.StatsTesting.TWO_VALUES_MIN;
 import static com.google.common.math.StatsTesting.TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 import static java.lang.Math.sqrt;
 
 import com.google.common.collect.ImmutableList;
@@ -76,7 +75,6 @@
   private StatsAccumulator manyValuesAccumulatorByRepeatedAdd;
   private StatsAccumulator manyValuesAccumulatorByAddAndAddAll;
   private StatsAccumulator manyValuesAccumulatorByAddAllStats;
-  private StatsAccumulator manyValuesAccumulatorByAddAllStatsAccumulator;
   private StatsAccumulator integerManyValuesAccumulatorByAddAllIterable;
   private StatsAccumulator longManyValuesAccumulatorByAddAllIterator;
   private StatsAccumulator longManyValuesAccumulatorByAddAllVarargs;
@@ -131,12 +129,6 @@
     manyValuesAccumulatorByAddAllStats.addAll(
         Stats.of(MANY_VALUES.subList(MANY_VALUES.size() / 2, MANY_VALUES.size())));
 
-    manyValuesAccumulatorByAddAllStatsAccumulator = new StatsAccumulator();
-    manyValuesAccumulatorByAddAllStatsAccumulator.addAll(
-        statsAccumulatorOf(MANY_VALUES.subList(0, MANY_VALUES.size() / 2)));
-    manyValuesAccumulatorByAddAllStatsAccumulator.addAll(
-        statsAccumulatorOf(MANY_VALUES.subList(MANY_VALUES.size() / 2, MANY_VALUES.size())));
-
     integerManyValuesAccumulatorByAddAllIterable = new StatsAccumulator();
     integerManyValuesAccumulatorByAddAllIterable.addAll(INTEGER_MANY_VALUES);
 
@@ -147,12 +139,6 @@
     longManyValuesAccumulatorByAddAllVarargs.addAll(Longs.toArray(LONG_MANY_VALUES));
   }
 
-  private static StatsAccumulator statsAccumulatorOf(Iterable<? extends Number> values) {
-    StatsAccumulator accumulator = new StatsAccumulator();
-    accumulator.addAll(values);
-    return accumulator;
-  }
-
   public void testCount() {
     assertThat(emptyAccumulator.count()).isEqualTo(0);
     assertThat(emptyAccumulatorByAddAllEmptyIterable.count()).isEqualTo(0);
@@ -167,7 +153,6 @@
     assertThat(manyValuesAccumulatorByRepeatedAdd.count()).isEqualTo(MANY_VALUES_COUNT);
     assertThat(manyValuesAccumulatorByAddAndAddAll.count()).isEqualTo(MANY_VALUES_COUNT);
     assertThat(manyValuesAccumulatorByAddAllStats.count()).isEqualTo(MANY_VALUES_COUNT);
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.count()).isEqualTo(MANY_VALUES_COUNT);
     assertThat(integerManyValuesAccumulatorByAddAllIterable.count())
         .isEqualTo(StatsTesting.INTEGER_MANY_VALUES_COUNT);
     assertThat(longManyValuesAccumulatorByAddAllIterator.count())
@@ -227,9 +212,6 @@
     assertThat(manyValuesAccumulatorByAddAllStats.mean())
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_MEAN);
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.mean())
-        .isWithin(ALLOWED_ERROR)
-        .of(MANY_VALUES_MEAN);
     // For datasets of many double values created from an iterable, we test many combinations of
     // finite and non-finite values:
     for (ManyValues values : ALL_MANY_VALUES) {
@@ -242,40 +224,37 @@
       double mean = accumulator.mean();
       double meanByAddAllStats = accumulatorByAddAllStats.mean();
       if (values.hasAnyNaN()) {
-        assertWithMessage("mean of " + values).that(mean).isNaN();
-        assertWithMessage("mean by addAll(Stats) of " + values).that(meanByAddAllStats).isNaN();
+        assertThat(mean).named("mean of " + values).isNaN();
+        assertThat(meanByAddAllStats).named("mean by addAll(Stats) of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isNaN();
-        assertWithMessage("mean by addAll(Stats) of " + values).that(meanByAddAllStats).isNaN();
+        assertThat(mean).named("mean of " + values).isNaN();
+        assertThat(meanByAddAllStats).named("mean by addAll(Stats) of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
-        assertWithMessage("mean by addAll(Stats) of " + values)
-            .that(meanByAddAllStats)
+        assertThat(mean).named("mean of " + values).isPositiveInfinity();
+        assertThat(meanByAddAllStats)
+            .named("mean by addAll(Stats) of " + values)
             .isPositiveInfinity();
       } else if (values.hasAnyNegativeInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
-        assertWithMessage("mean by addAll(Stats) of " + values)
-            .that(meanByAddAllStats)
+        assertThat(mean).named("mean of " + values).isNegativeInfinity();
+        assertThat(meanByAddAllStats)
+            .named("mean by addAll(Stats) of " + values)
             .isNegativeInfinity();
       } else {
-        assertWithMessage("mean of " + values)
-            .that(mean)
-            .isWithin(ALLOWED_ERROR)
-            .of(MANY_VALUES_MEAN);
-        assertWithMessage("mean by addAll(Stats) of " + values)
-            .that(meanByAddAllStats)
+        assertThat(mean).named("mean of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
+        assertThat(meanByAddAllStats)
+            .named("mean by addAll(Stats) of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_MEAN);
       }
     }
     assertThat(integerManyValuesAccumulatorByAddAllIterable.mean())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN);
     assertThat(longManyValuesAccumulatorByAddAllIterator.mean())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN);
     assertThat(longManyValuesAccumulatorByAddAllVarargs.mean())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN);
   }
 
@@ -307,17 +286,14 @@
     assertThat(manyValuesAccumulatorByAddAllStats.sum())
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.sum())
-        .isWithin(ALLOWED_ERROR)
-        .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
     assertThat(integerManyValuesAccumulatorByAddAllIterable.sum())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
     assertThat(longManyValuesAccumulatorByAddAllIterator.sum())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
     assertThat(longManyValuesAccumulatorByAddAllVarargs.sum())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
   }
 
@@ -363,9 +339,6 @@
     assertThat(manyValuesAccumulatorByAddAllStats.populationVariance())
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.populationVariance())
-        .isWithin(ALLOWED_ERROR)
-        .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
     // For datasets of many double values created from an iterator, we test many combinations of
     // finite and non-finite values:
     for (ManyValues values : ALL_MANY_VALUES) {
@@ -378,29 +351,29 @@
       double populationVariance = accumulator.populationVariance();
       double populationVarianceByAddAllStats = accumulatorByAddAllStats.populationVariance();
       if (values.hasAnyNonFinite()) {
-        assertWithMessage("population variance of " + values).that(populationVariance).isNaN();
-        assertWithMessage("population variance by addAll(Stats) of " + values)
-            .that(populationVarianceByAddAllStats)
+        assertThat(populationVariance).named("population variance of " + values).isNaN();
+        assertThat(populationVarianceByAddAllStats)
+            .named("population variance by addAll(Stats) of " + values)
             .isNaN();
       } else {
-        assertWithMessage("population variance of " + values)
-            .that(populationVariance)
+        assertThat(populationVariance)
+            .named("population variance of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
-        assertWithMessage("population variance by addAll(Stats) of " + values)
-            .that(populationVarianceByAddAllStats)
+        assertThat(populationVarianceByAddAllStats)
+            .named("population variance by addAll(Stats) of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
       }
     }
     assertThat(integerManyValuesAccumulatorByAddAllIterable.populationVariance())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
     assertThat(longManyValuesAccumulatorByAddAllIterator.populationVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
     assertThat(longManyValuesAccumulatorByAddAllVarargs.populationVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
   }
 
@@ -448,17 +421,14 @@
     assertThat(manyValuesAccumulatorByAddAllStats.populationStandardDeviation())
         .isWithin(ALLOWED_ERROR)
         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR)
-        .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
     assertThat(integerManyValuesAccumulatorByAddAllIterable.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
     assertThat(longManyValuesAccumulatorByAddAllIterator.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
     assertThat(longManyValuesAccumulatorByAddAllVarargs.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
   }
 
@@ -512,17 +482,14 @@
     assertThat(manyValuesAccumulatorByAddAllStats.sampleVariance())
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.sampleVariance())
-        .isWithin(ALLOWED_ERROR)
-        .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
     assertThat(integerManyValuesAccumulatorByAddAllIterable.sampleVariance())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
     assertThat(longManyValuesAccumulatorByAddAllIterator.sampleVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
     assertThat(longManyValuesAccumulatorByAddAllVarargs.sampleVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
   }
 
@@ -576,17 +543,14 @@
     assertThat(manyValuesAccumulatorByAddAllStats.sampleStandardDeviation())
         .isWithin(ALLOWED_ERROR)
         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR)
-        .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
     assertThat(integerManyValuesAccumulatorByAddAllIterable.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
     assertThat(longManyValuesAccumulatorByAddAllIterator.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
     assertThat(longManyValuesAccumulatorByAddAllVarargs.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
   }
 
@@ -606,17 +570,28 @@
       fail("Expected IllegalStateException");
     } catch (IllegalStateException expected) {
     }
-    assertThat(oneValueAccumulator.max()).isEqualTo(ONE_VALUE);
-    assertThat(oneValueAccumulatorByAddAllEmptyStats.max()).isEqualTo(ONE_VALUE);
-    assertThat(twoValuesAccumulator.max()).isEqualTo(TWO_VALUES_MAX);
-    assertThat(twoValuesAccumulatorByAddAllStats.max()).isEqualTo(TWO_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByAddAllIterable.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByAddAllIterator.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByAddAllVarargs.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByRepeatedAdd.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByAddAndAddAll.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByAddAllStats.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.max()).isEqualTo(MANY_VALUES_MAX);
+    assertThat(oneValueAccumulator.max()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
+    assertThat(oneValueAccumulatorByAddAllEmptyStats.max()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
+    assertThat(twoValuesAccumulator.max()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MAX);
+    assertThat(twoValuesAccumulatorByAddAllStats.max()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MAX);
+    assertThat(manyValuesAccumulatorByAddAllIterable.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MAX);
+    assertThat(manyValuesAccumulatorByAddAllIterator.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MAX);
+    assertThat(manyValuesAccumulatorByAddAllVarargs.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MAX);
+    assertThat(manyValuesAccumulatorByRepeatedAdd.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MAX);
+    assertThat(manyValuesAccumulatorByAddAndAddAll.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MAX);
+    assertThat(manyValuesAccumulatorByAddAllStats.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MAX);
     // For datasets of many double values created from an array, we test many combinations of
     // finite and non-finite values:
     for (ManyValues values : ALL_MANY_VALUES) {
@@ -629,24 +604,30 @@
       double max = accumulator.max();
       double maxByAddAllStats = accumulatorByAddAllStats.max();
       if (values.hasAnyNaN()) {
-        assertWithMessage("max of " + values).that(max).isNaN();
-        assertWithMessage("max by addAll(Stats) of " + values).that(maxByAddAllStats).isNaN();
+        assertThat(max).named("max of " + values).isNaN();
+        assertThat(maxByAddAllStats).named("max by addAll(Stats) of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity()) {
-        assertWithMessage("max of " + values).that(max).isPositiveInfinity();
-        assertWithMessage("max by addAll(Stats) of " + values)
-            .that(maxByAddAllStats)
+        assertThat(max).named("max of " + values).isPositiveInfinity();
+        assertThat(maxByAddAllStats)
+            .named("max by addAll(Stats) of " + values)
             .isPositiveInfinity();
       } else {
-        assertWithMessage("max of " + values).that(max).isEqualTo(MANY_VALUES_MAX);
-        assertWithMessage("max by addAll(Stats) of " + values)
-            .that(maxByAddAllStats)
-            .isEqualTo(MANY_VALUES_MAX);
+        assertThat(max).named("max of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MAX);
+        assertThat(maxByAddAllStats)
+            .named("max by addAll(Stats) of " + values)
+            .isWithin(ALLOWED_ERROR)
+            .of(MANY_VALUES_MAX);
       }
     }
     assertThat(integerManyValuesAccumulatorByAddAllIterable.max())
-        .isEqualTo(INTEGER_MANY_VALUES_MAX);
-    assertThat(longManyValuesAccumulatorByAddAllIterator.max()).isEqualTo(LONG_MANY_VALUES_MAX);
-    assertThat(longManyValuesAccumulatorByAddAllVarargs.max()).isEqualTo(LONG_MANY_VALUES_MAX);
+        .isWithin(ALLOWED_ERROR)
+        .of(INTEGER_MANY_VALUES_MAX);
+    assertThat(longManyValuesAccumulatorByAddAllIterator.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MAX);
+    assertThat(longManyValuesAccumulatorByAddAllVarargs.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MAX);
   }
 
   public void testMin() {
@@ -665,17 +646,28 @@
       fail("Expected IllegalStateException");
     } catch (IllegalStateException expected) {
     }
-    assertThat(oneValueAccumulator.min()).isEqualTo(ONE_VALUE);
-    assertThat(oneValueAccumulatorByAddAllEmptyStats.min()).isEqualTo(ONE_VALUE);
-    assertThat(twoValuesAccumulator.min()).isEqualTo(TWO_VALUES_MIN);
-    assertThat(twoValuesAccumulatorByAddAllStats.min()).isEqualTo(TWO_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByAddAllIterable.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByAddAllIterator.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByAddAllVarargs.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByRepeatedAdd.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByAddAndAddAll.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByAddAllStats.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(manyValuesAccumulatorByAddAllStatsAccumulator.min()).isEqualTo(MANY_VALUES_MIN);
+    assertThat(oneValueAccumulator.min()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
+    assertThat(oneValueAccumulatorByAddAllEmptyStats.min()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
+    assertThat(twoValuesAccumulator.min()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MIN);
+    assertThat(twoValuesAccumulatorByAddAllStats.min()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MIN);
+    assertThat(manyValuesAccumulatorByAddAllIterable.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MIN);
+    assertThat(manyValuesAccumulatorByAddAllIterator.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MIN);
+    assertThat(manyValuesAccumulatorByAddAllVarargs.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MIN);
+    assertThat(manyValuesAccumulatorByRepeatedAdd.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MIN);
+    assertThat(manyValuesAccumulatorByAddAndAddAll.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MIN);
+    assertThat(manyValuesAccumulatorByAddAllStats.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(MANY_VALUES_MIN);
     // For datasets of many double values created by adding elements individually, we test many
     // combinations of finite and non-finite values:
     for (ManyValues values : ALL_MANY_VALUES) {
@@ -688,23 +680,29 @@
       double min = accumulator.min();
       double minByAddAllStats = accumulatorByAddAllStats.min();
       if (values.hasAnyNaN()) {
-        assertWithMessage("min of " + values).that(min).isNaN();
-        assertWithMessage("min by addAll(Stats) of " + values).that(minByAddAllStats).isNaN();
+        assertThat(min).named("min of " + values).isNaN();
+        assertThat(minByAddAllStats).named("min by addAll(Stats) of " + values).isNaN();
       } else if (values.hasAnyNegativeInfinity()) {
-        assertWithMessage("min of " + values).that(min).isNegativeInfinity();
-        assertWithMessage("min by addAll(Stats) of " + values)
-            .that(minByAddAllStats)
+        assertThat(min).named("min of " + values).isNegativeInfinity();
+        assertThat(minByAddAllStats)
+            .named("min by addAll(Stats) of " + values)
             .isNegativeInfinity();
       } else {
-        assertWithMessage("min of " + values).that(min).isEqualTo(MANY_VALUES_MIN);
-        assertWithMessage("min by addAll(Stats) of " + values)
-            .that(minByAddAllStats)
-            .isEqualTo(MANY_VALUES_MIN);
+        assertThat(min).named("min of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MIN);
+        assertThat(minByAddAllStats)
+            .named("min by addAll(Stats) of " + values)
+            .isWithin(ALLOWED_ERROR)
+            .of(MANY_VALUES_MIN);
       }
     }
     assertThat(integerManyValuesAccumulatorByAddAllIterable.min())
-        .isEqualTo(INTEGER_MANY_VALUES_MIN);
-    assertThat(longManyValuesAccumulatorByAddAllIterator.min()).isEqualTo(LONG_MANY_VALUES_MIN);
-    assertThat(longManyValuesAccumulatorByAddAllVarargs.min()).isEqualTo(LONG_MANY_VALUES_MIN);
+        .isWithin(ALLOWED_ERROR)
+        .of(INTEGER_MANY_VALUES_MIN);
+    assertThat(longManyValuesAccumulatorByAddAllIterator.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MIN);
+    assertThat(longManyValuesAccumulatorByAddAllVarargs.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MIN);
   }
 }
diff --git a/android/guava-tests/test/com/google/common/math/StatsTest.java b/android/guava-tests/test/com/google/common/math/StatsTest.java
index 76de5b5..2e9e540 100644
--- a/android/guava-tests/test/com/google/common/math/StatsTest.java
+++ b/android/guava-tests/test/com/google/common/math/StatsTest.java
@@ -64,7 +64,6 @@
 import static com.google.common.math.StatsTesting.TWO_VALUES_STATS;
 import static com.google.common.math.StatsTesting.TWO_VALUES_SUM_OF_SQUARES_OF_DELTAS;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 import static java.lang.Double.NEGATIVE_INFINITY;
 import static java.lang.Double.NaN;
 import static java.lang.Double.POSITIVE_INFINITY;
@@ -124,18 +123,15 @@
     for (ManyValues values : ALL_MANY_VALUES) {
       double mean = Stats.of(values.asArray()).mean();
       if (values.hasAnyNaN()) {
-        assertWithMessage("mean of " + values).that(mean).isNaN();
+        assertThat(mean).named("mean of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isNaN();
+        assertThat(mean).named("mean of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
+        assertThat(mean).named("mean of " + values).isPositiveInfinity();
       } else if (values.hasAnyNegativeInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
+        assertThat(mean).named("mean of " + values).isNegativeInfinity();
       } else {
-        assertWithMessage("mean of " + values)
-            .that(mean)
-            .isWithin(ALLOWED_ERROR)
-            .of(MANY_VALUES_MEAN);
+        assertThat(mean).named("mean of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
       }
     }
     assertThat(MANY_VALUES_STATS_ITERABLE.mean()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
@@ -145,19 +141,19 @@
         .isWithin(ALLOWED_ERROR * Double.MAX_VALUE)
         .of(LARGE_VALUES_MEAN);
     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.mean())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN);
     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.mean())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN);
     assertThat(LARGE_INTEGER_VALUES_STATS.mean())
         .isWithin(ALLOWED_ERROR * Integer.MAX_VALUE)
         .of(LARGE_INTEGER_VALUES_MEAN);
     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.mean())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN);
     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.mean())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN);
     assertThat(LARGE_LONG_VALUES_STATS.mean())
         .isWithin(ALLOWED_ERROR * Long.MAX_VALUE)
@@ -182,16 +178,16 @@
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_MEAN * MANY_VALUES_COUNT);
     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sum())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sum())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN * INTEGER_MANY_VALUES_COUNT);
     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sum())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sum())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN * LONG_MANY_VALUES_COUNT);
   }
 
@@ -221,10 +217,10 @@
     for (ManyValues values : ALL_MANY_VALUES) {
       double populationVariance = Stats.of(values.asIterable()).populationVariance();
       if (values.hasAnyNonFinite()) {
-        assertWithMessage("population variance of " + values).that(populationVariance).isNaN();
+        assertThat(populationVariance).named("population variance of " + values).isNaN();
       } else {
-        assertWithMessage("population variance of " + values)
-            .that(populationVariance)
+        assertThat(populationVariance)
+            .named("population variance of " + values)
             .isWithin(ALLOWED_ERROR)
             .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
       }
@@ -236,19 +232,19 @@
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT);
     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.populationVariance())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.populationVariance())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT);
     assertThat(LARGE_INTEGER_VALUES_STATS.populationVariance())
         .isWithin(ALLOWED_ERROR * Integer.MAX_VALUE * Integer.MAX_VALUE)
         .of(LARGE_INTEGER_VALUES_POPULATION_VARIANCE);
     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.populationVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.populationVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT);
     assertThat(LARGE_LONG_VALUES_STATS.populationVariance())
         .isWithin(ALLOWED_ERROR * Long.MAX_VALUE * Long.MAX_VALUE)
@@ -283,16 +279,16 @@
         .isWithin(ALLOWED_ERROR)
         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / MANY_VALUES_COUNT));
     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / INTEGER_MANY_VALUES_COUNT));
     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.populationStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / LONG_MANY_VALUES_COUNT));
   }
 
@@ -328,16 +324,16 @@
         .isWithin(ALLOWED_ERROR)
         .of(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1));
     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sampleVariance())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sampleVariance())
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1));
     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sampleVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sampleVariance())
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1));
   }
 
@@ -373,16 +369,16 @@
         .isWithin(ALLOWED_ERROR)
         .of(sqrt(MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (MANY_VALUES_COUNT - 1)));
     assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
     assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(INTEGER_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (INTEGER_MANY_VALUES_COUNT - 1)));
     assertThat(LONG_MANY_VALUES_STATS_ITERATOR.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
     assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.sampleStandardDeviation())
-        .isWithin(ALLOWED_ERROR * sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS))
+        .isWithin(ALLOWED_ERROR)
         .of(sqrt(LONG_MANY_VALUES_SUM_OF_SQUARES_OF_DELTAS / (LONG_MANY_VALUES_COUNT - 1)));
   }
 
@@ -397,30 +393,38 @@
       fail("Expected IllegalStateException");
     } catch (IllegalStateException expected) {
     }
-    assertThat(ONE_VALUE_STATS.max()).isEqualTo(ONE_VALUE);
+    assertThat(ONE_VALUE_STATS.max()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
     assertThat(Stats.of(POSITIVE_INFINITY).max()).isPositiveInfinity();
     assertThat(Stats.of(NEGATIVE_INFINITY).max()).isNegativeInfinity();
     assertThat(Stats.of(NaN).max()).isNaN();
-    assertThat(TWO_VALUES_STATS.max()).isEqualTo(TWO_VALUES_MAX);
-    assertThat(MANY_VALUES_STATS_VARARGS.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(MANY_VALUES_STATS_ITERABLE.max()).isEqualTo(MANY_VALUES_MAX);
+    assertThat(TWO_VALUES_STATS.max()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MAX);
+    assertThat(MANY_VALUES_STATS_VARARGS.max()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MAX);
+    assertThat(MANY_VALUES_STATS_ITERABLE.max()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MAX);
     // For datasets of many double values created from an iterator, we test many combinations of
     // finite and non-finite values:
     for (ManyValues values : ALL_MANY_VALUES) {
       double max = Stats.of(values.asIterable().iterator()).max();
       if (values.hasAnyNaN()) {
-        assertWithMessage("max of " + values).that(max).isNaN();
+        assertThat(max).named("max of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity()) {
-        assertWithMessage("max of " + values).that(max).isPositiveInfinity();
+        assertThat(max).named("max of " + values).isPositiveInfinity();
       } else {
-        assertWithMessage("max of " + values).that(max).isEqualTo(MANY_VALUES_MAX);
+        assertThat(max).named("max of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MAX);
       }
     }
-    assertThat(MANY_VALUES_STATS_SNAPSHOT.max()).isEqualTo(MANY_VALUES_MAX);
-    assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.max()).isEqualTo(INTEGER_MANY_VALUES_MAX);
-    assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.max()).isEqualTo(INTEGER_MANY_VALUES_MAX);
-    assertThat(LONG_MANY_VALUES_STATS_ITERATOR.max()).isEqualTo(LONG_MANY_VALUES_MAX);
-    assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.max()).isEqualTo(LONG_MANY_VALUES_MAX);
+    assertThat(MANY_VALUES_STATS_SNAPSHOT.max()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MAX);
+    assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(INTEGER_MANY_VALUES_MAX);
+    assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(INTEGER_MANY_VALUES_MAX);
+    assertThat(LONG_MANY_VALUES_STATS_ITERATOR.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MAX);
+    assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.max())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MAX);
   }
 
   public void testMin() {
@@ -434,14 +438,14 @@
       fail("Expected IllegalStateException");
     } catch (IllegalStateException expected) {
     }
-    assertThat(ONE_VALUE_STATS.min()).isEqualTo(ONE_VALUE);
+    assertThat(ONE_VALUE_STATS.min()).isWithin(ALLOWED_ERROR).of(ONE_VALUE);
     assertThat(Stats.of(POSITIVE_INFINITY).min()).isPositiveInfinity();
     assertThat(Stats.of(NEGATIVE_INFINITY).min()).isNegativeInfinity();
     assertThat(Stats.of(NaN).min()).isNaN();
-    assertThat(TWO_VALUES_STATS.min()).isEqualTo(TWO_VALUES_MIN);
-    assertThat(MANY_VALUES_STATS_VARARGS.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(MANY_VALUES_STATS_ITERABLE.min()).isEqualTo(MANY_VALUES_MIN);
-    assertThat(MANY_VALUES_STATS_ITERATOR.min()).isEqualTo(MANY_VALUES_MIN);
+    assertThat(TWO_VALUES_STATS.min()).isWithin(ALLOWED_ERROR).of(TWO_VALUES_MIN);
+    assertThat(MANY_VALUES_STATS_VARARGS.min()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MIN);
+    assertThat(MANY_VALUES_STATS_ITERABLE.min()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MIN);
+    assertThat(MANY_VALUES_STATS_ITERATOR.min()).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MIN);
     // For datasets of many double values created from an accumulator snapshot, we test many
     // combinations of finite and non-finite values:
     for (ManyValues values : ALL_MANY_VALUES) {
@@ -449,17 +453,25 @@
       accumulator.addAll(values.asIterable());
       double min = accumulator.snapshot().min();
       if (values.hasAnyNaN()) {
-        assertWithMessage("min of " + values).that(min).isNaN();
+        assertThat(min).named("min of " + values).isNaN();
       } else if (values.hasAnyNegativeInfinity()) {
-        assertWithMessage("min of " + values).that(min).isNegativeInfinity();
+        assertThat(min).named("min of " + values).isNegativeInfinity();
       } else {
-        assertWithMessage("min of " + values).that(min).isEqualTo(MANY_VALUES_MIN);
+        assertThat(min).named("min of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MIN);
       }
     }
-    assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.min()).isEqualTo(INTEGER_MANY_VALUES_MIN);
-    assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.min()).isEqualTo(INTEGER_MANY_VALUES_MIN);
-    assertThat(LONG_MANY_VALUES_STATS_ITERATOR.min()).isEqualTo(LONG_MANY_VALUES_MIN);
-    assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.min()).isEqualTo(LONG_MANY_VALUES_MIN);
+    assertThat(INTEGER_MANY_VALUES_STATS_VARARGS.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(INTEGER_MANY_VALUES_MIN);
+    assertThat(INTEGER_MANY_VALUES_STATS_ITERABLE.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(INTEGER_MANY_VALUES_MIN);
+    assertThat(LONG_MANY_VALUES_STATS_ITERATOR.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MIN);
+    assertThat(LONG_MANY_VALUES_STATS_SNAPSHOT.min())
+        .isWithin(ALLOWED_ERROR)
+        .of(LONG_MANY_VALUES_MIN);
   }
 
   public void testEqualsAndHashCode() {
@@ -525,33 +537,28 @@
     for (ManyValues values : ALL_MANY_VALUES) {
       double mean = Stats.meanOf(values.asArray());
       if (values.hasAnyNaN()) {
-        assertWithMessage("mean of " + values).that(mean).isNaN();
+        assertThat(mean).named("mean of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity() && values.hasAnyNegativeInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isNaN();
+        assertThat(mean).named("mean of " + values).isNaN();
       } else if (values.hasAnyPositiveInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isPositiveInfinity();
+        assertThat(mean).named("mean of " + values).isPositiveInfinity();
       } else if (values.hasAnyNegativeInfinity()) {
-        assertWithMessage("mean of " + values).that(mean).isNegativeInfinity();
+        assertThat(mean).named("mean of " + values).isNegativeInfinity();
       } else {
-        assertWithMessage("mean of " + values)
-            .that(mean)
-            .isWithin(ALLOWED_ERROR)
-            .of(MANY_VALUES_MEAN);
+        assertThat(mean).named("mean of " + values).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
       }
     }
     assertThat(Stats.meanOf(MANY_VALUES)).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
     assertThat(Stats.meanOf(MANY_VALUES.iterator())).isWithin(ALLOWED_ERROR).of(MANY_VALUES_MEAN);
     assertThat(Stats.meanOf(INTEGER_MANY_VALUES))
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN);
     assertThat(Stats.meanOf(Ints.toArray(INTEGER_MANY_VALUES)))
-        .isWithin(ALLOWED_ERROR * INTEGER_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(INTEGER_MANY_VALUES_MEAN);
-    assertThat(Stats.meanOf(LONG_MANY_VALUES))
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
-        .of(LONG_MANY_VALUES_MEAN);
+    assertThat(Stats.meanOf(LONG_MANY_VALUES)).isWithin(ALLOWED_ERROR).of(LONG_MANY_VALUES_MEAN);
     assertThat(Stats.meanOf(Longs.toArray(LONG_MANY_VALUES)))
-        .isWithin(ALLOWED_ERROR * LONG_MANY_VALUES_MEAN)
+        .isWithin(ALLOWED_ERROR)
         .of(LONG_MANY_VALUES_MEAN);
   }
 
diff --git a/android/guava-tests/test/com/google/common/math/StatsTesting.java b/android/guava-tests/test/com/google/common/math/StatsTesting.java
index 12689d3..b0aa362 100644
--- a/android/guava-tests/test/com/google/common/math/StatsTesting.java
+++ b/android/guava-tests/test/com/google/common/math/StatsTesting.java
@@ -222,7 +222,7 @@
   static final Stats MANY_VALUES_STATS_VARARGS = Stats.of(1.1, -44.44, 33.33, 555.555, -2.2);
   static final Stats MANY_VALUES_STATS_ITERABLE = Stats.of(MANY_VALUES);
   static final Stats MANY_VALUES_STATS_ITERATOR = Stats.of(MANY_VALUES.iterator());
-  static final Stats MANY_VALUES_STATS_SNAPSHOT = buildManyValuesStatsSnapshot();
+  static final Stats MANY_VALUES_STATS_SNAPSHOT;
   static final Stats LARGE_VALUES_STATS = Stats.of(LARGE_VALUES);
   static final Stats OTHER_MANY_VALUES_STATS = Stats.of(OTHER_MANY_VALUES);
   static final Stats INTEGER_MANY_VALUES_STATS_VARARGS =
@@ -230,21 +230,20 @@
   static final Stats INTEGER_MANY_VALUES_STATS_ITERABLE = Stats.of(INTEGER_MANY_VALUES);
   static final Stats LARGE_INTEGER_VALUES_STATS = Stats.of(LARGE_INTEGER_VALUES);
   static final Stats LONG_MANY_VALUES_STATS_ITERATOR = Stats.of(LONG_MANY_VALUES.iterator());
-  static final Stats LONG_MANY_VALUES_STATS_SNAPSHOT = buildLongManyValuesStatsSnapshot();
+  static final Stats LONG_MANY_VALUES_STATS_SNAPSHOT;
   static final Stats LARGE_LONG_VALUES_STATS = Stats.of(LARGE_LONG_VALUES);
 
-  private static Stats buildManyValuesStatsSnapshot() {
+  static {
     StatsAccumulator accumulator = new StatsAccumulator();
     accumulator.addAll(MANY_VALUES);
-    Stats stats = accumulator.snapshot();
+    MANY_VALUES_STATS_SNAPSHOT = accumulator.snapshot();
     accumulator.add(999.999); // should do nothing to the snapshot
-    return stats;
   }
 
-  private static Stats buildLongManyValuesStatsSnapshot() {
+  static {
     StatsAccumulator accumulator = new StatsAccumulator();
     accumulator.addAll(LONG_MANY_VALUES);
-    return accumulator.snapshot();
+    LONG_MANY_VALUES_STATS_SNAPSHOT = accumulator.snapshot();
   }
 
   static final ImmutableList<Stats> ALL_STATS =
@@ -276,43 +275,42 @@
       createPairedStatsOf(ImmutableList.of(ONE_VALUE), ImmutableList.of(OTHER_ONE_VALUE));
   static final PairedStats TWO_VALUES_PAIRED_STATS =
       createPairedStatsOf(TWO_VALUES, OTHER_TWO_VALUES);
-  static final PairedStats MANY_VALUES_PAIRED_STATS = buildManyValuesPairedStats();
+  static final PairedStats MANY_VALUES_PAIRED_STATS;
   static final PairedStats DUPLICATE_MANY_VALUES_PAIRED_STATS =
       createPairedStatsOf(MANY_VALUES, OTHER_MANY_VALUES);
-  static final PairedStats HORIZONTAL_VALUES_PAIRED_STATS = buildHorizontalValuesPairedStats();
-  static final PairedStats VERTICAL_VALUES_PAIRED_STATS = buildVerticalValuesPairedStats();
-  static final PairedStats CONSTANT_VALUES_PAIRED_STATS = buildConstantValuesPairedStats();
+  static final PairedStats HORIZONTAL_VALUES_PAIRED_STATS;
+  static final PairedStats VERTICAL_VALUES_PAIRED_STATS;
+  static final PairedStats CONSTANT_VALUES_PAIRED_STATS;
 
-  private static PairedStats buildManyValuesPairedStats() {
+  static {
     PairedStatsAccumulator accumulator =
         createFilledPairedStatsAccumulator(MANY_VALUES, OTHER_MANY_VALUES);
-    PairedStats stats = accumulator.snapshot();
+    MANY_VALUES_PAIRED_STATS = accumulator.snapshot();
     accumulator.add(99.99, 9999.9999); // should do nothing to the snapshot
-    return stats;
   }
 
-  private static PairedStats buildHorizontalValuesPairedStats() {
+  static {
     PairedStatsAccumulator accumulator = new PairedStatsAccumulator();
     for (double x : MANY_VALUES) {
       accumulator.add(x, OTHER_ONE_VALUE);
     }
-    return accumulator.snapshot();
+    HORIZONTAL_VALUES_PAIRED_STATS = accumulator.snapshot();
   }
 
-  private static PairedStats buildVerticalValuesPairedStats() {
+  static {
     PairedStatsAccumulator accumulator = new PairedStatsAccumulator();
     for (double y : OTHER_MANY_VALUES) {
       accumulator.add(ONE_VALUE, y);
     }
-    return accumulator.snapshot();
+    VERTICAL_VALUES_PAIRED_STATS = accumulator.snapshot();
   }
 
-  private static PairedStats buildConstantValuesPairedStats() {
+  static {
     PairedStatsAccumulator accumulator = new PairedStatsAccumulator();
     for (int i = 0; i < MANY_VALUES_COUNT; ++i) {
       accumulator.add(ONE_VALUE, OTHER_ONE_VALUE);
     }
-    return accumulator.snapshot();
+    CONSTANT_VALUES_PAIRED_STATS = accumulator.snapshot();
   }
 
   static final ImmutableList<PairedStats> ALL_PAIRED_STATS =
@@ -389,8 +387,8 @@
         .of(x1 + xDelta);
     assertThat(transformation.slope()).isWithin(ALLOWED_ERROR).of(yDelta / xDelta);
     assertThat(transformation.inverse().slope()).isWithin(ALLOWED_ERROR).of(xDelta / yDelta);
-    assertThat(transformation.inverse()).isSameInstanceAs(transformation.inverse());
-    assertThat(transformation.inverse().inverse()).isSameInstanceAs(transformation);
+    assertThat(transformation.inverse()).isSameAs(transformation.inverse());
+    assertThat(transformation.inverse().inverse()).isSameAs(transformation);
   }
 
   /**
@@ -417,8 +415,8 @@
       fail("Expected IllegalStateException");
     } catch (IllegalStateException expected) {
     }
-    assertThat(transformation.inverse()).isSameInstanceAs(transformation.inverse());
-    assertThat(transformation.inverse().inverse()).isSameInstanceAs(transformation);
+    assertThat(transformation.inverse()).isSameAs(transformation.inverse());
+    assertThat(transformation.inverse().inverse()).isSameAs(transformation);
   }
 
   /**
@@ -445,8 +443,8 @@
     } catch (IllegalStateException expected) {
     }
     assertThat(transformation.inverse().slope()).isWithin(ALLOWED_ERROR).of(0.0);
-    assertThat(transformation.inverse()).isSameInstanceAs(transformation.inverse());
-    assertThat(transformation.inverse().inverse()).isSameInstanceAs(transformation);
+    assertThat(transformation.inverse()).isSameAs(transformation.inverse());
+    assertThat(transformation.inverse().inverse()).isSameAs(transformation);
   }
 
   /**
@@ -458,7 +456,7 @@
     assertThat(transformation.isVertical()).isFalse();
     assertThat(transformation.slope()).isNaN();
     assertThat(transformation.transform(0.0)).isNaN();
-    assertThat(transformation.inverse()).isSameInstanceAs(transformation);
+    assertThat(transformation.inverse()).isSameAs(transformation);
   }
 
   /**
diff --git a/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java b/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java
index 9927e6b..65e6fdb 100644
--- a/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java
+++ b/android/guava-tests/test/com/google/common/net/HttpHeadersTest.java
@@ -36,22 +36,18 @@
   public void testConstantNameMatchesString() throws Exception {
     // Special case some of the weird HTTP Header names...
     ImmutableBiMap<String, String> specialCases =
-        ImmutableBiMap.<String, String>builder()
-            .put("CDN_LOOP", "CDN-Loop")
-            .put("ETAG", "ETag")
-            .put("SOURCE_MAP", "SourceMap")
-            .put("SEC_WEBSOCKET_ACCEPT", "Sec-WebSocket-Accept")
-            .put("SEC_WEBSOCKET_EXTENSIONS", "Sec-WebSocket-Extensions")
-            .put("SEC_WEBSOCKET_KEY", "Sec-WebSocket-Key")
-            .put("SEC_WEBSOCKET_PROTOCOL", "Sec-WebSocket-Protocol")
-            .put("SEC_WEBSOCKET_VERSION", "Sec-WebSocket-Version")
-            .put("X_WEBKIT_CSP", "X-WebKit-CSP")
-            .put("X_WEBKIT_CSP_REPORT_ONLY", "X-WebKit-CSP-Report-Only")
-            .build();
+        ImmutableBiMap.of(
+            "ETAG",
+            "ETag",
+            "SOURCE_MAP",
+            "SourceMap",
+            "X_WEBKIT_CSP",
+            "X-WebKit-CSP",
+            "X_WEBKIT_CSP_REPORT_ONLY",
+            "X-WebKit-CSP-Report-Only");
     ImmutableSet<String> uppercaseAcronyms =
         ImmutableSet.of(
-            "CH", "ID", "DNT", "DNS", "HTTP2", "IP", "MD5", "P3P", "TE", "UA", "UID", "URL", "WWW",
-            "XSS");
+            "ID", "DNT", "DNS", "HTTP2", "IP", "MD5", "P3P", "TE", "UID", "URL", "WWW", "XSS");
     assertConstantNameMatchesString(HttpHeaders.class, specialCases, uppercaseAcronyms);
   }
 
diff --git a/android/guava-tests/test/com/google/common/net/InetAddressesTest.java b/android/guava-tests/test/com/google/common/net/InetAddressesTest.java
index ed3aa27..62c7bd0 100644
--- a/android/guava-tests/test/com/google/common/net/InetAddressesTest.java
+++ b/android/guava-tests/test/com/google/common/net/InetAddressesTest.java
@@ -18,9 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.common.testing.NullPointerTester;
-import java.math.BigInteger;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -41,80 +39,77 @@
   }
 
   public void testForStringBogusInput() {
-    ImmutableSet<String> bogusInputs =
-        ImmutableSet.of(
-            "",
-            "016.016.016.016",
-            "016.016.016",
-            "016.016",
-            "016",
-            "000.000.000.000",
-            "000",
-            "0x0a.0x0a.0x0a.0x0a",
-            "0x0a.0x0a.0x0a",
-            "0x0a.0x0a",
-            "0x0a",
-            "42.42.42.42.42",
-            "42.42.42",
-            "42.42",
-            "42",
-            "42..42.42",
-            "42..42.42.42",
-            "42.42.42.42.",
-            "42.42.42.42...",
-            ".42.42.42.42",
-            ".42.42.42",
-            "...42.42.42.42",
-            "42.42.42.-0",
-            "42.42.42.+0",
-            ".",
-            "...",
-            "bogus",
-            "bogus.com",
-            "192.168.0.1.com",
-            "12345.67899.-54321.-98765",
-            "257.0.0.0",
-            "42.42.42.-42",
-            "42.42.42.ab",
-            "3ffe::1.net",
-            "3ffe::1::1",
-            "1::2::3::4:5",
-            "::7:6:5:4:3:2:", // should end with ":0"
-            ":6:5:4:3:2:1::", // should begin with "0:"
-            "2001::db:::1",
-            "FEDC:9878",
-            "+1.+2.+3.4",
-            "1.2.3.4e0",
-            "6:5:4:3:2:1:0", // too few parts
-            "::7:6:5:4:3:2:1:0", // too many parts
-            "7:6:5:4:3:2:1:0::", // too many parts
-            "9:8:7:6:5:4:3::2:1", // too many parts
-            "0:1:2:3::4:5:6:7", // :: must remove at least one 0.
-            "3ffe:0:0:0:0:0:0:0:1", // too many parts (9 instead of 8)
-            "3ffe::10000", // hextet exceeds 16 bits
-            "3ffe::goog",
-            "3ffe::-0",
-            "3ffe::+0",
-            "3ffe::-1",
-            ":",
-            ":::",
-            "::1.2.3",
-            "::1.2.3.4.5",
-            "::1.2.3.4:",
-            "1.2.3.4::",
-            "2001:db8::1:",
-            ":2001:db8::1",
-            ":1:2:3:4:5:6:7",
-            "1:2:3:4:5:6:7:",
-            ":1:2:3:4:5:6:");
+    String[] bogusInputs = {
+      "",
+      "016.016.016.016",
+      "016.016.016",
+      "016.016",
+      "016",
+      "000.000.000.000",
+      "000",
+      "0x0a.0x0a.0x0a.0x0a",
+      "0x0a.0x0a.0x0a",
+      "0x0a.0x0a",
+      "0x0a",
+      "42.42.42.42.42",
+      "42.42.42",
+      "42.42",
+      "42",
+      "42..42.42",
+      "42..42.42.42",
+      "42.42.42.42.",
+      "42.42.42.42...",
+      ".42.42.42.42",
+      "...42.42.42.42",
+      "42.42.42.-0",
+      "42.42.42.+0",
+      ".",
+      "...",
+      "bogus",
+      "bogus.com",
+      "192.168.0.1.com",
+      "12345.67899.-54321.-98765",
+      "257.0.0.0",
+      "42.42.42.-42",
+      "3ffe::1.net",
+      "3ffe::1::1",
+      "1::2::3::4:5",
+      "::7:6:5:4:3:2:", // should end with ":0"
+      ":6:5:4:3:2:1::", // should begin with "0:"
+      "2001::db:::1",
+      "FEDC:9878",
+      "+1.+2.+3.4",
+      "1.2.3.4e0",
+      "::7:6:5:4:3:2:1:0", // too many parts
+      "7:6:5:4:3:2:1:0::", // too many parts
+      "9:8:7:6:5:4:3::2:1", // too many parts
+      "0:1:2:3::4:5:6:7", // :: must remove at least one 0.
+      "3ffe:0:0:0:0:0:0:0:1", // too many parts (9 instead of 8)
+      "3ffe::10000", // hextet exceeds 16 bits
+      "3ffe::goog",
+      "3ffe::-0",
+      "3ffe::+0",
+      "3ffe::-1",
+      ":",
+      ":::",
+      "::1.2.3",
+      "::1.2.3.4.5",
+      "::1.2.3.4:",
+      "1.2.3.4::",
+      "2001:db8::1:",
+      ":2001:db8::1",
+      ":1:2:3:4:5:6:7",
+      "1:2:3:4:5:6:7:",
+      ":1:2:3:4:5:6:"
+    };
 
-    for (String bogusInput : bogusInputs) {
+    for (int i = 0; i < bogusInputs.length; i++) {
       try {
-        InetAddresses.forString(bogusInput);
-        fail("IllegalArgumentException expected for '" + bogusInput + "'");
+        InetAddresses.forString(bogusInputs[i]);
+        fail("IllegalArgumentException expected for '" + bogusInputs[i] + "'");
       } catch (IllegalArgumentException expected) {
       }
-      assertFalse(InetAddresses.isInetAddress(bogusInput));
+      assertFalse(InetAddresses.isInetAddress(bogusInputs[i]));
     }
   }
 
@@ -129,35 +124,40 @@
 
   public void testForStringIPv4Input() throws UnknownHostException {
     String ipStr = "192.168.0.1";
+    InetAddress ipv4Addr = null;
     // Shouldn't hit DNS, because it's an IP string literal.
-    InetAddress ipv4Addr = InetAddress.getByName(ipStr);
+    ipv4Addr = InetAddress.getByName(ipStr);
     assertEquals(ipv4Addr, InetAddresses.forString(ipStr));
     assertTrue(InetAddresses.isInetAddress(ipStr));
   }
 
   public void testForStringIPv6Input() throws UnknownHostException {
     String ipStr = "3ffe::1";
+    InetAddress ipv6Addr = null;
     // Shouldn't hit DNS, because it's an IP string literal.
-    InetAddress ipv6Addr = InetAddress.getByName(ipStr);
+    ipv6Addr = InetAddress.getByName(ipStr);
     assertEquals(ipv6Addr, InetAddresses.forString(ipStr));
     assertTrue(InetAddresses.isInetAddress(ipStr));
   }
 
   public void testForStringIPv6EightColons() throws UnknownHostException {
-    ImmutableSet<String> eightColons =
-        ImmutableSet.of("::7:6:5:4:3:2:1", "::7:6:5:4:3:2:0", "7:6:5:4:3:2:1::", "0:6:5:4:3:2:1::");
+    String[] eightColons = {
+      "::7:6:5:4:3:2:1", "::7:6:5:4:3:2:0", "7:6:5:4:3:2:1::", "0:6:5:4:3:2:1::",
+    };
 
-    for (String ipString : eightColons) {
+    for (int i = 0; i < eightColons.length; i++) {
+      InetAddress ipv6Addr = null;
       // Shouldn't hit DNS, because it's an IP string literal.
-      InetAddress ipv6Addr = InetAddress.getByName(ipString);
-      assertEquals(ipv6Addr, InetAddresses.forString(ipString));
-      assertTrue(InetAddresses.isInetAddress(ipString));
+      ipv6Addr = InetAddress.getByName(eightColons[i]);
+      assertEquals(ipv6Addr, InetAddresses.forString(eightColons[i]));
+      assertTrue(InetAddresses.isInetAddress(eightColons[i]));
     }
   }
 
   public void testConvertDottedQuadToHex() throws UnknownHostException {
-    ImmutableSet<String> ipStrings =
-        ImmutableSet.of("7::0.128.0.127", "7::0.128.0.128", "7::128.128.0.127", "7::0.128.128.127");
+    String[] ipStrings = {
+      "7::0.128.0.127", "7::0.128.0.128", "7::128.128.0.127", "7::0.128.128.127"
+    };
 
     for (String ipString : ipStrings) {
       // Shouldn't hit DNS, because it's an IP string literal.
@@ -167,58 +167,6 @@
     }
   }
 
-  // see https://github.com/google/guava/issues/2587
-  private static final ImmutableSet<String> SCOPE_IDS =
-      ImmutableSet.of("eno1", "en1", "eth0", "X", "1", "2", "14", "20");
-
-  public void testIPv4AddressWithScopeId() {
-    ImmutableSet<String> ipStrings = ImmutableSet.of("1.2.3.4", "192.168.0.1");
-    for (String ipString : ipStrings) {
-      for (String scopeId : SCOPE_IDS) {
-        String withScopeId = ipString + "%" + scopeId;
-        assertFalse(
-            "InetAddresses.isInetAddress(" + withScopeId + ") should be false but was true",
-            InetAddresses.isInetAddress(withScopeId));
-      }
-    }
-  }
-
-  public void testDottedQuadAddressWithScopeId() {
-    ImmutableSet<String> ipStrings =
-        ImmutableSet.of("7::0.128.0.127", "7::0.128.0.128", "7::128.128.0.127", "7::0.128.128.127");
-    for (String ipString : ipStrings) {
-      for (String scopeId : SCOPE_IDS) {
-        String withScopeId = ipString + "%" + scopeId;
-        assertFalse(
-            "InetAddresses.isInetAddress(" + withScopeId + ") should be false but was true",
-            InetAddresses.isInetAddress(withScopeId));
-      }
-    }
-  }
-
-  public void testIPv6AddressWithScopeId() {
-    ImmutableSet<String> ipStrings =
-        ImmutableSet.of(
-            "0:0:0:0:0:0:0:1",
-            "fe80::a",
-            "fe80::1",
-            "fe80::2",
-            "fe80::42",
-            "fe80::3dd0:7f8e:57b7:34d5",
-            "fe80::71a3:2b00:ddd3:753f",
-            "fe80::8b2:d61e:e5c:b333",
-            "fe80::b059:65f4:e877:c40");
-    for (String ipString : ipStrings) {
-      for (String scopeId : SCOPE_IDS) {
-        String withScopeId = ipString + "%" + scopeId;
-        assertTrue(
-            "InetAddresses.isInetAddress(" + withScopeId + ") should be true but was false",
-            InetAddresses.isInetAddress(withScopeId));
-        assertEquals(InetAddresses.forString(withScopeId), InetAddresses.forString(ipString));
-      }
-    }
-  }
-
   public void testToAddrStringIPv4() {
     // Don't need to test IPv4 much; it just calls getHostAddress().
     assertEquals("1.2.3.4", InetAddresses.toAddrString(InetAddresses.forString("1.2.3.4")));
@@ -367,30 +315,34 @@
   }
 
   public void testCompatIPv4Addresses() {
-    ImmutableSet<String> nonCompatAddresses = ImmutableSet.of("3ffe::1", "::", "::1");
+    String[] nonCompatAddresses = {
+      "3ffe::1", "::", "::1",
+    };
 
-    for (String nonCompatAddress : nonCompatAddresses) {
-      InetAddress ip = InetAddresses.forString(nonCompatAddress);
+    for (int i = 0; i < nonCompatAddresses.length; i++) {
+      InetAddress ip = InetAddresses.forString(nonCompatAddresses[i]);
       assertFalse(InetAddresses.isCompatIPv4Address((Inet6Address) ip));
       try {
         InetAddresses.getCompatIPv4Address((Inet6Address) ip);
-        fail("IllegalArgumentException expected for '" + nonCompatAddress + "'");
+        fail("IllegalArgumentException expected for '" + nonCompatAddresses[i] + "'");
       } catch (IllegalArgumentException expected) {
       }
     }
 
-    ImmutableSet<String> validCompatAddresses = ImmutableSet.of("::1.2.3.4", "::102:304");
+    String[] validCompatAddresses = {
+      "::1.2.3.4", "::102:304",
+    };
     String compatStr = "1.2.3.4";
     InetAddress compat = InetAddresses.forString(compatStr);
 
-    for (String validCompatAddress : validCompatAddresses) {
-      InetAddress ip = InetAddresses.forString(validCompatAddress);
-      assertTrue("checking '" + validCompatAddress + "'", ip instanceof Inet6Address);
+    for (int i = 0; i < validCompatAddresses.length; i++) {
+      InetAddress ip = InetAddresses.forString(validCompatAddresses[i]);
+      assertTrue("checking '" + validCompatAddresses[i] + "'", ip instanceof Inet6Address);
       assertTrue(
-          "checking '" + validCompatAddress + "'",
+          "checking '" + validCompatAddresses[i] + "'",
           InetAddresses.isCompatIPv4Address((Inet6Address) ip));
       assertEquals(
-          "checking '" + validCompatAddress + "'",
+          "checking '" + validCompatAddresses[i] + "'",
           compat,
           InetAddresses.getCompatIPv4Address((Inet6Address) ip));
     }
@@ -437,14 +389,16 @@
   }
 
   public void test6to4Addresses() {
-    ImmutableSet<String> non6to4Addresses = ImmutableSet.of("::1.2.3.4", "3ffe::1", "::", "::1");
+    String[] non6to4Addresses = {
+      "::1.2.3.4", "3ffe::1", "::", "::1",
+    };
 
-    for (String non6to4Address : non6to4Addresses) {
-      InetAddress ip = InetAddresses.forString(non6to4Address);
+    for (int i = 0; i < non6to4Addresses.length; i++) {
+      InetAddress ip = InetAddresses.forString(non6to4Addresses[i]);
       assertFalse(InetAddresses.is6to4Address((Inet6Address) ip));
       try {
         InetAddresses.get6to4IPv4Address((Inet6Address) ip);
-        fail("IllegalArgumentException expected for '" + non6to4Address + "'");
+        fail("IllegalArgumentException expected for '" + non6to4Addresses[i] + "'");
       } catch (IllegalArgumentException expected) {
       }
     }
@@ -459,14 +413,16 @@
   }
 
   public void testTeredoAddresses() {
-    ImmutableSet<String> nonTeredoAddresses = ImmutableSet.of("::1.2.3.4", "3ffe::1", "::", "::1");
+    String[] nonTeredoAddresses = {
+      "::1.2.3.4", "3ffe::1", "::", "::1",
+    };
 
-    for (String nonTeredoAddress : nonTeredoAddresses) {
-      InetAddress ip = InetAddresses.forString(nonTeredoAddress);
+    for (int i = 0; i < nonTeredoAddresses.length; i++) {
+      InetAddress ip = InetAddresses.forString(nonTeredoAddresses[i]);
       assertFalse(InetAddresses.isTeredoAddress((Inet6Address) ip));
       try {
         InetAddresses.getTeredoInfo((Inet6Address) ip);
-        fail("IllegalArgumentException expected for '" + nonTeredoAddress + "'");
+        fail("IllegalArgumentException expected for '" + nonTeredoAddresses[i] + "'");
       } catch (IllegalArgumentException expected) {
       }
     }
@@ -501,39 +457,37 @@
 
   public void testIsatapAddresses() {
     InetAddress ipv4 = InetAddresses.forString("1.2.3.4");
-    ImmutableSet<String> validIsatapAddresses =
-        ImmutableSet.of(
-            "2001:db8::5efe:102:304",
-            "2001:db8::100:5efe:102:304", // Private Multicast? Not likely.
-            "2001:db8::200:5efe:102:304",
-            "2001:db8::300:5efe:102:304" // Public Multicast? Also unlikely.
-            );
-    ImmutableSet<String> nonIsatapAddresses =
-        ImmutableSet.of(
-            "::1.2.3.4",
-            "3ffe::1",
-            "::",
-            "::1",
-            "2001:db8::0040:5efe:102:304",
-            "2001:db8::5ffe:102:304",
-            "2001:db8::5eff:102:304",
-            "2001:0:102:203:200:5efe:506:708" // Teredo address; not ISATAP
-            );
+    String[] validIsatapAddresses = {
+      "2001:db8::5efe:102:304",
+      "2001:db8::100:5efe:102:304", // Private Multicast? Not likely.
+      "2001:db8::200:5efe:102:304",
+      "2001:db8::300:5efe:102:304" // Public Multicast? Also unlikely.
+    };
+    String[] nonIsatapAddresses = {
+      "::1.2.3.4",
+      "3ffe::1",
+      "::",
+      "::1",
+      "2001:db8::0040:5efe:102:304",
+      "2001:db8::5ffe:102:304",
+      "2001:db8::5eff:102:304",
+      "2001:0:102:203:200:5efe:506:708", // Teredo address; not ISATAP
+    };
 
-    for (String validIsatapAddress : validIsatapAddresses) {
-      InetAddress ip = InetAddresses.forString(validIsatapAddress);
+    for (int i = 0; i < validIsatapAddresses.length; i++) {
+      InetAddress ip = InetAddresses.forString(validIsatapAddresses[i]);
       assertTrue(InetAddresses.isIsatapAddress((Inet6Address) ip));
       assertEquals(
-          "checking '" + validIsatapAddress + "'",
+          "checking '" + validIsatapAddresses[i] + "'",
           ipv4,
           InetAddresses.getIsatapIPv4Address((Inet6Address) ip));
     }
-    for (String nonIsatapAddress : nonIsatapAddresses) {
-      InetAddress ip = InetAddresses.forString(nonIsatapAddress);
+    for (int i = 0; i < nonIsatapAddresses.length; i++) {
+      InetAddress ip = InetAddresses.forString(nonIsatapAddresses[i]);
       assertFalse(InetAddresses.isIsatapAddress((Inet6Address) ip));
       try {
         InetAddresses.getIsatapIPv4Address((Inet6Address) ip);
-        fail("IllegalArgumentException expected for '" + nonIsatapAddress + "'");
+        fail("IllegalArgumentException expected for '" + nonIsatapAddresses[i] + "'");
       } catch (IllegalArgumentException expected) {
       }
     }
@@ -571,77 +525,75 @@
 
   public void testGetCoercedIPv4Address() {
     // Check that a coerced IPv4 address is unaltered.
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("127.0.0.1")))
-        .isEqualTo(InetAddresses.forString("127.0.0.1"));
+    InetAddress localHost4 = InetAddresses.forString("127.0.0.1");
+    assertEquals(localHost4, InetAddresses.getCoercedIPv4Address(localHost4));
 
     // ::1 special case
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::1")))
-        .isEqualTo(InetAddresses.forString("127.0.0.1"));
+    assertEquals(localHost4, InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::1")));
 
     // :: special case
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::")))
-        .isEqualTo(InetAddresses.forString("0.0.0.0"));
+    assertEquals(
+        InetAddresses.forString("0.0.0.0"),
+        InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::")));
 
     // test compat address (should be hashed)
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::1.2.3.4")))
-        .isNotEqualTo(InetAddresses.forString("1.2.3.4"));
+    assertTrue(
+        InetAddresses.forString("1.2.3.4")
+            != InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::1.2.3.4")));
 
     // test 6to4 address (should be hashed)
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1")))
-        .isNotEqualTo(InetAddresses.forString("1.2.3.4"));
+    assertTrue(
+        InetAddresses.forString("1.2.3.4")
+            != InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1")));
 
     // 2 6to4 addresses differing in the embedded IPv4 address should
     // hash to the different values.
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1")))
-        .isNotEqualTo(
-            InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0506:0708::1")));
+    assertTrue(
+        InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1"))
+            != InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0506:0708::1")));
 
     // 2 6to4 addresses NOT differing in the embedded IPv4 address should
     // hash to the same value.
-    assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1")))
-        .isEqualTo(
-            InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::2")));
+    assertTrue(
+        InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1"))
+            != InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::2")));
 
     // test Teredo address (should be hashed)
-    assertThat(
-            InetAddresses.getCoercedIPv4Address(
-                InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2")))
-        .isNotEqualTo(InetAddresses.forString("192.0.2.45"));
+    assertTrue(
+        InetAddresses.forString("192.0.2.45")
+            != InetAddresses.getCoercedIPv4Address(
+                InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2")));
 
-    // 2 Teredo addresses differing in their embedded IPv4 addresses should hash to different
-    // values.
-    assertThat(
-            InetAddresses.getCoercedIPv4Address(
-                InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2")))
-        .isNotEqualTo(
-            InetAddresses.getCoercedIPv4Address(
-                InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd3")));
+    // 2 Teredo addresses differing in the embedded IPv4 address should
+    // hash to the different values.
+    assertTrue(
+        InetAddresses.getCoercedIPv4Address(
+                InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2"))
+            != InetAddresses.getCoercedIPv4Address(
+                InetAddresses.forString("2001:0000:4136:e379:8000:63bf:3fff:fdd2")));
 
-    // 2 Teredo addresses NOT differing in the their embedded IPv4 addresses should hash to the same
-    // value.
-    assertThat(
-            InetAddresses.getCoercedIPv4Address(
-                InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2")))
-        .isEqualTo(
-            InetAddresses.getCoercedIPv4Address(
-                InetAddresses.forString("2001:0000:5136:f378:9000:73bf:3fff:fdd2")));
+    // 2 Teredo addresses NOT differing in the embedded IPv4 address should
+    // hash to the same value.
+    assertEquals(
+        InetAddresses.getCoercedIPv4Address(
+            InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2")),
+        InetAddresses.getCoercedIPv4Address(
+            InetAddresses.forString("2001:0000:4136:e378:9000:63bf:3fff:fdd2")));
 
     // Test that an address hashes in to the 224.0.0.0/3 number-space.
-    int coercedInt =
-        InetAddresses.coerceToInteger(
-            InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2001:4860::1")));
-    assertThat(coercedInt).isAtLeast(0xe0000000);
-    assertThat(coercedInt).isAtMost(0xfffffffe);
+    InetAddress coerced =
+        InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2001:4860::1"));
+    assertTrue(0xe0000000 <= InetAddresses.coerceToInteger(coerced));
+    assertTrue(InetAddresses.coerceToInteger(coerced) <= 0xfffffffe);
   }
 
-  public void testCoerceToInteger() {
-    assertThat(InetAddresses.coerceToInteger(InetAddresses.forString("127.0.0.1")))
-        .isEqualTo(0x7f000001);
+  public void testToInteger() {
+    InetAddress ipv4Addr = InetAddresses.forString("127.0.0.1");
+    assertEquals(0x7f000001, InetAddresses.coerceToInteger(ipv4Addr));
   }
 
   public void testFromInteger() {
-    assertThat(InetAddresses.fromInteger(0x7f000001))
-        .isEqualTo(InetAddresses.forString("127.0.0.1"));
+    assertEquals(InetAddresses.fromInteger(0x7f000001), InetAddresses.forString("127.0.0.1"));
   }
 
   public void testFromLittleEndianByteArray() throws UnknownHostException {
@@ -770,80 +722,4 @@
     } catch (IllegalArgumentException expected) {
     }
   }
-
-  public void testFromIpv4BigIntegerThrowsLessThanZero() {
-    try {
-      InetAddresses.fromIPv4BigInteger(BigInteger.valueOf(-1L));
-      fail();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("BigInteger must be greater than or equal to 0", expected.getMessage());
-    }
-  }
-
-  public void testFromIpv6BigIntegerThrowsLessThanZero() {
-    try {
-      InetAddresses.fromIPv6BigInteger(BigInteger.valueOf(-1L));
-      fail();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("BigInteger must be greater than or equal to 0", expected.getMessage());
-    }
-  }
-
-  public void testFromIpv4BigIntegerValid() {
-    checkBigIntegerConversion("0.0.0.0", BigInteger.ZERO);
-    checkBigIntegerConversion("0.0.0.1", BigInteger.ONE);
-    checkBigIntegerConversion("127.255.255.255", BigInteger.valueOf(Integer.MAX_VALUE));
-    checkBigIntegerConversion(
-        "255.255.255.254", BigInteger.valueOf(Integer.MAX_VALUE).multiply(BigInteger.valueOf(2)));
-    checkBigIntegerConversion(
-        "255.255.255.255", BigInteger.ONE.shiftLeft(32).subtract(BigInteger.ONE));
-  }
-
-  public void testFromIpv6BigIntegerValid() {
-    checkBigIntegerConversion("::", BigInteger.ZERO);
-    checkBigIntegerConversion("::1", BigInteger.ONE);
-    checkBigIntegerConversion("::7fff:ffff", BigInteger.valueOf(Integer.MAX_VALUE));
-    checkBigIntegerConversion("::7fff:ffff:ffff:ffff", BigInteger.valueOf(Long.MAX_VALUE));
-    checkBigIntegerConversion(
-        "::ffff:ffff:ffff:ffff", BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE));
-    checkBigIntegerConversion(
-        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
-        BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE));
-  }
-
-  public void testFromIpv4BigIntegerInputTooLarge() {
-    try {
-      InetAddresses.fromIPv4BigInteger(BigInteger.ONE.shiftLeft(32).add(BigInteger.ONE));
-      fail();
-    } catch (IllegalArgumentException expected) {
-      assertEquals(
-          "BigInteger cannot be converted to InetAddress because it has more than 4 bytes:"
-              + " 4294967297",
-          expected.getMessage());
-    }
-  }
-
-  public void testFromIpv6BigIntegerInputTooLarge() {
-    try {
-      InetAddresses.fromIPv6BigInteger(BigInteger.ONE.shiftLeft(128).add(BigInteger.ONE));
-      fail();
-    } catch (IllegalArgumentException expected) {
-      assertEquals(
-          "BigInteger cannot be converted to InetAddress because it has more than 16 bytes:"
-              + " 340282366920938463463374607431768211457",
-          expected.getMessage());
-    }
-  }
-
-  /** Checks that the IP converts to the big integer and the big integer converts to the IP. */
-  private static void checkBigIntegerConversion(String ip, BigInteger bigIntegerIp) {
-    InetAddress address = InetAddresses.forString(ip);
-    boolean isIpv6 = address instanceof Inet6Address;
-    assertEquals(bigIntegerIp, InetAddresses.toBigInteger(address));
-    assertEquals(
-        address,
-        isIpv6
-            ? InetAddresses.fromIPv6BigInteger(bigIntegerIp)
-            : InetAddresses.fromIPv4BigInteger(bigIntegerIp));
-  }
 }
diff --git a/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java b/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
index 09602b7..126076e 100644
--- a/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
+++ b/android/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
@@ -63,8 +63,6 @@
           "f_a",
           "foo.net.us\uFF61ocm",
           "woo.com.",
-          "8server.shop",
-          "123.cn",
           "a" + DELTA + "b.com",
           ALMOST_TOO_MANY_LEVELS,
           ALMOST_TOO_LONG);
diff --git a/android/guava-tests/test/com/google/common/net/MediaTypeTest.java b/android/guava-tests/test/com/google/common/net/MediaTypeTest.java
index cec3cdd..7dfa9b8 100644
--- a/android/guava-tests/test/com/google/common/net/MediaTypeTest.java
+++ b/android/guava-tests/test/com/google/common/net/MediaTypeTest.java
@@ -148,38 +148,6 @@
     }
   }
 
-  public void testCreate_nonAsciiType() {
-    try {
-      MediaType.create("…", "a");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testCreate_nonAsciiSubtype() {
-    try {
-      MediaType.create("a", "…");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testCreate_emptyType() {
-    try {
-      MediaType.create("", "a");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testCreate_emptySubtype() {
-    try {
-      MediaType.create("a", "");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   public void testCreateApplicationType() {
     MediaType newType = MediaType.createApplicationType("yams");
     assertEquals("application", newType.type());
@@ -192,12 +160,6 @@
     assertEquals("yams", newType.subtype());
   }
 
-  public void testCreateFontType() {
-    MediaType newType = MediaType.createFontType("yams");
-    assertEquals("font", newType.type());
-    assertEquals("yams", newType.subtype());
-  }
-
   public void testCreateImageType() {
     MediaType newType = MediaType.createImageType("yams");
     assertEquals("image", newType.type());
@@ -263,26 +225,6 @@
     }
   }
 
-  public void testWithParameters_nonAsciiParameter() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    ImmutableListMultimap<String, String> parameters = ImmutableListMultimap.of("…", "a");
-    try {
-      mediaType.withParameters(parameters);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testWithParameters_nonAsciiParameterValue() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    ImmutableListMultimap<String, String> parameters = ImmutableListMultimap.of("a", "…");
-    try {
-      mediaType.withParameters(parameters);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   public void testWithParameter() {
     assertEquals(
         MediaType.parse("text/plain; a=1"), MediaType.parse("text/plain").withParameter("a", "1"));
@@ -306,33 +248,6 @@
     }
   }
 
-  public void testWithParameter_nonAsciiParameter() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    try {
-      mediaType.withParameter("…", "a");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testWithParameter_nonAsciiParameterValue() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    try {
-      mediaType.withParameter("a", "…");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testWithParameter_emptyParameter() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    try {
-      mediaType.withParameter("", "a");
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   public void testWithParametersIterable() {
     assertEquals(
         MediaType.parse("text/plain"),
@@ -360,24 +275,6 @@
     }
   }
 
-  public void testWithParametersIterable_nonAsciiParameter() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    try {
-      mediaType.withParameters("…", ImmutableSet.of("a"));
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
-  public void testWithParametersIterable_nonAsciiParameterValue() {
-    MediaType mediaType = MediaType.parse("text/plain");
-    try {
-      mediaType.withParameters("a", ImmutableSet.of("…"));
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-  }
-
   public void testWithParametersIterable_nullValue() {
     MediaType mediaType = MediaType.parse("text/plain");
     try {
@@ -610,13 +507,10 @@
   public void testToString() {
     assertEquals("text/plain", MediaType.create("text", "plain").toString());
     assertEquals(
-        "text/plain; something=\"cr@zy\"; something-else=\"crazy with spaces\";"
-            + " and-another-thing=\"\"; normal-thing=foo",
+        "text/plain; something=\"cr@zy\"; something-else=\"crazy with spaces\"",
         MediaType.create("text", "plain")
             .withParameter("something", "cr@zy")
             .withParameter("something-else", "crazy with spaces")
-            .withParameter("and-another-thing", "")
-            .withParameter("normal-thing", "foo")
             .toString());
   }
 }
diff --git a/android/guava-tests/test/com/google/common/primitives/DoublesTest.java b/android/guava-tests/test/com/google/common/primitives/DoublesTest.java
index 871b84c..293fdb1 100644
--- a/android/guava-tests/test/com/google/common/primitives/DoublesTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/DoublesTest.java
@@ -194,7 +194,6 @@
     assertEquals(-1, Doubles.lastIndexOf(new double[] {NaN, 5.0}, NaN));
   }
 
-  @GwtIncompatible
   public void testMax_noArgs() {
     try {
       Doubles.max();
@@ -217,7 +216,6 @@
     assertTrue(Double.isNaN(Doubles.max(VALUES)));
   }
 
-  @GwtIncompatible
   public void testMin_noArgs() {
     try {
       Doubles.min();
diff --git a/android/guava-tests/test/com/google/common/primitives/FloatsTest.java b/android/guava-tests/test/com/google/common/primitives/FloatsTest.java
index fd59ad4..7eb0c5b 100644
--- a/android/guava-tests/test/com/google/common/primitives/FloatsTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/FloatsTest.java
@@ -186,7 +186,6 @@
     assertEquals(-1, Floats.lastIndexOf(new float[] {NaN, 5f}, NaN));
   }
 
-  @GwtIncompatible
   public void testMax_noArgs() {
     try {
       Floats.max();
@@ -208,7 +207,6 @@
     assertTrue(Float.isNaN(Floats.max(VALUES)));
   }
 
-  @GwtIncompatible
   public void testMin_noArgs() {
     try {
       Floats.min();
diff --git a/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java b/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
index 4d98836..b55d4ba 100644
--- a/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
@@ -90,8 +90,7 @@
      * We don't guarantee the same-as property, so we aren't obligated to test it. However, it's
      * useful in testing - when two things are the same then one can't have bugs the other doesn't.
      */
-    assertThat(ImmutableDoubleArray.copyOf(new double[0]))
-        .isSameInstanceAs(ImmutableDoubleArray.of());
+    assertThat(ImmutableDoubleArray.copyOf(new double[0])).isSameAs(ImmutableDoubleArray.of());
   }
 
   public void testCopyOf_array_nonempty() {
@@ -103,7 +102,7 @@
 
   public void testCopyOf_iterable_notCollection_empty() {
     Iterable<Double> iterable = iterable(Collections.<Double>emptySet());
-    assertThat(ImmutableDoubleArray.copyOf(iterable)).isSameInstanceAs(ImmutableDoubleArray.of());
+    assertThat(ImmutableDoubleArray.copyOf(iterable)).isSameAs(ImmutableDoubleArray.of());
   }
 
   public void testCopyOf_iterable_notCollection_nonempty() {
@@ -115,7 +114,7 @@
 
   public void testCopyOf_iterable_collection_empty() {
     Iterable<Double> iterable = Collections.emptySet();
-    assertThat(ImmutableDoubleArray.copyOf(iterable)).isSameInstanceAs(ImmutableDoubleArray.of());
+    assertThat(ImmutableDoubleArray.copyOf(iterable)).isSameAs(ImmutableDoubleArray.of());
   }
 
   public void testCopyOf_iterable_collection_nonempty() {
@@ -127,7 +126,7 @@
 
   public void testCopyOf_collection_empty() {
     Collection<Double> iterable = Collections.emptySet();
-    assertThat(ImmutableDoubleArray.copyOf(iterable)).isSameInstanceAs(ImmutableDoubleArray.of());
+    assertThat(ImmutableDoubleArray.copyOf(iterable)).isSameAs(ImmutableDoubleArray.of());
   }
 
   public void testCopyOf_collection_nonempty() {
@@ -332,9 +331,9 @@
     ImmutableDoubleArray iia1 = ImmutableDoubleArray.of(5);
     ImmutableDoubleArray iia3 = ImmutableDoubleArray.of(5, 25, 125);
 
-    assertThat(iia0.subArray(0, 0)).isSameInstanceAs(ImmutableDoubleArray.of());
-    assertThat(iia1.subArray(0, 0)).isSameInstanceAs(ImmutableDoubleArray.of());
-    assertThat(iia1.subArray(1, 1)).isSameInstanceAs(ImmutableDoubleArray.of());
+    assertThat(iia0.subArray(0, 0)).isSameAs(ImmutableDoubleArray.of());
+    assertThat(iia1.subArray(0, 0)).isSameAs(ImmutableDoubleArray.of());
+    assertThat(iia1.subArray(1, 1)).isSameAs(ImmutableDoubleArray.of());
     assertThat(iia1.subArray(0, 1).asList()).containsExactly(5.0);
     assertThat(iia3.subArray(0, 2).asList()).containsExactly(5.0, 25.0).inOrder();
     assertThat(iia3.subArray(1, 3).asList()).containsExactly(25.0, 125.0).inOrder();
@@ -401,9 +400,9 @@
 
   @GwtIncompatible // SerializableTester
   public void testSerialization() {
-    assertThat(reserialize(ImmutableDoubleArray.of())).isSameInstanceAs(ImmutableDoubleArray.of());
+    assertThat(reserialize(ImmutableDoubleArray.of())).isSameAs(ImmutableDoubleArray.of());
     assertThat(reserialize(ImmutableDoubleArray.of(0, 1).subArray(1, 1)))
-        .isSameInstanceAs(ImmutableDoubleArray.of());
+        .isSameAs(ImmutableDoubleArray.of());
 
     ImmutableDoubleArray iia = ImmutableDoubleArray.of(0, 1, 3, 6).subArray(1, 3);
     ImmutableDoubleArray iia2 = reserialize(iia);
@@ -413,14 +412,14 @@
 
   private static void assertActuallyTrims(ImmutableDoubleArray iia) {
     ImmutableDoubleArray trimmed = iia.trimmed();
-    assertThat(trimmed).isNotSameInstanceAs(iia);
+    assertThat(trimmed).isNotSameAs(iia);
 
     // Yes, this is apparently how you check array equality in Truth
     assertThat(trimmed.toArray()).isEqualTo(iia.toArray());
   }
 
   private static void assertDoesntActuallyTrim(ImmutableDoubleArray iia) {
-    assertThat(iia.trimmed()).isSameInstanceAs(iia);
+    assertThat(iia.trimmed()).isSameAs(iia);
   }
 
   @GwtIncompatible // suite
diff --git a/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java b/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java
index 86274d4..7fd7dea 100644
--- a/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java
@@ -88,7 +88,7 @@
      * We don't guarantee the same-as property, so we aren't obligated to test it. However, it's
      * useful in testing - when two things are the same then one can't have bugs the other doesn't.
      */
-    assertThat(ImmutableIntArray.copyOf(new int[0])).isSameInstanceAs(ImmutableIntArray.of());
+    assertThat(ImmutableIntArray.copyOf(new int[0])).isSameAs(ImmutableIntArray.of());
   }
 
   public void testCopyOf_array_nonempty() {
@@ -100,7 +100,7 @@
 
   public void testCopyOf_iterable_notCollection_empty() {
     Iterable<Integer> iterable = iterable(Collections.<Integer>emptySet());
-    assertThat(ImmutableIntArray.copyOf(iterable)).isSameInstanceAs(ImmutableIntArray.of());
+    assertThat(ImmutableIntArray.copyOf(iterable)).isSameAs(ImmutableIntArray.of());
   }
 
   public void testCopyOf_iterable_notCollection_nonempty() {
@@ -112,7 +112,7 @@
 
   public void testCopyOf_iterable_collection_empty() {
     Iterable<Integer> iterable = Collections.emptySet();
-    assertThat(ImmutableIntArray.copyOf(iterable)).isSameInstanceAs(ImmutableIntArray.of());
+    assertThat(ImmutableIntArray.copyOf(iterable)).isSameAs(ImmutableIntArray.of());
   }
 
   public void testCopyOf_iterable_collection_nonempty() {
@@ -124,7 +124,7 @@
 
   public void testCopyOf_collection_empty() {
     Collection<Integer> iterable = Collections.emptySet();
-    assertThat(ImmutableIntArray.copyOf(iterable)).isSameInstanceAs(ImmutableIntArray.of());
+    assertThat(ImmutableIntArray.copyOf(iterable)).isSameAs(ImmutableIntArray.of());
   }
 
   public void testCopyOf_collection_nonempty() {
@@ -319,9 +319,9 @@
     ImmutableIntArray iia1 = ImmutableIntArray.of(5);
     ImmutableIntArray iia3 = ImmutableIntArray.of(5, 25, 125);
 
-    assertThat(iia0.subArray(0, 0)).isSameInstanceAs(ImmutableIntArray.of());
-    assertThat(iia1.subArray(0, 0)).isSameInstanceAs(ImmutableIntArray.of());
-    assertThat(iia1.subArray(1, 1)).isSameInstanceAs(ImmutableIntArray.of());
+    assertThat(iia0.subArray(0, 0)).isSameAs(ImmutableIntArray.of());
+    assertThat(iia1.subArray(0, 0)).isSameAs(ImmutableIntArray.of());
+    assertThat(iia1.subArray(1, 1)).isSameAs(ImmutableIntArray.of());
     assertThat(iia1.subArray(0, 1).asList()).containsExactly(5);
     assertThat(iia3.subArray(0, 2).asList()).containsExactly(5, 25).inOrder();
     assertThat(iia3.subArray(1, 3).asList()).containsExactly(25, 125).inOrder();
@@ -388,9 +388,9 @@
 
   @GwtIncompatible // SerializableTester
   public void testSerialization() {
-    assertThat(reserialize(ImmutableIntArray.of())).isSameInstanceAs(ImmutableIntArray.of());
+    assertThat(reserialize(ImmutableIntArray.of())).isSameAs(ImmutableIntArray.of());
     assertThat(reserialize(ImmutableIntArray.of(0, 1).subArray(1, 1)))
-        .isSameInstanceAs(ImmutableIntArray.of());
+        .isSameAs(ImmutableIntArray.of());
 
     ImmutableIntArray iia = ImmutableIntArray.of(0, 1, 3, 6).subArray(1, 3);
     ImmutableIntArray iia2 = reserialize(iia);
@@ -400,14 +400,14 @@
 
   private static void assertActuallyTrims(ImmutableIntArray iia) {
     ImmutableIntArray trimmed = iia.trimmed();
-    assertThat(trimmed).isNotSameInstanceAs(iia);
+    assertThat(trimmed).isNotSameAs(iia);
 
     // Yes, this is apparently how you check array equality in Truth
     assertThat(trimmed.toArray()).isEqualTo(iia.toArray());
   }
 
   private static void assertDoesntActuallyTrim(ImmutableIntArray iia) {
-    assertThat(iia.trimmed()).isSameInstanceAs(iia);
+    assertThat(iia.trimmed()).isSameAs(iia);
   }
 
   @GwtIncompatible // suite
diff --git a/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java b/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java
index ff879ec..e8813c1 100644
--- a/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java
@@ -90,7 +90,7 @@
      * We don't guarantee the same-as property, so we aren't obligated to test it. However, it's
      * useful in testing - when two things are the same then one can't have bugs the other doesn't.
      */
-    assertThat(ImmutableLongArray.copyOf(new long[0])).isSameInstanceAs(ImmutableLongArray.of());
+    assertThat(ImmutableLongArray.copyOf(new long[0])).isSameAs(ImmutableLongArray.of());
   }
 
   public void testCopyOf_array_nonempty() {
@@ -102,7 +102,7 @@
 
   public void testCopyOf_iterable_notCollection_empty() {
     Iterable<Long> iterable = iterable(Collections.<Long>emptySet());
-    assertThat(ImmutableLongArray.copyOf(iterable)).isSameInstanceAs(ImmutableLongArray.of());
+    assertThat(ImmutableLongArray.copyOf(iterable)).isSameAs(ImmutableLongArray.of());
   }
 
   public void testCopyOf_iterable_notCollection_nonempty() {
@@ -114,7 +114,7 @@
 
   public void testCopyOf_iterable_collection_empty() {
     Iterable<Long> iterable = Collections.emptySet();
-    assertThat(ImmutableLongArray.copyOf(iterable)).isSameInstanceAs(ImmutableLongArray.of());
+    assertThat(ImmutableLongArray.copyOf(iterable)).isSameAs(ImmutableLongArray.of());
   }
 
   public void testCopyOf_iterable_collection_nonempty() {
@@ -126,7 +126,7 @@
 
   public void testCopyOf_collection_empty() {
     Collection<Long> iterable = Collections.emptySet();
-    assertThat(ImmutableLongArray.copyOf(iterable)).isSameInstanceAs(ImmutableLongArray.of());
+    assertThat(ImmutableLongArray.copyOf(iterable)).isSameAs(ImmutableLongArray.of());
   }
 
   public void testCopyOf_collection_nonempty() {
@@ -321,9 +321,9 @@
     ImmutableLongArray iia1 = ImmutableLongArray.of(5);
     ImmutableLongArray iia3 = ImmutableLongArray.of(5, 25, 125);
 
-    assertThat(iia0.subArray(0, 0)).isSameInstanceAs(ImmutableLongArray.of());
-    assertThat(iia1.subArray(0, 0)).isSameInstanceAs(ImmutableLongArray.of());
-    assertThat(iia1.subArray(1, 1)).isSameInstanceAs(ImmutableLongArray.of());
+    assertThat(iia0.subArray(0, 0)).isSameAs(ImmutableLongArray.of());
+    assertThat(iia1.subArray(0, 0)).isSameAs(ImmutableLongArray.of());
+    assertThat(iia1.subArray(1, 1)).isSameAs(ImmutableLongArray.of());
     assertThat(iia1.subArray(0, 1).asList()).containsExactly(5L);
     assertThat(iia3.subArray(0, 2).asList()).containsExactly(5L, 25L).inOrder();
     assertThat(iia3.subArray(1, 3).asList()).containsExactly(25L, 125L).inOrder();
@@ -390,9 +390,9 @@
 
   @GwtIncompatible // SerializableTester
   public void testSerialization() {
-    assertThat(reserialize(ImmutableLongArray.of())).isSameInstanceAs(ImmutableLongArray.of());
+    assertThat(reserialize(ImmutableLongArray.of())).isSameAs(ImmutableLongArray.of());
     assertThat(reserialize(ImmutableLongArray.of(0, 1).subArray(1, 1)))
-        .isSameInstanceAs(ImmutableLongArray.of());
+        .isSameAs(ImmutableLongArray.of());
 
     ImmutableLongArray iia = ImmutableLongArray.of(0, 1, 3, 6).subArray(1, 3);
     ImmutableLongArray iia2 = reserialize(iia);
@@ -402,14 +402,14 @@
 
   private static void assertActuallyTrims(ImmutableLongArray iia) {
     ImmutableLongArray trimmed = iia.trimmed();
-    assertThat(trimmed).isNotSameInstanceAs(iia);
+    assertThat(trimmed).isNotSameAs(iia);
 
     // Yes, this is apparently how you check array equality in Truth
     assertThat(trimmed.toArray()).isEqualTo(iia.toArray());
   }
 
   private static void assertDoesntActuallyTrim(ImmutableLongArray iia) {
-    assertThat(iia.trimmed()).isSameInstanceAs(iia);
+    assertThat(iia.trimmed()).isSameAs(iia);
   }
 
   @GwtIncompatible // suite
diff --git a/android/guava-tests/test/com/google/common/primitives/IntsTest.java b/android/guava-tests/test/com/google/common/primitives/IntsTest.java
index 7215422..4487897 100644
--- a/android/guava-tests/test/com/google/common/primitives/IntsTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/IntsTest.java
@@ -155,7 +155,6 @@
     assertEquals(3, Ints.lastIndexOf(new int[] {(int) 2, (int) 3, (int) 2, (int) 3}, (int) 3));
   }
 
-  @GwtIncompatible
   public void testMax_noArgs() {
     try {
       Ints.max();
@@ -170,7 +169,6 @@
     assertEquals((int) 9, Ints.max((int) 8, (int) 6, (int) 7, (int) 5, (int) 3, (int) 0, (int) 9));
   }
 
-  @GwtIncompatible
   public void testMin_noArgs() {
     try {
       Ints.min();
diff --git a/android/guava-tests/test/com/google/common/primitives/ShortsTest.java b/android/guava-tests/test/com/google/common/primitives/ShortsTest.java
index 0816c69..bc4d951 100644
--- a/android/guava-tests/test/com/google/common/primitives/ShortsTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ShortsTest.java
@@ -175,7 +175,6 @@
         3, Shorts.lastIndexOf(new short[] {(short) 2, (short) 3, (short) 2, (short) 3}, (short) 3));
   }
 
-  @GwtIncompatible
   public void testMax_noArgs() {
     try {
       Shorts.max();
@@ -192,7 +191,6 @@
         Shorts.max((short) 8, (short) 6, (short) 7, (short) 5, (short) 3, (short) 0, (short) 9));
   }
 
-  @GwtIncompatible
   public void testMin_noArgs() {
     try {
       Shorts.min();
diff --git a/android/guava-tests/test/com/google/common/reflect/ClassPathTest.java b/android/guava-tests/test/com/google/common/reflect/ClassPathTest.java
index 8bccae7..58ebbbe 100644
--- a/android/guava-tests/test/com/google/common/reflect/ClassPathTest.java
+++ b/android/guava-tests/test/com/google/common/reflect/ClassPathTest.java
@@ -37,14 +37,17 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
@@ -56,16 +59,15 @@
 /** Functional tests of {@link ClassPath}. */
 public class ClassPathTest extends TestCase {
   private static final Logger log = Logger.getLogger(ClassPathTest.class.getName());
-  private static final File FILE = new File(".");
 
   public void testEquals() {
     new EqualsTester()
         .addEqualityGroup(classInfo(ClassPathTest.class), classInfo(ClassPathTest.class))
         .addEqualityGroup(classInfo(Test.class), classInfo(Test.class, getClass().getClassLoader()))
         .addEqualityGroup(
-            new ResourceInfo(FILE, "a/b/c.txt", getClass().getClassLoader()),
-            new ResourceInfo(FILE, "a/b/c.txt", getClass().getClassLoader()))
-        .addEqualityGroup(new ResourceInfo(FILE, "x.txt", getClass().getClassLoader()))
+            new ResourceInfo("a/b/c.txt", getClass().getClassLoader()),
+            new ResourceInfo("a/b/c.txt", getClass().getClassLoader()))
+        .addEqualityGroup(new ResourceInfo("x.txt", getClass().getClassLoader()))
         .testEquals();
   }
 
@@ -337,20 +339,19 @@
 
   public void testGetSimpleName() {
     ClassLoader classLoader = getClass().getClassLoader();
-    assertEquals("Foo", new ClassInfo(FILE, "Foo.class", classLoader).getSimpleName());
-    assertEquals("Foo", new ClassInfo(FILE, "a/b/Foo.class", classLoader).getSimpleName());
-    assertEquals("Foo", new ClassInfo(FILE, "a/b/Bar$Foo.class", classLoader).getSimpleName());
-    assertEquals("", new ClassInfo(FILE, "a/b/Bar$1.class", classLoader).getSimpleName());
-    assertEquals("Foo", new ClassInfo(FILE, "a/b/Bar$Foo.class", classLoader).getSimpleName());
-    assertEquals("", new ClassInfo(FILE, "a/b/Bar$1.class", classLoader).getSimpleName());
-    assertEquals("Local", new ClassInfo(FILE, "a/b/Bar$1Local.class", classLoader).getSimpleName());
+    assertEquals("Foo", new ClassInfo("Foo.class", classLoader).getSimpleName());
+    assertEquals("Foo", new ClassInfo("a/b/Foo.class", classLoader).getSimpleName());
+    assertEquals("Foo", new ClassInfo("a/b/Bar$Foo.class", classLoader).getSimpleName());
+    assertEquals("", new ClassInfo("a/b/Bar$1.class", classLoader).getSimpleName());
+    assertEquals("Foo", new ClassInfo("a/b/Bar$Foo.class", classLoader).getSimpleName());
+    assertEquals("", new ClassInfo("a/b/Bar$1.class", classLoader).getSimpleName());
+    assertEquals("Local", new ClassInfo("a/b/Bar$1Local.class", classLoader).getSimpleName());
   }
 
   public void testGetPackageName() {
+    assertEquals("", new ClassInfo("Foo.class", getClass().getClassLoader()).getPackageName());
     assertEquals(
-        "", new ClassInfo(FILE, "Foo.class", getClass().getClassLoader()).getPackageName());
-    assertEquals(
-        "a.b", new ClassInfo(FILE, "a/b/Foo.class", getClass().getClassLoader()).getPackageName());
+        "a.b", new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getPackageName());
   }
 
   // Test that ResourceInfo.urls() returns identical content to ClassLoader.getResources()
@@ -463,7 +464,7 @@
   private static ResourceInfo resourceInfo(Class<?> cls) {
     String resource = cls.getName().replace('.', '/') + ".class";
     ClassLoader loader = cls.getClassLoader();
-    return ResourceInfo.of(FILE, resource, loader);
+    return ResourceInfo.of(resource, loader);
   }
 
   private static ClassInfo classInfo(Class<?> cls) {
@@ -472,7 +473,7 @@
 
   private static ClassInfo classInfo(Class<?> cls, ClassLoader classLoader) {
     String resource = cls.getName().replace('.', '/') + ".class";
-    return new ClassInfo(FILE, resource, classLoader);
+    return new ClassInfo(resource, classLoader);
   }
 
   private static Manifest manifestClasspath(String classpath) throws IOException {
@@ -517,8 +518,20 @@
     final Set<String> resources = new HashSet<>();
 
     @Override
-    protected void scanResource(ResourceInfo resource) throws IOException {
-      resources.add(resource.getResourceName());
+    protected void scanDirectory(ClassLoader loader, File root) throws IOException {
+      URI base = root.toURI();
+      for (File entry : Files.fileTraverser().depthFirstPreOrder(root)) {
+        String resourceName = new File(base.relativize(entry.toURI()).getPath()).getPath();
+        resources.add(resourceName);
+      }
+    }
+
+    @Override
+    protected void scanJarFile(ClassLoader loader, JarFile file) throws IOException {
+      Enumeration<JarEntry> entries = file.entries();
+      while (entries.hasMoreElements()) {
+        resources.add(entries.nextElement().getName());
+      }
     }
   }
 
@@ -544,13 +557,13 @@
     }
 
     @Override
-    void scanJarFile(ClassLoader classloader, JarFile file) throws IOException {
+    protected void scanJarFile(ClassLoader loader, JarFile file) throws IOException {
       this.found = new File(file.getName());
       throw new StopScanningException();
     }
 
     @Override
-    protected void scanResource(ResourceInfo resource) {}
+    protected void scanDirectory(ClassLoader loader, File root) {}
 
     // Special exception just to terminate the scanning when we get any jar file to use.
     private static final class StopScanningException extends RuntimeException {}
diff --git a/android/guava-tests/test/com/google/common/reflect/SubtypeTester.java b/android/guava-tests/test/com/google/common/reflect/SubtypeTester.java
index 3eec668..dcf9626 100644
--- a/android/guava-tests/test/com/google/common/reflect/SubtypeTester.java
+++ b/android/guava-tests/test/com/google/common/reflect/SubtypeTester.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import com.google.errorprone.annotations.RequiredModifiers;
 import java.lang.annotation.ElementType;
@@ -85,11 +84,11 @@
     Type returnType = method.getGenericReturnType();
     Type paramType = getOnlyParameterType();
     TestSubtype spec = method.getAnnotation(TestSubtype.class);
-    assertWithMessage("%s is subtype of %s", paramType, returnType)
-        .that(TypeToken.of(paramType).isSubtypeOf(returnType))
+    assertThat(TypeToken.of(paramType).isSubtypeOf(returnType))
+        .named("%s is subtype of %s", paramType, returnType)
         .isTrue();
-    assertWithMessage("%s is supertype of %s", returnType, paramType)
-        .that(TypeToken.of(returnType).isSupertypeOf(paramType))
+    assertThat(TypeToken.of(returnType).isSupertypeOf(paramType))
+        .named("%s is supertype of %s", returnType, paramType)
         .isTrue();
     if (!spec.suppressGetSubtype()) {
       assertThat(getSubtype(returnType, TypeToken.of(paramType).getRawType())).isEqualTo(paramType);
@@ -109,11 +108,11 @@
     Type returnType = method.getGenericReturnType();
     Type paramType = getOnlyParameterType();
     TestSubtype spec = method.getAnnotation(TestSubtype.class);
-    assertWithMessage("%s is subtype of %s", paramType, returnType)
-        .that(TypeToken.of(paramType).isSubtypeOf(returnType))
+    assertThat(TypeToken.of(paramType).isSubtypeOf(returnType))
+        .named("%s is subtype of %s", paramType, returnType)
         .isFalse();
-    assertWithMessage("%s is supertype of %s", returnType, paramType)
-        .that(TypeToken.of(returnType).isSupertypeOf(paramType))
+    assertThat(TypeToken.of(returnType).isSupertypeOf(paramType))
+        .named("%s is supertype of %s", returnType, paramType)
         .isFalse();
     if (!spec.suppressGetSubtype()) {
       try {
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java
index f49b962..c7474f2 100644
--- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java
+++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractAbstractFutureTest.java
@@ -462,14 +462,14 @@
       getDone(future);
       fail();
     } catch (ExecutionException e) {
-      assertThat(e.getCause()).isSameInstanceAs(expectedException);
+      assertThat(e.getCause()).isSameAs(expectedException);
     }
 
     try {
       getDoneFromTimeoutOverload(future);
       fail();
     } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(expectedException);
+      assertThat(e).hasCauseThat().isSameAs(expectedException);
     }
   }
 
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java
index 77d04ff..d075f80 100644
--- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java
+++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureFallbackAtomicHelperTest.java
@@ -39,7 +39,7 @@
  * </ul>
  *
  * To force selection of our fallback strategies we load {@link AbstractFuture} (and all of {@code
- * com.google.common.util.concurrent}) in degenerate class loaders which make certain platform
+ * com.google.common.util.concurrent} in degenerate class loaders which make certain platform
  * classes unavailable. Then we construct a test suite so we can run the normal AbstractFutureTest
  * test methods in these degenerate classloaders.
  */
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
index 3c210ce..368e2d4 100644
--- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
+++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
@@ -19,13 +19,11 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import com.google.common.annotations.GwtIncompatible;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Range;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.internal.InternalFutureFailureAccess;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -80,8 +78,8 @@
     // Ensure we get a unique execution exception on each get
     assertNotSame(ee1, ee2);
 
-    assertThat(ee1).hasCauseThat().isSameInstanceAs(failure);
-    assertThat(ee2).hasCauseThat().isSameInstanceAs(failure);
+    assertThat(ee1).hasCauseThat().isSameAs(failure);
+    assertThat(ee2).hasCauseThat().isSameAs(failure);
 
     checkStackTrace(ee1);
     checkStackTrace(ee2);
@@ -157,7 +155,7 @@
       normalFuture.get();
       fail();
     } catch (ExecutionException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(exception);
+      assertThat(e).hasCauseThat().isSameAs(exception);
     }
   }
 
@@ -214,44 +212,6 @@
     assertThat(SettableFuture.create().toString()).isNotEqualTo(SettableFuture.create().toString());
   }
 
-  public void testToString_oom() throws Exception {
-    SettableFuture<Object> future = SettableFuture.create();
-    future.set(
-        new Object() {
-          @Override
-          public String toString() {
-            throw new OutOfMemoryError();
-          }
-
-          @Override
-          public int hashCode() {
-            throw new OutOfMemoryError();
-          }
-        });
-
-    String unused = future.toString();
-
-    SettableFuture<Object> future2 = SettableFuture.create();
-
-    // A more organic OOM from a toString implementation
-    Object object =
-        new Object() {
-          @Override
-          public String toString() {
-            return new String(new char[50_000]);
-          }
-        };
-    List<Object> list = Collections.singletonList(object);
-    for (int i = 0; i < 10; i++) {
-      Object[] array = new Object[500];
-      Arrays.fill(array, list);
-      list = Arrays.asList(array);
-    }
-    future2.set(list);
-
-    unused = future.toString();
-  }
-
   public void testToString_notDone() throws Exception {
     AbstractFuture<Object> testFuture =
         new AbstractFuture<Object>() {
@@ -272,20 +232,6 @@
     }
   }
 
-  public void testToString_completesDuringToString() throws Exception {
-    AbstractFuture<Object> testFuture =
-        new AbstractFuture<Object>() {
-          @Override
-          public String pendingToString() {
-            // Complete ourselves during the toString calculation
-            this.set(true);
-            return "cause=[Because this test isn't done]";
-          }
-        };
-    assertThat(testFuture.toString())
-        .matches("[^\\[]+\\[status=SUCCESS, result=\\[java.lang.Boolean@\\w+\\]\\]");
-  }
-
   /**
    * This test attempts to cause a future to wait for longer than it was requested to from a timed
    * get() call. As measurements of time are prone to flakiness, it tries to assert based on ranges
@@ -344,11 +290,11 @@
     testFuture3.setFuture(testFuture2);
     assertThat(testFuture3.toString())
         .matches(
-            "[^\\[]+\\[status=PENDING, setFuture=\\[[^\\[]+\\[status=PENDING,"
-                + " info=\\[cause=\\[Someday...]]]]]");
+            "[^\\[]+\\[status=PENDING, info=\\[setFuture="
+                + "\\[[^\\[]+\\[status=PENDING, info=\\[cause=\\[Someday...\\]\\]\\]\\]\\]\\]");
     testFuture2.set("result string");
     assertThat(testFuture3.toString())
-        .matches("[^\\[]+\\[status=SUCCESS, result=\\[java.lang.String@\\w+\\]\\]");
+        .matches("[^\\[]+\\[status=SUCCESS, result=\\[result string\\]\\]");
   }
 
   public void testToString_cancelled() throws Exception {
@@ -435,7 +381,7 @@
     final ExecutorService executor = Executors.newFixedThreadPool(barrier.getParties());
     final AtomicReference<AbstractFuture<String>> currentFuture = Atomics.newReference();
     final AtomicInteger numSuccessfulSetCalls = new AtomicInteger();
-    Callable<Void> completeSuccessfullyRunnable =
+    Callable<Void> completeSucessFullyRunnable =
         new Callable<Void>() {
           @Override
           public Void call() {
@@ -470,7 +416,7 @@
             return null;
           }
         };
-    Callable<Void> setFutureCompleteSuccessfullyRunnable =
+    Callable<Void> setFutureCompleteSucessFullyRunnable =
         new Callable<Void>() {
           ListenableFuture<String> future = Futures.immediateFuture("setFuture");
 
@@ -551,10 +497,10 @@
           }
         };
     List<Callable<?>> allTasks = new ArrayList<>();
-    allTasks.add(completeSuccessfullyRunnable);
+    allTasks.add(completeSucessFullyRunnable);
     allTasks.add(completeExceptionallyRunnable);
     allTasks.add(cancelRunnable);
-    allTasks.add(setFutureCompleteSuccessfullyRunnable);
+    allTasks.add(setFutureCompleteSucessFullyRunnable);
     allTasks.add(setFutureCompleteExceptionallyRunnable);
     allTasks.add(setFutureCancelRunnable);
     for (int k = 0; k < 50; k++) {
@@ -617,24 +563,24 @@
     final ExecutorService executor = Executors.newFixedThreadPool(barrier.getParties());
     final AtomicReference<AbstractFuture<String>> currentFuture = Atomics.newReference();
     final AtomicReference<AbstractFuture<String>> setFutureFuture = Atomics.newReference();
-    final AtomicBoolean setFutureSetSuccess = new AtomicBoolean();
-    final AtomicBoolean setFutureCompletionSuccess = new AtomicBoolean();
-    final AtomicBoolean cancellationSuccess = new AtomicBoolean();
+    final AtomicBoolean setFutureSetSucess = new AtomicBoolean();
+    final AtomicBoolean setFutureCompletionSucess = new AtomicBoolean();
+    final AtomicBoolean cancellationSucess = new AtomicBoolean();
     Runnable cancelRunnable =
         new Runnable() {
           @Override
           public void run() {
-            cancellationSuccess.set(currentFuture.get().cancel(true));
+            cancellationSucess.set(currentFuture.get().cancel(true));
             awaitUnchecked(barrier);
           }
         };
-    Runnable setFutureCompleteSuccessfullyRunnable =
+    Runnable setFutureCompleteSucessFullyRunnable =
         new Runnable() {
           @Override
           public void run() {
             AbstractFuture<String> future = setFutureFuture.get();
-            setFutureSetSuccess.set(currentFuture.get().setFuture(future));
-            setFutureCompletionSuccess.set(future.set("hello-async-world"));
+            setFutureSetSucess.set(currentFuture.get().setFuture(future));
+            setFutureCompletionSucess.set(future.set("hello-async-world"));
             awaitUnchecked(barrier);
           }
         };
@@ -680,7 +626,7 @@
         };
     List<Runnable> allTasks = new ArrayList<>();
     allTasks.add(cancelRunnable);
-    allTasks.add(setFutureCompleteSuccessfullyRunnable);
+    allTasks.add(setFutureCompleteSucessFullyRunnable);
     for (int k = 0; k < size; k++) {
       // For each listener we add a task that submits it to the executor directly for the blocking
       // get usecase and another task that adds it as a listener to the future to exercise both
@@ -713,12 +659,12 @@
       Object result = Iterables.getOnlyElement(finalResults);
       if (result == CancellationException.class) {
         assertTrue(future.isCancelled());
-        assertTrue(cancellationSuccess.get());
+        assertTrue(cancellationSucess.get());
         // cancellation can interleave in 3 ways
         // 1. prior to setFuture
         // 2. after setFuture before set() on the future assigned
         // 3. after setFuture and set() are called but before the listener completes.
-        if (!setFutureSetSuccess.get() || !setFutureCompletionSuccess.get()) {
+        if (!setFutureSetSucess.get() || !setFutureCompletionSucess.get()) {
           // If setFuture fails or set on the future fails then it must be because that future was
           // cancelled
           assertTrue(setFuture.isCancelled());
@@ -726,14 +672,14 @@
         }
       } else {
         // set on the future completed
-        assertFalse(cancellationSuccess.get());
-        assertTrue(setFutureSetSuccess.get());
-        assertTrue(setFutureCompletionSuccess.get());
+        assertFalse(cancellationSucess.get());
+        assertTrue(setFutureSetSucess.get());
+        assertTrue(setFutureCompletionSucess.get());
       }
       // reset for next iteration
-      setFutureSetSuccess.set(false);
-      setFutureCompletionSuccess.set(false);
-      cancellationSuccess.set(false);
+      setFutureSetSucess.set(false);
+      setFutureCompletionSucess.set(false);
+      cancellationSucess.set(false);
       finalResults.clear();
     }
     executor.shutdown();
@@ -750,17 +696,17 @@
     final ExecutorService executor = Executors.newFixedThreadPool(barrier.getParties());
     final AtomicReference<AbstractFuture<String>> currentFuture = Atomics.newReference();
     final AtomicBoolean setFutureSuccess = new AtomicBoolean();
-    final AtomicBoolean cancellationSuccess = new AtomicBoolean();
+    final AtomicBoolean cancellationSucess = new AtomicBoolean();
     Callable<Void> cancelRunnable =
         new Callable<Void>() {
           @Override
           public Void call() {
-            cancellationSuccess.set(currentFuture.get().cancel(true));
+            cancellationSucess.set(currentFuture.get().cancel(true));
             awaitUnchecked(barrier);
             return null;
           }
         };
-    Callable<Void> setFutureCompleteSuccessfullyRunnable =
+    Callable<Void> setFutureCompleteSucessFullyRunnable =
         new Callable<Void>() {
           final ListenableFuture<String> future = Futures.immediateFuture("hello");
 
@@ -790,7 +736,7 @@
         };
     List<Callable<?>> allTasks = new ArrayList<>();
     allTasks.add(cancelRunnable);
-    allTasks.add(setFutureCompleteSuccessfullyRunnable);
+    allTasks.add(setFutureCompleteSucessFullyRunnable);
     allTasks.add(Executors.callable(collectResultsRunnable));
     assertEquals(allTasks.size() + 1, barrier.getParties()); // sanity check
     for (int i = 0; i < 1000; i++) {
@@ -808,15 +754,15 @@
       Object result = Iterables.getOnlyElement(finalResults);
       if (result == CancellationException.class) {
         assertTrue(future.isCancelled());
-        assertTrue(cancellationSuccess.get());
+        assertTrue(cancellationSucess.get());
         assertFalse(setFutureSuccess.get());
       } else {
         assertTrue(setFutureSuccess.get());
-        assertFalse(cancellationSuccess.get());
+        assertFalse(cancellationSucess.get());
       }
       // reset for next iteration
       setFutureSuccess.set(false);
-      cancellationSuccess.set(false);
+      cancellationSucess.set(false);
       finalResults.clear();
     }
     executor.shutdown();
@@ -837,23 +783,6 @@
     assertTrue(orig.isDone());
   }
 
-  // Verify that StackOverflowError in a long chain of SetFuture doesn't cause the entire toString
-  // call to fail
-  @GwtIncompatible
-  @AndroidIncompatible
-  public void testSetFutureToString_stackOverflow() {
-    SettableFuture<String> orig = SettableFuture.create();
-    SettableFuture<String> prev = orig;
-    for (int i = 0; i < 100000; i++) {
-      SettableFuture<String> curr = SettableFuture.create();
-      prev.setFuture(curr);
-      prev = curr;
-    }
-    // orig represents the 'outermost' future
-    assertThat(orig.toString())
-        .contains("Exception thrown from implementation: class java.lang.StackOverflowError");
-  }
-
   public void testSetFuture_misbehavingFutureThrows() throws Exception {
     SettableFuture<String> future = SettableFuture.create();
     ListenableFuture<String> badFuture =
@@ -957,7 +886,7 @@
   public void testSetFutureSelf_toString() {
     SettableFuture<String> orig = SettableFuture.create();
     orig.setFuture(orig);
-    assertThat(orig.toString()).contains("[status=PENDING, setFuture=[this future]]");
+    assertThat(orig.toString()).contains("[status=PENDING, info=[setFuture=[this future]]]");
   }
 
   public void testSetSelf_toString() {
@@ -966,33 +895,21 @@
     assertThat(orig.toString()).contains("[status=SUCCESS, result=[this future]]");
   }
 
-  public void testSetFutureSelf_toStringException() {
-    SettableFuture<String> orig = SettableFuture.create();
-    orig.setFuture(
-        new AbstractFuture<String>() {
-          @Override
-          public String toString() {
-            throw new NullPointerException();
-          }
-        });
-    assertThat(orig.toString())
-        .contains(
-            "[status=PENDING, setFuture=[Exception thrown from implementation: class"
-                + " java.lang.NullPointerException]]");
-  }
-
   public void testSetIndirectSelf_toString() {
     final SettableFuture<Object> orig = SettableFuture.create();
     // unlike the above this indirection defeats the trivial cycle detection and causes a SOE
-    orig.setFuture(
-        new ForwardingListenableFuture<Object>() {
+    orig.set(
+        new Object() {
           @Override
-          protected ListenableFuture<Object> delegate() {
-            return orig;
+          public String toString() {
+            return orig.toString();
           }
         });
-    assertThat(orig.toString())
-        .contains("Exception thrown from implementation: class java.lang.StackOverflowError");
+    try {
+      orig.toString();
+      fail();
+    } catch (StackOverflowError expected) {
+    }
   }
 
   // Regression test for a case where we would fail to execute listeners immediately on done futures
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
index 7cad8b0..74f5d7c 100644
--- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
+++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
@@ -68,7 +68,7 @@
         service.startAsync().awaitRunning();
         fail();
       } catch (RuntimeException e) {
-        assertThat(e).hasCauseThat().isSameInstanceAs(exception);
+        assertThat(e).hasCauseThat().isSameAs(exception);
       }
       assertEquals(Service.State.FAILED, service.state());
     }
@@ -87,7 +87,7 @@
         service.stopAsync().awaitTerminated();
         fail();
       } catch (RuntimeException e) {
-        assertThat(e).hasCauseThat().isSameInstanceAs(exception);
+        assertThat(e).hasCauseThat().isSameAs(exception);
       }
       assertEquals(Service.State.FAILED, service.state());
     }
@@ -117,7 +117,7 @@
       service.startAsync().awaitRunning();
       fail();
     } catch (RuntimeException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(exception);
+      assertThat(e).hasCauseThat().isSameAs(exception);
     }
     assertEquals(1, service.startUpCalled);
     assertEquals(Service.State.FAILED, service.state());
@@ -164,7 +164,7 @@
       service.stopAsync().awaitTerminated();
       fail();
     } catch (RuntimeException e) {
-      assertThat(e).hasCauseThat().isSameInstanceAs(exception);
+      assertThat(e).hasCauseThat().isSameAs(exception);
     }
     assertEquals(1, service.startUpCalled);
     assertEquals(1, service.shutDownCalled);
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
index 16a4cd0..8e7cde9 100644
--- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
+++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
@@ -98,7 +98,7 @@
       fail();
     } catch (CancellationException expected) {
     }
-    // An execution exception holds a runtime exception (from throwables.propagate) that holds our
+    // An execution exception holds a runtime exception (from throwables.propogate) that holds our
     // original exception.
     assertEquals(service.runException, service.failureCause());
     assertEquals(Service.State.FAILED, service.state());
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
index 5f42106..faac76e 100644
--- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
+++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
@@ -42,7 +42,7 @@
  */
 public class AbstractServiceTest extends TestCase {
 
-  private static final long LONG_TIMEOUT_MILLIS = 10000;
+  private static final long LONG_TIMEOUT_MILLIS = 2500;
   private Thread executionThread;
   private Throwable thrownByExecutionThread;
 
@@ -234,21 +234,21 @@
    */
   public void testManualServiceStopMultipleTimesWhileStarting() throws Exception {
     ManualSwitchedService service = new ManualSwitchedService();
-    final AtomicInteger stoppingCount = new AtomicInteger();
+    final AtomicInteger stopppingCount = new AtomicInteger();
     service.addListener(
         new Listener() {
           @Override
           public void stopping(State from) {
-            stoppingCount.incrementAndGet();
+            stopppingCount.incrementAndGet();
           }
         },
         directExecutor());
 
     service.startAsync();
     service.stopAsync();
-    assertEquals(1, stoppingCount.get());
+    assertEquals(1, stopppingCount.get());
     service.stopAsync();
-    assertEquals(1, stoppingCount.get());
+    assertEquals(1, stopppingCount.get());
   }
 
   public void testManualServiceStopWhileNew() throws Exception {
diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java
deleted file mode 100644
index d905dcd..0000000
--- a/android/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapBasherTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.annotations.GwtIncompatible;
-import java.util.Random;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import junit.framework.TestCase;
-
-/**
- * Basher test for {@link AtomicLongMap}.
- *
- * @author mike nonemacher
- */
-@GwtIncompatible // threads
-
-public class AtomicLongMapBasherTest extends TestCase {
-  private final Random random = new Random(301);
-
-  public void testModify_basher() throws InterruptedException {
-    int nTasks = 3000;
-    int nThreads = 100;
-    final int getsPerTask = 1000;
-    final int deltaRange = 10000;
-    final String key = "key";
-
-    final AtomicLong sum = new AtomicLong();
-    final AtomicLongMap<String> map = AtomicLongMap.create();
-
-    ExecutorService threadPool = Executors.newFixedThreadPool(nThreads);
-    for (int i = 0; i < nTasks; i++) {
-      @SuppressWarnings("unused") // go/futurereturn-lsc
-      Future<?> possiblyIgnoredError =
-          threadPool.submit(
-              new Runnable() {
-                @Override
-                public void run() {
-                  int threadSum = 0;
-                  for (int j = 0; j < getsPerTask; j++) {
-                    long delta = random.nextInt(deltaRange);
-                    int behavior = random.nextInt(10);
-                    switch (behavior) {
-                      case 0:
-                        map.incrementAndGet(key);
-