diff --git a/d8_r8/test_modules/tests_java_9/build.gradle.kts b/d8_r8/test_modules/tests_java_9/build.gradle.kts
index 136a506..337f868d 100644
--- a/d8_r8/test_modules/tests_java_9/build.gradle.kts
+++ b/d8_r8/test_modules/tests_java_9/build.gradle.kts
@@ -19,9 +19,21 @@
   }
   sourceCompatibility = JavaVersion.VERSION_1_9
   targetCompatibility = JavaVersion.VERSION_1_9
+  toolchain {
+    languageVersion = JavaLanguageVersion.of(JvmCompatibility.release)
+  }
 }
 
-dependencies { }
+val testbaseJavaCompileTask = projectTask("testbase", "compileJava")
+val testbaseDepsJarTask = projectTask("testbase", "depsJar")
+val mainCompileTask = projectTask("main", "compileJava")
+
+dependencies {
+  implementation(files(testbaseDepsJarTask.outputs.files.getSingleFile()))
+  implementation(testbaseJavaCompileTask.outputs.files)
+  implementation(mainCompileTask.outputs.files)
+  implementation(projectTask("main", "processResources").outputs.files)
+}
 
 // We just need to register the examples jars for it to be referenced by other modules.
 val buildExampleJars = buildExampleJars("examplesJava9")
@@ -29,9 +41,19 @@
 tasks {
   withType<JavaCompile> {
     dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
-    options.setFork(true)
-    options.forkOptions.memoryMaximumSize = "3g"
-    options.forkOptions.executable = getCompilerPath(Jdk.JDK_9)
+  }
+
+  withType<Test> {
+    notCompatibleWithConfigurationCache(
+      "Failure storing the configuration cache: cannot serialize object of type 'org.gradle.api.internal.project.DefaultProject', a subtype of 'org.gradle.api.Project', as these are not supported with the configuration cache")
+    TestingState.setUpTestingState(this)
+    systemProperty("TEST_DATA_LOCATION",
+      // This should be
+      //   layout.buildDirectory.dir("classes/java/test").get().toString()
+      // once the use of 'buildExampleJars' above is removed.
+                   getRoot().resolveAll("build", "test", "examplesJava9", "classes"))
+    systemProperty("TESTBASE_DATA_LOCATION",
+                   testbaseJavaCompileTask.outputs.files.getAsPath().split(File.pathSeparator)[0])
   }
 }
 
diff --git a/d8_r8/test_modules/tests_java_9/settings.gradle.kts b/d8_r8/test_modules/tests_java_9/settings.gradle.kts
index ad1c8ab..7d7a19b 100644
--- a/d8_r8/test_modules/tests_java_9/settings.gradle.kts
+++ b/d8_r8/test_modules/tests_java_9/settings.gradle.kts
@@ -23,4 +23,7 @@
 
 rootProject.name = "tests_java_9"
 val root = rootProject.projectDir.parentFile.parentFile
+
 includeBuild(root.resolve("shared"))
+includeBuild(root.resolve("main"))
+includeBuild(root.resolve("test_modules").resolve("testbase"))
diff --git a/src/test/examplesJava9/backport/ByteBackportJava9Main.java b/src/test/examplesJava9/backport/ByteBackportJava9Main.java
deleted file mode 100644
index 2487a81..0000000
--- a/src/test/examplesJava9/backport/ByteBackportJava9Main.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package backport;
-
-public final class ByteBackportJava9Main {
-  private static final byte MIN_UNSIGNED_VALUE = (byte) 0;
-  private static final byte MAX_UNSIGNED_VALUE = (byte) -1;
-
-  public static void main(String[] args) {
-    testCompareUnsigned();
-  }
-
-  private static void testCompareUnsigned() {
-    assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) == 0);
-    assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, Byte.MAX_VALUE) < 0);
-    assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, Byte.MIN_VALUE) < 0);
-    assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) < 0);
-
-    assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, MIN_UNSIGNED_VALUE) > 0);
-    assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, Byte.MAX_VALUE) == 0);
-    assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, Byte.MIN_VALUE) < 0);
-    assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, MAX_UNSIGNED_VALUE) < 0);
-
-    assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, MIN_UNSIGNED_VALUE) > 0);
-    assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, Byte.MAX_VALUE) > 0);
-    assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, Byte.MIN_VALUE) == 0);
-    assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, MAX_UNSIGNED_VALUE) < 0);
-
-    assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) > 0);
-    assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, Byte.MAX_VALUE) > 0);
-    assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, Byte.MIN_VALUE) > 0);
-    assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/ByteBackportJava9Test.java b/src/test/examplesJava9/backport/ByteBackportJava9Test.java
new file mode 100644
index 0000000..9f689fd
--- /dev/null
+++ b/src/test/examplesJava9/backport/ByteBackportJava9Test.java
@@ -0,0 +1,71 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class ByteBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public ByteBackportJava9Test(TestParameters parameters) {
+    super(parameters, Byte.class, ByteBackportJava9Main.class);
+
+    // Byte.compareUnsigned added in API 31.
+    registerTarget(AndroidApiLevel.S, 16);
+  }
+
+  public static class ByteBackportJava9Main {
+
+    private static final byte MIN_UNSIGNED_VALUE = (byte) 0;
+    private static final byte MAX_UNSIGNED_VALUE = (byte) -1;
+
+    public static void main(String[] args) {
+      testCompareUnsigned();
+    }
+
+    private static void testCompareUnsigned() {
+      assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) == 0);
+      assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, Byte.MAX_VALUE) < 0);
+      assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, Byte.MIN_VALUE) < 0);
+      assertTrue(Byte.compareUnsigned(MIN_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) < 0);
+
+      assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, MIN_UNSIGNED_VALUE) > 0);
+      assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, Byte.MAX_VALUE) == 0);
+      assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, Byte.MIN_VALUE) < 0);
+      assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, MAX_UNSIGNED_VALUE) < 0);
+
+      assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, MIN_UNSIGNED_VALUE) > 0);
+      assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, Byte.MAX_VALUE) > 0);
+      assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, Byte.MIN_VALUE) == 0);
+      assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, MAX_UNSIGNED_VALUE) < 0);
+
+      assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) > 0);
+      assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, Byte.MAX_VALUE) > 0);
+      assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, Byte.MIN_VALUE) > 0);
+      assertTrue(Byte.compareUnsigned(MAX_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/IntegerBackportJava9Main.java b/src/test/examplesJava9/backport/IntegerBackportJava9Main.java
deleted file mode 100644
index acf18d2..0000000
--- a/src/test/examplesJava9/backport/IntegerBackportJava9Main.java
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-public final class IntegerBackportJava9Main {
-  private static final int[] interestingValues = {
-    Integer.MIN_VALUE,
-    Integer.MAX_VALUE,
-    Short.MIN_VALUE,
-    Short.MAX_VALUE,
-    Byte.MIN_VALUE,
-    Byte.MAX_VALUE,
-    0,
-    -1,
-    1,
-    -42,
-    42
-  };
-
-  public static void main(String[] args) {
-    testParseIntegerSubsequenceWithRadix();
-    testParseUnsignedIntegerSubsequenceWithRadix();
-  }
-
-  private static void testParseIntegerSubsequenceWithRadix() {
-    for (int value : interestingValues) {
-      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-        for (String prefix : new String[] {"", "x", "xxx"}) {
-          for (String postfix : new String[] {"", "x", "xxx"}) {
-            String valueString = prefix + Long.toString(value, radix) + postfix;
-            int start = prefix.length();
-            int end = valueString.length() - postfix.length();
-            assertEquals(valueString, value, Integer.parseInt(valueString, start, end, radix));
-            if (value > 0) {
-              valueString = prefix + '+' + Long.toString(value, radix) + postfix;
-              end++;
-              assertEquals(valueString, value, Integer.parseInt(valueString, start, end, radix));
-            }
-          }
-        }
-      }
-    }
-
-    try {
-      throw new AssertionError(Integer.parseInt("0", 0, 1, Character.MIN_RADIX - 1));
-    } catch (IllegalArgumentException expected) {
-    }
-    try {
-      throw new AssertionError(Integer.parseInt("0", 0, 1, Character.MAX_RADIX + 1));
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      throw new AssertionError(Integer.parseInt("", 0, 0, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Integer.parseInt("-", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Integer.parseInt("+", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-
-    try {
-      throw new AssertionError(Integer.parseInt("+a", 0, 2, 10));
-    } catch (NumberFormatException expected) {
-    }
-
-    long overflow = 73709551616L;
-    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-      for (String prefix : new String[] {"", "x", "xxx"}) {
-        for (String postfix : new String[] {"", "x", "xxx"}) {
-          String overflowString = prefix + Long.toString(overflow, radix) + postfix;
-          int start = prefix.length();
-          int end = overflowString.length() - postfix.length();
-          try {
-            throw new AssertionError(Integer.parseInt(overflowString, start, end, radix));
-          } catch (NumberFormatException expected) {
-          }
-          String underflowString = prefix + '-' + Long.toString(overflow, radix) + postfix;
-          start = prefix.length();
-          end = underflowString.length() - postfix.length();
-          try {
-            throw new AssertionError(Integer.parseInt(underflowString, start, end, radix));
-          } catch (NumberFormatException expected) {
-          }
-        }
-      }
-    }
-  }
-
-  private static void testParseUnsignedIntegerSubsequenceWithRadix() {
-    for (int value : interestingValues) {
-      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-        for (String prefix : new String[] {"", "x", "xxx"}) {
-          for (String postfix : new String[] {"", "x", "xxx"}) {
-            String unsignedIntergerString = Long.toString(Integer.toUnsignedLong(value), radix);
-            String valueString = prefix + unsignedIntergerString + postfix;
-            int start = prefix.length();
-            int end = valueString.length() - postfix.length();
-            assertEquals(
-                valueString, value, Integer.parseUnsignedInt(valueString, start, end, radix));
-            if (value > 0) {
-              valueString = prefix + '+' + unsignedIntergerString + postfix;
-              end++;
-              assertEquals(
-                  valueString, value, Integer.parseUnsignedInt(valueString, start, end, radix));
-            }
-          }
-        }
-      }
-    }
-
-    try {
-      throw new AssertionError(Integer.parseUnsignedInt("0", 0, 1, Character.MIN_RADIX - 1));
-    } catch (IllegalArgumentException expected) {
-    }
-    try {
-      throw new AssertionError(Integer.parseUnsignedInt("0", 0, 1, Character.MAX_RADIX + 1));
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      throw new AssertionError(Integer.parseUnsignedInt("", 0, 0, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Integer.parseUnsignedInt("-", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Integer.parseUnsignedInt("+", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-
-    try {
-      throw new AssertionError(Integer.parseUnsignedInt("+a", 0, 2, 10));
-    } catch (NumberFormatException expected) {
-    }
-
-    long overflow = 73709551616L;
-    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-      for (String prefix : new String[] {"", "x", "xxx"}) {
-        for (String postfix : new String[] {"", "x", "xxx"}) {
-          String overflowString = prefix + Long.toString(overflow, radix) + postfix;
-          int start = prefix.length();
-          int end = overflowString.length() - postfix.length();
-          try {
-            throw new AssertionError(Integer.parseUnsignedInt(overflowString, start, end, radix));
-          } catch (NumberFormatException expected) {
-          }
-        }
-      }
-    }
-  }
-
-  private static void assertEquals(String m, int expected, int actual) {
-    if (expected != actual) {
-      throw new AssertionError(m + " Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/IntegerBackportJava9Test.java b/src/test/examplesJava9/backport/IntegerBackportJava9Test.java
new file mode 100644
index 0000000..cbafce8
--- /dev/null
+++ b/src/test/examplesJava9/backport/IntegerBackportJava9Test.java
@@ -0,0 +1,196 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class IntegerBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public IntegerBackportJava9Test(TestParameters parameters) {
+    super(parameters, Integer.class, IntegerBackportJava9Main.class);
+    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
+    // Java 11 move these tests to IntegerBackportTest (out of examplesJava9).
+
+    registerTarget(AndroidApiLevel.O, 1);
+    registerTarget(AndroidApiLevel.T, 20);
+  }
+
+  public static class IntegerBackportJava9Main {
+    private static final int[] interestingValues = {
+      Integer.MIN_VALUE,
+      Integer.MAX_VALUE,
+      Short.MIN_VALUE,
+      Short.MAX_VALUE,
+      Byte.MIN_VALUE,
+      Byte.MAX_VALUE,
+      0,
+      -1,
+      1,
+      -42,
+      42
+    };
+
+    public static void main(String[] args) {
+      testParseIntegerSubsequenceWithRadix();
+      testParseUnsignedIntegerSubsequenceWithRadix();
+    }
+
+    private static void testParseIntegerSubsequenceWithRadix() {
+      for (int value : interestingValues) {
+        for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+          for (String prefix : new String[] {"", "x", "xxx"}) {
+            for (String postfix : new String[] {"", "x", "xxx"}) {
+              String valueString = prefix + Long.toString(value, radix) + postfix;
+              int start = prefix.length();
+              int end = valueString.length() - postfix.length();
+              assertEquals(valueString, value, Integer.parseInt(valueString, start, end, radix));
+              if (value > 0) {
+                valueString = prefix + '+' + Long.toString(value, radix) + postfix;
+                end++;
+                assertEquals(valueString, value, Integer.parseInt(valueString, start, end, radix));
+              }
+            }
+          }
+        }
+      }
+
+      try {
+        throw new AssertionError(Integer.parseInt("0", 0, 1, Character.MIN_RADIX - 1));
+      } catch (IllegalArgumentException expected) {
+      }
+      try {
+        throw new AssertionError(Integer.parseInt("0", 0, 1, Character.MAX_RADIX + 1));
+      } catch (IllegalArgumentException expected) {
+      }
+
+      try {
+        throw new AssertionError(Integer.parseInt("", 0, 0, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Integer.parseInt("-", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Integer.parseInt("+", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+
+      try {
+        throw new AssertionError(Integer.parseInt("+a", 0, 2, 10));
+      } catch (NumberFormatException expected) {
+      }
+
+      long overflow = 73709551616L;
+      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+        for (String prefix : new String[] {"", "x", "xxx"}) {
+          for (String postfix : new String[] {"", "x", "xxx"}) {
+            String overflowString = prefix + Long.toString(overflow, radix) + postfix;
+            int start = prefix.length();
+            int end = overflowString.length() - postfix.length();
+            try {
+              throw new AssertionError(Integer.parseInt(overflowString, start, end, radix));
+            } catch (NumberFormatException expected) {
+            }
+            String underflowString = prefix + '-' + Long.toString(overflow, radix) + postfix;
+            start = prefix.length();
+            end = underflowString.length() - postfix.length();
+            try {
+              throw new AssertionError(Integer.parseInt(underflowString, start, end, radix));
+            } catch (NumberFormatException expected) {
+            }
+          }
+        }
+      }
+    }
+
+    private static void testParseUnsignedIntegerSubsequenceWithRadix() {
+      for (int value : interestingValues) {
+        for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+          for (String prefix : new String[] {"", "x", "xxx"}) {
+            for (String postfix : new String[] {"", "x", "xxx"}) {
+              String unsignedIntergerString = Long.toString(Integer.toUnsignedLong(value), radix);
+              String valueString = prefix + unsignedIntergerString + postfix;
+              int start = prefix.length();
+              int end = valueString.length() - postfix.length();
+              assertEquals(
+                  valueString, value, Integer.parseUnsignedInt(valueString, start, end, radix));
+              if (value > 0) {
+                valueString = prefix + '+' + unsignedIntergerString + postfix;
+                end++;
+                assertEquals(
+                    valueString, value, Integer.parseUnsignedInt(valueString, start, end, radix));
+              }
+            }
+          }
+        }
+      }
+
+      try {
+        throw new AssertionError(Integer.parseUnsignedInt("0", 0, 1, Character.MIN_RADIX - 1));
+      } catch (IllegalArgumentException expected) {
+      }
+      try {
+        throw new AssertionError(Integer.parseUnsignedInt("0", 0, 1, Character.MAX_RADIX + 1));
+      } catch (IllegalArgumentException expected) {
+      }
+
+      try {
+        throw new AssertionError(Integer.parseUnsignedInt("", 0, 0, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Integer.parseUnsignedInt("-", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Integer.parseUnsignedInt("+", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+
+      try {
+        throw new AssertionError(Integer.parseUnsignedInt("+a", 0, 2, 10));
+      } catch (NumberFormatException expected) {
+      }
+
+      long overflow = 73709551616L;
+      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+        for (String prefix : new String[] {"", "x", "xxx"}) {
+          for (String postfix : new String[] {"", "x", "xxx"}) {
+            String overflowString = prefix + Long.toString(overflow, radix) + postfix;
+            int start = prefix.length();
+            int end = overflowString.length() - postfix.length();
+            try {
+              throw new AssertionError(Integer.parseUnsignedInt(overflowString, start, end, radix));
+            } catch (NumberFormatException expected) {
+            }
+          }
+        }
+      }
+    }
+
+    private static void assertEquals(String m, int expected, int actual) {
+      if (expected != actual) {
+        throw new AssertionError(m + " Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/ListBackportJava9Main.java b/src/test/examplesJava9/backport/ListBackportJava9Main.java
deleted file mode 100644
index 4c8ae88..0000000
--- a/src/test/examplesJava9/backport/ListBackportJava9Main.java
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.List;
-
-public class ListBackportJava9Main {
-
-  public static void main(String[] args) {
-    testOf0();
-    testOf1();
-    testOf2();
-    testOf10();
-    testOfVarargs();
-  }
-
-  private static void testOf0() {
-    List<Object> ofObject = List.of();
-    assertEquals(0, ofObject.size());
-    assertMutationNotAllowed(ofObject);
-
-    List<Integer> ofInteger = List.of();
-    assertEquals(0, ofInteger.size());
-    assertMutationNotAllowed(ofObject);
-  }
-
-  private static void testOf1() {
-    Object anObject = new Object();
-    List<Object> ofObject = List.of(anObject);
-    assertEquals(1, ofObject.size());
-    assertSame(anObject, ofObject.get(0));
-    assertMutationNotAllowed(ofObject);
-
-    List<Integer> ofInteger = List.of(1);
-    assertEquals(1, ofInteger.size());
-    assertEquals(1, ofInteger.get(0));
-
-    try {
-      List.of((Object) null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testOf2() {
-    Object anObject0 = new Object();
-    Object anObject1 = new Object();
-    List<Object> ofObject = List.of(anObject0, anObject1);
-    assertEquals(2, ofObject.size());
-    assertSame(anObject0, ofObject.get(0));
-    assertSame(anObject1, ofObject.get(1));
-    assertMutationNotAllowed(ofObject);
-
-    List<Integer> ofInteger = List.of(1, 2);
-    assertEquals(2, ofInteger.size());
-    assertEquals(1, ofInteger.get(0));
-    assertEquals(2, ofInteger.get(1));
-
-    List<Object> ofMixed = List.of(anObject0, 1);
-    assertEquals(2, ofMixed.size());
-    assertSame(anObject0, ofMixed.get(0));
-    assertEquals(1, ofMixed.get(1));
-    assertMutationNotAllowed(ofMixed);
-
-    try {
-      List.of(1, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testOf10() {
-    Object anObject0 = new Object();
-    Object anObject6 = new Object();
-    Object anObject9 = new Object();
-    List<Object> ofObject =
-        List.of(anObject0, new Object(), new Object(), new Object(), new Object(), new Object(),
-            anObject6, new Object(), new Object(), anObject9);
-    assertEquals(10, ofObject.size());
-    assertSame(anObject0, ofObject.get(0));
-    assertSame(anObject6, ofObject.get(6));
-    assertSame(anObject9, ofObject.get(9));
-    assertMutationNotAllowed(ofObject);
-
-    List<Integer> ofInteger = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
-    assertEquals(10, ofInteger.size());
-    assertEquals(0, ofInteger.get(0));
-    assertEquals(6, ofInteger.get(6));
-    assertEquals(9, ofInteger.get(9));
-
-    List<Object> ofMixed = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, anObject9);
-    assertEquals(10, ofMixed.size());
-    assertEquals(0, ofMixed.get(0));
-    assertEquals(6, ofMixed.get(6));
-    assertSame(anObject9, ofMixed.get(9));
-    assertMutationNotAllowed(ofMixed);
-
-    try {
-      List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testOfVarargs() {
-    Object anObject0 = new Object();
-    Object anObject6 = new Object();
-    Object anObject10 = new Object();
-    List<Object> ofObject =
-        List.of(anObject0, new Object(), new Object(), new Object(), new Object(), new Object(),
-            anObject6, new Object(), new Object(), new Object(), anObject10);
-    assertEquals(11, ofObject.size());
-    assertSame(anObject0, ofObject.get(0));
-    assertSame(anObject6, ofObject.get(6));
-    assertSame(anObject10, ofObject.get(10));
-    assertMutationNotAllowed(ofObject);
-
-    List<Integer> ofInteger = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
-    assertEquals(11, ofInteger.size());
-    assertEquals(0, ofInteger.get(0));
-    assertEquals(6, ofInteger.get(6));
-    assertEquals(10, ofInteger.get(10));
-
-    List<Object> ofMixed = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, anObject10);
-    assertEquals(11, ofMixed.size());
-    assertEquals(0, ofMixed.get(0));
-    assertEquals(6, ofMixed.get(6));
-    assertSame(anObject10, ofMixed.get(10));
-    assertMutationNotAllowed(ofMixed);
-
-    // Ensure the supplied mutable array is not used directly since it is mutable.
-    Object[] mutableArray = { anObject0 };
-    List<Object> ofMutableArray = List.of(mutableArray);
-    mutableArray[0] = anObject10;
-    assertSame(anObject0, ofMutableArray.get(0));
-
-    try {
-      List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void assertMutationNotAllowed(List<Object> ofObject) {
-    try {
-      ofObject.add(new Object());
-      throw new AssertionError();
-    } catch (UnsupportedOperationException expected) {
-    }
-    try {
-      ofObject.set(0, new Object());
-      throw new AssertionError();
-    } catch (UnsupportedOperationException expected) {
-    }
-  }
-
-  private static void assertSame(Object expected, Object actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
-    }
-  }
-
-  private static void assertEquals(Object expected, Object actual) {
-    if (expected != actual && !expected.equals(actual)) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/ListBackportJava9Test.java b/src/test/examplesJava9/backport/ListBackportJava9Test.java
new file mode 100644
index 0000000..f7ea015
--- /dev/null
+++ b/src/test/examplesJava9/backport/ListBackportJava9Test.java
@@ -0,0 +1,244 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.desugar.backports.IgnoreInvokes;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.List;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ListBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public ListBackportJava9Test(TestParameters parameters) {
+    super(parameters, List.class, ListBackportJava9Main.class);
+    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
+    // an actual API level, migrate these tests to ListBackportTest.
+
+    // Available since API 1 and used to test created lists.
+    ignoreInvokes("add");
+    ignoreInvokes("get");
+    ignoreInvokes("set");
+    ignoreInvokes("size");
+
+    // List.of added in API 30.
+    registerTarget(AndroidApiLevel.R, 18);
+  }
+
+  @Test
+  public void desugaringApiLevelR() throws Exception {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added check and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.Q)) {
+      testForD8()
+          .setMinApi(AndroidApiLevel.R)
+          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
+          .addProgramClasses(ListBackportJava9Main.class)
+          .setIncludeClassesChecksum(true)
+          .compile()
+          .run(parameters.getRuntime(), ListBackportJava9Main.class)
+          .assertFailureWithErrorThatMatches(
+              CoreMatchers.containsString("java.lang.NoSuchMethodError"));
+    }
+  }
+
+  public static class ListBackportJava9Main {
+
+    public static void main(String[] args) {
+      testOf0();
+      testOf1();
+      testOf2();
+      testOf10();
+      testOfVarargs();
+    }
+
+    private static void testOf0() {
+      List<Object> ofObject = List.of();
+      assertEquals(0, ofObject.size());
+      assertMutationNotAllowed(ofObject);
+
+      List<Integer> ofInteger = List.of();
+      assertEquals(0, ofInteger.size());
+      assertMutationNotAllowed(ofObject);
+    }
+
+    private static void testOf1() {
+      Object anObject = new Object();
+      List<Object> ofObject = List.of(anObject);
+      assertEquals(1, ofObject.size());
+      assertSame(anObject, ofObject.get(0));
+      assertMutationNotAllowed(ofObject);
+
+      List<Integer> ofInteger = List.of(1);
+      assertEquals(1, ofInteger.size());
+      assertEquals(1, ofInteger.get(0));
+
+      try {
+        List.of((Object) null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testOf2() {
+      Object anObject0 = new Object();
+      Object anObject1 = new Object();
+      List<Object> ofObject = List.of(anObject0, anObject1);
+      assertEquals(2, ofObject.size());
+      assertSame(anObject0, ofObject.get(0));
+      assertSame(anObject1, ofObject.get(1));
+      assertMutationNotAllowed(ofObject);
+
+      List<Integer> ofInteger = List.of(1, 2);
+      assertEquals(2, ofInteger.size());
+      assertEquals(1, ofInteger.get(0));
+      assertEquals(2, ofInteger.get(1));
+
+      List<Object> ofMixed = List.of(anObject0, 1);
+      assertEquals(2, ofMixed.size());
+      assertSame(anObject0, ofMixed.get(0));
+      assertEquals(1, ofMixed.get(1));
+      assertMutationNotAllowed(ofMixed);
+
+      try {
+        List.of(1, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testOf10() {
+      Object anObject0 = new Object();
+      Object anObject6 = new Object();
+      Object anObject9 = new Object();
+      List<Object> ofObject =
+          List.of(
+              anObject0,
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              anObject6,
+              new Object(),
+              new Object(),
+              anObject9);
+      assertEquals(10, ofObject.size());
+      assertSame(anObject0, ofObject.get(0));
+      assertSame(anObject6, ofObject.get(6));
+      assertSame(anObject9, ofObject.get(9));
+      assertMutationNotAllowed(ofObject);
+
+      List<Integer> ofInteger = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+      assertEquals(10, ofInteger.size());
+      assertEquals(0, ofInteger.get(0));
+      assertEquals(6, ofInteger.get(6));
+      assertEquals(9, ofInteger.get(9));
+
+      List<Object> ofMixed = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, anObject9);
+      assertEquals(10, ofMixed.size());
+      assertEquals(0, ofMixed.get(0));
+      assertEquals(6, ofMixed.get(6));
+      assertSame(anObject9, ofMixed.get(9));
+      assertMutationNotAllowed(ofMixed);
+
+      try {
+        List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testOfVarargs() {
+      Object anObject0 = new Object();
+      Object anObject6 = new Object();
+      Object anObject10 = new Object();
+      List<Object> ofObject =
+          List.of(
+              anObject0,
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              anObject6,
+              new Object(),
+              new Object(),
+              new Object(),
+              anObject10);
+      assertEquals(11, ofObject.size());
+      assertSame(anObject0, ofObject.get(0));
+      assertSame(anObject6, ofObject.get(6));
+      assertSame(anObject10, ofObject.get(10));
+      assertMutationNotAllowed(ofObject);
+
+      List<Integer> ofInteger = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+      assertEquals(11, ofInteger.size());
+      assertEquals(0, ofInteger.get(0));
+      assertEquals(6, ofInteger.get(6));
+      assertEquals(10, ofInteger.get(10));
+
+      List<Object> ofMixed = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, anObject10);
+      assertEquals(11, ofMixed.size());
+      assertEquals(0, ofMixed.get(0));
+      assertEquals(6, ofMixed.get(6));
+      assertSame(anObject10, ofMixed.get(10));
+      assertMutationNotAllowed(ofMixed);
+
+      // Ensure the supplied mutable array is not used directly since it is mutable.
+      Object[] mutableArray = {anObject0};
+      List<Object> ofMutableArray = List.of(mutableArray);
+      mutableArray[0] = anObject10;
+      assertSame(anObject0, ofMutableArray.get(0));
+
+      try {
+        List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void assertMutationNotAllowed(List<Object> ofObject) {
+      try {
+        ofObject.add(new Object());
+        throw new AssertionError();
+      } catch (UnsupportedOperationException expected) {
+      }
+      try {
+        ofObject.set(0, new Object());
+        throw new AssertionError();
+      } catch (UnsupportedOperationException expected) {
+      }
+    }
+
+    private static void assertSame(Object expected, Object actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
+      }
+    }
+
+    private static void assertEquals(Object expected, Object actual) {
+      if (expected != actual && !expected.equals(actual)) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/LongBackportJava9Main.java b/src/test/examplesJava9/backport/LongBackportJava9Main.java
deleted file mode 100644
index f24c337..0000000
--- a/src/test/examplesJava9/backport/LongBackportJava9Main.java
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.math.BigInteger;
-
-public final class LongBackportJava9Main {
-  private static final long[] interestingValues = {
-    Long.MIN_VALUE,
-    Long.MAX_VALUE,
-    Integer.MIN_VALUE,
-    Integer.MAX_VALUE,
-    Short.MIN_VALUE,
-    Short.MAX_VALUE,
-    Byte.MIN_VALUE,
-    Byte.MAX_VALUE,
-    0L,
-    -1L,
-    1L,
-    -42L,
-    42L
-  };
-
-  public static void main(String[] args) {
-    testParseLongSubsequenceWithRadix();
-    testParseUnsignedLongSubsequenceWithRadix();
-  }
-
-  private static void testParseLongSubsequenceWithRadix() {
-    for (long value : interestingValues) {
-      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-        for (String prefix : new String[] {"", "x", "xxx"}) {
-          for (String postfix : new String[] {"", "x", "xxx"}) {
-            String valueString = prefix + Long.toString(value, radix) + postfix;
-            int start = prefix.length();
-            int end = valueString.length() - postfix.length();
-            assertEquals(valueString, value, Long.parseLong(valueString, start, end, radix));
-            if (value > 0) {
-              valueString = prefix + "+" + Long.toString(value, radix) + postfix;
-              end++;
-              assertEquals(valueString, value, Long.parseLong(valueString, start, end, radix));
-            }
-          }
-        }
-      }
-    }
-
-    try {
-      throw new AssertionError(Long.parseLong("0", 0, 1, Character.MIN_RADIX - 1));
-    } catch (IllegalArgumentException expected) {
-    }
-    try {
-      throw new AssertionError(Long.parseLong("0", 0, 1, Character.MAX_RADIX + 1));
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      throw new AssertionError(Long.parseLong("", 0, 0, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Long.parseLong("-", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Long.parseLong("+", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-
-    try {
-      throw new AssertionError(Long.parseLong("+a", 0, 2, 10));
-    } catch (NumberFormatException expected) {
-    }
-
-    BigInteger overflow = new BigInteger("18446744073709551616");
-    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-      for (String prefix : new String[] {"", "x", "xxx"}) {
-        for (String postfix : new String[] {"", "x", "xxx"}) {
-          String overflowString = prefix + overflow.toString(radix) + postfix;
-          int start = prefix.length();
-          int end = overflowString.length() - postfix.length();
-          try {
-            throw new AssertionError(Long.parseLong(overflowString, start, end, radix));
-          } catch (NumberFormatException expected) {
-          }
-        }
-      }
-    }
-  }
-
-  private static void testParseUnsignedLongSubsequenceWithRadix() {
-    for (long value : interestingValues) {
-      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-        for (String prefix : new String[] {"", "x", "xxx"}) {
-          for (String postfix : new String[] {"", "x", "xxx"}) {
-            String valueString = prefix + unsignedLongToBigInteger(value).toString(radix) + postfix;
-            int start = prefix.length();
-            int end = valueString.length() - postfix.length();
-            assertEquals(
-                valueString, value, Long.parseUnsignedLong(valueString, start, end, radix));
-            valueString = prefix + "+" + unsignedLongToBigInteger(value).toString(radix) + postfix;
-            end++;
-            assertEquals(
-                valueString, value, Long.parseUnsignedLong(valueString, start, end, radix));
-          }
-        }
-      }
-    }
-
-    try {
-      throw new AssertionError(Long.parseUnsignedLong("0", 0, 1, Character.MIN_RADIX - 1));
-    } catch (IllegalArgumentException expected) {
-    }
-    try {
-      throw new AssertionError(Long.parseUnsignedLong("0", 0, 1, Character.MAX_RADIX + 1));
-    } catch (IllegalArgumentException expected) {
-    }
-
-    try {
-      throw new AssertionError(Long.parseUnsignedLong("", 0, 0, 16));
-    } catch (NumberFormatException expected) {
-    }
-    try {
-      throw new AssertionError(Long.parseUnsignedLong("+", 0, 1, 16));
-    } catch (NumberFormatException expected) {
-    }
-
-    try {
-      throw new AssertionError(Long.parseUnsignedLong("+a", 0, 2, 10));
-    } catch (NumberFormatException expected) {
-    }
-
-    BigInteger overflow = new BigInteger("18446744073709551616");
-    for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
-      for (String prefix : new String[] {"", "x", "xxx", "+", "x+", "xxx+"}) {
-        for (String postfix : new String[] {"", "x", "xxx"}) {
-          String overflowString = prefix + overflow.toString(radix) + postfix;
-          int start = prefix.length();
-          int end = overflowString.length() - postfix.length();
-          try {
-            throw new AssertionError(Long.parseUnsignedLong(overflowString, start, end, radix));
-          } catch (NumberFormatException expected) {
-          }
-        }
-      }
-    }
-  }
-
-  private static BigInteger unsignedLongToBigInteger(long value) {
-    BigInteger bigInt = BigInteger.valueOf(value & 0x7fffffffffffffffL);
-    if (value < 0) {
-      bigInt = bigInt.setBit(Long.SIZE - 1);
-    }
-    return bigInt;
-  }
-
-  private static void assertEquals(String m, long expected, long actual) {
-    if (expected != actual) {
-      throw new AssertionError(m + " Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/LongBackportJava9Test.java b/src/test/examplesJava9/backport/LongBackportJava9Test.java
new file mode 100644
index 0000000..cb64b6d
--- /dev/null
+++ b/src/test/examplesJava9/backport/LongBackportJava9Test.java
@@ -0,0 +1,196 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.math.BigInteger;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class LongBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public LongBackportJava9Test(TestParameters parameters) {
+    super(parameters, Long.class, LongBackportJava9Main.class);
+    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
+    // Java 11 move these tests to LongBackportTest (out of examplesJava9).
+
+    ignoreInvokes("toString");
+
+    registerTarget(AndroidApiLevel.T, 17);
+  }
+
+  public static class LongBackportJava9Main {
+    private static final long[] interestingValues = {
+      Long.MIN_VALUE,
+      Long.MAX_VALUE,
+      Integer.MIN_VALUE,
+      Integer.MAX_VALUE,
+      Short.MIN_VALUE,
+      Short.MAX_VALUE,
+      Byte.MIN_VALUE,
+      Byte.MAX_VALUE,
+      0L,
+      -1L,
+      1L,
+      -42L,
+      42L
+    };
+
+    public static void main(String[] args) {
+      testParseLongSubsequenceWithRadix();
+      testParseUnsignedLongSubsequenceWithRadix();
+    }
+
+    private static void testParseLongSubsequenceWithRadix() {
+      for (long value : interestingValues) {
+        for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+          for (String prefix : new String[] {"", "x", "xxx"}) {
+            for (String postfix : new String[] {"", "x", "xxx"}) {
+              String valueString = prefix + Long.toString(value, radix) + postfix;
+              int start = prefix.length();
+              int end = valueString.length() - postfix.length();
+              assertEquals(valueString, value, Long.parseLong(valueString, start, end, radix));
+              if (value > 0) {
+                valueString = prefix + "+" + Long.toString(value, radix) + postfix;
+                end++;
+                assertEquals(valueString, value, Long.parseLong(valueString, start, end, radix));
+              }
+            }
+          }
+        }
+      }
+
+      try {
+        throw new AssertionError(Long.parseLong("0", 0, 1, Character.MIN_RADIX - 1));
+      } catch (IllegalArgumentException expected) {
+      }
+      try {
+        throw new AssertionError(Long.parseLong("0", 0, 1, Character.MAX_RADIX + 1));
+      } catch (IllegalArgumentException expected) {
+      }
+
+      try {
+        throw new AssertionError(Long.parseLong("", 0, 0, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Long.parseLong("-", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Long.parseLong("+", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+
+      try {
+        throw new AssertionError(Long.parseLong("+a", 0, 2, 10));
+      } catch (NumberFormatException expected) {
+      }
+
+      BigInteger overflow = new BigInteger("18446744073709551616");
+      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+        for (String prefix : new String[] {"", "x", "xxx"}) {
+          for (String postfix : new String[] {"", "x", "xxx"}) {
+            String overflowString = prefix + overflow.toString(radix) + postfix;
+            int start = prefix.length();
+            int end = overflowString.length() - postfix.length();
+            try {
+              throw new AssertionError(Long.parseLong(overflowString, start, end, radix));
+            } catch (NumberFormatException expected) {
+            }
+          }
+        }
+      }
+    }
+
+    private static void testParseUnsignedLongSubsequenceWithRadix() {
+      for (long value : interestingValues) {
+        for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+          for (String prefix : new String[] {"", "x", "xxx"}) {
+            for (String postfix : new String[] {"", "x", "xxx"}) {
+              String valueString =
+                  prefix + unsignedLongToBigInteger(value).toString(radix) + postfix;
+              int start = prefix.length();
+              int end = valueString.length() - postfix.length();
+              assertEquals(
+                  valueString, value, Long.parseUnsignedLong(valueString, start, end, radix));
+              valueString =
+                  prefix + "+" + unsignedLongToBigInteger(value).toString(radix) + postfix;
+              end++;
+              assertEquals(
+                  valueString, value, Long.parseUnsignedLong(valueString, start, end, radix));
+            }
+          }
+        }
+      }
+
+      try {
+        throw new AssertionError(Long.parseUnsignedLong("0", 0, 1, Character.MIN_RADIX - 1));
+      } catch (IllegalArgumentException expected) {
+      }
+      try {
+        throw new AssertionError(Long.parseUnsignedLong("0", 0, 1, Character.MAX_RADIX + 1));
+      } catch (IllegalArgumentException expected) {
+      }
+
+      try {
+        throw new AssertionError(Long.parseUnsignedLong("", 0, 0, 16));
+      } catch (NumberFormatException expected) {
+      }
+      try {
+        throw new AssertionError(Long.parseUnsignedLong("+", 0, 1, 16));
+      } catch (NumberFormatException expected) {
+      }
+
+      try {
+        throw new AssertionError(Long.parseUnsignedLong("+a", 0, 2, 10));
+      } catch (NumberFormatException expected) {
+      }
+
+      BigInteger overflow = new BigInteger("18446744073709551616");
+      for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+        for (String prefix : new String[] {"", "x", "xxx", "+", "x+", "xxx+"}) {
+          for (String postfix : new String[] {"", "x", "xxx"}) {
+            String overflowString = prefix + overflow.toString(radix) + postfix;
+            int start = prefix.length();
+            int end = overflowString.length() - postfix.length();
+            try {
+              throw new AssertionError(Long.parseUnsignedLong(overflowString, start, end, radix));
+            } catch (NumberFormatException expected) {
+            }
+          }
+        }
+      }
+    }
+
+    private static BigInteger unsignedLongToBigInteger(long value) {
+      BigInteger bigInt = BigInteger.valueOf(value & 0x7fffffffffffffffL);
+      if (value < 0) {
+        bigInt = bigInt.setBit(Long.SIZE - 1);
+      }
+      return bigInt;
+    }
+
+    private static void assertEquals(String m, long expected, long actual) {
+      if (expected != actual) {
+        throw new AssertionError(m + " Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/MapBackportJava9Main.java b/src/test/examplesJava9/backport/MapBackportJava9Main.java
deleted file mode 100644
index 442fd9b..0000000
--- a/src/test/examplesJava9/backport/MapBackportJava9Main.java
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.AbstractMap;
-import java.util.Map;
-
-public class MapBackportJava9Main {
-
-  public static void main(String[] args) {
-    testOf0();
-    testOf1();
-    testOf2();
-    testOf10();
-    testOfEntries();
-    testEntry();
-  }
-
-  private static void testOf0() {
-    Map<Object, Object> ofObject = Map.of();
-    assertEquals(0, ofObject.size());
-    assertEquals(null, ofObject.get(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Map<Integer, Integer> ofInteger = Map.of();
-    assertEquals(0, ofInteger.size());
-    assertEquals(null, ofInteger.get(0));
-  }
-
-  private static void testOf1() {
-    Object objectKey0 = new Object();
-    Object objectValue0 = new Object();
-    Map<Object, Object> ofObject = Map.of(objectKey0, objectValue0);
-    assertEquals(1, ofObject.size());
-    assertSame(objectValue0, ofObject.get(objectKey0));
-    assertEquals(null, ofObject.get(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Map<Integer, Integer> ofInteger = Map.of(0, 0);
-    assertEquals(1, ofInteger.size());
-    assertEquals(0, ofInteger.get(0));
-    assertEquals(null, ofInteger.get(1));
-
-    try {
-      Map.of((Object) null, 1);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map.of(1, (Object) null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testOf2() {
-    Object objectKey0 = new Object();
-    Object objectValue0 = new Object();
-    Object objectKey1 = new Object();
-    Object objectValue1 = new Object();
-    Map<Object, Object> ofObject = Map.of(objectKey0, objectValue0, objectKey1, objectValue1);
-    assertEquals(2, ofObject.size());
-    assertSame(objectValue0, ofObject.get(objectKey0));
-    assertSame(objectValue1, ofObject.get(objectKey1));
-    assertEquals(null, ofObject.get(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Map<Integer, Integer> ofInteger = Map.of(0, 0, 1, 1);
-    assertEquals(2, ofInteger.size());
-    assertEquals(0, ofInteger.get(0));
-    assertEquals(1, ofInteger.get(1));
-    assertEquals(null, ofInteger.get(3));
-
-    Map<Object, Object> ofMixed = Map.of(objectKey0, 0, objectKey1, 1);
-    assertEquals(2, ofMixed.size());
-    assertEquals(0, ofMixed.get(objectKey0));
-    assertEquals(1, ofMixed.get(objectKey1));
-    assertEquals(null, ofMixed.get(new Object()));
-
-    try {
-      Map.of(1, 1, null, 2);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map.of(1, 1, 2, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Map.of(1, 1, 1, 2);
-      throw new AssertionError();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("duplicate key: 1", expected.getMessage());
-    }
-  }
-
-  private static void testOf10() {
-    Object objectKey0 = new Object();
-    Object objectValue0 = new Object();
-    Object objectKey6 = new Object();
-    Object objectValue6 = new Object();
-    Object objectKey9 = new Object();
-    Object objectValue9 = new Object();
-    Map<Object, Object> ofObject =
-        Map.of(objectKey0, objectValue0, new Object(), new Object(), new Object(), new Object(),
-            new Object(), new Object(), new Object(), new Object(), new Object(), new Object(),
-            objectKey6, objectValue6, new Object(), new Object(), new Object(), new Object(),
-            objectKey9, objectValue9);
-    assertEquals(10, ofObject.size());
-    assertSame(objectValue0, ofObject.get(objectKey0));
-    assertSame(objectValue6, ofObject.get(objectKey6));
-    assertSame(objectValue9, ofObject.get(objectKey9));
-    assertEquals(null, ofObject.get(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Map<Integer, Integer> ofInteger =
-        Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9);
-    assertEquals(10, ofInteger.size());
-    assertEquals(0, ofInteger.get(0));
-    assertEquals(6, ofInteger.get(6));
-    assertEquals(9, ofInteger.get(9));
-    assertEquals(null, ofInteger.get(10));
-
-    Map<Object, Object> ofMixed =
-        Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, objectKey9, objectValue9);
-    assertEquals(10, ofMixed.size());
-    assertEquals(0, ofMixed.get(0));
-    assertEquals(6, ofMixed.get(6));
-    assertSame(objectValue9, ofMixed.get(objectKey9));
-    assertEquals(null, ofMixed.get(9));
-
-    try {
-      Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, null, objectValue9);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, objectKey9, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 0, 9);
-      throw new AssertionError();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("duplicate key: 0", expected.getMessage());
-    }
-  }
-
-  private static void testOfEntries() {
-    Object objectKey0 = new Object();
-    Object objectValue0 = new Object();
-    Object objectKey1 = new Object();
-    Object objectValue1 = new Object();
-    Map<Object, Object> ofObject = Map.ofEntries(
-        new AbstractMap.SimpleEntry<>(objectKey0, objectValue0),
-        new AbstractMap.SimpleEntry<>(objectKey1, objectValue1));
-    assertEquals(2, ofObject.size());
-    assertSame(objectValue0, ofObject.get(objectKey0));
-    assertSame(objectValue1, ofObject.get(objectKey1));
-    assertEquals(null, ofObject.get(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Map<Integer, Integer> ofInteger = Map.ofEntries(
-        new AbstractMap.SimpleEntry<>(0, 0),
-        new AbstractMap.SimpleEntry<>(1, 1));
-    assertEquals(2, ofInteger.size());
-    assertEquals(0, ofInteger.get(0));
-    assertEquals(1, ofInteger.get(1));
-    assertEquals(null, ofInteger.get(2));
-
-    Map<Object, Object> ofMixed = Map.ofEntries(
-        new AbstractMap.SimpleEntry<>(0, objectValue0),
-        new AbstractMap.SimpleEntry<>(objectKey1, 1));
-    assertEquals(2, ofMixed.size());
-    assertSame(objectValue0, ofMixed.get(0));
-    assertEquals(1, ofMixed.get(objectKey1));
-    assertEquals(null, ofMixed.get(1));
-
-    // Ensure the supplied entry objects are not used directly since they are mutable.
-    Map.Entry<Object, Object> mutableEntry =
-        new AbstractMap.SimpleEntry<>(objectKey0, objectValue0);
-    Map<Object, Object> ofMutableEntry = Map.ofEntries(mutableEntry);
-    mutableEntry.setValue(objectValue1);
-    assertSame(objectValue0, ofMutableEntry.get(objectKey0));
-
-    // Ensure the supplied mutable array is not used directly since it is mutable.
-    @SuppressWarnings("unchecked")
-    Map.Entry<Object, Object>[] mutableArray =
-        new Map.Entry[] { new AbstractMap.SimpleEntry<>(objectKey0, objectValue0) };
-    Map<Object, Object> ofArray = Map.ofEntries(mutableArray);
-    mutableArray[0] = new AbstractMap.SimpleEntry<>(objectKey1, objectValue1);
-    assertSame(objectValue0, ofArray.get(objectKey0));
-    assertEquals(null, ofArray.get(objectKey1));
-
-    try {
-      Map.ofEntries(new AbstractMap.SimpleEntry<Object, Integer>(null, 1));
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map.ofEntries(new AbstractMap.SimpleEntry<Object, Integer>(1, null));
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Map.ofEntries(
-          new AbstractMap.SimpleEntry<>(0, objectValue0),
-          new AbstractMap.SimpleEntry<>(0, objectValue1));
-      throw new AssertionError();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("duplicate key: 0", expected.getMessage());
-    }
-  }
-
-  private static void testEntry() {
-    Object key = new Object();
-    Object value = new Object();
-    Map.Entry<Object, Object> entry = Map.entry(key, value);
-    assertSame(key, entry.getKey());
-    assertSame(value, entry.getValue());
-
-    try {
-      entry.setValue(new Object());
-      throw new AssertionError();
-    } catch (UnsupportedOperationException expected) {
-    }
-
-    try {
-      Map.entry(null, value);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map.entry(key, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void assertMutationNotAllowed(Map<Object, Object> ofObject) {
-    try {
-      ofObject.put(new Object(), new Object());
-      throw new AssertionError();
-    } catch (UnsupportedOperationException expected) {
-    }
-    for (Map.Entry<Object, Object> entry : ofObject.entrySet()) {
-      try {
-        entry.setValue(new Object());
-        throw new AssertionError();
-      } catch (UnsupportedOperationException expected) {
-      }
-    }
-  }
-
-  private static void assertSame(Object expected, Object actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
-    }
-  }
-
-  private static void assertEquals(Object expected, Object actual) {
-    if (expected != actual && !expected.equals(actual)) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/MapBackportJava9Test.java b/src/test/examplesJava9/backport/MapBackportJava9Test.java
new file mode 100644
index 0000000..df6af49
--- /dev/null
+++ b/src/test/examplesJava9/backport/MapBackportJava9Test.java
@@ -0,0 +1,346 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.desugar.backports.IgnoreInvokes;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.AbstractMap;
+import java.util.Map;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class MapBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public MapBackportJava9Test(TestParameters parameters) {
+    super(parameters, Map.class, MapBackportJava9Main.class);
+    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
+    // an actual API level, migrate these tests to MapBackportTest.
+
+    // Available since API 1 and used to test created maps.
+    ignoreInvokes("entrySet");
+    ignoreInvokes("get");
+    ignoreInvokes("put");
+    ignoreInvokes("size");
+
+    // Map.entry, Map.of and Map.ofEntries added in API 30.
+    registerTarget(AndroidApiLevel.R, 29);
+  }
+
+  @Test
+  public void desugaringApiLevelR() throws Exception {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added check and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
+      testForD8()
+          .setMinApi(AndroidApiLevel.R)
+          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
+          .addProgramClasses(MapBackportJava9Main.class)
+          .setIncludeClassesChecksum(true)
+          .compile()
+          .run(parameters.getRuntime(), MapBackportJava9Main.class)
+          .assertFailureWithErrorThatMatches(
+              CoreMatchers.containsString("java.lang.NoSuchMethodError"));
+    }
+  }
+
+  public static class MapBackportJava9Main {
+
+    public static void main(String[] args) {
+      testOf0();
+      testOf1();
+      testOf2();
+      testOf10();
+      testOfEntries();
+      testEntry();
+    }
+
+    private static void testOf0() {
+      Map<Object, Object> ofObject = Map.of();
+      assertEquals(0, ofObject.size());
+      assertEquals(null, ofObject.get(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Map<Integer, Integer> ofInteger = Map.of();
+      assertEquals(0, ofInteger.size());
+      assertEquals(null, ofInteger.get(0));
+    }
+
+    private static void testOf1() {
+      Object objectKey0 = new Object();
+      Object objectValue0 = new Object();
+      Map<Object, Object> ofObject = Map.of(objectKey0, objectValue0);
+      assertEquals(1, ofObject.size());
+      assertSame(objectValue0, ofObject.get(objectKey0));
+      assertEquals(null, ofObject.get(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Map<Integer, Integer> ofInteger = Map.of(0, 0);
+      assertEquals(1, ofInteger.size());
+      assertEquals(0, ofInteger.get(0));
+      assertEquals(null, ofInteger.get(1));
+
+      try {
+        Map.of((Object) null, 1);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map.of(1, (Object) null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testOf2() {
+      Object objectKey0 = new Object();
+      Object objectValue0 = new Object();
+      Object objectKey1 = new Object();
+      Object objectValue1 = new Object();
+      Map<Object, Object> ofObject = Map.of(objectKey0, objectValue0, objectKey1, objectValue1);
+      assertEquals(2, ofObject.size());
+      assertSame(objectValue0, ofObject.get(objectKey0));
+      assertSame(objectValue1, ofObject.get(objectKey1));
+      assertEquals(null, ofObject.get(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Map<Integer, Integer> ofInteger = Map.of(0, 0, 1, 1);
+      assertEquals(2, ofInteger.size());
+      assertEquals(0, ofInteger.get(0));
+      assertEquals(1, ofInteger.get(1));
+      assertEquals(null, ofInteger.get(3));
+
+      Map<Object, Object> ofMixed = Map.of(objectKey0, 0, objectKey1, 1);
+      assertEquals(2, ofMixed.size());
+      assertEquals(0, ofMixed.get(objectKey0));
+      assertEquals(1, ofMixed.get(objectKey1));
+      assertEquals(null, ofMixed.get(new Object()));
+
+      try {
+        Map.of(1, 1, null, 2);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map.of(1, 1, 2, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+
+      try {
+        Map.of(1, 1, 1, 2);
+        throw new AssertionError();
+      } catch (IllegalArgumentException expected) {
+        assertEquals("duplicate key: 1", expected.getMessage());
+      }
+    }
+
+    private static void testOf10() {
+      Object objectKey0 = new Object();
+      Object objectValue0 = new Object();
+      Object objectKey6 = new Object();
+      Object objectValue6 = new Object();
+      Object objectKey9 = new Object();
+      Object objectValue9 = new Object();
+      Map<Object, Object> ofObject =
+          Map.of(
+              objectKey0,
+              objectValue0,
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              objectKey6,
+              objectValue6,
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              objectKey9,
+              objectValue9);
+      assertEquals(10, ofObject.size());
+      assertSame(objectValue0, ofObject.get(objectKey0));
+      assertSame(objectValue6, ofObject.get(objectKey6));
+      assertSame(objectValue9, ofObject.get(objectKey9));
+      assertEquals(null, ofObject.get(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Map<Integer, Integer> ofInteger =
+          Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9);
+      assertEquals(10, ofInteger.size());
+      assertEquals(0, ofInteger.get(0));
+      assertEquals(6, ofInteger.get(6));
+      assertEquals(9, ofInteger.get(9));
+      assertEquals(null, ofInteger.get(10));
+
+      Map<Object, Object> ofMixed =
+          Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, objectKey9, objectValue9);
+      assertEquals(10, ofMixed.size());
+      assertEquals(0, ofMixed.get(0));
+      assertEquals(6, ofMixed.get(6));
+      assertSame(objectValue9, ofMixed.get(objectKey9));
+      assertEquals(null, ofMixed.get(9));
+
+      try {
+        Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, null, objectValue9);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, objectKey9, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+
+      try {
+        Map.of(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 0, 9);
+        throw new AssertionError();
+      } catch (IllegalArgumentException expected) {
+        assertEquals("duplicate key: 0", expected.getMessage());
+      }
+    }
+
+    private static void testOfEntries() {
+      Object objectKey0 = new Object();
+      Object objectValue0 = new Object();
+      Object objectKey1 = new Object();
+      Object objectValue1 = new Object();
+      Map<Object, Object> ofObject =
+          Map.ofEntries(
+              new AbstractMap.SimpleEntry<>(objectKey0, objectValue0),
+              new AbstractMap.SimpleEntry<>(objectKey1, objectValue1));
+      assertEquals(2, ofObject.size());
+      assertSame(objectValue0, ofObject.get(objectKey0));
+      assertSame(objectValue1, ofObject.get(objectKey1));
+      assertEquals(null, ofObject.get(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Map<Integer, Integer> ofInteger =
+          Map.ofEntries(new AbstractMap.SimpleEntry<>(0, 0), new AbstractMap.SimpleEntry<>(1, 1));
+      assertEquals(2, ofInteger.size());
+      assertEquals(0, ofInteger.get(0));
+      assertEquals(1, ofInteger.get(1));
+      assertEquals(null, ofInteger.get(2));
+
+      Map<Object, Object> ofMixed =
+          Map.ofEntries(
+              new AbstractMap.SimpleEntry<>(0, objectValue0),
+              new AbstractMap.SimpleEntry<>(objectKey1, 1));
+      assertEquals(2, ofMixed.size());
+      assertSame(objectValue0, ofMixed.get(0));
+      assertEquals(1, ofMixed.get(objectKey1));
+      assertEquals(null, ofMixed.get(1));
+
+      // Ensure the supplied entry objects are not used directly since they are mutable.
+      Map.Entry<Object, Object> mutableEntry =
+          new AbstractMap.SimpleEntry<>(objectKey0, objectValue0);
+      Map<Object, Object> ofMutableEntry = Map.ofEntries(mutableEntry);
+      mutableEntry.setValue(objectValue1);
+      assertSame(objectValue0, ofMutableEntry.get(objectKey0));
+
+      // Ensure the supplied mutable array is not used directly since it is mutable.
+      @SuppressWarnings("unchecked")
+      Map.Entry<Object, Object>[] mutableArray =
+          new Map.Entry[] {new AbstractMap.SimpleEntry<>(objectKey0, objectValue0)};
+      Map<Object, Object> ofArray = Map.ofEntries(mutableArray);
+      mutableArray[0] = new AbstractMap.SimpleEntry<>(objectKey1, objectValue1);
+      assertSame(objectValue0, ofArray.get(objectKey0));
+      assertEquals(null, ofArray.get(objectKey1));
+
+      try {
+        Map.ofEntries(new AbstractMap.SimpleEntry<Object, Integer>(null, 1));
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map.ofEntries(new AbstractMap.SimpleEntry<Object, Integer>(1, null));
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+
+      try {
+        Map.ofEntries(
+            new AbstractMap.SimpleEntry<>(0, objectValue0),
+            new AbstractMap.SimpleEntry<>(0, objectValue1));
+        throw new AssertionError();
+      } catch (IllegalArgumentException expected) {
+        assertEquals("duplicate key: 0", expected.getMessage());
+      }
+    }
+
+    private static void testEntry() {
+      Object key = new Object();
+      Object value = new Object();
+      Map.Entry<Object, Object> entry = Map.entry(key, value);
+      assertSame(key, entry.getKey());
+      assertSame(value, entry.getValue());
+
+      try {
+        entry.setValue(new Object());
+        throw new AssertionError();
+      } catch (UnsupportedOperationException expected) {
+      }
+
+      try {
+        Map.entry(null, value);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map.entry(key, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void assertMutationNotAllowed(Map<Object, Object> ofObject) {
+      try {
+        ofObject.put(new Object(), new Object());
+        throw new AssertionError();
+      } catch (UnsupportedOperationException expected) {
+      }
+      for (Map.Entry<Object, Object> entry : ofObject.entrySet()) {
+        try {
+          entry.setValue(new Object());
+          throw new AssertionError();
+        } catch (UnsupportedOperationException expected) {
+        }
+      }
+    }
+
+    private static void assertSame(Object expected, Object actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
+      }
+    }
+
+    private static void assertEquals(Object expected, Object actual) {
+      if (expected != actual && !expected.equals(actual)) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/MathBackportJava9Main.java b/src/test/examplesJava9/backport/MathBackportJava9Main.java
deleted file mode 100644
index 9030283..0000000
--- a/src/test/examplesJava9/backport/MathBackportJava9Main.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.math.BigInteger;
-
-public class MathBackportJava9Main {
-
-  public static void main(String[] args) {
-    testMultiplyExactLongInt();
-    testMultiplyFull();
-    testMultiplyHigh();
-    testFloorDivLongInt();
-    testFloorModLongInt();
-  }
-
-  public static void testMultiplyExactLongInt() {
-    assertEquals(8L, Math.multiplyExact(2L, 4));
-    assertEquals(Long.MAX_VALUE, Math.multiplyExact(Long.MAX_VALUE, 1));
-    assertEquals(Long.MIN_VALUE, Math.multiplyExact(Long.MIN_VALUE / 2L, 2));
-    try {
-      throw new AssertionError(Math.multiplyExact(Long.MAX_VALUE, 2));
-    } catch (ArithmeticException expected) {
-    }
-    try {
-      throw new AssertionError(Math.multiplyExact(Long.MIN_VALUE, 2));
-    } catch (ArithmeticException expected) {
-    }
-  }
-
-  public static void testMultiplyFull() {
-    assertEquals(8L, Math.multiplyFull(2, 4));
-    assertEquals(4611686014132420609L,
-        Math.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE));
-    assertEquals(-4611686016279904256L,
-        Math.multiplyFull(Integer.MAX_VALUE, Integer.MIN_VALUE));
-    assertEquals(4611686018427387904L,
-        Math.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE));
-  }
-
-  public static void testMultiplyHigh() {
-    long[] interestingValues = {
-        Long.MIN_VALUE, Long.MAX_VALUE,
-        Integer.MIN_VALUE, Integer.MAX_VALUE,
-        Short.MIN_VALUE, Short.MAX_VALUE,
-        Byte.MIN_VALUE, Byte.MAX_VALUE,
-        0L,
-        -1L, 1L,
-        -42L, 42L
-    };
-    for (long x : interestingValues) {
-      for (long y : interestingValues) {
-        long expected = BigInteger.valueOf(x)
-            .multiply(BigInteger.valueOf(y))
-            .shiftRight(64)
-            .longValue();
-        assertEquals(expected, Math.multiplyHigh(x, y));
-      }
-    }
-  }
-
-  public static void testFloorDivLongInt() {
-    assertEquals(1L, Math.floorDiv(4L, 4));
-    assertEquals(1L, Math.floorDiv(-4L, -4));
-    assertEquals(-1L, Math.floorDiv(-4L, 4));
-    assertEquals(-1L, Math.floorDiv(4L, -4));
-
-    assertEquals(1L, Math.floorDiv(4L, 3));
-    assertEquals(1L, Math.floorDiv(-4L, -3));
-    assertEquals(-2L, Math.floorDiv(-4L, 3));
-    assertEquals(-2L, Math.floorDiv(4L, -3));
-
-    // Spec edge case: result is actually MAX_VALUE+1 which becomes MIN_VALUE.
-    assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, -1));
-  }
-
-  public static void testFloorModLongInt() {
-    assertEquals(0, Math.floorMod(4L, 4));
-    assertEquals(0, Math.floorMod(-4L, -4));
-    assertEquals(0, Math.floorMod(-4L, 4));
-    assertEquals(0, Math.floorMod(4L, -4));
-
-    assertEquals(1, Math.floorMod(4L, 3));
-    assertEquals(-1, Math.floorMod(-4L, -3));
-    assertEquals(2, Math.floorMod(-4L, 3));
-    assertEquals(-2, Math.floorMod(4L, -3));
-  }
-
-  private static void assertEquals(int expected, int actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-
-  private static void assertEquals(long expected, long actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/MathBackportJava9Test.java b/src/test/examplesJava9/backport/MathBackportJava9Test.java
new file mode 100644
index 0000000..19b600b
--- /dev/null
+++ b/src/test/examplesJava9/backport/MathBackportJava9Test.java
@@ -0,0 +1,131 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.math.BigInteger;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class MathBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimes()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public MathBackportJava9Test(TestParameters parameters) {
+    super(parameters, Math.class, MathBackportJava9Main.class);
+
+    // Math.floorDiv, Math.floorMod, Math.multiplyExact, Math.multiplyFull and Math.multiplyHigh
+    // added in API 31.
+    registerTarget(AndroidApiLevel.S, 27);
+  }
+
+  public static class MathBackportJava9Main {
+
+    public static void main(String[] args) {
+      testMultiplyExactLongInt();
+      testMultiplyFull();
+      testMultiplyHigh();
+      testFloorDivLongInt();
+      testFloorModLongInt();
+    }
+
+    public static void testMultiplyExactLongInt() {
+      assertEquals(8L, Math.multiplyExact(2L, 4));
+      assertEquals(Long.MAX_VALUE, Math.multiplyExact(Long.MAX_VALUE, 1));
+      assertEquals(Long.MIN_VALUE, Math.multiplyExact(Long.MIN_VALUE / 2L, 2));
+      try {
+        throw new AssertionError(Math.multiplyExact(Long.MAX_VALUE, 2));
+      } catch (ArithmeticException expected) {
+      }
+      try {
+        throw new AssertionError(Math.multiplyExact(Long.MIN_VALUE, 2));
+      } catch (ArithmeticException expected) {
+      }
+    }
+
+    public static void testMultiplyFull() {
+      assertEquals(8L, Math.multiplyFull(2, 4));
+      assertEquals(4611686014132420609L, Math.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE));
+      assertEquals(-4611686016279904256L, Math.multiplyFull(Integer.MAX_VALUE, Integer.MIN_VALUE));
+      assertEquals(4611686018427387904L, Math.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    }
+
+    public static void testMultiplyHigh() {
+      long[] interestingValues = {
+        Long.MIN_VALUE,
+        Long.MAX_VALUE,
+        Integer.MIN_VALUE,
+        Integer.MAX_VALUE,
+        Short.MIN_VALUE,
+        Short.MAX_VALUE,
+        Byte.MIN_VALUE,
+        Byte.MAX_VALUE,
+        0L,
+        -1L,
+        1L,
+        -42L,
+        42L
+      };
+      for (long x : interestingValues) {
+        for (long y : interestingValues) {
+          long expected =
+              BigInteger.valueOf(x).multiply(BigInteger.valueOf(y)).shiftRight(64).longValue();
+          assertEquals(expected, Math.multiplyHigh(x, y));
+        }
+      }
+    }
+
+    public static void testFloorDivLongInt() {
+      assertEquals(1L, Math.floorDiv(4L, 4));
+      assertEquals(1L, Math.floorDiv(-4L, -4));
+      assertEquals(-1L, Math.floorDiv(-4L, 4));
+      assertEquals(-1L, Math.floorDiv(4L, -4));
+
+      assertEquals(1L, Math.floorDiv(4L, 3));
+      assertEquals(1L, Math.floorDiv(-4L, -3));
+      assertEquals(-2L, Math.floorDiv(-4L, 3));
+      assertEquals(-2L, Math.floorDiv(4L, -3));
+
+      // Spec edge case: result is actually MAX_VALUE+1 which becomes MIN_VALUE.
+      assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, -1));
+    }
+
+    public static void testFloorModLongInt() {
+      assertEquals(0, Math.floorMod(4L, 4));
+      assertEquals(0, Math.floorMod(-4L, -4));
+      assertEquals(0, Math.floorMod(-4L, 4));
+      assertEquals(0, Math.floorMod(4L, -4));
+
+      assertEquals(1, Math.floorMod(4L, 3));
+      assertEquals(-1, Math.floorMod(-4L, -3));
+      assertEquals(2, Math.floorMod(-4L, 3));
+      assertEquals(-2, Math.floorMod(4L, -3));
+    }
+
+    private static void assertEquals(int expected, int actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+
+    private static void assertEquals(long expected, long actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/ObjectsBackportJava9Main.java b/src/test/examplesJava9/backport/ObjectsBackportJava9Main.java
deleted file mode 100644
index 5f0f97f..0000000
--- a/src/test/examplesJava9/backport/ObjectsBackportJava9Main.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package backport;
-
-import java.util.Objects;
-
-public final class ObjectsBackportJava9Main {
-  public static void main(String[] args) {
-    boolean isAndroid = "Dalvik".equals(System.getProperty("java.vm.name"));
-    String majorVersion = System.getProperty("java.vm.version").split("\\.", -1)[0];
-
-    testRequireNonNullElse();
-    if (!isAndroid || Integer.parseInt(majorVersion) >= 7) {
-      // TODO desugaring desugaredlibrary is blocked by
-      // https://issuetracker.google.com/issues/114481425
-      testRequireNonNullElseGet();
-    }
-    testCheckIndex();
-    testCheckFromToIndex();
-    testCheckFromIndexSize();
-  }
-
-  private static void testRequireNonNullElse() {
-    Object one = new Object();
-    Object two = new Object();
-
-    assertSame(one, Objects.requireNonNullElse(one, two));
-    assertSame(two, Objects.requireNonNullElse(null, two));
-
-    try {
-      throw new AssertionError(Objects.requireNonNullElse(null, null));
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testRequireNonNullElseGet() {
-    Object one = new Object();
-    Object two = new Object();
-
-    assertSame(one, Objects.requireNonNullElseGet(one, () -> two));
-    assertSame(two, Objects.requireNonNullElseGet(null, () -> two));
-
-    try {
-      throw new AssertionError(Objects.requireNonNullElseGet(null, null));
-    } catch (NullPointerException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.requireNonNullElseGet(null, () -> null));
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testCheckIndex() {
-    for (int i = 0; i < 10; i++) {
-      assertEquals(i, Objects.checkIndex(i, 10));
-    }
-
-    try {
-      throw new AssertionError(Objects.checkIndex(-1, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkIndex(10, 0));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkIndex(0, 0));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-  }
-
-  private static void testCheckFromToIndex() {
-    for (int i = 0; i <= 10; i++) {
-      for (int j = i; j <= 10; j++) {
-        assertEquals(i, Objects.checkFromToIndex(i, j, 10));
-      }
-    }
-    assertEquals(0, Objects.checkFromToIndex(0, 0, 0));
-
-    try {
-      throw new AssertionError(Objects.checkFromToIndex(4, 2, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromToIndex(-1, 5, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromToIndex(0, -1, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromToIndex(11, 11, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromToIndex(0, 1, 0));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromToIndex(1, 1, 0));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-  }
-
-  private static void testCheckFromIndexSize() {
-    for (int i = 0; i <= 10; i++) {
-      for (int j = 10 - i; j >= 0; j--) {
-        assertEquals(i, Objects.checkFromIndexSize(i, j, 10));
-      }
-    }
-    assertEquals(0, Objects.checkFromIndexSize(0, 0, 0));
-
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(8, 4, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(-1, 5, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(11, 0, 10));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(0, 1, 0));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(1, 1, 0));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-
-    // Check for cases where overflow might occur producing incorrect results.
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(Integer.MAX_VALUE, 1, Integer.MAX_VALUE));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-    try {
-      throw new AssertionError(Objects.checkFromIndexSize(0, 1, Integer.MIN_VALUE));
-    } catch (IndexOutOfBoundsException expected) {
-    }
-  }
-
-  private static void assertEquals(int expected, int actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-
-  private static void assertSame(Object expected, Object actual) {
-    if (expected != actual) {
-      throw new AssertionError(
-          "Expected <" + expected + "> to be same instance as <" + actual + '>');
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/ObjectsBackportJava9Test.java b/src/test/examplesJava9/backport/ObjectsBackportJava9Test.java
new file mode 100644
index 0000000..d41850e
--- /dev/null
+++ b/src/test/examplesJava9/backport/ObjectsBackportJava9Test.java
@@ -0,0 +1,211 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.desugar.backports.IgnoreInvokes;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.Objects;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class ObjectsBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimes()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public ObjectsBackportJava9Test(TestParameters parameters) {
+    super(parameters, Objects.class, ObjectsBackportJava9Main.class);
+    // Objects.checkFromIndexSize, Objects.checkFromToIndex, Objects.checkIndex,
+    // Objects.requireNonNullElse and Objects.requireNonNullElseGet added in API 30.
+    registerTarget(AndroidApiLevel.R, 28);
+    registerTarget(AndroidApiLevel.N, 0);
+    // Objects.requireNonNullElseGet is not desugared if Supplier is absent.
+    registerTarget(AndroidApiLevel.B, 4);
+  }
+
+  @Test
+  public void desugaringApiLevelR() throws Exception {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added chck and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
+      testForD8()
+          .setMinApi(AndroidApiLevel.R)
+          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
+          .addProgramClasses(ObjectsBackportJava9Main.class)
+          .setIncludeClassesChecksum(true)
+          .compile()
+          .run(parameters.getRuntime(), ObjectsBackportJava9Main.class)
+          .assertFailureWithErrorThatMatches(
+              CoreMatchers.containsString("java.lang.NoSuchMethodError"));
+    }
+  }
+
+  public static class ObjectsBackportJava9Main {
+    public static void main(String[] args) {
+      boolean isAndroid = "Dalvik".equals(System.getProperty("java.vm.name"));
+      String majorVersion = System.getProperty("java.vm.version").split("\\.", -1)[0];
+
+      testRequireNonNullElse();
+      if (!isAndroid || Integer.parseInt(majorVersion) >= 7) {
+        // TODO desugaring desugaredlibrary is blocked by
+        // https://issuetracker.google.com/issues/114481425
+        testRequireNonNullElseGet();
+      }
+      testCheckIndex();
+      testCheckFromToIndex();
+      testCheckFromIndexSize();
+    }
+
+    private static void testRequireNonNullElse() {
+      Object one = new Object();
+      Object two = new Object();
+
+      assertSame(one, Objects.requireNonNullElse(one, two));
+      assertSame(two, Objects.requireNonNullElse(null, two));
+
+      try {
+        throw new AssertionError(Objects.requireNonNullElse(null, null));
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testRequireNonNullElseGet() {
+      Object one = new Object();
+      Object two = new Object();
+
+      assertSame(one, Objects.requireNonNullElseGet(one, () -> two));
+      assertSame(two, Objects.requireNonNullElseGet(null, () -> two));
+
+      try {
+        throw new AssertionError(Objects.requireNonNullElseGet(null, null));
+      } catch (NullPointerException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.requireNonNullElseGet(null, () -> null));
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testCheckIndex() {
+      for (int i = 0; i < 10; i++) {
+        assertEquals(i, Objects.checkIndex(i, 10));
+      }
+
+      try {
+        throw new AssertionError(Objects.checkIndex(-1, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkIndex(10, 0));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkIndex(0, 0));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+    }
+
+    private static void testCheckFromToIndex() {
+      for (int i = 0; i <= 10; i++) {
+        for (int j = i; j <= 10; j++) {
+          assertEquals(i, Objects.checkFromToIndex(i, j, 10));
+        }
+      }
+      assertEquals(0, Objects.checkFromToIndex(0, 0, 0));
+
+      try {
+        throw new AssertionError(Objects.checkFromToIndex(4, 2, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromToIndex(-1, 5, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromToIndex(0, -1, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromToIndex(11, 11, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromToIndex(0, 1, 0));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromToIndex(1, 1, 0));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+    }
+
+    private static void testCheckFromIndexSize() {
+      for (int i = 0; i <= 10; i++) {
+        for (int j = 10 - i; j >= 0; j--) {
+          assertEquals(i, Objects.checkFromIndexSize(i, j, 10));
+        }
+      }
+      assertEquals(0, Objects.checkFromIndexSize(0, 0, 0));
+
+      try {
+        throw new AssertionError(Objects.checkFromIndexSize(8, 4, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromIndexSize(-1, 5, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromIndexSize(11, 0, 10));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromIndexSize(0, 1, 0));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromIndexSize(1, 1, 0));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+
+      // Check for cases where overflow might occur producing incorrect results.
+      try {
+        throw new AssertionError(
+            Objects.checkFromIndexSize(Integer.MAX_VALUE, 1, Integer.MAX_VALUE));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+      try {
+        throw new AssertionError(Objects.checkFromIndexSize(0, 1, Integer.MIN_VALUE));
+      } catch (IndexOutOfBoundsException expected) {
+      }
+    }
+
+    private static void assertEquals(int expected, int actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+
+    private static void assertSame(Object expected, Object actual) {
+      if (expected != actual) {
+        throw new AssertionError(
+            "Expected <" + expected + "> to be same instance as <" + actual + '>');
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/OptionalBackportJava9Main.java b/src/test/examplesJava9/backport/OptionalBackportJava9Main.java
deleted file mode 100644
index c25226f..0000000
--- a/src/test/examplesJava9/backport/OptionalBackportJava9Main.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.Optional;
-
-public final class OptionalBackportJava9Main {
-
-  public static void main(String[] args) {
-    testOr();
-    testOrNull();
-    testIfPresentOrElse();
-    testStream();
-  }
-
-  private static void testOr() {
-    Optional<String> value = Optional.of("value");
-    Optional<String> defaultValue = Optional.of("default");
-    Optional<String> emptyValue = Optional.empty();
-    Optional<String> result;
-
-    result = value.or(() -> defaultValue);
-    assertTrue(value == result);
-    result = emptyValue.or(() -> defaultValue);
-    assertTrue(result == defaultValue);
-  }
-
-  private static void testOrNull() {
-    Optional<String> value = Optional.of("value");
-    Optional<String> emptyValue = Optional.empty();
-
-    try {
-      value.or(null);
-      fail();
-    } catch (NullPointerException e) {
-    }
-
-    try {
-      emptyValue.or(null);
-      fail();
-    } catch (NullPointerException e) {
-    }
-
-    try {
-      value.or(() -> null);
-    } catch (NullPointerException e) {
-      fail();
-    }
-
-    try {
-      emptyValue.or(() -> null);
-      fail();
-    } catch (NullPointerException e) {
-    }
-  }
-
-  private static void testIfPresentOrElse() {
-    Optional<String> value = Optional.of("value");
-    Optional<String> emptyValue = Optional.empty();
-    value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
-    emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
-  }
-
-  private static void testStream() {
-    Optional<String> value = Optional.of("value");
-    Optional<String> emptyValue = Optional.empty();
-    assertTrue(value.stream().count() == 1);
-    assertTrue(emptyValue.stream().count() == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-
-  private static void fail() {
-    throw new AssertionError("Failure.");
-  }
-}
diff --git a/src/test/examplesJava9/backport/OptionalBackportJava9Test.java b/src/test/examplesJava9/backport/OptionalBackportJava9Test.java
new file mode 100644
index 0000000..3ecc125
--- /dev/null
+++ b/src/test/examplesJava9/backport/OptionalBackportJava9Test.java
@@ -0,0 +1,116 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.Optional;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class OptionalBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalBackportJava9Test(TestParameters parameters) {
+    super(parameters, Optional.class, OptionalBackportJava9Main.class);
+    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
+    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 10);
+  }
+
+  public static class OptionalBackportJava9Main {
+
+    public static void main(String[] args) {
+      testOr();
+      testOrNull();
+      testIfPresentOrElse();
+      testStream();
+    }
+
+    private static void testOr() {
+      Optional<String> value = Optional.of("value");
+      Optional<String> defaultValue = Optional.of("default");
+      Optional<String> emptyValue = Optional.empty();
+      Optional<String> result;
+
+      result = value.or(() -> defaultValue);
+      assertTrue(value == result);
+      result = emptyValue.or(() -> defaultValue);
+      assertTrue(result == defaultValue);
+    }
+
+    private static void testOrNull() {
+      Optional<String> value = Optional.of("value");
+      Optional<String> emptyValue = Optional.empty();
+
+      try {
+        value.or(null);
+        fail();
+      } catch (NullPointerException e) {
+      }
+
+      try {
+        emptyValue.or(null);
+        fail();
+      } catch (NullPointerException e) {
+      }
+
+      try {
+        value.or(() -> null);
+      } catch (NullPointerException e) {
+        fail();
+      }
+
+      try {
+        emptyValue.or(() -> null);
+        fail();
+      } catch (NullPointerException e) {
+      }
+    }
+
+    private static void testIfPresentOrElse() {
+      Optional<String> value = Optional.of("value");
+      Optional<String> emptyValue = Optional.empty();
+      value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
+      emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
+    }
+
+    private static void testStream() {
+      Optional<String> value = Optional.of("value");
+      Optional<String> emptyValue = Optional.empty();
+      assertTrue(value.stream().count() == 1);
+      assertTrue(emptyValue.stream().count() == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+
+    private static void fail() {
+      throw new AssertionError("Failure.");
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/OptionalDoubleBackportJava9Main.java b/src/test/examplesJava9/backport/OptionalDoubleBackportJava9Main.java
deleted file mode 100644
index 9b08718..0000000
--- a/src/test/examplesJava9/backport/OptionalDoubleBackportJava9Main.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.OptionalDouble;
-
-public final class OptionalDoubleBackportJava9Main {
-
-  public static void main(String[] args) {
-    testIfPresentOrElseDouble();
-    testStreamDouble();
-  }
-
-  private static void testIfPresentOrElseDouble() {
-    OptionalDouble value = OptionalDouble.of(1.0d);
-    OptionalDouble emptyValue = OptionalDouble.empty();
-    value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
-    emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
-  }
-
-  private static void testStreamDouble() {
-    OptionalDouble value = OptionalDouble.of(2d);
-    OptionalDouble emptyValue = OptionalDouble.empty();
-    assertTrue(value.stream().count() == 1);
-    assertTrue(emptyValue.stream().count() == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/OptionalDoubleBackportJava9Test.java b/src/test/examplesJava9/backport/OptionalDoubleBackportJava9Test.java
new file mode 100644
index 0000000..28ea1e2
--- /dev/null
+++ b/src/test/examplesJava9/backport/OptionalDoubleBackportJava9Test.java
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.OptionalDouble;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class OptionalDoubleBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalDoubleBackportJava9Test(TestParameters parameters) {
+    super(parameters, OptionalDouble.class, OptionalDoubleBackportJava9Main.class);
+    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
+    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 4);
+  }
+
+  public static class OptionalDoubleBackportJava9Main {
+
+    public static void main(String[] args) {
+      testIfPresentOrElseDouble();
+      testStreamDouble();
+    }
+
+    private static void testIfPresentOrElseDouble() {
+      OptionalDouble value = OptionalDouble.of(1.0d);
+      OptionalDouble emptyValue = OptionalDouble.empty();
+      value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
+      emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
+    }
+
+    private static void testStreamDouble() {
+      OptionalDouble value = OptionalDouble.of(2d);
+      OptionalDouble emptyValue = OptionalDouble.empty();
+      assertTrue(value.stream().count() == 1);
+      assertTrue(emptyValue.stream().count() == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/OptionalIntBackportJava9Main.java b/src/test/examplesJava9/backport/OptionalIntBackportJava9Main.java
deleted file mode 100644
index fedc472..0000000
--- a/src/test/examplesJava9/backport/OptionalIntBackportJava9Main.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.OptionalInt;
-
-public final class OptionalIntBackportJava9Main {
-
-  public static void main(String[] args) {
-    testIfPresentOrElseInt();
-    testStreamInt();
-  }
-
-  private static void testIfPresentOrElseInt() {
-    OptionalInt value = OptionalInt.of(1);
-    OptionalInt emptyValue = OptionalInt.empty();
-    value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
-    emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
-  }
-
-  private static void testStreamInt() {
-    OptionalInt value = OptionalInt.of(2);
-    OptionalInt emptyValue = OptionalInt.empty();
-    assertTrue(value.stream().count() == 1);
-    assertTrue(emptyValue.stream().count() == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/OptionalIntBackportJava9Test.java b/src/test/examplesJava9/backport/OptionalIntBackportJava9Test.java
new file mode 100644
index 0000000..d0a625d
--- /dev/null
+++ b/src/test/examplesJava9/backport/OptionalIntBackportJava9Test.java
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.OptionalInt;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class OptionalIntBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalIntBackportJava9Test(TestParameters parameters) {
+    super(parameters, OptionalInt.class, OptionalIntBackportJava9Main.class);
+    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
+    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 4);
+  }
+
+  public static class OptionalIntBackportJava9Main {
+
+    public static void main(String[] args) {
+      testIfPresentOrElseInt();
+      testStreamInt();
+    }
+
+    private static void testIfPresentOrElseInt() {
+      OptionalInt value = OptionalInt.of(1);
+      OptionalInt emptyValue = OptionalInt.empty();
+      value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
+      emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
+    }
+
+    private static void testStreamInt() {
+      OptionalInt value = OptionalInt.of(2);
+      OptionalInt emptyValue = OptionalInt.empty();
+      assertTrue(value.stream().count() == 1);
+      assertTrue(emptyValue.stream().count() == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/OptionalLongBackportJava9Main.java b/src/test/examplesJava9/backport/OptionalLongBackportJava9Main.java
deleted file mode 100644
index 07438e1..0000000
--- a/src/test/examplesJava9/backport/OptionalLongBackportJava9Main.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.OptionalLong;
-
-public final class OptionalLongBackportJava9Main {
-
-  public static void main(String[] args) {
-    testIfPresentOrElseLong();
-    testStreamLong();
-  }
-
-  private static void testIfPresentOrElseLong() {
-    OptionalLong value = OptionalLong.of(1L);
-    OptionalLong emptyValue = OptionalLong.empty();
-    value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
-    emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
-  }
-
-  private static void testStreamLong() {
-    OptionalLong value = OptionalLong.of(2L);
-    OptionalLong emptyValue = OptionalLong.empty();
-    assertTrue(value.stream().count() == 1);
-    assertTrue(emptyValue.stream().count() == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/OptionalLongBackportJava9Test.java b/src/test/examplesJava9/backport/OptionalLongBackportJava9Test.java
new file mode 100644
index 0000000..019a0f2
--- /dev/null
+++ b/src/test/examplesJava9/backport/OptionalLongBackportJava9Test.java
@@ -0,0 +1,71 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.OptionalLong;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class OptionalLongBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalLongBackportJava9Test(TestParameters parameters) {
+    super(parameters, OptionalLong.class, OptionalLongBackportJava9Main.class);
+    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
+    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("getAsLong");
+    ignoreInvokes("isPresent");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 4);
+  }
+
+  public static class OptionalLongBackportJava9Main {
+
+    public static void main(String[] args) {
+      testIfPresentOrElseLong();
+      testStreamLong();
+    }
+
+    private static void testIfPresentOrElseLong() {
+      OptionalLong value = OptionalLong.of(1L);
+      OptionalLong emptyValue = OptionalLong.empty();
+      value.ifPresentOrElse(val -> {}, () -> assertTrue(false));
+      emptyValue.ifPresentOrElse(val -> assertTrue(false), () -> {});
+    }
+
+    private static void testStreamLong() {
+      OptionalLong value = OptionalLong.of(2L);
+      OptionalLong emptyValue = OptionalLong.empty();
+      assertTrue(value.stream().count() == 1);
+      assertTrue(emptyValue.stream().count() == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/SetBackportJava9Main.java b/src/test/examplesJava9/backport/SetBackportJava9Main.java
deleted file mode 100644
index d824bd0..0000000
--- a/src/test/examplesJava9/backport/SetBackportJava9Main.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.Set;
-
-public class SetBackportJava9Main {
-
-  public static void main(String[] args) {
-    testOf0();
-    testOf1();
-    testOf2();
-    testOf10();
-    testOfVarargs();
-  }
-
-  private static void testOf0() {
-    Set<Object> ofObject = Set.of();
-    assertEquals(0, ofObject.size());
-    assertFalse(ofObject.contains(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Set<Integer> ofInteger = Set.of();
-    assertEquals(0, ofInteger.size());
-    assertFalse(ofInteger.contains(0));
-  }
-
-  private static void testOf1() {
-    Object anObject = new Object();
-    Set<Object> ofObject = Set.of(anObject);
-    assertEquals(1, ofObject.size());
-    assertTrue(ofObject.contains(anObject));
-    assertFalse(ofObject.contains(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Set<Integer> ofInteger = Set.of(1);
-    assertEquals(1, ofInteger.size());
-    assertTrue(ofInteger.contains(1));
-    assertFalse(ofInteger.contains(2));
-
-    try {
-      Set.of((Object) null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  private static void testOf2() {
-    Object anObject0 = new Object();
-    Object anObject1 = new Object();
-    Set<Object> ofObject = Set.of(anObject0, anObject1);
-    assertEquals(2, ofObject.size());
-    assertTrue(ofObject.contains(anObject0));
-    assertTrue(ofObject.contains(anObject1));
-    assertFalse(ofObject.contains(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Set<Integer> ofInteger = Set.of(1, 2);
-    assertEquals(2, ofInteger.size());
-    assertTrue(ofInteger.contains(1));
-    assertTrue(ofInteger.contains(2));
-    assertFalse(ofInteger.contains(3));
-
-    Set<Object> ofMixed = Set.of(anObject0, 1);
-    assertEquals(2, ofMixed.size());
-    assertTrue(ofMixed.contains(anObject0));
-    assertTrue(ofMixed.contains(1));
-    assertFalse(ofMixed.contains(2));
-    assertFalse(ofMixed.contains(anObject1));
-    assertMutationNotAllowed(ofMixed);
-
-    try {
-      Set.of(1, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Set.of(1, 1);
-      throw new AssertionError();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("duplicate element: 1", expected.getMessage());
-    }
-  }
-
-  private static void testOf10() {
-    Object anObject0 = new Object();
-    Object anObject6 = new Object();
-    Object anObject9 = new Object();
-    Set<Object> ofObject =
-        Set.of(anObject0, new Object(), new Object(), new Object(), new Object(), new Object(),
-            anObject6, new Object(), new Object(), anObject9);
-    assertEquals(10, ofObject.size());
-    assertTrue(ofObject.contains(anObject0));
-    assertTrue(ofObject.contains(anObject6));
-    assertTrue(ofObject.contains(anObject9));
-    assertFalse(ofObject.contains(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Set<Integer> ofInteger = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
-    assertEquals(10, ofInteger.size());
-    assertTrue(ofInteger.contains(0));
-    assertTrue(ofInteger.contains(6));
-    assertTrue(ofInteger.contains(9));
-    assertFalse(ofInteger.contains(10));
-
-    Set<Object> ofMixed = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, anObject9);
-    assertEquals(10, ofMixed.size());
-    assertTrue(ofMixed.contains(0));
-    assertTrue(ofMixed.contains(6));
-    assertTrue(ofMixed.contains(anObject9));
-    assertFalse(ofMixed.contains(anObject0));
-    assertMutationNotAllowed(ofMixed);
-
-    try {
-      Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 0);
-      throw new AssertionError();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("duplicate element: 0", expected.getMessage());
-    }
-  }
-
-  private static void testOfVarargs() {
-    Object anObject0 = new Object();
-    Object anObject6 = new Object();
-    Object anObject10 = new Object();
-    Set<Object> ofObject =
-        Set.of(anObject0, new Object(), new Object(), new Object(), new Object(), new Object(),
-            anObject6, new Object(), new Object(), new Object(), anObject10);
-    assertEquals(11, ofObject.size());
-    assertTrue(ofObject.contains(anObject0));
-    assertTrue(ofObject.contains(anObject6));
-    assertTrue(ofObject.contains(anObject10));
-    assertFalse(ofObject.contains(new Object()));
-    assertMutationNotAllowed(ofObject);
-
-    Set<Integer> ofInteger = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
-    assertEquals(11, ofInteger.size());
-    assertTrue(ofInteger.contains(0));
-    assertTrue(ofInteger.contains(6));
-    assertTrue(ofInteger.contains(10));
-    assertFalse(ofInteger.contains(11));
-
-    Set<Object> ofMixed = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, anObject10);
-    assertEquals(11, ofMixed.size());
-    assertTrue(ofMixed.contains(0));
-    assertTrue(ofMixed.contains(6));
-    assertTrue(ofMixed.contains(anObject10));
-    assertFalse(ofMixed.contains(10));
-    assertFalse(ofMixed.contains(anObject0));
-    assertMutationNotAllowed(ofMixed);
-
-    // Ensure the supplied mutable array is not used directly since it is mutable.
-    Object[] mutableArray = { anObject0 };
-    Set<Object> ofMutableArray = Set.of(mutableArray);
-    mutableArray[0] = anObject10;
-    assertTrue(ofMutableArray.contains(anObject0));
-    assertFalse(ofMutableArray.contains(anObject10));
-
-    try {
-      Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-
-    try {
-      Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
-      throw new AssertionError();
-    } catch (IllegalArgumentException expected) {
-      assertEquals("duplicate element: 0", expected.getMessage());
-    }
-  }
-
-  private static void assertMutationNotAllowed(Set<Object> ofObject) {
-    try {
-      ofObject.add(new Object());
-      throw new AssertionError();
-    } catch (UnsupportedOperationException expected) {
-    }
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-
-  private static void assertFalse(boolean value) {
-    if (value) {
-      throw new AssertionError("Expected <false> but was <true>");
-    }
-  }
-
-  private static void assertEquals(Object expected, Object actual) {
-    if (expected != actual && !expected.equals(actual)) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/SetBackportJava9Test.java b/src/test/examplesJava9/backport/SetBackportJava9Test.java
new file mode 100644
index 0000000..9682a77
--- /dev/null
+++ b/src/test/examplesJava9/backport/SetBackportJava9Test.java
@@ -0,0 +1,280 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.desugar.backports.IgnoreInvokes;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.Set;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class SetBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public SetBackportJava9Test(TestParameters parameters) {
+    super(parameters, Set.class, SetBackportJava9Main.class);
+    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
+    // an actual API level, migrate these tests to SetBackportTest.
+
+    // Available since API 1 and used to test created sets.
+    ignoreInvokes("add");
+    ignoreInvokes("contains");
+    ignoreInvokes("size");
+
+    // Set.of added in API 30.
+    registerTarget(AndroidApiLevel.R, 21);
+  }
+
+  @Test
+  public void desugaringApiLevelR() throws Exception {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added check and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
+      testForD8()
+          .setMinApi(AndroidApiLevel.R)
+          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
+          .addProgramClasses(SetBackportJava9Main.class)
+          .setIncludeClassesChecksum(true)
+          .compile()
+          .run(parameters.getRuntime(), SetBackportJava9Main.class)
+          .assertFailureWithErrorThatMatches(
+              CoreMatchers.containsString("java.lang.NoSuchMethodError"));
+    }
+  }
+
+  public static class SetBackportJava9Main {
+
+    public static void main(String[] args) {
+      testOf0();
+      testOf1();
+      testOf2();
+      testOf10();
+      testOfVarargs();
+    }
+
+    private static void testOf0() {
+      Set<Object> ofObject = Set.of();
+      assertEquals(0, ofObject.size());
+      assertFalse(ofObject.contains(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Set<Integer> ofInteger = Set.of();
+      assertEquals(0, ofInteger.size());
+      assertFalse(ofInteger.contains(0));
+    }
+
+    private static void testOf1() {
+      Object anObject = new Object();
+      Set<Object> ofObject = Set.of(anObject);
+      assertEquals(1, ofObject.size());
+      assertTrue(ofObject.contains(anObject));
+      assertFalse(ofObject.contains(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Set<Integer> ofInteger = Set.of(1);
+      assertEquals(1, ofInteger.size());
+      assertTrue(ofInteger.contains(1));
+      assertFalse(ofInteger.contains(2));
+
+      try {
+        Set.of((Object) null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    private static void testOf2() {
+      Object anObject0 = new Object();
+      Object anObject1 = new Object();
+      Set<Object> ofObject = Set.of(anObject0, anObject1);
+      assertEquals(2, ofObject.size());
+      assertTrue(ofObject.contains(anObject0));
+      assertTrue(ofObject.contains(anObject1));
+      assertFalse(ofObject.contains(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Set<Integer> ofInteger = Set.of(1, 2);
+      assertEquals(2, ofInteger.size());
+      assertTrue(ofInteger.contains(1));
+      assertTrue(ofInteger.contains(2));
+      assertFalse(ofInteger.contains(3));
+
+      Set<Object> ofMixed = Set.of(anObject0, 1);
+      assertEquals(2, ofMixed.size());
+      assertTrue(ofMixed.contains(anObject0));
+      assertTrue(ofMixed.contains(1));
+      assertFalse(ofMixed.contains(2));
+      assertFalse(ofMixed.contains(anObject1));
+      assertMutationNotAllowed(ofMixed);
+
+      try {
+        Set.of(1, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+
+      try {
+        Set.of(1, 1);
+        throw new AssertionError();
+      } catch (IllegalArgumentException expected) {
+        assertEquals("duplicate element: 1", expected.getMessage());
+      }
+    }
+
+    private static void testOf10() {
+      Object anObject0 = new Object();
+      Object anObject6 = new Object();
+      Object anObject9 = new Object();
+      Set<Object> ofObject =
+          Set.of(
+              anObject0,
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              anObject6,
+              new Object(),
+              new Object(),
+              anObject9);
+      assertEquals(10, ofObject.size());
+      assertTrue(ofObject.contains(anObject0));
+      assertTrue(ofObject.contains(anObject6));
+      assertTrue(ofObject.contains(anObject9));
+      assertFalse(ofObject.contains(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Set<Integer> ofInteger = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+      assertEquals(10, ofInteger.size());
+      assertTrue(ofInteger.contains(0));
+      assertTrue(ofInteger.contains(6));
+      assertTrue(ofInteger.contains(9));
+      assertFalse(ofInteger.contains(10));
+
+      Set<Object> ofMixed = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, anObject9);
+      assertEquals(10, ofMixed.size());
+      assertTrue(ofMixed.contains(0));
+      assertTrue(ofMixed.contains(6));
+      assertTrue(ofMixed.contains(anObject9));
+      assertFalse(ofMixed.contains(anObject0));
+      assertMutationNotAllowed(ofMixed);
+
+      try {
+        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+
+      try {
+        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 0);
+        throw new AssertionError();
+      } catch (IllegalArgumentException expected) {
+        assertEquals("duplicate element: 0", expected.getMessage());
+      }
+    }
+
+    private static void testOfVarargs() {
+      Object anObject0 = new Object();
+      Object anObject6 = new Object();
+      Object anObject10 = new Object();
+      Set<Object> ofObject =
+          Set.of(
+              anObject0,
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              new Object(),
+              anObject6,
+              new Object(),
+              new Object(),
+              new Object(),
+              anObject10);
+      assertEquals(11, ofObject.size());
+      assertTrue(ofObject.contains(anObject0));
+      assertTrue(ofObject.contains(anObject6));
+      assertTrue(ofObject.contains(anObject10));
+      assertFalse(ofObject.contains(new Object()));
+      assertMutationNotAllowed(ofObject);
+
+      Set<Integer> ofInteger = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+      assertEquals(11, ofInteger.size());
+      assertTrue(ofInteger.contains(0));
+      assertTrue(ofInteger.contains(6));
+      assertTrue(ofInteger.contains(10));
+      assertFalse(ofInteger.contains(11));
+
+      Set<Object> ofMixed = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, anObject10);
+      assertEquals(11, ofMixed.size());
+      assertTrue(ofMixed.contains(0));
+      assertTrue(ofMixed.contains(6));
+      assertTrue(ofMixed.contains(anObject10));
+      assertFalse(ofMixed.contains(10));
+      assertFalse(ofMixed.contains(anObject0));
+      assertMutationNotAllowed(ofMixed);
+
+      // Ensure the supplied mutable array is not used directly since it is mutable.
+      Object[] mutableArray = {anObject0};
+      Set<Object> ofMutableArray = Set.of(mutableArray);
+      mutableArray[0] = anObject10;
+      assertTrue(ofMutableArray.contains(anObject0));
+      assertFalse(ofMutableArray.contains(anObject10));
+
+      try {
+        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+
+      try {
+        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
+        throw new AssertionError();
+      } catch (IllegalArgumentException expected) {
+        assertEquals("duplicate element: 0", expected.getMessage());
+      }
+    }
+
+    private static void assertMutationNotAllowed(Set<Object> ofObject) {
+      try {
+        ofObject.add(new Object());
+        throw new AssertionError();
+      } catch (UnsupportedOperationException expected) {
+      }
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+
+    private static void assertFalse(boolean value) {
+      if (value) {
+        throw new AssertionError("Expected <false> but was <true>");
+      }
+    }
+
+    private static void assertEquals(Object expected, Object actual) {
+      if (expected != actual && !expected.equals(actual)) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/ShortBackportJava9Main.java b/src/test/examplesJava9/backport/ShortBackportJava9Main.java
deleted file mode 100644
index 63764dd..0000000
--- a/src/test/examplesJava9/backport/ShortBackportJava9Main.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package backport;
-
-public final class ShortBackportJava9Main {
-  private static final byte MIN_UNSIGNED_VALUE = (short) 0;
-  private static final byte MAX_UNSIGNED_VALUE = (short) -1;
-
-  public static void main(String[] args) {
-    testCompareUnsigned();
-  }
-
-  private static void testCompareUnsigned() {
-    assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) == 0);
-    assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, Short.MAX_VALUE) < 0);
-    assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, Short.MIN_VALUE) < 0);
-    assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) < 0);
-
-    assertTrue(Short.compareUnsigned(Short.MAX_VALUE, MIN_UNSIGNED_VALUE) > 0);
-    assertTrue(Short.compareUnsigned(Short.MAX_VALUE, Short.MAX_VALUE) == 0);
-    assertTrue(Short.compareUnsigned(Short.MAX_VALUE, Short.MIN_VALUE) < 0);
-    assertTrue(Short.compareUnsigned(Short.MAX_VALUE, MAX_UNSIGNED_VALUE) < 0);
-
-    assertTrue(Short.compareUnsigned(Short.MIN_VALUE, MIN_UNSIGNED_VALUE) > 0);
-    assertTrue(Short.compareUnsigned(Short.MIN_VALUE, Short.MAX_VALUE) > 0);
-    assertTrue(Short.compareUnsigned(Short.MIN_VALUE, Short.MIN_VALUE) == 0);
-    assertTrue(Short.compareUnsigned(Short.MIN_VALUE, MAX_UNSIGNED_VALUE) < 0);
-
-    assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) > 0);
-    assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, Short.MAX_VALUE) > 0);
-    assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, Short.MIN_VALUE) > 0);
-    assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/ShortBackportJava9Test.java b/src/test/examplesJava9/backport/ShortBackportJava9Test.java
new file mode 100644
index 0000000..43ccb9f
--- /dev/null
+++ b/src/test/examplesJava9/backport/ShortBackportJava9Test.java
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class ShortBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public ShortBackportJava9Test(TestParameters parameters) {
+    super(parameters, Short.class, ShortBackportJava9Main.class);
+
+    // Short.compareUnsigned added in API 31.
+    registerTarget(AndroidApiLevel.S, 16);
+  }
+
+  public static class ShortBackportJava9Main {
+    private static final byte MIN_UNSIGNED_VALUE = (short) 0;
+    private static final byte MAX_UNSIGNED_VALUE = (short) -1;
+
+    public static void main(String[] args) {
+      testCompareUnsigned();
+    }
+
+    private static void testCompareUnsigned() {
+      assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) == 0);
+      assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, Short.MAX_VALUE) < 0);
+      assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, Short.MIN_VALUE) < 0);
+      assertTrue(Short.compareUnsigned(MIN_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) < 0);
+
+      assertTrue(Short.compareUnsigned(Short.MAX_VALUE, MIN_UNSIGNED_VALUE) > 0);
+      assertTrue(Short.compareUnsigned(Short.MAX_VALUE, Short.MAX_VALUE) == 0);
+      assertTrue(Short.compareUnsigned(Short.MAX_VALUE, Short.MIN_VALUE) < 0);
+      assertTrue(Short.compareUnsigned(Short.MAX_VALUE, MAX_UNSIGNED_VALUE) < 0);
+
+      assertTrue(Short.compareUnsigned(Short.MIN_VALUE, MIN_UNSIGNED_VALUE) > 0);
+      assertTrue(Short.compareUnsigned(Short.MIN_VALUE, Short.MAX_VALUE) > 0);
+      assertTrue(Short.compareUnsigned(Short.MIN_VALUE, Short.MIN_VALUE) == 0);
+      assertTrue(Short.compareUnsigned(Short.MIN_VALUE, MAX_UNSIGNED_VALUE) < 0);
+
+      assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, MIN_UNSIGNED_VALUE) > 0);
+      assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, Short.MAX_VALUE) > 0);
+      assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, Short.MIN_VALUE) > 0);
+      assertTrue(Short.compareUnsigned(MAX_UNSIGNED_VALUE, MAX_UNSIGNED_VALUE) == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+  }
+}
diff --git a/src/test/examplesJava9/backport/StreamBackportJava9Main.java b/src/test/examplesJava9/backport/StreamBackportJava9Main.java
deleted file mode 100644
index b8c8f28..0000000
--- a/src/test/examplesJava9/backport/StreamBackportJava9Main.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.util.stream.Stream;
-
-public final class StreamBackportJava9Main {
-
-  public static void main(String[] args) {
-    testOfNullable();
-  }
-
-  public static void testOfNullable() {
-    Object guineaPig = new Object();
-    Stream<Object> streamNonEmpty = Stream.ofNullable(guineaPig);
-    assertTrue(streamNonEmpty.count() == 1);
-    Stream<Object> streamEmpty = Stream.ofNullable(null);
-    assertTrue(streamEmpty.count() == 0);
-  }
-
-  private static void assertTrue(boolean value) {
-    if (!value) {
-      throw new AssertionError("Expected <true> but was <false>");
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/StreamBackportJava9Test.java b/src/test/examplesJava9/backport/StreamBackportJava9Test.java
similarity index 63%
rename from src/test/java/com/android/tools/r8/desugar/backports/StreamBackportJava9Test.java
rename to src/test/examplesJava9/backport/StreamBackportJava9Test.java
index 2416783..c6a7a75 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/StreamBackportJava9Test.java
+++ b/src/test/examplesJava9/backport/StreamBackportJava9Test.java
@@ -2,17 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-package com.android.tools.r8.desugar.backports;
+package backport;
 
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
+import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
 import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.stream.Stream;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -22,7 +19,7 @@
 public final class StreamBackportJava9Test extends AbstractBackportTest {
   @Parameters(name = "{0}")
   public static Iterable<?> data() {
-    return getTestParameters()
+    return TestBase.getTestParameters()
         .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
         .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
         .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
@@ -30,11 +27,8 @@
         .build();
   }
 
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
   public StreamBackportJava9Test(TestParameters parameters) {
-    super(parameters, Stream.class, TEST_JAR, "backport.StreamBackportJava9Main");
+    super(parameters, Stream.class, StreamBackportJava9Main.class);
     // Note: The methods in this test exist from Android U. However, they are only available from
     // Java 9. When tests build with Java 9 migrate to StreamBackportTest and add insert
     // StreamBackportJava9Main as an inner class here.
@@ -46,4 +40,25 @@
 
     registerTarget(AndroidApiLevel.U, 2);
   }
+
+  public static class StreamBackportJava9Main {
+
+    public static void main(String[] args) {
+      testOfNullable();
+    }
+
+    public static void testOfNullable() {
+      Object guineaPig = new Object();
+      Stream<Object> streamNonEmpty = Stream.ofNullable(guineaPig);
+      assertTrue(streamNonEmpty.count() == 1);
+      Stream<Object> streamEmpty = Stream.ofNullable(null);
+      assertTrue(streamEmpty.count() == 0);
+    }
+
+    private static void assertTrue(boolean value) {
+      if (!value) {
+        throw new AssertionError("Expected <true> but was <false>");
+      }
+    }
+  }
 }
diff --git a/src/test/examplesJava9/backport/StrictMathBackportJava9Main.java b/src/test/examplesJava9/backport/StrictMathBackportJava9Main.java
deleted file mode 100644
index e9c33ca..0000000
--- a/src/test/examplesJava9/backport/StrictMathBackportJava9Main.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package backport;
-
-import java.math.BigInteger;
-
-public class StrictMathBackportJava9Main {
-
-  public static void main(String[] args) {
-    testMultiplyExactLongInt();
-    testMultiplyFull();
-    testFloorDivLongInt();
-    testFloorModLongInt();
-  }
-
-  public static void testMultiplyExactLongInt() {
-    assertEquals(8L, StrictMath.multiplyExact(2L, 4));
-    assertEquals(Long.MAX_VALUE, StrictMath.multiplyExact(Long.MAX_VALUE, 1));
-    assertEquals(Long.MIN_VALUE, StrictMath.multiplyExact(Long.MIN_VALUE / 2L, 2));
-    try {
-      throw new AssertionError(StrictMath.multiplyExact(Long.MAX_VALUE, 2));
-    } catch (ArithmeticException expected) {
-    }
-    try {
-      throw new AssertionError(StrictMath.multiplyExact(Long.MIN_VALUE, 2));
-    } catch (ArithmeticException expected) {
-    }
-  }
-
-  public static void testMultiplyFull() {
-    assertEquals(8L, StrictMath.multiplyFull(2, 4));
-    assertEquals(4611686014132420609L,
-        StrictMath.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE));
-    assertEquals(-4611686016279904256L,
-        StrictMath.multiplyFull(Integer.MAX_VALUE, Integer.MIN_VALUE));
-    assertEquals(4611686018427387904L,
-        StrictMath.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE));
-  }
-
-  public static void testMultiplyHigh() {
-    long[] interestingValues = {
-        Long.MIN_VALUE, Long.MAX_VALUE,
-        Integer.MIN_VALUE, Integer.MAX_VALUE,
-        Short.MIN_VALUE, Short.MAX_VALUE,
-        Byte.MIN_VALUE, Byte.MAX_VALUE,
-        0L,
-        -1L, 1L,
-        -42L, 42L
-    };
-    for (long x : interestingValues) {
-      for (long y : interestingValues) {
-        long expected = BigInteger.valueOf(x)
-            .multiply(BigInteger.valueOf(y))
-            .shiftRight(64)
-            .longValue();
-        assertEquals(expected, StrictMath.multiplyHigh(x, y));
-      }
-    }
-  }
-
-  public static void testFloorDivLongInt() {
-    assertEquals(1L, StrictMath.floorDiv(4L, 4));
-    assertEquals(1L, StrictMath.floorDiv(-4L, -4));
-    assertEquals(-1L, StrictMath.floorDiv(-4L, 4));
-    assertEquals(-1L, StrictMath.floorDiv(4L, -4));
-
-    assertEquals(1L, StrictMath.floorDiv(4L, 3));
-    assertEquals(1L, StrictMath.floorDiv(-4L, -3));
-    assertEquals(-2L, StrictMath.floorDiv(-4L, 3));
-    assertEquals(-2L, StrictMath.floorDiv(4L, -3));
-
-    // Spec edge case: result is actually MAX_VALUE+1 which becomes MIN_VALUE.
-    assertEquals(Long.MIN_VALUE, StrictMath.floorDiv(Long.MIN_VALUE, -1));
-  }
-
-  public static void testFloorModLongInt() {
-    assertEquals(0, StrictMath.floorMod(4L, 4));
-    assertEquals(0, StrictMath.floorMod(-4L, -4));
-    assertEquals(0, StrictMath.floorMod(-4L, 4));
-    assertEquals(0, StrictMath.floorMod(4L, -4));
-
-    assertEquals(1, StrictMath.floorMod(4L, 3));
-    assertEquals(-1, StrictMath.floorMod(-4L, -3));
-    assertEquals(2, StrictMath.floorMod(-4L, 3));
-    assertEquals(-2, StrictMath.floorMod(4L, -3));
-  }
-
-  private static void assertEquals(int expected, int actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-
-  private static void assertEquals(long expected, long actual) {
-    if (expected != actual) {
-      throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
-    }
-  }
-}
diff --git a/src/test/examplesJava9/backport/StrictMathBackportJava9Test.java b/src/test/examplesJava9/backport/StrictMathBackportJava9Test.java
new file mode 100644
index 0000000..b71e4ac
--- /dev/null
+++ b/src/test/examplesJava9/backport/StrictMathBackportJava9Test.java
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package backport;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import java.math.BigInteger;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class StrictMathBackportJava9Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return TestBase.getTestParameters()
+        .withDexRuntimes()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public StrictMathBackportJava9Test(TestParameters parameters) {
+    super(parameters, Math.class, StrictMathBackportJava9Main.class);
+    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
+    // an actual API level, migrate these tests to StrictMathBackportTest.
+  }
+
+  public static class StrictMathBackportJava9Main {
+
+    public static void main(String[] args) {
+      testMultiplyExactLongInt();
+      testMultiplyFull();
+      testFloorDivLongInt();
+      testFloorModLongInt();
+    }
+
+    public static void testMultiplyExactLongInt() {
+      assertEquals(8L, StrictMath.multiplyExact(2L, 4));
+      assertEquals(Long.MAX_VALUE, StrictMath.multiplyExact(Long.MAX_VALUE, 1));
+      assertEquals(Long.MIN_VALUE, StrictMath.multiplyExact(Long.MIN_VALUE / 2L, 2));
+      try {
+        throw new AssertionError(StrictMath.multiplyExact(Long.MAX_VALUE, 2));
+      } catch (ArithmeticException expected) {
+      }
+      try {
+        throw new AssertionError(StrictMath.multiplyExact(Long.MIN_VALUE, 2));
+      } catch (ArithmeticException expected) {
+      }
+    }
+
+    public static void testMultiplyFull() {
+      assertEquals(8L, StrictMath.multiplyFull(2, 4));
+      assertEquals(
+          4611686014132420609L, StrictMath.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE));
+      assertEquals(
+          -4611686016279904256L, StrictMath.multiplyFull(Integer.MAX_VALUE, Integer.MIN_VALUE));
+      assertEquals(
+          4611686018427387904L, StrictMath.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    }
+
+    public static void testMultiplyHigh() {
+      long[] interestingValues = {
+        Long.MIN_VALUE,
+        Long.MAX_VALUE,
+        Integer.MIN_VALUE,
+        Integer.MAX_VALUE,
+        Short.MIN_VALUE,
+        Short.MAX_VALUE,
+        Byte.MIN_VALUE,
+        Byte.MAX_VALUE,
+        0L,
+        -1L,
+        1L,
+        -42L,
+        42L
+      };
+      for (long x : interestingValues) {
+        for (long y : interestingValues) {
+          long expected =
+              BigInteger.valueOf(x).multiply(BigInteger.valueOf(y)).shiftRight(64).longValue();
+          assertEquals(expected, StrictMath.multiplyHigh(x, y));
+        }
+      }
+    }
+
+    public static void testFloorDivLongInt() {
+      assertEquals(1L, StrictMath.floorDiv(4L, 4));
+      assertEquals(1L, StrictMath.floorDiv(-4L, -4));
+      assertEquals(-1L, StrictMath.floorDiv(-4L, 4));
+      assertEquals(-1L, StrictMath.floorDiv(4L, -4));
+
+      assertEquals(1L, StrictMath.floorDiv(4L, 3));
+      assertEquals(1L, StrictMath.floorDiv(-4L, -3));
+      assertEquals(-2L, StrictMath.floorDiv(-4L, 3));
+      assertEquals(-2L, StrictMath.floorDiv(4L, -3));
+
+      // Spec edge case: result is actually MAX_VALUE+1 which becomes MIN_VALUE.
+      assertEquals(Long.MIN_VALUE, StrictMath.floorDiv(Long.MIN_VALUE, -1));
+    }
+
+    public static void testFloorModLongInt() {
+      assertEquals(0, StrictMath.floorMod(4L, 4));
+      assertEquals(0, StrictMath.floorMod(-4L, -4));
+      assertEquals(0, StrictMath.floorMod(-4L, 4));
+      assertEquals(0, StrictMath.floorMod(4L, -4));
+
+      assertEquals(1, StrictMath.floorMod(4L, 3));
+      assertEquals(-1, StrictMath.floorMod(-4L, -3));
+      assertEquals(2, StrictMath.floorMod(-4L, 3));
+      assertEquals(-2, StrictMath.floorMod(4L, -3));
+    }
+
+    private static void assertEquals(int expected, int actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+
+    private static void assertEquals(long expected, long actual) {
+      if (expected != actual) {
+        throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
+      }
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
deleted file mode 100644
index 010f36d..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class ByteBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public ByteBackportJava9Test(TestParameters parameters) {
-    super(parameters, Byte.class, TEST_JAR, "backport.ByteBackportJava9Main");
-
-    // Byte.compareUnsigned added in API 31.
-    registerTarget(AndroidApiLevel.S, 16);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/IntegerBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/IntegerBackportJava9Test.java
deleted file mode 100644
index 5cc2e23..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/IntegerBackportJava9Test.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class IntegerBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public IntegerBackportJava9Test(TestParameters parameters) {
-    super(parameters, Integer.class, TEST_JAR, "backport.IntegerBackportJava9Main");
-    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
-    // Java 11 move these tests to IntegerBackportTest (out of examplesJava9).
-
-    registerTarget(AndroidApiLevel.O, 1);
-    registerTarget(AndroidApiLevel.T, 20);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
deleted file mode 100644
index 604e82c..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-import static org.hamcrest.CoreMatchers.containsString;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class ListBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-  private static final String TEST_CLASS = "backport.ListBackportJava9Main";
-
-  public ListBackportJava9Test(TestParameters parameters) {
-    super(parameters, List.class, TEST_JAR, TEST_CLASS);
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to ListBackportTest.
-
-    // Available since API 1 and used to test created lists.
-    ignoreInvokes("add");
-    ignoreInvokes("get");
-    ignoreInvokes("set");
-    ignoreInvokes("size");
-
-    // List.of added in API 30.
-    registerTarget(AndroidApiLevel.R, 18);
-  }
-
-  @Test
-  public void desugaringApiLevelR() throws Exception {
-    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
-    // This has now been checked with S, when R testing is added check and remove this.
-    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.Q)) {
-      testForD8()
-          .setMinApi(AndroidApiLevel.R)
-          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
-          .addProgramFiles(TEST_JAR)
-          .setIncludeClassesChecksum(true)
-          .compile()
-          .run(parameters.getRuntime(), TEST_CLASS)
-          .assertFailureWithErrorThatMatches(containsString("java.lang.NoSuchMethodError"));
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java
deleted file mode 100644
index 8ffb905..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class LongBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public LongBackportJava9Test(TestParameters parameters) {
-    super(parameters, Long.class, TEST_JAR, "backport.LongBackportJava9Main");
-    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
-    // Java 11 move these tests to LongBackportTest (out of examplesJava9).
-
-    ignoreInvokes("toString");
-
-    registerTarget(AndroidApiLevel.T, 17);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
deleted file mode 100644
index a5c1b1f..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-import static org.hamcrest.CoreMatchers.containsString;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Map;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MapBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-  private static final String TEST_CLASS = "backport.MapBackportJava9Main";
-
-  public MapBackportJava9Test(TestParameters parameters) {
-    super(parameters, Map.class, TEST_JAR, TEST_CLASS);
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to MapBackportTest.
-
-    // Available since API 1 and used to test created maps.
-    ignoreInvokes("entrySet");
-    ignoreInvokes("get");
-    ignoreInvokes("put");
-    ignoreInvokes("size");
-
-    // Map.entry, Map.of and Map.ofEntries added in API 30.
-    registerTarget(AndroidApiLevel.R, 29);
-  }
-
-  @Test
-  public void desugaringApiLevelR() throws Exception {
-    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
-    // This has now been checked with S, when R testing is added check and remove this.
-    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
-      testForD8()
-          .setMinApi(AndroidApiLevel.R)
-          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
-          .addProgramFiles(TEST_JAR)
-          .setIncludeClassesChecksum(true)
-          .compile()
-          .run(parameters.getRuntime(), TEST_CLASS)
-          .assertFailureWithErrorThatMatches(containsString("java.lang.NoSuchMethodError"));
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
deleted file mode 100644
index f41ce56..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class MathBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimes()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public MathBackportJava9Test(TestParameters parameters) {
-    super(parameters, Math.class, TEST_JAR, "backport.MathBackportJava9Main");
-
-    // Math.floorDiv, Math.floorMod, Math.multiplyExact, Math.multiplyFull and Math.multiplyHigh
-    // added in API 31.
-    registerTarget(AndroidApiLevel.S, 27);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
deleted file mode 100644
index 3864c5e..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-import static org.hamcrest.CoreMatchers.containsString;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Objects;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class ObjectsBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimes()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-  private static final String TEST_CLASS = "backport.ObjectsBackportJava9Main";
-
-  public ObjectsBackportJava9Test(TestParameters parameters) {
-    super(parameters, Objects.class, TEST_JAR, TEST_CLASS);
-    // Objects.checkFromIndexSize, Objects.checkFromToIndex, Objects.checkIndex,
-    // Objects.requireNonNullElse and Objects.requireNonNullElseGet added in API 30.
-    registerTarget(AndroidApiLevel.R, 28);
-    registerTarget(AndroidApiLevel.N, 0);
-    // Objects.requireNonNullElseGet is not desugared if Supplier is absent.
-    registerTarget(AndroidApiLevel.B, 4);
-  }
-
-  @Test
-  public void desugaringApiLevelR() throws Exception {
-    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
-    // This has now been checked with S, when R testing is added chck and remove this.
-    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
-      testForD8()
-          .setMinApi(AndroidApiLevel.R)
-          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
-          .addProgramFiles(TEST_JAR)
-          .setIncludeClassesChecksum(true)
-          .compile()
-          .run(parameters.getRuntime(), TEST_CLASS)
-          .assertFailureWithErrorThatMatches(containsString("java.lang.NoSuchMethodError"));
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/OptionalBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/OptionalBackportJava9Test.java
deleted file mode 100644
index e71d3ca..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/OptionalBackportJava9Test.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Optional;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class OptionalBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
-        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .enableApiLevelsForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public OptionalBackportJava9Test(TestParameters parameters) {
-    super(parameters, Optional.class, TEST_JAR, "backport.OptionalBackportJava9Main");
-    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
-    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
-
-    // Available since N.
-    ignoreInvokes("empty");
-    ignoreInvokes("of");
-
-    registerTarget(AndroidApiLevel.T, 10);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/OptionalDoubleBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/OptionalDoubleBackportJava9Test.java
deleted file mode 100644
index b3dacdd..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/OptionalDoubleBackportJava9Test.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.OptionalDouble;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class OptionalDoubleBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
-        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .enableApiLevelsForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public OptionalDoubleBackportJava9Test(TestParameters parameters) {
-    super(parameters, OptionalDouble.class, TEST_JAR, "backport.OptionalDoubleBackportJava9Main");
-    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
-    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
-
-    // Available since N.
-    ignoreInvokes("empty");
-    ignoreInvokes("of");
-
-    registerTarget(AndroidApiLevel.T, 4);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/OptionalIntBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/OptionalIntBackportJava9Test.java
deleted file mode 100644
index d061489..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/OptionalIntBackportJava9Test.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.OptionalInt;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class OptionalIntBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
-        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .enableApiLevelsForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public OptionalIntBackportJava9Test(TestParameters parameters) {
-    super(parameters, OptionalInt.class, TEST_JAR, "backport.OptionalIntBackportJava9Main");
-    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
-    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
-
-    // Available since N.
-    ignoreInvokes("empty");
-    ignoreInvokes("of");
-
-    registerTarget(AndroidApiLevel.T, 4);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/OptionalLongBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/OptionalLongBackportJava9Test.java
deleted file mode 100644
index ea02d61..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/OptionalLongBackportJava9Test.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.OptionalLong;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class OptionalLongBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
-        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .enableApiLevelsForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public OptionalLongBackportJava9Test(TestParameters parameters) {
-    super(parameters, OptionalLong.class, TEST_JAR, "backport.OptionalLongBackportJava9Main");
-    // Note: The methods in this test exist in android.jar from Android T. When R8 builds targeting
-    // Java 11 move these tests to OptionalBackportTest (out of examplesJava9).
-
-    // Available since N.
-    ignoreInvokes("empty");
-    ignoreInvokes("getAsLong");
-    ignoreInvokes("isPresent");
-    ignoreInvokes("of");
-
-    registerTarget(AndroidApiLevel.T, 4);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
deleted file mode 100644
index efdc935..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-import static org.hamcrest.CoreMatchers.containsString;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class SetBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-  private static final String TEST_CLASS = "backport.SetBackportJava9Main";
-
-  public SetBackportJava9Test(TestParameters parameters) {
-    super(parameters, Set.class, TEST_JAR, TEST_CLASS);
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to SetBackportTest.
-
-    // Available since API 1 and used to test created sets.
-    ignoreInvokes("add");
-    ignoreInvokes("contains");
-    ignoreInvokes("size");
-
-    // Set.of added in API 30.
-    registerTarget(AndroidApiLevel.R, 21);
-  }
-
-  @Test
-  public void desugaringApiLevelR() throws Exception {
-    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
-    // This has now been checked with S, when R testing is added check and remove this.
-    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
-      testForD8()
-          .setMinApi(AndroidApiLevel.R)
-          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
-          .addProgramFiles(TEST_JAR)
-          .setIncludeClassesChecksum(true)
-          .compile()
-          .run(parameters.getRuntime(), TEST_CLASS)
-          .assertFailureWithErrorThatMatches(containsString("java.lang.NoSuchMethodError"));
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
deleted file mode 100644
index d641452..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class ShortBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withDexRuntimes()
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public ShortBackportJava9Test(TestParameters parameters) {
-    super(parameters, Short.class, TEST_JAR, "backport.ShortBackportJava9Main");
-
-    // Short.compareUnsigned added in API 31.
-    registerTarget(AndroidApiLevel.S, 16);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/StrictMathBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/StrictMathBackportJava9Test.java
deleted file mode 100644
index 105c190..0000000
--- a/src/test/java/com/android/tools/r8/desugar/backports/StrictMathBackportJava9Test.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.desugar.backports;
-
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.ToolHelper;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class StrictMathBackportJava9Test extends AbstractBackportTest {
-  @Parameters(name = "{0}")
-  public static Iterable<?> data() {
-    return getTestParameters()
-        .withDexRuntimes()
-        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
-        .withAllApiLevelsAlsoForCf()
-        .build();
-  }
-
-  private static final Path TEST_JAR =
-      Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR).resolve("backport" + JAR_EXTENSION);
-
-  public StrictMathBackportJava9Test(TestParameters parameters) {
-    super(parameters, Math.class, TEST_JAR, "backport.StrictMathBackportJava9Main");
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to StrictMathBackportTest.
-  }
-}
