diff --git a/src/test/examplesJava10/backport/ListBackportJava10Main.java b/src/test/examplesJava10/backport/ListBackportJava10Main.java
deleted file mode 100644
index 376f67a..0000000
--- a/src/test/examplesJava10/backport/ListBackportJava10Main.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 backport;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class ListBackportJava10Main {
-
-  public static void main(String[] args) {
-    testCopyOf();
-  }
-
-  private static void testCopyOf() {
-    Object anObject0 = new Object();
-    Object anObject1 = new Object();
-    List<Object> original = Arrays.asList(anObject0, anObject1);
-    List<Object> copy = List.copyOf(original);
-    assertEquals(2, copy.size());
-    assertEquals(original, copy);
-    assertSame(anObject0, copy.get(0));
-    assertSame(anObject1, copy.get(1));
-    assertMutationNotAllowed(copy);
-
-    // Mutate the original backing collection and ensure it's not reflected in copy.
-    original.set(0, new Object());
-    assertSame(anObject0, copy.get(0));
-
-    try {
-      List.copyOf(null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      List.copyOf(Arrays.asList(1, null, 2));
-      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/examplesJava10/backport/ListBackportJava10Test.java b/src/test/examplesJava10/backport/ListBackportJava10Test.java
new file mode 100644
index 0000000..f8abd84
--- /dev/null
+++ b/src/test/examplesJava10/backport/ListBackportJava10Test.java
@@ -0,0 +1,101 @@
+// 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 java.util.Arrays;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ListBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public ListBackportJava10Test(TestParameters parameters) {
+    super(parameters, List.class, ListBackportJava10Main.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.copyOf added in API 31.
+    registerTarget(AndroidApiLevel.S, 3);
+  }
+
+  public static class ListBackportJava10Main {
+
+    public static void main(String[] args) {
+      testCopyOf();
+    }
+
+    private static void testCopyOf() {
+      Object anObject0 = new Object();
+      Object anObject1 = new Object();
+      List<Object> original = Arrays.asList(anObject0, anObject1);
+      List<Object> copy = List.copyOf(original);
+      assertEquals(2, copy.size());
+      assertEquals(original, copy);
+      assertSame(anObject0, copy.get(0));
+      assertSame(anObject1, copy.get(1));
+      assertMutationNotAllowed(copy);
+
+      // Mutate the original backing collection and ensure it's not reflected in copy.
+      original.set(0, new Object());
+      assertSame(anObject0, copy.get(0));
+
+      try {
+        List.copyOf(null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        List.copyOf(Arrays.asList(1, null, 2));
+        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/examplesJava10/backport/MapBackportJava10Main.java b/src/test/examplesJava10/backport/MapBackportJava10Main.java
deleted file mode 100644
index 95413e9..0000000
--- a/src/test/examplesJava10/backport/MapBackportJava10Main.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.HashMap;
-import java.util.Map;
-
-public class MapBackportJava10Main {
-
-  public static void main(String[] args) {
-    testCopyOf();
-  }
-
-  private static void testCopyOf() {
-    Object key0 = new Object();
-    Object value0 = new Object();
-    Object key1 = new Object();
-    Object value1 = new Object();
-    Map<Object, Object> original = new HashMap<>();
-    original.put(key0, value0);
-    original.put(key1, value1);
-    Map<Object, Object> copy = Map.copyOf(original);
-    assertEquals(2, copy.size());
-    assertEquals(original, copy);
-    assertSame(value0, copy.get(key0));
-    assertSame(value1, copy.get(key1));
-    assertMutationNotAllowed(copy);
-
-    // Mutate the original backing collection and ensure it's not reflected in copy.
-    original.put(key0, new Object());
-    assertSame(value0, copy.get(key0));
-
-    try {
-      Map.copyOf(null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map<Object, Object> map = new HashMap<>();
-      map.put(null, new Object());
-      Map.copyOf(map);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Map<Object, Object> map = new HashMap<>();
-      map.put(new Object(), null);
-      Map.copyOf(map);
-      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/examplesJava10/backport/MapBackportJava10Test.java b/src/test/examplesJava10/backport/MapBackportJava10Test.java
new file mode 100644
index 0000000..fa9864e
--- /dev/null
+++ b/src/test/examplesJava10/backport/MapBackportJava10Test.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.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.util.HashMap;
+import java.util.Map;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class MapBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public MapBackportJava10Test(TestParameters parameters) {
+    super(parameters, Map.class, MapBackportJava10Main.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.copyOf added in API 31.
+    registerTarget(AndroidApiLevel.S, 4);
+  }
+
+  public static class MapBackportJava10Main {
+
+    public static void main(String[] args) {
+      testCopyOf();
+    }
+
+    private static void testCopyOf() {
+      Object key0 = new Object();
+      Object value0 = new Object();
+      Object key1 = new Object();
+      Object value1 = new Object();
+      Map<Object, Object> original = new HashMap<>();
+      original.put(key0, value0);
+      original.put(key1, value1);
+      Map<Object, Object> copy = Map.copyOf(original);
+      assertEquals(2, copy.size());
+      assertEquals(original, copy);
+      assertSame(value0, copy.get(key0));
+      assertSame(value1, copy.get(key1));
+      assertMutationNotAllowed(copy);
+
+      // Mutate the original backing collection and ensure it's not reflected in copy.
+      original.put(key0, new Object());
+      assertSame(value0, copy.get(key0));
+
+      try {
+        Map.copyOf(null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map<Object, Object> map = new HashMap<>();
+        map.put(null, new Object());
+        Map.copyOf(map);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Map<Object, Object> map = new HashMap<>();
+        map.put(new Object(), null);
+        Map.copyOf(map);
+        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/examplesJava10/backport/OptionalBackportJava10Main.java b/src/test/examplesJava10/backport/OptionalBackportJava10Main.java
deleted file mode 100644
index 3d2c919..0000000
--- a/src/test/examplesJava10/backport/OptionalBackportJava10Main.java
+++ /dev/null
@@ -1,32 +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.NoSuchElementException;
-import java.util.Optional;
-
-public final class OptionalBackportJava10Main {
-
-  public static void main(String[] args) {
-    testOrElseThrow();
-  }
-
-  private static void testOrElseThrow() {
-    Optional<String> present = Optional.of("hey");
-    assertEquals("hey", present.orElseThrow());
-
-    Optional<String> absent = Optional.empty();
-    try {
-      throw new AssertionError(absent.orElseThrow());
-    } catch (NoSuchElementException expected) {
-    }
-  }
-
-  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/examplesJava10/backport/OptionalBackportJava10Test.java b/src/test/examplesJava10/backport/OptionalBackportJava10Test.java
new file mode 100644
index 0000000..86165e5
--- /dev/null
+++ b/src/test/examplesJava10/backport/OptionalBackportJava10Test.java
@@ -0,0 +1,66 @@
+// 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.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.NoSuchElementException;
+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 OptionalBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalBackportJava10Test(TestParameters parameters) {
+    super(parameters, Optional.class, OptionalBackportJava10Main.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 examplesJava10).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("get");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 2);
+  }
+
+  public static class OptionalBackportJava10Main {
+
+    public static void main(String[] args) {
+      testOrElseThrow();
+    }
+
+    private static void testOrElseThrow() {
+      Optional<String> present = Optional.of("hey");
+      assertEquals("hey", present.orElseThrow());
+
+      Optional<String> absent = Optional.empty();
+      try {
+        throw new AssertionError(absent.orElseThrow());
+      } catch (NoSuchElementException expected) {
+      }
+    }
+
+    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/examplesJava10/backport/OptionalDoubleBackportJava10Main.java b/src/test/examplesJava10/backport/OptionalDoubleBackportJava10Main.java
deleted file mode 100644
index 1c27538..0000000
--- a/src/test/examplesJava10/backport/OptionalDoubleBackportJava10Main.java
+++ /dev/null
@@ -1,32 +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.NoSuchElementException;
-import java.util.OptionalDouble;
-
-public final class OptionalDoubleBackportJava10Main {
-
-  public static void main(String[] args) {
-    testOrElseThrow();
-  }
-
-  private static void testOrElseThrow() {
-    OptionalDouble present = OptionalDouble.of(2d);
-    assertEquals(2d, present.orElseThrow());
-
-    OptionalDouble absent = OptionalDouble.empty();
-    try {
-      throw new AssertionError(absent.orElseThrow());
-    } catch (NoSuchElementException expected) {
-    }
-  }
-
-  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/examplesJava10/backport/OptionalDoubleBackportJava10Test.java b/src/test/examplesJava10/backport/OptionalDoubleBackportJava10Test.java
new file mode 100644
index 0000000..3f78ec2
--- /dev/null
+++ b/src/test/examplesJava10/backport/OptionalDoubleBackportJava10Test.java
@@ -0,0 +1,66 @@
+// 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.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.NoSuchElementException;
+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 OptionalDoubleBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalDoubleBackportJava10Test(TestParameters parameters) {
+    super(parameters, OptionalDouble.class, OptionalDoubleBackportJava10Main.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 examplesJava10).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("getAsDouble");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 2);
+  }
+
+  public static class OptionalDoubleBackportJava10Main {
+
+    public static void main(String[] args) {
+      testOrElseThrow();
+    }
+
+    private static void testOrElseThrow() {
+      OptionalDouble present = OptionalDouble.of(2d);
+      assertEquals(2d, present.orElseThrow());
+
+      OptionalDouble absent = OptionalDouble.empty();
+      try {
+        throw new AssertionError(absent.orElseThrow());
+      } catch (NoSuchElementException expected) {
+      }
+    }
+
+    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/examplesJava10/backport/OptionalIntBackportJava10Main.java b/src/test/examplesJava10/backport/OptionalIntBackportJava10Main.java
deleted file mode 100644
index 06c85f5..0000000
--- a/src/test/examplesJava10/backport/OptionalIntBackportJava10Main.java
+++ /dev/null
@@ -1,32 +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.NoSuchElementException;
-import java.util.OptionalInt;
-
-public final class OptionalIntBackportJava10Main {
-
-  public static void main(String[] args) {
-    testOrElseThrow();
-  }
-
-  private static void testOrElseThrow() {
-    OptionalInt present = OptionalInt.of(2);
-    assertEquals(2, present.orElseThrow());
-
-    OptionalInt absent = OptionalInt.empty();
-    try {
-      throw new AssertionError(absent.orElseThrow());
-    } catch (NoSuchElementException expected) {
-    }
-  }
-
-  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/examplesJava10/backport/OptionalIntBackportJava10Test.java b/src/test/examplesJava10/backport/OptionalIntBackportJava10Test.java
new file mode 100644
index 0000000..1e2f17a
--- /dev/null
+++ b/src/test/examplesJava10/backport/OptionalIntBackportJava10Test.java
@@ -0,0 +1,66 @@
+// 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.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.NoSuchElementException;
+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 OptionalIntBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalIntBackportJava10Test(TestParameters parameters) {
+    super(parameters, OptionalInt.class, OptionalIntBackportJava10Main.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 examplesJava10).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("getAsInt");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 2);
+  }
+
+  public static class OptionalIntBackportJava10Main {
+
+    public static void main(String[] args) {
+      testOrElseThrow();
+    }
+
+    private static void testOrElseThrow() {
+      OptionalInt present = OptionalInt.of(2);
+      assertEquals(2, present.orElseThrow());
+
+      OptionalInt absent = OptionalInt.empty();
+      try {
+        throw new AssertionError(absent.orElseThrow());
+      } catch (NoSuchElementException expected) {
+      }
+    }
+
+    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/examplesJava10/backport/OptionalLongBackportJava10Main.java b/src/test/examplesJava10/backport/OptionalLongBackportJava10Main.java
deleted file mode 100644
index e92b9a5..0000000
--- a/src/test/examplesJava10/backport/OptionalLongBackportJava10Main.java
+++ /dev/null
@@ -1,32 +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.NoSuchElementException;
-import java.util.OptionalLong;
-
-public final class OptionalLongBackportJava10Main {
-
-  public static void main(String[] args) {
-    testOrElseThrow();
-  }
-
-  private static void testOrElseThrow() {
-    OptionalLong present = OptionalLong.of(2L);
-    assertEquals(2L, present.orElseThrow());
-
-    OptionalLong absent = OptionalLong.empty();
-    try {
-      throw new AssertionError(absent.orElseThrow());
-    } catch (NoSuchElementException expected) {
-    }
-  }
-
-  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/examplesJava10/backport/OptionalLongBackportJava10Test.java b/src/test/examplesJava10/backport/OptionalLongBackportJava10Test.java
new file mode 100644
index 0000000..4c0ffe3
--- /dev/null
+++ b/src/test/examplesJava10/backport/OptionalLongBackportJava10Test.java
@@ -0,0 +1,66 @@
+// 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.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.backports.AbstractBackportTest;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.util.NoSuchElementException;
+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 OptionalLongBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withDexRuntimesStartingFromIncluding(Version.V7_0_0)
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .enableApiLevelsForCf()
+        .build();
+  }
+
+  public OptionalLongBackportJava10Test(TestParameters parameters) {
+    super(parameters, OptionalLong.class, OptionalLongBackportJava10Main.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 examplesJava10).
+
+    // Available since N.
+    ignoreInvokes("empty");
+    ignoreInvokes("getAsLong");
+    ignoreInvokes("of");
+
+    registerTarget(AndroidApiLevel.T, 2);
+  }
+
+  public static class OptionalLongBackportJava10Main {
+
+    public static void main(String[] args) {
+      testOrElseThrow();
+    }
+
+    private static void testOrElseThrow() {
+      OptionalLong present = OptionalLong.of(2L);
+      assertEquals(2L, present.orElseThrow());
+
+      OptionalLong absent = OptionalLong.empty();
+      try {
+        throw new AssertionError(absent.orElseThrow());
+      } catch (NoSuchElementException expected) {
+      }
+    }
+
+    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/examplesJava10/backport/SetBackportJava10Main.java b/src/test/examplesJava10/backport/SetBackportJava10Main.java
deleted file mode 100644
index b8fb356..0000000
--- a/src/test/examplesJava10/backport/SetBackportJava10Main.java
+++ /dev/null
@@ -1,74 +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.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class SetBackportJava10Main {
-
-  public static void main(String[] args) {
-    testCopyOf();
-  }
-
-  private static void testCopyOf() {
-    Object anObject0 = new Object();
-    Object anObject1 = new Object();
-    List<Object> original = Arrays.asList(anObject0, anObject1);
-    Set<Object> copy = Set.copyOf(original);
-    assertEquals(2, copy.size());
-    assertEquals(new HashSet<>(original), copy);
-    assertTrue(copy.contains(anObject0));
-    assertTrue(copy.contains(anObject1));
-    assertMutationNotAllowed(copy);
-
-    // Mutate the original backing collection and ensure it's not reflected in copy.
-    Object newObject = new Object();
-    original.set(0, newObject);
-    assertFalse(copy.contains(newObject));
-
-    // Ensure duplicates are allowed and are de-duped.
-    assertEquals(Set.of(1, 2), Set.copyOf(List.of(1, 2, 1, 2)));
-
-    try {
-      Set.copyOf(null);
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-    try {
-      Set.copyOf(Arrays.asList(1, null, 2));
-      throw new AssertionError();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  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/examplesJava10/backport/SetBackportJava10Test.java b/src/test/examplesJava10/backport/SetBackportJava10Test.java
new file mode 100644
index 0000000..8a4ffee
--- /dev/null
+++ b/src/test/examplesJava10/backport/SetBackportJava10Test.java
@@ -0,0 +1,109 @@
+// 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 java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class SetBackportJava10Test extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK10)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public SetBackportJava10Test(TestParameters parameters) {
+    super(parameters, Set.class, SetBackportJava10Main.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, 1);
+    // Set.copyOf added in API 31
+    registerTarget(AndroidApiLevel.S, 5);
+  }
+
+  public static class SetBackportJava10Main {
+
+    public static void main(String[] args) {
+      testCopyOf();
+    }
+
+    private static void testCopyOf() {
+      Object anObject0 = new Object();
+      Object anObject1 = new Object();
+      List<Object> original = Arrays.asList(anObject0, anObject1);
+      Set<Object> copy = Set.copyOf(original);
+      assertEquals(2, copy.size());
+      assertEquals(new HashSet<>(original), copy);
+      assertTrue(copy.contains(anObject0));
+      assertTrue(copy.contains(anObject1));
+      assertMutationNotAllowed(copy);
+
+      // Mutate the original backing collection and ensure it's not reflected in copy.
+      Object newObject = new Object();
+      original.set(0, newObject);
+      assertFalse(copy.contains(newObject));
+
+      // Ensure duplicates are allowed and are de-duped.
+      assertEquals(Set.of(1, 2), Set.copyOf(List.of(1, 2, 1, 2)));
+
+      try {
+        Set.copyOf(null);
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+      try {
+        Set.copyOf(Arrays.asList(1, null, 2));
+        throw new AssertionError();
+      } catch (NullPointerException expected) {
+      }
+    }
+
+    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 + ">");
+      }
+    }
+  }
+}
