Fix Collector#characteristics

Change-Id: Idc5942e14c3b74c788ae7c393774647c30ab672e
diff --git a/src/library_desugar/java/j$/util/stream/Collector.java b/src/library_desugar/java/j$/util/stream/Collector.java
new file mode 100644
index 0000000..126d6ad
--- /dev/null
+++ b/src/library_desugar/java/j$/util/stream/Collector.java
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, 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 j$.util.stream;
+
+public class Collector {
+  public enum Characteristics {
+    ;
+
+    public static java.util.stream.Collector.Characteristics wrap_convert(
+        j$.util.stream.Collector.Characteristics option) {
+      return null;
+    }
+
+    public static j$.util.stream.Collector.Characteristics wrap_convert(
+        java.util.stream.Collector.Characteristics option) {
+      return null;
+    }
+  }
+}
diff --git a/src/library_desugar/java/java/util/stream/StreamApiFlips.java b/src/library_desugar/java/java/util/stream/StreamApiFlips.java
new file mode 100644
index 0000000..632c7bd
--- /dev/null
+++ b/src/library_desugar/java/java/util/stream/StreamApiFlips.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2022, 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 java.util.stream;
+
+import static java.util.ConversionRuntimeException.exception;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class StreamApiFlips {
+
+  public static RuntimeException exceptionCharacteristics(Object suffix) {
+    throw exception("java.util.stream.Collector.Characteristics", suffix);
+  }
+
+  public static Set<?> flipCharacteristicSet(Set<?> characteristicSet) {
+    if (characteristicSet == null || characteristicSet.isEmpty()) {
+      return characteristicSet;
+    }
+    HashSet<Object> convertedSet = new HashSet<>();
+    Object guineaPig = characteristicSet.iterator().next();
+    if (guineaPig instanceof java.util.stream.Collector.Characteristics) {
+      for (Object item : characteristicSet) {
+        java.util.stream.Collector.Characteristics characteristics;
+        try {
+          characteristics = (java.util.stream.Collector.Characteristics) item;
+        } catch (ClassCastException cce) {
+          throw exceptionCharacteristics(cce);
+        }
+        convertedSet.add(j$.util.stream.Collector.Characteristics.wrap_convert(characteristics));
+      }
+      return convertedSet;
+    }
+    if (guineaPig instanceof j$.util.stream.Collector.Characteristics) {
+      for (Object item : characteristicSet) {
+        j$.util.stream.Collector.Characteristics characteristics;
+        try {
+          characteristics = (j$.util.stream.Collector.Characteristics) item;
+        } catch (ClassCastException cce) {
+          throw exceptionCharacteristics(cce);
+        }
+        convertedSet.add(j$.util.stream.Collector.Characteristics.wrap_convert(characteristics));
+      }
+      return convertedSet;
+    }
+    throw exceptionCharacteristics(guineaPig.getClass());
+  }
+}
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs.json b/src/library_desugar/jdk11/desugar_jdk_libs.json
index ef9b604..c764f31 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs.json
@@ -95,56 +95,24 @@
         "java.util.stream.Stream java.io.BufferedReader#lines()": "java.io.DesugarBufferedReader",
         "java.util.Spliterator java.util.LinkedHashSet#spliterator()": "java.util.DesugarLinkedHashSet"
       },
+      "api_generic_types_conversion": {
+        "java.util.Set java.util.stream.Collector#characteristics()" : [-1, "java.util.Set java.util.stream.StreamApiFlips#flipCharacteristicSet(java.util.Set)"]
+      },
       "wrapper_conversion": [
-        "java.util.function.IntUnaryOperator",
-        "java.util.function.BiFunction",
-        "java.util.function.IntConsumer",
-        "java.util.function.IntBinaryOperator",
-        "java.util.function.UnaryOperator",
-        "java.util.function.DoubleConsumer",
-        "java.util.function.IntPredicate",
-        "java.util.Spliterator$OfLong",
-        "java.util.stream.Collector",
-        "java.util.function.LongPredicate",
-        "java.util.function.ToLongFunction",
-        "java.util.function.LongToDoubleFunction",
-        "java.util.PrimitiveIterator$OfInt",
-        "java.util.function.LongToIntFunction",
-        "java.util.function.Predicate",
-        "java.util.Spliterator$OfPrimitive",
-        "java.util.function.DoubleToIntFunction",
-        "java.util.function.ObjDoubleConsumer",
-        "java.util.function.BinaryOperator",
-        "java.util.stream.DoubleStream",
-        "java.util.Spliterator$OfInt",
-        "java.util.stream.Stream",
-        "java.util.function.ObjLongConsumer",
-        "java.util.function.ToDoubleFunction",
-        "java.util.stream.IntStream",
-        "java.util.function.LongBinaryOperator",
-        "java.util.Spliterator$OfDouble",
-        "java.util.function.DoubleFunction",
-        "java.util.function.ObjIntConsumer",
-        "java.util.function.Function",
-        "java.util.function.Supplier",
-        "java.util.function.DoubleUnaryOperator",
-        "java.util.function.BiPredicate",
         "java.util.PrimitiveIterator$OfDouble",
-        "java.util.function.DoubleBinaryOperator",
+        "java.util.PrimitiveIterator$OfInt",
         "java.util.PrimitiveIterator$OfLong",
-        "java.util.function.BiConsumer",
-        "java.util.function.IntFunction",
-        "java.util.stream.LongStream",
-        "java.util.function.IntToDoubleFunction",
-        "java.util.function.LongFunction",
-        "java.util.function.ToIntFunction",
-        "java.util.function.LongConsumer",
-        "java.util.function.Consumer",
-        "java.util.function.IntToLongFunction",
-        "java.util.function.DoubleToLongFunction",
-        "java.util.function.LongUnaryOperator",
+        "java.util.Spliterator$OfDouble",
+        "java.util.Spliterator$OfInt",
+        "java.util.Spliterator$OfLong",
+        "java.util.Spliterator$OfPrimitive",
         "java.util.stream.BaseStream",
-        "java.util.function.DoublePredicate"
+        "java.util.stream.Collector",
+        "java.util.stream.Collector$Characteristics",
+        "java.util.stream.DoubleStream",
+        "java.util.stream.IntStream",
+        "java.util.stream.LongStream",
+        "java.util.stream.Stream"
       ],
       "wrapper_conversion_excluding": {
         "java.util.Spliterator": [
@@ -242,7 +210,8 @@
         "java.util.KeyValueHolder": "j$.util.KeyValueHolder",
         "java.util.SortedSet$1": "j$.util.SortedSet$1",
         "java.util.Tripwire": "j$.util.Tripwire",
-        "java.util.concurrent.Helpers": "j$.util.concurrent.Helpers"
+        "java.util.concurrent.Helpers": "j$.util.concurrent.Helpers",
+        "java.util.ConversionRuntimeException": "j$.util.ConversionRuntimeException"
       },
       "rewrite_derived_prefix": {
         "java.util.DoubleSummaryStatistics": {
@@ -254,6 +223,9 @@
         "java.util.LongSummaryStatistics": {
           "j$.util.LongSummaryStatistics": "java.util.LongSummaryStatistics"
         },
+        "java.util.stream.Collector": {
+          "j$.util.stream.Collector": "java.util.stream.Collector"
+        },
         "java.util.Optional": {
           "j$.util.Optional": "java.util.Optional"
         }
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_path.json b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
index 038efba..11f7999 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_path.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
@@ -232,57 +232,25 @@
         "java.util.stream.Stream java.io.BufferedReader#lines()": "java.io.DesugarBufferedReader",
         "java.util.Spliterator java.util.LinkedHashSet#spliterator()": "java.util.DesugarLinkedHashSet"
       },
+      "api_generic_conversion": {
+        "java.util.Set java.util.stream.Collector#characteristics()" : [-1, "java.util.Set java.util.stream.StreamApiFlips#flipCharacteristicSet(java.util.Set)"]
+      },
       "wrapper_conversion": [
         "java.nio.channels.SeekableByteChannel",
-        "java.util.function.IntUnaryOperator",
-        "java.util.function.BiFunction",
-        "java.util.function.IntConsumer",
-        "java.util.function.IntBinaryOperator",
-        "java.util.function.UnaryOperator",
-        "java.util.function.DoubleConsumer",
-        "java.util.function.IntPredicate",
-        "java.util.Spliterator$OfLong",
-        "java.util.stream.Collector",
-        "java.util.function.LongPredicate",
-        "java.util.function.ToLongFunction",
-        "java.util.function.LongToDoubleFunction",
-        "java.util.PrimitiveIterator$OfInt",
-        "java.util.function.LongToIntFunction",
-        "java.util.function.Predicate",
-        "java.util.Spliterator$OfPrimitive",
-        "java.util.function.DoubleToIntFunction",
-        "java.util.function.ObjDoubleConsumer",
-        "java.util.function.BinaryOperator",
-        "java.util.stream.DoubleStream",
-        "java.util.Spliterator$OfInt",
-        "java.util.stream.Stream",
-        "java.util.function.ObjLongConsumer",
-        "java.util.function.ToDoubleFunction",
-        "java.util.stream.IntStream",
-        "java.util.function.LongBinaryOperator",
-        "java.util.Spliterator$OfDouble",
-        "java.util.function.DoubleFunction",
-        "java.util.function.ObjIntConsumer",
-        "java.util.function.Function",
-        "java.util.function.Supplier",
-        "java.util.function.DoubleUnaryOperator",
-        "java.util.function.BiPredicate",
         "java.util.PrimitiveIterator$OfDouble",
-        "java.util.function.DoubleBinaryOperator",
+        "java.util.PrimitiveIterator$OfInt",
         "java.util.PrimitiveIterator$OfLong",
-        "java.util.function.BiConsumer",
-        "java.util.function.IntFunction",
-        "java.util.stream.LongStream",
-        "java.util.function.IntToDoubleFunction",
-        "java.util.function.LongFunction",
-        "java.util.function.ToIntFunction",
-        "java.util.function.LongConsumer",
-        "java.util.function.Consumer",
-        "java.util.function.IntToLongFunction",
-        "java.util.function.DoubleToLongFunction",
-        "java.util.function.LongUnaryOperator",
+        "java.util.Spliterator$OfDouble",
+        "java.util.Spliterator$OfInt",
+        "java.util.Spliterator$OfLong",
+        "java.util.Spliterator$OfPrimitive",
         "java.util.stream.BaseStream",
-        "java.util.function.DoublePredicate"
+        "java.util.stream.Collector",
+        "java.util.stream.Collector$Characteristics",
+        "java.util.stream.DoubleStream",
+        "java.util.stream.IntStream",
+        "java.util.stream.LongStream",
+        "java.util.stream.Stream"
       ],
       "wrapper_conversion_excluding": {
         "java.util.Spliterator": [
@@ -473,6 +441,9 @@
         "java.util.LongSummaryStatistics": {
           "j$.util.LongSummaryStatistics": "java.util.LongSummaryStatistics"
         },
+        "java.util.stream.Collector": {
+          "j$.util.stream.Collector": "java.util.stream.Collector"
+        },
         "java.util.Optional": {
           "j$.util.Optional": "java.util.Optional"
         }
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 810ea37..4330b97 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -17,6 +17,7 @@
 import com.android.tools.r8.benchmarks.BenchmarkResults;
 import com.android.tools.r8.desugar.desugaredlibrary.jdk11.ConversionConverter;
 import com.android.tools.r8.desugar.desugaredlibrary.jdk11.DesugaredLibraryJDK11Undesugarer;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion;
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
@@ -188,8 +189,8 @@
   public static final Path DESUGARED_JDK_11_LIB_JAR =
       Paths.get(OPEN_JDK_DIR + "desugar_jdk_libs_11/desugar_jdk_libs.jar");
 
-  public static Path getConvertedDesugaredLibConversions() {
-    return ConversionConverter.convertJar(DESUGAR_LIB_CONVERSIONS);
+  public static Path getConvertedDesugaredLibConversions(CustomConversionVersion legacy) {
+    return ConversionConverter.convertJar(DESUGAR_LIB_CONVERSIONS, legacy);
   }
 
   public static Path getUndesugaredJdk11LibJarForTesting() {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvalidTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvalidTest.java
index 6a169bf..505ba43 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvalidTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvalidTest.java
@@ -40,14 +40,16 @@
             DESUGARED_JDK_8_LIB_JAR,
             "desugar_jdk_libs.json",
             AndroidApiLevel.L,
-            LibraryDesugaringSpecification.JDK8_DESCRIPTOR);
+            LibraryDesugaringSpecification.JDK8_DESCRIPTOR,
+            true);
     LibraryDesugaringSpecification jdk11InvalidLib =
         new LibraryDesugaringSpecification(
             "JDK11_INVALID_LIB",
             ToolHelper.getUndesugaredJdk11LibJarForTesting(),
             "jdk11/desugar_jdk_libs.json",
             AndroidApiLevel.L,
-            LibraryDesugaringSpecification.JDK11_DESCRIPTOR);
+            LibraryDesugaringSpecification.JDK11_DESCRIPTOR,
+            false);
     return buildParameters(
         getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build(),
         ImmutableList.of(jdk8InvalidLib, jdk11InvalidLib),
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java
index d303418..2a185ea 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java
@@ -15,7 +15,6 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
 import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import com.android.tools.r8.dex.code.DexInstruction;
@@ -60,7 +59,6 @@
 
   @Test
   public void testEmulatedInterface() throws Exception {
-    new CodeInspector(ToolHelper.getConvertedDesugaredLibConversions());
     Assume.assumeTrue(libraryDesugaringSpecification.hasEmulatedInterfaceDesugaring(parameters));
     CodeInspector inspector =
         testForL8(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
index 66438e9..15f6bef 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
@@ -76,14 +76,16 @@
             DESUGARED_JDK_8_LIB_JAR,
             "desugar_jdk_libs.json",
             AndroidApiLevel.LATEST,
-            LibraryDesugaringSpecification.JDK8_DESCRIPTOR);
+            LibraryDesugaringSpecification.JDK8_DESCRIPTOR,
+            true);
     LibraryDesugaringSpecification jdk11MaxCompileSdk =
         new LibraryDesugaringSpecification(
             "JDK11_MAX",
             ToolHelper.getUndesugaredJdk11LibJarForTesting(),
             "jdk11/desugar_jdk_libs.json",
             AndroidApiLevel.LATEST,
-            LibraryDesugaringSpecification.JDK11_DESCRIPTOR);
+            LibraryDesugaringSpecification.JDK11_DESCRIPTOR,
+            false);
     return buildParameters(
         getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build(),
         ImmutableList.of(JDK8, JDK11, jdk8MaxCompileSdk, jdk11MaxCompileSdk),
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
index e58134c..efee088 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
@@ -6,6 +6,8 @@
 
 import static com.android.tools.r8.ToolHelper.DESUGARED_JDK_8_LIB_JAR;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion.LATEST;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion.LEGACY;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK8;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
@@ -52,7 +54,7 @@
             "JDK8_CL",
             ImmutableSet.of(
                 DESUGARED_JDK_8_LIB_JAR,
-                ToolHelper.getConvertedDesugaredLibConversions(),
+                ToolHelper.getConvertedDesugaredLibConversions(LEGACY),
                 ToolHelper.getCoreLambdaStubs()),
             JDK8.getSpecification(),
             ImmutableSet.of(ToolHelper.getAndroidJar(AndroidApiLevel.O)),
@@ -63,7 +65,7 @@
             "JDK11_CL",
             ImmutableSet.of(
                 ToolHelper.getUndesugaredJdk11LibJarForTesting(),
-                ToolHelper.getConvertedDesugaredLibConversions(),
+                ToolHelper.getConvertedDesugaredLibConversions(LATEST),
                 ToolHelper.getCoreLambdaStubs()),
             JDK11.getSpecification(),
             ImmutableSet.of(ToolHelper.getAndroidJar(AndroidApiLevel.R)),
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java
index 5ccb580..746a1d2 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java
@@ -4,6 +4,9 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.jdk11;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion.LEGACY;
+
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.transformers.ClassFileTransformer;
 import com.android.tools.r8.transformers.MethodTransformer;
@@ -57,6 +60,9 @@
     JAVA_WRAP_CONVERT_OWNER.put(
         "j$/nio/file/attribute/PosixFilePermission",
         "java/nio/file/attribute/PosixFilePermission$EnumConversion");
+    JAVA_WRAP_CONVERT_OWNER.put(
+        "j$/util/stream/Collector$Characteristics",
+        "java/util/stream/Collector$Characteristics$EnumConversion");
 
     J$_WRAP_CONVERT_OWNER.put(
         "j$/nio/file/spi/FileSystemProvider", "java/nio/file/spi/FileSystemProvider$Wrapper");
@@ -85,17 +91,23 @@
     J$_WRAP_CONVERT_OWNER.put(
         "j$/nio/file/attribute/PosixFilePermission",
         "java/nio/file/attribute/PosixFilePermission$EnumConversion");
+    J$_WRAP_CONVERT_OWNER.put(
+        "j$/util/stream/Collector$Characteristics",
+        "java/util/stream/Collector$Characteristics$EnumConversion");
   }
 
-  public static Path convertJar(Path jar) {
+  public static Path convertJar(Path jar, CustomConversionVersion legacy) {
     String fileName = jar.getFileName().toString();
     String newFileName =
-        fileName.substring(0, fileName.length() - ".jar".length()) + "_converted.jar";
+        fileName.substring(0, fileName.length() - ".jar".length())
+            + (legacy == LEGACY ? "_legacy" : "")
+            + "_converted.jar";
     Path convertedJar = jar.getParent().resolve(newFileName);
-    return internalConvert(jar, convertedJar);
+    return internalConvert(jar, convertedJar, legacy);
   }
 
-  private static synchronized Path internalConvert(Path jar, Path convertedJar) {
+  private static synchronized Path internalConvert(
+      Path jar, Path convertedJar, CustomConversionVersion legacy) {
     if (Files.exists(convertedJar)) {
       return convertedJar;
     }
@@ -105,20 +117,26 @@
     try (ZipOutputStream out =
         new ZipOutputStream(
             new BufferedOutputStream(Files.newOutputStream(convertedJar, options)))) {
-      new ConversionConverter().convert(jar, out);
+      new ConversionConverter().convert(jar, out, legacy);
     } catch (IOException e) {
       throw new RuntimeException(e);
     }
     return convertedJar;
   }
 
-  private void convert(Path desugaredLibraryFiles, ZipOutputStream out) throws IOException {
+  private void convert(
+      Path desugaredLibraryFiles, ZipOutputStream out, CustomConversionVersion legacy)
+      throws IOException {
     ZipUtils.iter(
         desugaredLibraryFiles,
         ((entry, input) -> {
           if (!entry.getName().endsWith(".class")) {
             return;
           }
+          if (legacy == LEGACY
+              && (entry.getName().contains("nio.file") || entry.getName().contains("ApiFlips"))) {
+            return;
+          }
           final byte[] bytes = StreamUtils.streamToByteArrayClose(input);
           final byte[] rewrittenBytes =
               transformInvoke(entry.getName().substring(0, entry.getName().length() - 6), bytes);
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/StreamCollectorCharacteristicsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/StreamCollectorCharacteristicsTest.java
new file mode 100644
index 0000000..56bfcd6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/StreamCollectorCharacteristicsTest.java
@@ -0,0 +1,75 @@
+// Copyright (c) 2022, 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.desugaredlibrary.jdk11;
+
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CustomLibrarySpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+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 StreamCollectorCharacteristicsTest extends DesugaredLibraryTestBase {
+
+  private final TestParameters parameters;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+  private final CompilationSpecification compilationSpecification;
+
+  private static final AndroidApiLevel MIN_SUPPORTED = AndroidApiLevel.O;
+  private static final String EXPECTED_RESULT = StringUtils.lines("IDENTITY_FINISH");
+
+  @Parameters(name = "{0}, spec: {1}, {2}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getConversionParametersUpToExcluding(MIN_SUPPORTED),
+        ImmutableList.of(JDK11),
+        DEFAULT_SPECIFICATIONS);
+  }
+
+  public StreamCollectorCharacteristicsTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
+    this.parameters = parameters;
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+    this.compilationSpecification = compilationSpecification;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+        .addProgramClasses(TestClass.class)
+        .addKeepMainRule(TestClass.class)
+        .setCustomLibrarySpecification(
+            new CustomLibrarySpecification(CustomLib.class, MIN_SUPPORTED))
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED_RESULT);
+  }
+
+  public static class CustomLib {
+    public static Collector<?, ?, ?> getCollector() {
+      return Collectors.toList();
+    }
+  }
+
+  public static class TestClass {
+    public static void main(String[] args) {
+      System.out.println(CustomLib.getCollector().characteristics().iterator().next().toString());
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
index d0b9e66..143a52d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
@@ -7,6 +7,8 @@
 import static com.android.tools.r8.ToolHelper.DESUGARED_JDK_8_LIB_JAR;
 import static com.android.tools.r8.ToolHelper.DESUGARED_LIB_RELEASES_DIR;
 import static com.android.tools.r8.ToolHelper.getUndesugaredJdk11LibJarForTesting;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion.LATEST;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion.LEGACY;
 
 import com.android.tools.r8.L8TestBuilder;
 import com.android.tools.r8.TestParameters;
@@ -74,6 +76,11 @@
     }
   }
 
+  public enum CustomConversionVersion {
+    LEGACY,
+    LATEST
+  }
+
   // Main head specifications.
   public static LibraryDesugaringSpecification JDK8 =
       new LibraryDesugaringSpecification(
@@ -81,28 +88,32 @@
           DESUGARED_JDK_8_LIB_JAR,
           "desugar_jdk_libs.json",
           AndroidApiLevel.P,
-          JDK8_DESCRIPTOR);
+          JDK8_DESCRIPTOR,
+          LEGACY);
   public static LibraryDesugaringSpecification JDK11 =
       new LibraryDesugaringSpecification(
           "JDK11",
           getUndesugaredJdk11LibJarForTesting(),
           "jdk11/desugar_jdk_libs.json",
           AndroidApiLevel.R,
-          JDK11_DESCRIPTOR);
+          JDK11_DESCRIPTOR,
+          LATEST);
   public static LibraryDesugaringSpecification JDK11_MINIMAL =
       new LibraryDesugaringSpecification(
           "JDK11_MINIMAL",
           getUndesugaredJdk11LibJarForTesting(),
           "jdk11/desugar_jdk_libs_minimal.json",
           AndroidApiLevel.R,
-          EMPTY_DESCRIPTOR_24);
+          EMPTY_DESCRIPTOR_24,
+          LATEST);
   public static LibraryDesugaringSpecification JDK11_PATH =
       new LibraryDesugaringSpecification(
           "JDK11_PATH",
           getUndesugaredJdk11LibJarForTesting(),
           "jdk11/desugar_jdk_libs_path.json",
           AndroidApiLevel.R,
-          JDK11_PATH_DESCRIPTOR);
+          JDK11_PATH_DESCRIPTOR,
+          LATEST);
 
   // Legacy specifications.
   public static LibraryDesugaringSpecification JDK11_PATH_ALTERNATIVE_3 =
@@ -111,14 +122,16 @@
           getUndesugaredJdk11LibJarForTesting(),
           "jdk11/desugar_jdk_libs_path_alternative_3.json",
           AndroidApiLevel.R,
-          JDK11_PATH_DESCRIPTOR);
+          JDK11_PATH_DESCRIPTOR,
+          LATEST);
   public static LibraryDesugaringSpecification JDK11_CHM_ONLY =
       new LibraryDesugaringSpecification(
           "JDK11_CHM_ONLY",
           getUndesugaredJdk11LibJarForTesting(),
           "jdk11/chm_only_desugar_jdk_libs.json",
           AndroidApiLevel.R,
-          EMPTY_DESCRIPTOR_24);
+          EMPTY_DESCRIPTOR_24,
+          LATEST);
   public static LibraryDesugaringSpecification JDK11_LEGACY =
       new LibraryDesugaringSpecification(
           "JDK11_LEGACY",
@@ -126,7 +139,8 @@
           DESUGARED_JDK_11_LIB_JAR,
           "jdk11/desugar_jdk_libs_legacy.json",
           AndroidApiLevel.R,
-          JDK11_LEGACY_DESCRIPTOR);
+          JDK11_LEGACY_DESCRIPTOR,
+          LEGACY);
   public static final LibraryDesugaringSpecification RELEASED_1_0_9 =
       new LibraryDesugaringSpecification("1.0.9", AndroidApiLevel.P);
   public static final LibraryDesugaringSpecification RELEASED_1_0_10 =
@@ -150,10 +164,11 @@
       Path desugarJdkLibs,
       String specificationPath,
       AndroidApiLevel androidJarLevel,
-      Descriptor descriptor) {
+      Descriptor descriptor,
+      CustomConversionVersion legacy) {
     this(
         name,
-        ImmutableSet.of(desugarJdkLibs, ToolHelper.getConvertedDesugaredLibConversions()),
+        ImmutableSet.of(desugarJdkLibs, ToolHelper.getConvertedDesugaredLibConversions(legacy)),
         Paths.get("src/library_desugar/" + specificationPath),
         ImmutableSet.of(ToolHelper.getAndroidJar(androidJarLevel)),
         descriptor,