Update to support Java 16

Support class files with version 60.

Move all use of JDK 15 for testing new features to JDK 16,
leaving JDK 15 not used for testing any more.

Added a test for JDK 16 "Pattern Matching For instanceof"
which is pure javac requiring no desugaring.

Content of README.google:
Name: Java Development Kit (JDK)
URL: https://jdk.java.net/16/
Version: 16.0.2
Revision: NA
License: the GNU General Public License, version 2, with the Classpath Exception.

Description:
This is pulled directly from the website for the JDK releases that has an open source license.
Synlinks have reen resolved using `cp -rL` before uploading.

Fixes: 195025241
Change-Id: I85be8765f71688760f51d5adef8fa626c8e287b3
diff --git a/.gitignore b/.gitignore
index f16c1ba..80c9662 100644
--- a/.gitignore
+++ b/.gitignore
@@ -131,6 +131,12 @@
 third_party/openjdk/desugar_jdk_libs_releases/1.1.1.tar.gz
 third_party/openjdk/desugar_jdk_libs_releases/1.1.5
 third_party/openjdk/desugar_jdk_libs_releases/1.1.5.tar.gz
+third_party/openjdk/jdk-16/linux
+third_party/openjdk/jdk-16/linux.tar.gz
+third_party/openjdk/jdk-16/osx
+third_party/openjdk/jdk-16/osx.tar.gz
+third_party/openjdk/jdk-16/windows
+third_party/openjdk/jdk-16/windows.tar.gz
 third_party/openjdk/jdk-15/linux
 third_party/openjdk/jdk-15/linux.tar.gz
 third_party/openjdk/jdk-15/osx
diff --git a/build.gradle b/build.gradle
index 17206b1..3acdbf2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -131,9 +131,9 @@
             srcDirs = ['src/test/examplesJava11']
         }
     }
-    examplesJava15 {
+    examplesJava16 {
         java {
-            srcDirs = ['src/test/examplesJava15']
+            srcDirs = ['src/test/examplesJava16']
         }
     }
     jdk11TimeTests {
@@ -372,18 +372,18 @@
                 "third_party": ["openjdk/openjdk-9.0.4/linux",
                                 "openjdk/jdk8/linux-x86",
                                 "openjdk/jdk-11/linux",
-                                "openjdk/jdk-15/linux"],
+                                "openjdk/jdk-16/linux"],
         ],
         osx: [
                 "third_party": ["openjdk/openjdk-9.0.4/osx",
                                 "openjdk/jdk8/darwin-x86",
                                 "openjdk/jdk-11/osx",
-                                "openjdk/jdk-15/osx"],
+                                "openjdk/jdk-16/osx"],
         ],
         windows: [
                 "third_party": ["openjdk/openjdk-9.0.4/windows",
                                 "openjdk/jdk-11/windows",
-                                "openjdk/jdk-15/windows"],
+                                "openjdk/jdk-16/windows"],
         ],
 ]
 
@@ -575,12 +575,15 @@
             options.compilerArgs.add('--enable-preview')
         }
         if (OperatingSystem.current().isLinux()) {
+            dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/linux")
             options.forkOptions.javaHome = file(jdkDir + 'linux')
         } else if (OperatingSystem.current().isMacOsX()) {
+            dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/osx")
             options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
                     ? file(jdkDir + 'osx/Contents/Home')
                     : file(jdkDir + 'osx')
         } else {
+            dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/windows")
             options.forkOptions.javaHome = file(jdkDir + 'windows')
         }
         sourceCompatibility = compatibility
@@ -619,9 +622,9 @@
         JavaVersion.VERSION_11,
         false)
 setJdkCompilationWithCompatibility(
-        sourceSets.examplesJava15.compileJavaTaskName,
-        'jdk-15',
-        JavaVersion.VERSION_15,
+        sourceSets.examplesJava16.compileJavaTaskName,
+        'jdk-16',
+        JavaVersion.VERSION_16,
         true)
 
 task compileMainWithJava11 (type: JavaCompile) {
@@ -1591,7 +1594,7 @@
 buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9)
 buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10)
 buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11)
-buildExampleJarsCreateTask("Java15", sourceSets.examplesJava15)
+buildExampleJarsCreateTask("Java16", sourceSets.examplesJava16)
 
 task provideArtFrameworksDependencies {
     cloudDependencies.tools.forEach({ art ->
@@ -1674,7 +1677,7 @@
     dependsOn buildExampleJava9Jars
     dependsOn buildExampleJava10Jars
     dependsOn buildExampleJava11Jars
-    dependsOn buildExampleJava15Jars
+    dependsOn buildExampleJava16Jars
     dependsOn buildExampleAndroidApi
     def examplesDir = file("src/test/examples")
     def noDexTests = [
diff --git a/scripts/add-openjdk.sh b/scripts/add-openjdk.sh
new file mode 100644
index 0000000..8587b93
--- /dev/null
+++ b/scripts/add-openjdk.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+# 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.
+
+set -e
+set -x
+
+echo "Update this script manually before using"
+exit -1
+
+# Download JDK from https://jdk.java.net/X/ (X = version) into ~/Downloads
+# Create directory third_party/openjdk/jdk-X
+# cd into third_party/openjdk/jdk-X
+# Prepare README.google
+# Update JDK_VERSION below
+
+# Now run script wit fingers crossed!
+
+JDK_VERSION=16.0.2
+
+tar xf ~/Downloads/openjdk-${JDK_VERSION}_linux-x64_bin.tar.gz
+cp -rL jdk-${JDK_VERSION} linux
+cp README.google linux
+upload_to_google_storage.py -a --bucket r8-deps linux
+rm -rf jdk-${JDK_VERSION}
+rm -rf linux
+rm linux.tar.gz
+
+tar xf ~/Downloads/openjdk-${JDK_VERSION}_osx-x64_bin.tar.gz
+cp -rL jdk-${JDK_VERSION}.jdk osx
+cp README.google osx
+upload_to_google_storage.py -a --bucket r8-deps osx
+rm -rf osx
+rm -rf jdk-${JDK_VERSION}.jdk
+rm osx.tar.gz
+
+unzip ~/Downloads/openjdk-${JDK_VERSION}_windows-x64_bin.zip
+cp -rL jdk-${JDK_VERSION} windows
+cp README.google windows
+upload_to_google_storage.py -a --bucket r8-deps windows
+rm -rf windows
+rm -rf jdk-${JDK_VERSION}
+rm windows.tar.gz
diff --git a/src/main/java/com/android/tools/r8/cf/CfVersion.java b/src/main/java/com/android/tools/r8/cf/CfVersion.java
index 07610dd..5b877b8 100644
--- a/src/main/java/com/android/tools/r8/cf/CfVersion.java
+++ b/src/main/java/com/android/tools/r8/cf/CfVersion.java
@@ -34,6 +34,8 @@
   public static final CfVersion V14_PREVIEW = new CfVersion(Opcodes.V14 | Opcodes.V_PREVIEW);
   public static final CfVersion V15 = new CfVersion(Opcodes.V15);
   public static final CfVersion V15_PREVIEW = new CfVersion(Opcodes.V15 | Opcodes.V_PREVIEW);
+  public static final CfVersion V16 = new CfVersion(Opcodes.V16);
+  public static final CfVersion V16_PREVIEW = new CfVersion(Opcodes.V16 | Opcodes.V_PREVIEW);
 
   private final int version;
 
@@ -52,7 +54,8 @@
     CfVersion.V12,
     CfVersion.V13,
     CfVersion.V14,
-    CfVersion.V15
+    CfVersion.V15,
+    CfVersion.V16
   };
 
   // Private constructor in case we want to canonicalize versions.
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 513cfe8..c9e6675 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -123,7 +123,7 @@
     }
   }
 
-  public static final CfVersion SUPPORTED_CF_VERSION = CfVersion.V15_PREVIEW;
+  public static final CfVersion SUPPORTED_CF_VERSION = CfVersion.V16_PREVIEW;
   public static final CfVersion EXPERIMENTAL_CF_VERSION = CfVersion.V12;
 
   public static final int SUPPORTED_DEX_VERSION =
diff --git a/src/test/examplesJava16/pattern_matching_for_instanceof/Main.java b/src/test/examplesJava16/pattern_matching_for_instanceof/Main.java
new file mode 100644
index 0000000..35a3632
--- /dev/null
+++ b/src/test/examplesJava16/pattern_matching_for_instanceof/Main.java
@@ -0,0 +1,14 @@
+// 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 pattern_matching_for_instanceof;
+
+final class Main {
+  public static void main(String[] args) {
+    Object obj = "Hello, world!";
+    if (obj instanceof String s) {
+      System.out.println(s);
+    }
+  }
+}
diff --git a/src/test/examplesJava15/records/EmptyRecord.java b/src/test/examplesJava16/records/EmptyRecord.java
similarity index 100%
rename from src/test/examplesJava15/records/EmptyRecord.java
rename to src/test/examplesJava16/records/EmptyRecord.java
diff --git a/src/test/examplesJava15/records/RecordInstanceOf.java b/src/test/examplesJava16/records/RecordInstanceOf.java
similarity index 100%
rename from src/test/examplesJava15/records/RecordInstanceOf.java
rename to src/test/examplesJava16/records/RecordInstanceOf.java
diff --git a/src/test/examplesJava15/records/RecordInvokeCustom.java b/src/test/examplesJava16/records/RecordInvokeCustom.java
similarity index 100%
rename from src/test/examplesJava15/records/RecordInvokeCustom.java
rename to src/test/examplesJava16/records/RecordInvokeCustom.java
diff --git a/src/test/examplesJava15/records/RecordReflection.java b/src/test/examplesJava16/records/RecordReflection.java
similarity index 100%
rename from src/test/examplesJava15/records/RecordReflection.java
rename to src/test/examplesJava16/records/RecordReflection.java
diff --git a/src/test/examplesJava15/records/RecordWithMembers.java b/src/test/examplesJava16/records/RecordWithMembers.java
similarity index 100%
rename from src/test/examplesJava15/records/RecordWithMembers.java
rename to src/test/examplesJava16/records/RecordWithMembers.java
diff --git a/src/test/examplesJava15/records/SimpleRecord.java b/src/test/examplesJava16/records/SimpleRecord.java
similarity index 100%
rename from src/test/examplesJava15/records/SimpleRecord.java
rename to src/test/examplesJava16/records/SimpleRecord.java
diff --git a/src/test/examplesJava15/sealed/Compiler.java b/src/test/examplesJava16/sealed/Compiler.java
similarity index 100%
rename from src/test/examplesJava15/sealed/Compiler.java
rename to src/test/examplesJava16/sealed/Compiler.java
diff --git a/src/test/examplesJava15/sealed/D8Compiler.java b/src/test/examplesJava16/sealed/D8Compiler.java
similarity index 100%
rename from src/test/examplesJava15/sealed/D8Compiler.java
rename to src/test/examplesJava16/sealed/D8Compiler.java
diff --git a/src/test/examplesJava15/sealed/Main.java b/src/test/examplesJava16/sealed/Main.java
similarity index 100%
rename from src/test/examplesJava15/sealed/Main.java
rename to src/test/examplesJava16/sealed/Main.java
diff --git a/src/test/examplesJava15/sealed/R8Compiler.java b/src/test/examplesJava16/sealed/R8Compiler.java
similarity index 100%
rename from src/test/examplesJava15/sealed/R8Compiler.java
rename to src/test/examplesJava16/sealed/R8Compiler.java
diff --git a/src/test/java/com/android/tools/r8/TestRuntime.java b/src/test/java/com/android/tools/r8/TestRuntime.java
index a51fcf0..6fd2f96 100644
--- a/src/test/java/com/android/tools/r8/TestRuntime.java
+++ b/src/test/java/com/android/tools/r8/TestRuntime.java
@@ -29,7 +29,7 @@
     JDK9("jdk9", 53),
     JDK10("jdk10", 54),
     JDK11("jdk11", 55),
-    JDK15("jdk15", 59),
+    JDK16("jdk16", 60),
     ;
 
     private final String name;
@@ -70,13 +70,13 @@
   private static final Path JDK9_PATH =
       Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "openjdk-9.0.4");
   private static final Path JDK11_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-11");
-  private static final Path JDK15_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-15");
+  private static final Path JDK16_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-16");
   private static final Map<CfVm, Path> jdkPaths =
       ImmutableMap.of(
           CfVm.JDK8, JDK8_PATH,
           CfVm.JDK9, JDK9_PATH,
           CfVm.JDK11, JDK11_PATH,
-          CfVm.JDK15, JDK15_PATH);
+          CfVm.JDK16, JDK16_PATH);
 
   public static CfRuntime getCheckedInJdk(CfVm vm) {
     if (vm == CfVm.JDK8) {
@@ -121,9 +121,9 @@
     return new CfRuntime(CfVm.JDK11, getCheckedInJdkHome(CfVm.JDK11));
   }
 
-  // TODO(b/169692487): Add this to 'getCheckedInCfRuntimes' when we start having support for JDK15.
-  public static CfRuntime getCheckedInJdk15() {
-    return new CfRuntime(CfVm.JDK15, getCheckedInJdkHome(CfVm.JDK15));
+  // TODO(b/169692487): Add this to 'getCheckedInCfRuntimes' when we start having support for JDK16.
+  public static CfRuntime getCheckedInJdk16() {
+    return new CfRuntime(CfVm.JDK16, getCheckedInJdkHome(CfVm.JDK16));
   }
 
   public static List<CfRuntime> getCheckedInCfRuntimes() {
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
index 9f9dd85..3f0992a 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
@@ -34,10 +34,10 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
         getTestParameters()
-            .withCustomRuntime(CfRuntime.getCheckedInJdk15())
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
             .withDexRuntimes()
             .withAllApiLevelsAlsoForCf()
             .build());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java b/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java
index e936a33..7064af6 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/InvalidRecordAttributeTest.java
@@ -37,9 +37,9 @@
 
   @Parameters(name = "{0} back: {1}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
-        getTestParameters().withCustomRuntime(CfRuntime.getCheckedInJdk15()).build(),
+        getTestParameters().withCustomRuntime(CfRuntime.getCheckedInJdk16()).build(),
         Backend.values());
   }
 
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
index d388ac4..c6b3f68 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInstanceOfTest.java
@@ -37,7 +37,7 @@
     // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
     return buildParameters(
         getTestParameters()
-            .withCustomRuntime(CfRuntime.getCheckedInJdk15())
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
             .withDexRuntimes()
             .withAllApiLevelsAlsoForCf()
             .build());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
index 711909f..55cb175 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomTest.java
@@ -47,10 +47,10 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
         getTestParameters()
-            .withCustomRuntime(CfRuntime.getCheckedInJdk15())
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
             .withDexRuntimes()
             .withAllApiLevelsAlsoForCf()
             .build());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
index bd08a25..240e128 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
@@ -40,10 +40,10 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
         getTestParameters()
-            .withCustomRuntime(CfRuntime.getCheckedInJdk15())
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
             .withDexRuntimes()
             .withAllApiLevelsAlsoForCf()
             .build());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
index 15684fe..9663f43 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
@@ -43,9 +43,9 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
-        getTestParameters().withCustomRuntime(CfRuntime.getCheckedInJdk15()).build());
+        getTestParameters().withCustomRuntime(CfRuntime.getCheckedInJdk16()).build());
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
index 7589764..86e30a6 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordTestUtils.java
@@ -31,7 +31,7 @@
  */
 public class RecordTestUtils {
 
-  private static final String EXAMPLE_FOLDER = "examplesJava15";
+  private static final String EXAMPLE_FOLDER = "examplesJava16";
   private static final String RECORD_FOLDER = "records";
 
   public static Path jar() {
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
index 5472f22..c36375e 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordWithMembersTest.java
@@ -36,10 +36,10 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
         getTestParameters()
-            .withCustomRuntime(CfRuntime.getCheckedInJdk15())
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
             .withDexRuntimes()
             .withAllApiLevelsAlsoForCf()
             .build());
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
index 4820c08..51596a1 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -35,10 +35,10 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
         getTestParameters()
-            .withCustomRuntime(CfRuntime.getCheckedInJdk15())
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
             .withDexRuntimes()
             .withAllApiLevelsAlsoForCf()
             .build());
diff --git a/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java b/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java
index ee2e4e1..d311db8 100644
--- a/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/sealed/SealedAttributeTest.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime;
-import com.android.tools.r8.examples.jdk15.Sealed;
+import com.android.tools.r8.examples.jdk16.Sealed;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import java.util.List;
 import org.junit.Test;
@@ -28,9 +28,9 @@
 
   @Parameters(name = "{0}")
   public static List<Object[]> data() {
-    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk15).
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
     return buildParameters(
-        getTestParameters().withCustomRuntime(TestRuntime.getCheckedInJdk15()).build(),
+        getTestParameters().withCustomRuntime(TestRuntime.getCheckedInJdk16()).build(),
         Backend.values());
   }
 
@@ -44,7 +44,7 @@
     testForJvm()
         .addRunClasspathFiles(Sealed.jar())
         .enablePreview()
-        .run(TestRuntime.getCheckedInJdk15(), Sealed.Main.typeName())
+        .run(TestRuntime.getCheckedInJdk16(), Sealed.Main.typeName())
         .assertSuccessWithOutputLines("R8 compiler", "D8 compiler");
   }
 
diff --git a/src/test/java/com/android/tools/r8/examples/jdk16/PatternMatchingForInstenceof.java b/src/test/java/com/android/tools/r8/examples/jdk16/PatternMatchingForInstenceof.java
new file mode 100644
index 0000000..0cc4846
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/jdk16/PatternMatchingForInstenceof.java
@@ -0,0 +1,20 @@
+// 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.examples.jdk16;
+
+import com.android.tools.r8.examples.JavaExampleClassProxy;
+import java.nio.file.Path;
+
+public class PatternMatchingForInstenceof {
+
+  private static final String EXAMPLE_FILE = "examplesJava16/pattern_matching_for_instanceof";
+
+  public static final JavaExampleClassProxy Main =
+      new JavaExampleClassProxy(EXAMPLE_FILE, "pattern_matching_for_instanceof/Main");
+
+  public static Path jar() {
+    return JavaExampleClassProxy.examplesJar(EXAMPLE_FILE);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/examples/jdk15/Records.java b/src/test/java/com/android/tools/r8/examples/jdk16/Records.java
similarity index 85%
rename from src/test/java/com/android/tools/r8/examples/jdk15/Records.java
rename to src/test/java/com/android/tools/r8/examples/jdk16/Records.java
index 9eafc56..a8677b8 100644
--- a/src/test/java/com/android/tools/r8/examples/jdk15/Records.java
+++ b/src/test/java/com/android/tools/r8/examples/jdk16/Records.java
@@ -2,14 +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.examples.jdk15;
+package com.android.tools.r8.examples.jdk16;
 
 import com.android.tools.r8.examples.JavaExampleClassProxy;
 import java.nio.file.Path;
 
 public class Records {
 
-  private static final String EXAMPLE_FILE = "examplesJava15/records";
+  private static final String EXAMPLE_FILE = "examplesJava16/records";
 
   public static final JavaExampleClassProxy Main =
       new JavaExampleClassProxy(EXAMPLE_FILE, "records/Main");
diff --git a/src/test/java/com/android/tools/r8/examples/jdk15/Sealed.java b/src/test/java/com/android/tools/r8/examples/jdk16/Sealed.java
similarity index 89%
rename from src/test/java/com/android/tools/r8/examples/jdk15/Sealed.java
rename to src/test/java/com/android/tools/r8/examples/jdk16/Sealed.java
index 1450ee8..c995d13 100644
--- a/src/test/java/com/android/tools/r8/examples/jdk15/Sealed.java
+++ b/src/test/java/com/android/tools/r8/examples/jdk16/Sealed.java
@@ -2,14 +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.examples.jdk15;
+package com.android.tools.r8.examples.jdk16;
 
 import com.android.tools.r8.examples.JavaExampleClassProxy;
 import java.nio.file.Path;
 
 public class Sealed {
 
-  private static final String EXAMPLE_FILE = "examplesJava15/sealed";
+  private static final String EXAMPLE_FILE = "examplesJava16/sealed";
 
   public static final JavaExampleClassProxy Compiler =
       new JavaExampleClassProxy(EXAMPLE_FILE, "sealed/Compiler");
diff --git a/src/test/java/com/android/tools/r8/java_language/pattern_matching_for_instenceof/PattternMatchingForInstanceOfTest.java b/src/test/java/com/android/tools/r8/java_language/pattern_matching_for_instenceof/PattternMatchingForInstanceOfTest.java
new file mode 100644
index 0000000..345f198
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/java_language/pattern_matching_for_instenceof/PattternMatchingForInstanceOfTest.java
@@ -0,0 +1,79 @@
+// 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.java_language.pattern_matching_for_instenceof;
+
+import com.android.tools.r8.R8TestBuilder;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime.CfRuntime;
+import com.android.tools.r8.examples.jdk16.PatternMatchingForInstenceof;
+import com.android.tools.r8.utils.InternalOptions.TestingOptions;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class PattternMatchingForInstanceOfTest extends TestBase {
+
+  @Parameter public TestParameters parameters;
+
+  private static List<String> EXPECTED = ImmutableList.of("Hello, world!");
+
+  private static final Path JAR = PatternMatchingForInstenceof.jar();
+  private static final String MAIN = PatternMatchingForInstenceof.Main.typeName();
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> data() {
+    // TODO(b/174431251): This should be replaced with .withCfRuntimes(start = jdk16).
+    return buildParameters(
+        getTestParameters()
+            .withCustomRuntime(CfRuntime.getCheckedInJdk16())
+            .withDexRuntimes()
+            .withAllApiLevelsAlsoForCf()
+            .build());
+  }
+
+  @Test
+  public void testD8AndJvm() throws Exception {
+    if (parameters.isCfRuntime()) {
+      testForJvm()
+          .addRunClasspathFiles(JAR)
+          .enablePreview()
+          .run(parameters.getRuntime(), MAIN)
+          .assertSuccessWithOutputLines(EXPECTED);
+    }
+    testForD8(parameters.getBackend())
+        .addProgramFiles(JAR)
+        .setMinApi(parameters.getApiLevel())
+        .addOptionsModification(TestingOptions::allowExperimentClassFileVersion)
+        .compile()
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    R8TestBuilder<?> builder =
+        testForR8(parameters.getBackend())
+            .addProgramFiles(JAR)
+            .setMinApi(parameters.getApiLevel())
+            .addKeepMainRule(MAIN)
+            .addOptionsModification(TestingOptions::allowExperimentClassFileVersion);
+    if (parameters.getBackend().isDex()) {
+      builder.run(parameters.getRuntime(), MAIN).assertSuccessWithOutputLines(EXPECTED);
+    } else {
+      testForJvm()
+          .addRunClasspathFiles(builder.compile().writeToZip())
+          .enablePreview()
+          .run(parameters.getRuntime(), MAIN)
+          .assertSuccessWithOutputLines(EXPECTED);
+    }
+  }
+}
diff --git a/third_party/openjdk/jdk-16/linux.tar.gz.sha1 b/third_party/openjdk/jdk-16/linux.tar.gz.sha1
new file mode 100644
index 0000000..0a22059
--- /dev/null
+++ b/third_party/openjdk/jdk-16/linux.tar.gz.sha1
@@ -0,0 +1 @@
+8fa0d8caeed71708c442eabb610b794c1efa63a3
\ No newline at end of file
diff --git a/third_party/openjdk/jdk-16/osx.tar.gz.sha1 b/third_party/openjdk/jdk-16/osx.tar.gz.sha1
new file mode 100644
index 0000000..ebbc803
--- /dev/null
+++ b/third_party/openjdk/jdk-16/osx.tar.gz.sha1
@@ -0,0 +1 @@
+b7db69925ff470d6b118e70f28f39451afb027b7
\ No newline at end of file
diff --git a/third_party/openjdk/jdk-16/windows.tar.gz.sha1 b/third_party/openjdk/jdk-16/windows.tar.gz.sha1
new file mode 100644
index 0000000..fe6a7bd
--- /dev/null
+++ b/third_party/openjdk/jdk-16/windows.tar.gz.sha1
@@ -0,0 +1 @@
+ce1494575976dbc8ac4702ef6f08c15cc6b38c47
\ No newline at end of file