diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/.gitignore b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/.gitignore
index 082790e..47fe72c 100644
--- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/.gitignore
+++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/.gitignore
@@ -3,3 +3,4 @@
 # such as a flag to suppress version stamp generation.
 *.java
 !AlternateLanguageTestPlugin.java
+!CoreTests.java
\ No newline at end of file
diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java
new file mode 100644
index 0000000..9c02562
--- /dev/null
+++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java
@@ -0,0 +1,1605 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+package com.example.alternate_language_test_plugin;
+
+import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import io.flutter.plugin.common.BasicMessageChannel;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.MessageCodec;
+import io.flutter.plugin.common.StandardMessageCodec;
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/** Generated class from Pigeon. */
+@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})
+public class CoreTests {
+
+  public enum AnEnum {
+    ONE(0),
+    TWO(1),
+    THREE(2);
+
+    private final int index;
+
+    private AnEnum(final int index) {
+      this.index = index;
+    }
+  }
+
+  /** Generated class from Pigeon that represents data sent in messages. */
+  public static class AllTypes {
+    private @NonNull Boolean aBool;
+
+    public @NonNull Boolean getABool() {
+      return aBool;
+    }
+
+    public void setABool(@NonNull Boolean setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aBool\" is null.");
+      }
+      this.aBool = setterArg;
+    }
+
+    private @NonNull Long anInt;
+
+    public @NonNull Long getAnInt() {
+      return anInt;
+    }
+
+    public void setAnInt(@NonNull Long setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"anInt\" is null.");
+      }
+      this.anInt = setterArg;
+    }
+
+    private @NonNull Double aDouble;
+
+    public @NonNull Double getADouble() {
+      return aDouble;
+    }
+
+    public void setADouble(@NonNull Double setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aDouble\" is null.");
+      }
+      this.aDouble = setterArg;
+    }
+
+    private @NonNull String aString;
+
+    public @NonNull String getAString() {
+      return aString;
+    }
+
+    public void setAString(@NonNull String setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aString\" is null.");
+      }
+      this.aString = setterArg;
+    }
+
+    private @NonNull byte[] aByteArray;
+
+    public @NonNull byte[] getAByteArray() {
+      return aByteArray;
+    }
+
+    public void setAByteArray(@NonNull byte[] setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aByteArray\" is null.");
+      }
+      this.aByteArray = setterArg;
+    }
+
+    private @NonNull int[] a4ByteArray;
+
+    public @NonNull int[] getA4ByteArray() {
+      return a4ByteArray;
+    }
+
+    public void setA4ByteArray(@NonNull int[] setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"a4ByteArray\" is null.");
+      }
+      this.a4ByteArray = setterArg;
+    }
+
+    private @NonNull long[] a8ByteArray;
+
+    public @NonNull long[] getA8ByteArray() {
+      return a8ByteArray;
+    }
+
+    public void setA8ByteArray(@NonNull long[] setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"a8ByteArray\" is null.");
+      }
+      this.a8ByteArray = setterArg;
+    }
+
+    private @NonNull double[] aFloatArray;
+
+    public @NonNull double[] getAFloatArray() {
+      return aFloatArray;
+    }
+
+    public void setAFloatArray(@NonNull double[] setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aFloatArray\" is null.");
+      }
+      this.aFloatArray = setterArg;
+    }
+
+    private @NonNull List<Object> aList;
+
+    public @NonNull List<Object> getAList() {
+      return aList;
+    }
+
+    public void setAList(@NonNull List<Object> setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aList\" is null.");
+      }
+      this.aList = setterArg;
+    }
+
+    private @NonNull Map<Object, Object> aMap;
+
+    public @NonNull Map<Object, Object> getAMap() {
+      return aMap;
+    }
+
+    public void setAMap(@NonNull Map<Object, Object> setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"aMap\" is null.");
+      }
+      this.aMap = setterArg;
+    }
+
+    private @NonNull AnEnum anEnum;
+
+    public @NonNull AnEnum getAnEnum() {
+      return anEnum;
+    }
+
+    public void setAnEnum(@NonNull AnEnum setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"anEnum\" is null.");
+      }
+      this.anEnum = setterArg;
+    }
+
+    /** Constructor is private to enforce null safety; use Builder. */
+    private AllTypes() {}
+
+    public static final class Builder {
+      private @Nullable Boolean aBool;
+
+      public @NonNull Builder setABool(@NonNull Boolean setterArg) {
+        this.aBool = setterArg;
+        return this;
+      }
+
+      private @Nullable Long anInt;
+
+      public @NonNull Builder setAnInt(@NonNull Long setterArg) {
+        this.anInt = setterArg;
+        return this;
+      }
+
+      private @Nullable Double aDouble;
+
+      public @NonNull Builder setADouble(@NonNull Double setterArg) {
+        this.aDouble = setterArg;
+        return this;
+      }
+
+      private @Nullable String aString;
+
+      public @NonNull Builder setAString(@NonNull String setterArg) {
+        this.aString = setterArg;
+        return this;
+      }
+
+      private @Nullable byte[] aByteArray;
+
+      public @NonNull Builder setAByteArray(@NonNull byte[] setterArg) {
+        this.aByteArray = setterArg;
+        return this;
+      }
+
+      private @Nullable int[] a4ByteArray;
+
+      public @NonNull Builder setA4ByteArray(@NonNull int[] setterArg) {
+        this.a4ByteArray = setterArg;
+        return this;
+      }
+
+      private @Nullable long[] a8ByteArray;
+
+      public @NonNull Builder setA8ByteArray(@NonNull long[] setterArg) {
+        this.a8ByteArray = setterArg;
+        return this;
+      }
+
+      private @Nullable double[] aFloatArray;
+
+      public @NonNull Builder setAFloatArray(@NonNull double[] setterArg) {
+        this.aFloatArray = setterArg;
+        return this;
+      }
+
+      private @Nullable List<Object> aList;
+
+      public @NonNull Builder setAList(@NonNull List<Object> setterArg) {
+        this.aList = setterArg;
+        return this;
+      }
+
+      private @Nullable Map<Object, Object> aMap;
+
+      public @NonNull Builder setAMap(@NonNull Map<Object, Object> setterArg) {
+        this.aMap = setterArg;
+        return this;
+      }
+
+      private @Nullable AnEnum anEnum;
+
+      public @NonNull Builder setAnEnum(@NonNull AnEnum setterArg) {
+        this.anEnum = setterArg;
+        return this;
+      }
+
+      public @NonNull AllTypes build() {
+        AllTypes pigeonReturn = new AllTypes();
+        pigeonReturn.setABool(aBool);
+        pigeonReturn.setAnInt(anInt);
+        pigeonReturn.setADouble(aDouble);
+        pigeonReturn.setAString(aString);
+        pigeonReturn.setAByteArray(aByteArray);
+        pigeonReturn.setA4ByteArray(a4ByteArray);
+        pigeonReturn.setA8ByteArray(a8ByteArray);
+        pigeonReturn.setAFloatArray(aFloatArray);
+        pigeonReturn.setAList(aList);
+        pigeonReturn.setAMap(aMap);
+        pigeonReturn.setAnEnum(anEnum);
+        return pigeonReturn;
+      }
+    }
+
+    @NonNull
+    ArrayList<Object> toList() {
+      ArrayList<Object> toListResult = new ArrayList<Object>(11);
+      toListResult.add(aBool);
+      toListResult.add(anInt);
+      toListResult.add(aDouble);
+      toListResult.add(aString);
+      toListResult.add(aByteArray);
+      toListResult.add(a4ByteArray);
+      toListResult.add(a8ByteArray);
+      toListResult.add(aFloatArray);
+      toListResult.add(aList);
+      toListResult.add(aMap);
+      toListResult.add(anEnum == null ? null : anEnum.index);
+      return toListResult;
+    }
+
+    static @NonNull AllTypes fromList(@NonNull ArrayList<Object> list) {
+      AllTypes pigeonResult = new AllTypes();
+      Object aBool = list.get(0);
+      pigeonResult.setABool((Boolean) aBool);
+      Object anInt = list.get(1);
+      pigeonResult.setAnInt(
+          (anInt == null) ? null : ((anInt instanceof Integer) ? (Integer) anInt : (Long) anInt));
+      Object aDouble = list.get(2);
+      pigeonResult.setADouble((Double) aDouble);
+      Object aString = list.get(3);
+      pigeonResult.setAString((String) aString);
+      Object aByteArray = list.get(4);
+      pigeonResult.setAByteArray((byte[]) aByteArray);
+      Object a4ByteArray = list.get(5);
+      pigeonResult.setA4ByteArray((int[]) a4ByteArray);
+      Object a8ByteArray = list.get(6);
+      pigeonResult.setA8ByteArray((long[]) a8ByteArray);
+      Object aFloatArray = list.get(7);
+      pigeonResult.setAFloatArray((double[]) aFloatArray);
+      Object aList = list.get(8);
+      pigeonResult.setAList((List<Object>) aList);
+      Object aMap = list.get(9);
+      pigeonResult.setAMap((Map<Object, Object>) aMap);
+      Object anEnum = list.get(10);
+      pigeonResult.setAnEnum(anEnum == null ? null : AnEnum.values()[(int) anEnum]);
+      return pigeonResult;
+    }
+  }
+
+  /** Generated class from Pigeon that represents data sent in messages. */
+  public static class AllNullableTypes {
+    private @Nullable Boolean aNullableBool;
+
+    public @Nullable Boolean getANullableBool() {
+      return aNullableBool;
+    }
+
+    public void setANullableBool(@Nullable Boolean setterArg) {
+      this.aNullableBool = setterArg;
+    }
+
+    private @Nullable Long aNullableInt;
+
+    public @Nullable Long getANullableInt() {
+      return aNullableInt;
+    }
+
+    public void setANullableInt(@Nullable Long setterArg) {
+      this.aNullableInt = setterArg;
+    }
+
+    private @Nullable Double aNullableDouble;
+
+    public @Nullable Double getANullableDouble() {
+      return aNullableDouble;
+    }
+
+    public void setANullableDouble(@Nullable Double setterArg) {
+      this.aNullableDouble = setterArg;
+    }
+
+    private @Nullable String aNullableString;
+
+    public @Nullable String getANullableString() {
+      return aNullableString;
+    }
+
+    public void setANullableString(@Nullable String setterArg) {
+      this.aNullableString = setterArg;
+    }
+
+    private @Nullable byte[] aNullableByteArray;
+
+    public @Nullable byte[] getANullableByteArray() {
+      return aNullableByteArray;
+    }
+
+    public void setANullableByteArray(@Nullable byte[] setterArg) {
+      this.aNullableByteArray = setterArg;
+    }
+
+    private @Nullable int[] aNullable4ByteArray;
+
+    public @Nullable int[] getANullable4ByteArray() {
+      return aNullable4ByteArray;
+    }
+
+    public void setANullable4ByteArray(@Nullable int[] setterArg) {
+      this.aNullable4ByteArray = setterArg;
+    }
+
+    private @Nullable long[] aNullable8ByteArray;
+
+    public @Nullable long[] getANullable8ByteArray() {
+      return aNullable8ByteArray;
+    }
+
+    public void setANullable8ByteArray(@Nullable long[] setterArg) {
+      this.aNullable8ByteArray = setterArg;
+    }
+
+    private @Nullable double[] aNullableFloatArray;
+
+    public @Nullable double[] getANullableFloatArray() {
+      return aNullableFloatArray;
+    }
+
+    public void setANullableFloatArray(@Nullable double[] setterArg) {
+      this.aNullableFloatArray = setterArg;
+    }
+
+    private @Nullable List<Object> aNullableList;
+
+    public @Nullable List<Object> getANullableList() {
+      return aNullableList;
+    }
+
+    public void setANullableList(@Nullable List<Object> setterArg) {
+      this.aNullableList = setterArg;
+    }
+
+    private @Nullable Map<Object, Object> aNullableMap;
+
+    public @Nullable Map<Object, Object> getANullableMap() {
+      return aNullableMap;
+    }
+
+    public void setANullableMap(@Nullable Map<Object, Object> setterArg) {
+      this.aNullableMap = setterArg;
+    }
+
+    private @Nullable List<List<Boolean>> nullableNestedList;
+
+    public @Nullable List<List<Boolean>> getNullableNestedList() {
+      return nullableNestedList;
+    }
+
+    public void setNullableNestedList(@Nullable List<List<Boolean>> setterArg) {
+      this.nullableNestedList = setterArg;
+    }
+
+    private @Nullable Map<String, String> nullableMapWithAnnotations;
+
+    public @Nullable Map<String, String> getNullableMapWithAnnotations() {
+      return nullableMapWithAnnotations;
+    }
+
+    public void setNullableMapWithAnnotations(@Nullable Map<String, String> setterArg) {
+      this.nullableMapWithAnnotations = setterArg;
+    }
+
+    private @Nullable Map<String, Object> nullableMapWithObject;
+
+    public @Nullable Map<String, Object> getNullableMapWithObject() {
+      return nullableMapWithObject;
+    }
+
+    public void setNullableMapWithObject(@Nullable Map<String, Object> setterArg) {
+      this.nullableMapWithObject = setterArg;
+    }
+
+    private @Nullable AnEnum aNullableEnum;
+
+    public @Nullable AnEnum getANullableEnum() {
+      return aNullableEnum;
+    }
+
+    public void setANullableEnum(@Nullable AnEnum setterArg) {
+      this.aNullableEnum = setterArg;
+    }
+
+    public static final class Builder {
+      private @Nullable Boolean aNullableBool;
+
+      public @NonNull Builder setANullableBool(@Nullable Boolean setterArg) {
+        this.aNullableBool = setterArg;
+        return this;
+      }
+
+      private @Nullable Long aNullableInt;
+
+      public @NonNull Builder setANullableInt(@Nullable Long setterArg) {
+        this.aNullableInt = setterArg;
+        return this;
+      }
+
+      private @Nullable Double aNullableDouble;
+
+      public @NonNull Builder setANullableDouble(@Nullable Double setterArg) {
+        this.aNullableDouble = setterArg;
+        return this;
+      }
+
+      private @Nullable String aNullableString;
+
+      public @NonNull Builder setANullableString(@Nullable String setterArg) {
+        this.aNullableString = setterArg;
+        return this;
+      }
+
+      private @Nullable byte[] aNullableByteArray;
+
+      public @NonNull Builder setANullableByteArray(@Nullable byte[] setterArg) {
+        this.aNullableByteArray = setterArg;
+        return this;
+      }
+
+      private @Nullable int[] aNullable4ByteArray;
+
+      public @NonNull Builder setANullable4ByteArray(@Nullable int[] setterArg) {
+        this.aNullable4ByteArray = setterArg;
+        return this;
+      }
+
+      private @Nullable long[] aNullable8ByteArray;
+
+      public @NonNull Builder setANullable8ByteArray(@Nullable long[] setterArg) {
+        this.aNullable8ByteArray = setterArg;
+        return this;
+      }
+
+      private @Nullable double[] aNullableFloatArray;
+
+      public @NonNull Builder setANullableFloatArray(@Nullable double[] setterArg) {
+        this.aNullableFloatArray = setterArg;
+        return this;
+      }
+
+      private @Nullable List<Object> aNullableList;
+
+      public @NonNull Builder setANullableList(@Nullable List<Object> setterArg) {
+        this.aNullableList = setterArg;
+        return this;
+      }
+
+      private @Nullable Map<Object, Object> aNullableMap;
+
+      public @NonNull Builder setANullableMap(@Nullable Map<Object, Object> setterArg) {
+        this.aNullableMap = setterArg;
+        return this;
+      }
+
+      private @Nullable List<List<Boolean>> nullableNestedList;
+
+      public @NonNull Builder setNullableNestedList(@Nullable List<List<Boolean>> setterArg) {
+        this.nullableNestedList = setterArg;
+        return this;
+      }
+
+      private @Nullable Map<String, String> nullableMapWithAnnotations;
+
+      public @NonNull Builder setNullableMapWithAnnotations(
+          @Nullable Map<String, String> setterArg) {
+        this.nullableMapWithAnnotations = setterArg;
+        return this;
+      }
+
+      private @Nullable Map<String, Object> nullableMapWithObject;
+
+      public @NonNull Builder setNullableMapWithObject(@Nullable Map<String, Object> setterArg) {
+        this.nullableMapWithObject = setterArg;
+        return this;
+      }
+
+      private @Nullable AnEnum aNullableEnum;
+
+      public @NonNull Builder setANullableEnum(@Nullable AnEnum setterArg) {
+        this.aNullableEnum = setterArg;
+        return this;
+      }
+
+      public @NonNull AllNullableTypes build() {
+        AllNullableTypes pigeonReturn = new AllNullableTypes();
+        pigeonReturn.setANullableBool(aNullableBool);
+        pigeonReturn.setANullableInt(aNullableInt);
+        pigeonReturn.setANullableDouble(aNullableDouble);
+        pigeonReturn.setANullableString(aNullableString);
+        pigeonReturn.setANullableByteArray(aNullableByteArray);
+        pigeonReturn.setANullable4ByteArray(aNullable4ByteArray);
+        pigeonReturn.setANullable8ByteArray(aNullable8ByteArray);
+        pigeonReturn.setANullableFloatArray(aNullableFloatArray);
+        pigeonReturn.setANullableList(aNullableList);
+        pigeonReturn.setANullableMap(aNullableMap);
+        pigeonReturn.setNullableNestedList(nullableNestedList);
+        pigeonReturn.setNullableMapWithAnnotations(nullableMapWithAnnotations);
+        pigeonReturn.setNullableMapWithObject(nullableMapWithObject);
+        pigeonReturn.setANullableEnum(aNullableEnum);
+        return pigeonReturn;
+      }
+    }
+
+    @NonNull
+    ArrayList<Object> toList() {
+      ArrayList<Object> toListResult = new ArrayList<Object>(14);
+      toListResult.add(aNullableBool);
+      toListResult.add(aNullableInt);
+      toListResult.add(aNullableDouble);
+      toListResult.add(aNullableString);
+      toListResult.add(aNullableByteArray);
+      toListResult.add(aNullable4ByteArray);
+      toListResult.add(aNullable8ByteArray);
+      toListResult.add(aNullableFloatArray);
+      toListResult.add(aNullableList);
+      toListResult.add(aNullableMap);
+      toListResult.add(nullableNestedList);
+      toListResult.add(nullableMapWithAnnotations);
+      toListResult.add(nullableMapWithObject);
+      toListResult.add(aNullableEnum == null ? null : aNullableEnum.index);
+      return toListResult;
+    }
+
+    static @NonNull AllNullableTypes fromList(@NonNull ArrayList<Object> list) {
+      AllNullableTypes pigeonResult = new AllNullableTypes();
+      Object aNullableBool = list.get(0);
+      pigeonResult.setANullableBool((Boolean) aNullableBool);
+      Object aNullableInt = list.get(1);
+      pigeonResult.setANullableInt(
+          (aNullableInt == null)
+              ? null
+              : ((aNullableInt instanceof Integer) ? (Integer) aNullableInt : (Long) aNullableInt));
+      Object aNullableDouble = list.get(2);
+      pigeonResult.setANullableDouble((Double) aNullableDouble);
+      Object aNullableString = list.get(3);
+      pigeonResult.setANullableString((String) aNullableString);
+      Object aNullableByteArray = list.get(4);
+      pigeonResult.setANullableByteArray((byte[]) aNullableByteArray);
+      Object aNullable4ByteArray = list.get(5);
+      pigeonResult.setANullable4ByteArray((int[]) aNullable4ByteArray);
+      Object aNullable8ByteArray = list.get(6);
+      pigeonResult.setANullable8ByteArray((long[]) aNullable8ByteArray);
+      Object aNullableFloatArray = list.get(7);
+      pigeonResult.setANullableFloatArray((double[]) aNullableFloatArray);
+      Object aNullableList = list.get(8);
+      pigeonResult.setANullableList((List<Object>) aNullableList);
+      Object aNullableMap = list.get(9);
+      pigeonResult.setANullableMap((Map<Object, Object>) aNullableMap);
+      Object nullableNestedList = list.get(10);
+      pigeonResult.setNullableNestedList((List<List<Boolean>>) nullableNestedList);
+      Object nullableMapWithAnnotations = list.get(11);
+      pigeonResult.setNullableMapWithAnnotations((Map<String, String>) nullableMapWithAnnotations);
+      Object nullableMapWithObject = list.get(12);
+      pigeonResult.setNullableMapWithObject((Map<String, Object>) nullableMapWithObject);
+      Object aNullableEnum = list.get(13);
+      pigeonResult.setANullableEnum(
+          aNullableEnum == null ? null : AnEnum.values()[(int) aNullableEnum]);
+      return pigeonResult;
+    }
+  }
+
+  /** Generated class from Pigeon that represents data sent in messages. */
+  public static class AllNullableTypesWrapper {
+    private @NonNull AllNullableTypes values;
+
+    public @NonNull AllNullableTypes getValues() {
+      return values;
+    }
+
+    public void setValues(@NonNull AllNullableTypes setterArg) {
+      if (setterArg == null) {
+        throw new IllegalStateException("Nonnull field \"values\" is null.");
+      }
+      this.values = setterArg;
+    }
+
+    /** Constructor is private to enforce null safety; use Builder. */
+    private AllNullableTypesWrapper() {}
+
+    public static final class Builder {
+      private @Nullable AllNullableTypes values;
+
+      public @NonNull Builder setValues(@NonNull AllNullableTypes setterArg) {
+        this.values = setterArg;
+        return this;
+      }
+
+      public @NonNull AllNullableTypesWrapper build() {
+        AllNullableTypesWrapper pigeonReturn = new AllNullableTypesWrapper();
+        pigeonReturn.setValues(values);
+        return pigeonReturn;
+      }
+    }
+
+    @NonNull
+    ArrayList<Object> toList() {
+      ArrayList<Object> toListResult = new ArrayList<Object>(1);
+      toListResult.add((values == null) ? null : values.toList());
+      return toListResult;
+    }
+
+    static @NonNull AllNullableTypesWrapper fromList(@NonNull ArrayList<Object> list) {
+      AllNullableTypesWrapper pigeonResult = new AllNullableTypesWrapper();
+      Object values = list.get(0);
+      pigeonResult.setValues(
+          (values == null) ? null : AllNullableTypes.fromList((ArrayList<Object>) values));
+      return pigeonResult;
+    }
+  }
+
+  public interface Result<T> {
+    void success(T result);
+
+    void error(Throwable error);
+  }
+
+  private static class HostIntegrationCoreApiCodec extends StandardMessageCodec {
+    public static final HostIntegrationCoreApiCodec INSTANCE = new HostIntegrationCoreApiCodec();
+
+    private HostIntegrationCoreApiCodec() {}
+
+    @Override
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
+      switch (type) {
+        case (byte) 128:
+          return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
+
+        case (byte) 129:
+          return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
+
+        case (byte) 130:
+          return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));
+
+        case (byte) 131:
+          return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
+
+        default:
+          return super.readValueOfType(type, buffer);
+      }
+    }
+
+    @Override
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
+      if (value instanceof AllNullableTypes) {
+        stream.write(128);
+        writeValue(stream, ((AllNullableTypes) value).toList());
+      } else if (value instanceof AllNullableTypes) {
+        stream.write(129);
+        writeValue(stream, ((AllNullableTypes) value).toList());
+      } else if (value instanceof AllNullableTypesWrapper) {
+        stream.write(130);
+        writeValue(stream, ((AllNullableTypesWrapper) value).toList());
+      } else if (value instanceof AllTypes) {
+        stream.write(131);
+        writeValue(stream, ((AllTypes) value).toList());
+      } else {
+        super.writeValue(stream, value);
+      }
+    }
+  }
+
+  /**
+   * The core interface that each host language plugin must implement in platform_test integration
+   * tests.
+   *
+   * <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
+   */
+  public interface HostIntegrationCoreApi {
+    /**
+     * A no-op function taking no arguments and returning no value, to sanity test basic calling.
+     */
+    void noop();
+    /** Returns the passed object, to test serialization and deserialization. */
+    @NonNull
+    AllTypes echoAllTypes(@NonNull AllTypes everything);
+    /** Returns the passed object, to test serialization and deserialization. */
+    @Nullable
+    AllNullableTypes echoAllNullableTypes(@Nullable AllNullableTypes everything);
+    /** Returns an error, to test error handling. */
+    void throwError();
+    /** Returns passed in int. */
+    @NonNull
+    Long echoInt(@NonNull Long anInt);
+    /** Returns passed in double. */
+    @NonNull
+    Double echoDouble(@NonNull Double aDouble);
+    /** Returns the passed in boolean. */
+    @NonNull
+    Boolean echoBool(@NonNull Boolean aBool);
+    /** Returns the passed in string. */
+    @NonNull
+    String echoString(@NonNull String aString);
+    /** Returns the passed in Uint8List. */
+    @NonNull
+    byte[] echoUint8List(@NonNull byte[] aUint8List);
+    /**
+     * Returns the inner `aString` value from the wrapped object, to test sending of nested objects.
+     */
+    @Nullable
+    String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper);
+    /**
+     * Returns the inner `aString` value from the wrapped object, to test sending of nested objects.
+     */
+    @NonNull
+    AllNullableTypesWrapper createNestedNullableString(@Nullable String nullableString);
+    /** Returns passed in arguments of multiple types. */
+    @NonNull
+    AllNullableTypes sendMultipleNullableTypes(
+        @Nullable Boolean aNullableBool,
+        @Nullable Long aNullableInt,
+        @Nullable String aNullableString);
+    /** Returns passed in int. */
+    @Nullable
+    Long echoNullableInt(@Nullable Long aNullableInt);
+    /** Returns passed in double. */
+    @Nullable
+    Double echoNullableDouble(@Nullable Double aNullableDouble);
+    /** Returns the passed in boolean. */
+    @Nullable
+    Boolean echoNullableBool(@Nullable Boolean aNullableBool);
+    /** Returns the passed in string. */
+    @Nullable
+    String echoNullableString(@Nullable String aNullableString);
+    /** Returns the passed in Uint8List. */
+    @Nullable
+    byte[] echoNullableUint8List(@Nullable byte[] aNullableUint8List);
+    /**
+     * A no-op function taking no arguments and returning no value, to sanity test basic
+     * asynchronous calling.
+     */
+    void noopAsync(Result<Void> result);
+    /** Returns the passed string asynchronously. */
+    void echoAsyncString(@NonNull String aString, Result<String> result);
+
+    void callFlutterNoop(Result<Void> result);
+
+    void callFlutterEchoString(@NonNull String aString, Result<String> result);
+
+    /** The codec used by HostIntegrationCoreApi. */
+    static MessageCodec<Object> getCodec() {
+      return HostIntegrationCoreApiCodec.INSTANCE;
+    }
+    /**
+     * Sets up an instance of `HostIntegrationCoreApi` to handle messages through the
+     * `binaryMessenger`.
+     */
+    static void setup(BinaryMessenger binaryMessenger, HostIntegrationCoreApi api) {
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop", getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  api.noop();
+                  wrapped.add(0, null);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  AllTypes everythingArg = (AllTypes) args.get(0);
+                  if (everythingArg == null) {
+                    throw new NullPointerException("everythingArg unexpectedly null.");
+                  }
+                  AllTypes output = api.echoAllTypes(everythingArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  AllNullableTypes everythingArg = (AllNullableTypes) args.get(0);
+                  AllNullableTypes output = api.echoAllNullableTypes(everythingArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.throwError",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  api.throwError();
+                  wrapped.add(0, null);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Number anIntArg = (Number) args.get(0);
+                  if (anIntArg == null) {
+                    throw new NullPointerException("anIntArg unexpectedly null.");
+                  }
+                  Long output = api.echoInt((anIntArg == null) ? null : anIntArg.longValue());
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Double aDoubleArg = (Double) args.get(0);
+                  if (aDoubleArg == null) {
+                    throw new NullPointerException("aDoubleArg unexpectedly null.");
+                  }
+                  Double output = api.echoDouble(aDoubleArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Boolean aBoolArg = (Boolean) args.get(0);
+                  if (aBoolArg == null) {
+                    throw new NullPointerException("aBoolArg unexpectedly null.");
+                  }
+                  Boolean output = api.echoBool(aBoolArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoString",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  String aStringArg = (String) args.get(0);
+                  if (aStringArg == null) {
+                    throw new NullPointerException("aStringArg unexpectedly null.");
+                  }
+                  String output = api.echoString(aStringArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  byte[] aUint8ListArg = (byte[]) args.get(0);
+                  if (aUint8ListArg == null) {
+                    throw new NullPointerException("aUint8ListArg unexpectedly null.");
+                  }
+                  byte[] output = api.echoUint8List(aUint8ListArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  AllNullableTypesWrapper wrapperArg = (AllNullableTypesWrapper) args.get(0);
+                  if (wrapperArg == null) {
+                    throw new NullPointerException("wrapperArg unexpectedly null.");
+                  }
+                  String output = api.extractNestedNullableString(wrapperArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  String nullableStringArg = (String) args.get(0);
+                  AllNullableTypesWrapper output =
+                      api.createNestedNullableString(nullableStringArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Boolean aNullableBoolArg = (Boolean) args.get(0);
+                  Number aNullableIntArg = (Number) args.get(1);
+                  String aNullableStringArg = (String) args.get(2);
+                  AllNullableTypes output =
+                      api.sendMultipleNullableTypes(
+                          aNullableBoolArg,
+                          (aNullableIntArg == null) ? null : aNullableIntArg.longValue(),
+                          aNullableStringArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Number aNullableIntArg = (Number) args.get(0);
+                  Long output =
+                      api.echoNullableInt(
+                          (aNullableIntArg == null) ? null : aNullableIntArg.longValue());
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Double aNullableDoubleArg = (Double) args.get(0);
+                  Double output = api.echoNullableDouble(aNullableDoubleArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Boolean aNullableBoolArg = (Boolean) args.get(0);
+                  Boolean output = api.echoNullableBool(aNullableBoolArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  String aNullableStringArg = (String) args.get(0);
+                  String output = api.echoNullableString(aNullableStringArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  byte[] aNullableUint8ListArg = (byte[]) args.get(0);
+                  byte[] output = api.echoNullableUint8List(aNullableUint8ListArg);
+                  wrapped.add(0, output);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  Result<Void> resultCallback =
+                      new Result<Void>() {
+                        public void success(Void result) {
+                          wrapped.add(0, null);
+                          reply.reply(wrapped);
+                        }
+
+                        public void error(Throwable error) {
+                          ArrayList<Object> wrappedError = wrapError(error);
+                          reply.reply(wrappedError);
+                        }
+                      };
+
+                  api.noopAsync(resultCallback);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  reply.reply(wrappedError);
+                }
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  String aStringArg = (String) args.get(0);
+                  if (aStringArg == null) {
+                    throw new NullPointerException("aStringArg unexpectedly null.");
+                  }
+                  Result<String> resultCallback =
+                      new Result<String>() {
+                        public void success(String result) {
+                          wrapped.add(0, result);
+                          reply.reply(wrapped);
+                        }
+
+                        public void error(Throwable error) {
+                          ArrayList<Object> wrappedError = wrapError(error);
+                          reply.reply(wrappedError);
+                        }
+                      };
+
+                  api.echoAsyncString(aStringArg, resultCallback);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  reply.reply(wrappedError);
+                }
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  Result<Void> resultCallback =
+                      new Result<Void>() {
+                        public void success(Void result) {
+                          wrapped.add(0, null);
+                          reply.reply(wrapped);
+                        }
+
+                        public void error(Throwable error) {
+                          ArrayList<Object> wrappedError = wrapError(error);
+                          reply.reply(wrappedError);
+                        }
+                      };
+
+                  api.callFlutterNoop(resultCallback);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  reply.reply(wrappedError);
+                }
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  String aStringArg = (String) args.get(0);
+                  if (aStringArg == null) {
+                    throw new NullPointerException("aStringArg unexpectedly null.");
+                  }
+                  Result<String> resultCallback =
+                      new Result<String>() {
+                        public void success(String result) {
+                          wrapped.add(0, result);
+                          reply.reply(wrapped);
+                        }
+
+                        public void error(Throwable error) {
+                          ArrayList<Object> wrappedError = wrapError(error);
+                          reply.reply(wrappedError);
+                        }
+                      };
+
+                  api.callFlutterEchoString(aStringArg, resultCallback);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  reply.reply(wrappedError);
+                }
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+    }
+  }
+
+  private static class FlutterIntegrationCoreApiCodec extends StandardMessageCodec {
+    public static final FlutterIntegrationCoreApiCodec INSTANCE =
+        new FlutterIntegrationCoreApiCodec();
+
+    private FlutterIntegrationCoreApiCodec() {}
+
+    @Override
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
+      switch (type) {
+        case (byte) 128:
+          return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
+
+        case (byte) 129:
+          return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
+
+        default:
+          return super.readValueOfType(type, buffer);
+      }
+    }
+
+    @Override
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
+      if (value instanceof AllNullableTypes) {
+        stream.write(128);
+        writeValue(stream, ((AllNullableTypes) value).toList());
+      } else if (value instanceof AllTypes) {
+        stream.write(129);
+        writeValue(stream, ((AllTypes) value).toList());
+      } else {
+        super.writeValue(stream, value);
+      }
+    }
+  }
+
+  /**
+   * The core interface that the Dart platform_test code implements for host integration tests to
+   * call into.
+   *
+   * <p>Generated class from Pigeon that represents Flutter messages that can be called from Java.
+   */
+  public static class FlutterIntegrationCoreApi {
+    private final BinaryMessenger binaryMessenger;
+
+    public FlutterIntegrationCoreApi(BinaryMessenger argBinaryMessenger) {
+      this.binaryMessenger = argBinaryMessenger;
+    }
+
+    public interface Reply<T> {
+      void reply(T reply);
+    }
+    /** The codec used by FlutterIntegrationCoreApi. */
+    static MessageCodec<Object> getCodec() {
+      return FlutterIntegrationCoreApiCodec.INSTANCE;
+    }
+    /**
+     * A no-op function taking no arguments and returning no value, to sanity test basic calling.
+     */
+    public void noop(Reply<Void> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", getCodec());
+      channel.send(
+          null,
+          channelReply -> {
+            callback.reply(null);
+          });
+    }
+    /** Returns the passed object, to test serialization and deserialization. */
+    public void echoAllTypes(@NonNull AllTypes everythingArg, Reply<AllTypes> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(everythingArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            AllTypes output = (AllTypes) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed object, to test serialization and deserialization. */
+    public void echoAllNullableTypes(
+        @NonNull AllNullableTypes everythingArg, Reply<AllNullableTypes> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(everythingArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            AllNullableTypes output = (AllNullableTypes) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed string, to test serialization and deserialization. */
+    public void echoString(@NonNull String aStringArg, Reply<String> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aStringArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            String output = (String) channelReply;
+            callback.reply(output);
+          });
+    }
+  }
+  /**
+   * An API that can be implemented for minimal, compile-only tests.
+   *
+   * <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
+   */
+  public interface HostTrivialApi {
+    void noop();
+
+    /** The codec used by HostTrivialApi. */
+    static MessageCodec<Object> getCodec() {
+      return new StandardMessageCodec();
+    }
+    /** Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`. */
+    static void setup(BinaryMessenger binaryMessenger, HostTrivialApi api) {
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger, "dev.flutter.pigeon.HostTrivialApi.noop", getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                ArrayList wrapped = new ArrayList<>();
+                try {
+                  api.noop();
+                  wrapped.add(0, null);
+                } catch (Error | RuntimeException exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+    }
+  }
+
+  @NonNull
+  private static ArrayList<Object> wrapError(@NonNull Throwable exception) {
+    ArrayList<Object> errorList = new ArrayList<>(3);
+    errorList.add(exception.toString());
+    errorList.add(exception.getClass().getSimpleName());
+    errorList.add(
+        "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception));
+    return errorList;
+  }
+}
diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/.gitignore b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/.gitignore
index 7ebd556..a00d32b 100644
--- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/.gitignore
+++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/.gitignore
@@ -3,3 +3,4 @@
 # such as a flag to suppress version stamp generation.
 *.gen.h
 *.gen.m
+!CoreTests.gen.*
\ No newline at end of file
diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h
new file mode 100644
index 0000000..80a40d5
--- /dev/null
+++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h
@@ -0,0 +1,214 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+#import <Foundation/Foundation.h>
+@protocol FlutterBinaryMessenger;
+@protocol FlutterMessageCodec;
+@class FlutterError;
+@class FlutterStandardTypedData;
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSUInteger, AnEnum) {
+  AnEnumOne = 0,
+  AnEnumTwo = 1,
+  AnEnumThree = 2,
+};
+
+@class AllTypes;
+@class AllNullableTypes;
+@class AllNullableTypesWrapper;
+
+@interface AllTypes : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithABool:(NSNumber *)aBool
+                        anInt:(NSNumber *)anInt
+                      aDouble:(NSNumber *)aDouble
+                      aString:(NSString *)aString
+                   aByteArray:(FlutterStandardTypedData *)aByteArray
+                  a4ByteArray:(FlutterStandardTypedData *)a4ByteArray
+                  a8ByteArray:(FlutterStandardTypedData *)a8ByteArray
+                  aFloatArray:(FlutterStandardTypedData *)aFloatArray
+                        aList:(NSArray *)aList
+                         aMap:(NSDictionary *)aMap
+                       anEnum:(AnEnum)anEnum;
+@property(nonatomic, strong) NSNumber *aBool;
+@property(nonatomic, strong) NSNumber *anInt;
+@property(nonatomic, strong) NSNumber *aDouble;
+@property(nonatomic, copy) NSString *aString;
+@property(nonatomic, strong) FlutterStandardTypedData *aByteArray;
+@property(nonatomic, strong) FlutterStandardTypedData *a4ByteArray;
+@property(nonatomic, strong) FlutterStandardTypedData *a8ByteArray;
+@property(nonatomic, strong) FlutterStandardTypedData *aFloatArray;
+@property(nonatomic, strong) NSArray *aList;
+@property(nonatomic, strong) NSDictionary *aMap;
+@property(nonatomic, assign) AnEnum anEnum;
+@end
+
+@interface AllNullableTypes : NSObject
++ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool
+                         aNullableInt:(nullable NSNumber *)aNullableInt
+                      aNullableDouble:(nullable NSNumber *)aNullableDouble
+                      aNullableString:(nullable NSString *)aNullableString
+                   aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray
+                  aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray
+                  aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray
+                  aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray
+                        aNullableList:(nullable NSArray *)aNullableList
+                         aNullableMap:(nullable NSDictionary *)aNullableMap
+                   nullableNestedList:(nullable NSArray<NSArray<NSNumber *> *> *)nullableNestedList
+           nullableMapWithAnnotations:
+               (nullable NSDictionary<NSString *, NSString *> *)nullableMapWithAnnotations
+                nullableMapWithObject:(nullable NSDictionary<NSString *, id> *)nullableMapWithObject
+                        aNullableEnum:(AnEnum)aNullableEnum;
+@property(nonatomic, strong, nullable) NSNumber *aNullableBool;
+@property(nonatomic, strong, nullable) NSNumber *aNullableInt;
+@property(nonatomic, strong, nullable) NSNumber *aNullableDouble;
+@property(nonatomic, copy, nullable) NSString *aNullableString;
+@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableByteArray;
+@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray;
+@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray;
+@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray;
+@property(nonatomic, strong, nullable) NSArray *aNullableList;
+@property(nonatomic, strong, nullable) NSDictionary *aNullableMap;
+@property(nonatomic, strong, nullable) NSArray<NSArray<NSNumber *> *> *nullableNestedList;
+@property(nonatomic, strong, nullable)
+    NSDictionary<NSString *, NSString *> *nullableMapWithAnnotations;
+@property(nonatomic, strong, nullable) NSDictionary<NSString *, id> *nullableMapWithObject;
+@property(nonatomic, assign) AnEnum aNullableEnum;
+@end
+
+@interface AllNullableTypesWrapper : NSObject
+/// `init` unavailable to enforce nonnull fields, see the `make` class method.
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)makeWithValues:(AllNullableTypes *)values;
+@property(nonatomic, strong) AllNullableTypes *values;
+@end
+
+/// The codec used by HostIntegrationCoreApi.
+NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec(void);
+
+/// The core interface that each host language plugin must implement in
+/// platform_test integration tests.
+@protocol HostIntegrationCoreApi
+/// A no-op function taking no arguments and returning no value, to sanity
+/// test basic calling.
+- (void)noopWithError:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed object, to test serialization and deserialization.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable AllTypes *)echoAllTypes:(AllTypes *)everything
+                              error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed object, to test serialization and deserialization.
+- (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything
+                                              error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns an error, to test error handling.
+- (void)throwErrorWithError:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns passed in int.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable NSNumber *)echoInt:(NSNumber *)anInt error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns passed in double.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable NSNumber *)echoDouble:(NSNumber *)aDouble
+                            error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed in boolean.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable NSNumber *)echoBool:(NSNumber *)aBool error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed in string.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable NSString *)echoString:(NSString *)aString
+                            error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed in Uint8List.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable FlutterStandardTypedData *)echoUint8List:(FlutterStandardTypedData *)aUint8List
+                                               error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the inner `aString` value from the wrapped object, to test
+/// sending of nested objects.
+- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper
+                                                 error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the inner `aString` value from the wrapped object, to test
+/// sending of nested objects.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable AllNullableTypesWrapper *)
+    createNestedObjectWithNullableString:(nullable NSString *)nullableString
+                                   error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns passed in arguments of multiple types.
+///
+/// @return `nil` only when `error != nil`.
+- (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool
+                                                        anInt:(nullable NSNumber *)aNullableInt
+                                                      aString:(nullable NSString *)aNullableString
+                                                        error:(FlutterError *_Nullable *_Nonnull)
+                                                                  error;
+/// Returns passed in int.
+- (nullable NSNumber *)echoNullableInt:(nullable NSNumber *)aNullableInt
+                                 error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns passed in double.
+- (nullable NSNumber *)echoNullableDouble:(nullable NSNumber *)aNullableDouble
+                                    error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed in boolean.
+- (nullable NSNumber *)echoNullableBool:(nullable NSNumber *)aNullableBool
+                                  error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed in string.
+- (nullable NSString *)echoNullableString:(nullable NSString *)aNullableString
+                                    error:(FlutterError *_Nullable *_Nonnull)error;
+/// Returns the passed in Uint8List.
+- (nullable FlutterStandardTypedData *)
+    echoNullableUint8List:(nullable FlutterStandardTypedData *)aNullableUint8List
+                    error:(FlutterError *_Nullable *_Nonnull)error;
+/// A no-op function taking no arguments and returning no value, to sanity
+/// test basic asynchronous calling.
+- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion;
+/// Returns the passed string asynchronously.
+- (void)echoAsyncString:(NSString *)aString
+             completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion;
+- (void)callFlutterNoopWithCompletion:(void (^)(FlutterError *_Nullable))completion;
+- (void)callFlutterEchoString:(NSString *)aString
+                   completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion;
+@end
+
+extern void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                                        NSObject<HostIntegrationCoreApi> *_Nullable api);
+
+/// The codec used by FlutterIntegrationCoreApi.
+NSObject<FlutterMessageCodec> *FlutterIntegrationCoreApiGetCodec(void);
+
+/// The core interface that the Dart platform_test code implements for host
+/// integration tests to call into.
+@interface FlutterIntegrationCoreApi : NSObject
+- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger;
+/// A no-op function taking no arguments and returning no value, to sanity
+/// test basic calling.
+- (void)noopWithCompletion:(void (^)(NSError *_Nullable))completion;
+/// Returns the passed object, to test serialization and deserialization.
+- (void)echoAllTypes:(AllTypes *)everything
+          completion:(void (^)(AllTypes *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed object, to test serialization and deserialization.
+- (void)echoAllNullableTypes:(AllNullableTypes *)everything
+                  completion:(void (^)(AllNullableTypes *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed string, to test serialization and deserialization.
+- (void)echoString:(NSString *)aString
+        completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion;
+@end
+/// The codec used by HostTrivialApi.
+NSObject<FlutterMessageCodec> *HostTrivialApiGetCodec(void);
+
+/// An API that can be implemented for minimal, compile-only tests.
+@protocol HostTrivialApi
+- (void)noopWithError:(FlutterError *_Nullable *_Nonnull)error;
+@end
+
+extern void HostTrivialApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                                NSObject<HostTrivialApi> *_Nullable api);
+
+NS_ASSUME_NONNULL_END
diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m
new file mode 100644
index 0000000..adb33d0
--- /dev/null
+++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m
@@ -0,0 +1,885 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+#import "CoreTests.gen.h"
+#import <Flutter/Flutter.h>
+
+#if !__has_feature(objc_arc)
+#error File requires ARC to be enabled.
+#endif
+
+static NSArray *wrapResult(id result, FlutterError *error) {
+  if (error) {
+    return @[
+      error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null]
+    ];
+  }
+  return @[ result ?: [NSNull null] ];
+}
+static id GetNullableObject(NSDictionary *dict, id key) {
+  id result = dict[key];
+  return (result == [NSNull null]) ? nil : result;
+}
+static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
+  id result = array[key];
+  return (result == [NSNull null]) ? nil : result;
+}
+
+@interface AllTypes ()
++ (AllTypes *)fromList:(NSArray *)list;
++ (nullable AllTypes *)nullableFromList:(NSArray *)list;
+- (NSArray *)toList;
+@end
+@interface AllNullableTypes ()
++ (AllNullableTypes *)fromList:(NSArray *)list;
++ (nullable AllNullableTypes *)nullableFromList:(NSArray *)list;
+- (NSArray *)toList;
+@end
+@interface AllNullableTypesWrapper ()
++ (AllNullableTypesWrapper *)fromList:(NSArray *)list;
++ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list;
+- (NSArray *)toList;
+@end
+
+@implementation AllTypes
++ (instancetype)makeWithABool:(NSNumber *)aBool
+                        anInt:(NSNumber *)anInt
+                      aDouble:(NSNumber *)aDouble
+                      aString:(NSString *)aString
+                   aByteArray:(FlutterStandardTypedData *)aByteArray
+                  a4ByteArray:(FlutterStandardTypedData *)a4ByteArray
+                  a8ByteArray:(FlutterStandardTypedData *)a8ByteArray
+                  aFloatArray:(FlutterStandardTypedData *)aFloatArray
+                        aList:(NSArray *)aList
+                         aMap:(NSDictionary *)aMap
+                       anEnum:(AnEnum)anEnum {
+  AllTypes *pigeonResult = [[AllTypes alloc] init];
+  pigeonResult.aBool = aBool;
+  pigeonResult.anInt = anInt;
+  pigeonResult.aDouble = aDouble;
+  pigeonResult.aString = aString;
+  pigeonResult.aByteArray = aByteArray;
+  pigeonResult.a4ByteArray = a4ByteArray;
+  pigeonResult.a8ByteArray = a8ByteArray;
+  pigeonResult.aFloatArray = aFloatArray;
+  pigeonResult.aList = aList;
+  pigeonResult.aMap = aMap;
+  pigeonResult.anEnum = anEnum;
+  return pigeonResult;
+}
++ (AllTypes *)fromList:(NSArray *)list {
+  AllTypes *pigeonResult = [[AllTypes alloc] init];
+  pigeonResult.aBool = GetNullableObjectAtIndex(list, 0);
+  NSAssert(pigeonResult.aBool != nil, @"");
+  pigeonResult.anInt = GetNullableObjectAtIndex(list, 1);
+  NSAssert(pigeonResult.anInt != nil, @"");
+  pigeonResult.aDouble = GetNullableObjectAtIndex(list, 2);
+  NSAssert(pigeonResult.aDouble != nil, @"");
+  pigeonResult.aString = GetNullableObjectAtIndex(list, 3);
+  NSAssert(pigeonResult.aString != nil, @"");
+  pigeonResult.aByteArray = GetNullableObjectAtIndex(list, 4);
+  NSAssert(pigeonResult.aByteArray != nil, @"");
+  pigeonResult.a4ByteArray = GetNullableObjectAtIndex(list, 5);
+  NSAssert(pigeonResult.a4ByteArray != nil, @"");
+  pigeonResult.a8ByteArray = GetNullableObjectAtIndex(list, 6);
+  NSAssert(pigeonResult.a8ByteArray != nil, @"");
+  pigeonResult.aFloatArray = GetNullableObjectAtIndex(list, 7);
+  NSAssert(pigeonResult.aFloatArray != nil, @"");
+  pigeonResult.aList = GetNullableObjectAtIndex(list, 8);
+  NSAssert(pigeonResult.aList != nil, @"");
+  pigeonResult.aMap = GetNullableObjectAtIndex(list, 9);
+  NSAssert(pigeonResult.aMap != nil, @"");
+  pigeonResult.anEnum = [GetNullableObjectAtIndex(list, 10) integerValue];
+  return pigeonResult;
+}
++ (nullable AllTypes *)nullableFromList:(NSArray *)list {
+  return (list) ? [AllTypes fromList:list] : nil;
+}
+- (NSArray *)toList {
+  return @[
+    (self.aBool ?: [NSNull null]),
+    (self.anInt ?: [NSNull null]),
+    (self.aDouble ?: [NSNull null]),
+    (self.aString ?: [NSNull null]),
+    (self.aByteArray ?: [NSNull null]),
+    (self.a4ByteArray ?: [NSNull null]),
+    (self.a8ByteArray ?: [NSNull null]),
+    (self.aFloatArray ?: [NSNull null]),
+    (self.aList ?: [NSNull null]),
+    (self.aMap ?: [NSNull null]),
+    @(self.anEnum),
+  ];
+}
+@end
+
+@implementation AllNullableTypes
++ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool
+                         aNullableInt:(nullable NSNumber *)aNullableInt
+                      aNullableDouble:(nullable NSNumber *)aNullableDouble
+                      aNullableString:(nullable NSString *)aNullableString
+                   aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray
+                  aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray
+                  aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray
+                  aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray
+                        aNullableList:(nullable NSArray *)aNullableList
+                         aNullableMap:(nullable NSDictionary *)aNullableMap
+                   nullableNestedList:(nullable NSArray<NSArray<NSNumber *> *> *)nullableNestedList
+           nullableMapWithAnnotations:
+               (nullable NSDictionary<NSString *, NSString *> *)nullableMapWithAnnotations
+                nullableMapWithObject:(nullable NSDictionary<NSString *, id> *)nullableMapWithObject
+                        aNullableEnum:(AnEnum)aNullableEnum {
+  AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init];
+  pigeonResult.aNullableBool = aNullableBool;
+  pigeonResult.aNullableInt = aNullableInt;
+  pigeonResult.aNullableDouble = aNullableDouble;
+  pigeonResult.aNullableString = aNullableString;
+  pigeonResult.aNullableByteArray = aNullableByteArray;
+  pigeonResult.aNullable4ByteArray = aNullable4ByteArray;
+  pigeonResult.aNullable8ByteArray = aNullable8ByteArray;
+  pigeonResult.aNullableFloatArray = aNullableFloatArray;
+  pigeonResult.aNullableList = aNullableList;
+  pigeonResult.aNullableMap = aNullableMap;
+  pigeonResult.nullableNestedList = nullableNestedList;
+  pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations;
+  pigeonResult.nullableMapWithObject = nullableMapWithObject;
+  pigeonResult.aNullableEnum = aNullableEnum;
+  return pigeonResult;
+}
++ (AllNullableTypes *)fromList:(NSArray *)list {
+  AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init];
+  pigeonResult.aNullableBool = GetNullableObjectAtIndex(list, 0);
+  pigeonResult.aNullableInt = GetNullableObjectAtIndex(list, 1);
+  pigeonResult.aNullableDouble = GetNullableObjectAtIndex(list, 2);
+  pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 3);
+  pigeonResult.aNullableByteArray = GetNullableObjectAtIndex(list, 4);
+  pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5);
+  pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6);
+  pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7);
+  pigeonResult.aNullableList = GetNullableObjectAtIndex(list, 8);
+  pigeonResult.aNullableMap = GetNullableObjectAtIndex(list, 9);
+  pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 10);
+  pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 11);
+  pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 12);
+  pigeonResult.aNullableEnum = [GetNullableObjectAtIndex(list, 13) integerValue];
+  return pigeonResult;
+}
++ (nullable AllNullableTypes *)nullableFromList:(NSArray *)list {
+  return (list) ? [AllNullableTypes fromList:list] : nil;
+}
+- (NSArray *)toList {
+  return @[
+    (self.aNullableBool ?: [NSNull null]),
+    (self.aNullableInt ?: [NSNull null]),
+    (self.aNullableDouble ?: [NSNull null]),
+    (self.aNullableString ?: [NSNull null]),
+    (self.aNullableByteArray ?: [NSNull null]),
+    (self.aNullable4ByteArray ?: [NSNull null]),
+    (self.aNullable8ByteArray ?: [NSNull null]),
+    (self.aNullableFloatArray ?: [NSNull null]),
+    (self.aNullableList ?: [NSNull null]),
+    (self.aNullableMap ?: [NSNull null]),
+    (self.nullableNestedList ?: [NSNull null]),
+    (self.nullableMapWithAnnotations ?: [NSNull null]),
+    (self.nullableMapWithObject ?: [NSNull null]),
+    @(self.aNullableEnum),
+  ];
+}
+@end
+
+@implementation AllNullableTypesWrapper
++ (instancetype)makeWithValues:(AllNullableTypes *)values {
+  AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init];
+  pigeonResult.values = values;
+  return pigeonResult;
+}
++ (AllNullableTypesWrapper *)fromList:(NSArray *)list {
+  AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init];
+  pigeonResult.values = [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))];
+  NSAssert(pigeonResult.values != nil, @"");
+  return pigeonResult;
+}
++ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list {
+  return (list) ? [AllNullableTypesWrapper fromList:list] : nil;
+}
+- (NSArray *)toList {
+  return @[
+    (self.values ? [self.values toList] : [NSNull null]),
+  ];
+}
+@end
+
+@interface HostIntegrationCoreApiCodecReader : FlutterStandardReader
+@end
+@implementation HostIntegrationCoreApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+  switch (type) {
+    case 128:
+      return [AllNullableTypes fromList:[self readValue]];
+
+    case 129:
+      return [AllNullableTypes fromList:[self readValue]];
+
+    case 130:
+      return [AllNullableTypesWrapper fromList:[self readValue]];
+
+    case 131:
+      return [AllTypes fromList:[self readValue]];
+
+    default:
+      return [super readValueOfType:type];
+  }
+}
+@end
+
+@interface HostIntegrationCoreApiCodecWriter : FlutterStandardWriter
+@end
+@implementation HostIntegrationCoreApiCodecWriter
+- (void)writeValue:(id)value {
+  if ([value isKindOfClass:[AllNullableTypes class]]) {
+    [self writeByte:128];
+    [self writeValue:[value toList]];
+  } else if ([value isKindOfClass:[AllNullableTypes class]]) {
+    [self writeByte:129];
+    [self writeValue:[value toList]];
+  } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) {
+    [self writeByte:130];
+    [self writeValue:[value toList]];
+  } else if ([value isKindOfClass:[AllTypes class]]) {
+    [self writeByte:131];
+    [self writeValue:[value toList]];
+  } else {
+    [super writeValue:value];
+  }
+}
+@end
+
+@interface HostIntegrationCoreApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation HostIntegrationCoreApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+  return [[HostIntegrationCoreApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+  return [[HostIntegrationCoreApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec() {
+  static FlutterStandardMessageCodec *sSharedObject = nil;
+  static dispatch_once_t sPred = 0;
+  dispatch_once(&sPred, ^{
+    HostIntegrationCoreApiCodecReaderWriter *readerWriter =
+        [[HostIntegrationCoreApiCodecReaderWriter alloc] init];
+    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+  });
+  return sSharedObject;
+}
+
+void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                                 NSObject<HostIntegrationCoreApi> *api) {
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic calling.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.noop"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(noopWithError:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(noopWithError:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        [api noopWithError:&error];
+        callback(wrapResult(nil, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed object, to test serialization and deserialization.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(echoAllTypes:error:)],
+          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoAllTypes:error:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        AllTypes *arg_everything = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        AllTypes *output = [api echoAllTypes:arg_everything error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed object, to test serialization and deserialization.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoAllNullableTypes:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(echoAllNullableTypes:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        AllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        AllNullableTypes *output = [api echoAllNullableTypes:arg_everything error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns an error, to test error handling.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.throwError"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(throwErrorWithError:)],
+          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(throwErrorWithError:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        [api throwErrorWithError:&error];
+        callback(wrapResult(nil, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns passed in int.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoInt"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoInt:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoInt:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSNumber *output = [api echoInt:arg_anInt error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns passed in double.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoDouble:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoDouble:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSNumber *output = [api echoDouble:arg_aDouble error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed in boolean.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoBool"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoBool:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoBool:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSNumber *output = [api echoBool:arg_aBool error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed in string.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoString"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoString:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoString:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSString *output = [api echoString:arg_aString error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed in Uint8List.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(echoUint8List:error:)],
+          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoUint8List:error:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        FlutterStandardTypedData *output = [api echoUint8List:arg_aUint8List error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the inner `aString` value from the wrapped object, to test
+  /// sending of nested objects.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(extractNestedNullableStringFrom:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(extractNestedNullableStringFrom:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        AllNullableTypesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the inner `aString` value from the wrapped object, to test
+  /// sending of nested objects.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(createNestedObjectWithNullableString:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(createNestedObjectWithNullableString:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        AllNullableTypesWrapper *output =
+            [api createNestedObjectWithNullableString:arg_nullableString error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns passed in arguments of multiple types.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(sendMultipleNullableTypesABool:
+                                                                           anInt:aString:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(sendMultipleNullableTypesABool:anInt:aString:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0);
+        NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1);
+        NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2);
+        FlutterError *error;
+        AllNullableTypes *output = [api sendMultipleNullableTypesABool:arg_aNullableBool
+                                                                 anInt:arg_aNullableInt
+                                                               aString:arg_aNullableString
+                                                                 error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns passed in int.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(echoNullableInt:error:)],
+          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableInt:error:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSNumber *output = [api echoNullableInt:arg_aNullableInt error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns passed in double.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoNullableDouble:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(echoNullableDouble:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_aNullableDouble = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSNumber *output = [api echoNullableDouble:arg_aNullableDouble error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed in boolean.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(echoNullableBool:error:)],
+          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableBool:error:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSNumber *output = [api echoNullableBool:arg_aNullableBool error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed in string.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoNullableString:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(echoNullableString:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        NSString *output = [api echoNullableString:arg_aNullableString error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed in Uint8List.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoNullableUint8List:error:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(echoNullableUint8List:error:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        FlutterStandardTypedData *arg_aNullableUint8List = GetNullableObjectAtIndex(args, 0);
+        FlutterError *error;
+        FlutterStandardTypedData *output = [api echoNullableUint8List:arg_aNullableUint8List
+                                                                error:&error];
+        callback(wrapResult(output, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic asynchronous calling.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert(
+          [api respondsToSelector:@selector(noopAsyncWithCompletion:)],
+          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(noopAsyncWithCompletion:)",
+          api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        [api noopAsyncWithCompletion:^(FlutterError *_Nullable error) {
+          callback(wrapResult(nil, error));
+        }];
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  /// Returns the passed string asynchronously.
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(echoAsyncString:completion:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(echoAsyncString:completion:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
+        [api echoAsyncString:arg_aString
+                  completion:^(NSString *_Nullable output, FlutterError *_Nullable error) {
+                    callback(wrapResult(output, error));
+                  }];
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(callFlutterNoopWithCompletion:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(callFlutterNoopWithCompletion:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        [api callFlutterNoopWithCompletion:^(FlutterError *_Nullable error) {
+          callback(wrapResult(nil, error));
+        }];
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+  {
+    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
+           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString"
+        binaryMessenger:binaryMessenger
+                  codec:HostIntegrationCoreApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(callFlutterEchoString:completion:)],
+                @"HostIntegrationCoreApi api (%@) doesn't respond to "
+                @"@selector(callFlutterEchoString:completion:)",
+                api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        NSArray *args = message;
+        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
+        [api callFlutterEchoString:arg_aString
+                        completion:^(NSString *_Nullable output, FlutterError *_Nullable error) {
+                          callback(wrapResult(output, error));
+                        }];
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+}
+@interface FlutterIntegrationCoreApiCodecReader : FlutterStandardReader
+@end
+@implementation FlutterIntegrationCoreApiCodecReader
+- (nullable id)readValueOfType:(UInt8)type {
+  switch (type) {
+    case 128:
+      return [AllNullableTypes fromList:[self readValue]];
+
+    case 129:
+      return [AllTypes fromList:[self readValue]];
+
+    default:
+      return [super readValueOfType:type];
+  }
+}
+@end
+
+@interface FlutterIntegrationCoreApiCodecWriter : FlutterStandardWriter
+@end
+@implementation FlutterIntegrationCoreApiCodecWriter
+- (void)writeValue:(id)value {
+  if ([value isKindOfClass:[AllNullableTypes class]]) {
+    [self writeByte:128];
+    [self writeValue:[value toList]];
+  } else if ([value isKindOfClass:[AllTypes class]]) {
+    [self writeByte:129];
+    [self writeValue:[value toList]];
+  } else {
+    [super writeValue:value];
+  }
+}
+@end
+
+@interface FlutterIntegrationCoreApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation FlutterIntegrationCoreApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+  return [[FlutterIntegrationCoreApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+  return [[FlutterIntegrationCoreApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject<FlutterMessageCodec> *FlutterIntegrationCoreApiGetCodec() {
+  static FlutterStandardMessageCodec *sSharedObject = nil;
+  static dispatch_once_t sPred = 0;
+  dispatch_once(&sPred, ^{
+    FlutterIntegrationCoreApiCodecReaderWriter *readerWriter =
+        [[FlutterIntegrationCoreApiCodecReaderWriter alloc] init];
+    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+  });
+  return sSharedObject;
+}
+
+@interface FlutterIntegrationCoreApi ()
+@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
+@end
+
+@implementation FlutterIntegrationCoreApi
+
+- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
+  self = [super init];
+  if (self) {
+    _binaryMessenger = binaryMessenger;
+  }
+  return self;
+}
+- (void)noopWithCompletion:(void (^)(NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.noop"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:nil
+                 reply:^(id reply) {
+                   completion(nil);
+                 }];
+}
+- (void)echoAllTypes:(AllTypes *)arg_everything
+          completion:(void (^)(AllTypes *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_everything ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   AllTypes *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoAllNullableTypes:(AllNullableTypes *)arg_everything
+                  completion:(void (^)(AllNullableTypes *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_everything ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   AllNullableTypes *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoString:(NSString *)arg_aString
+        completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aString ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSString *output = reply;
+                   completion(output, nil);
+                 }];
+}
+@end
+NSObject<FlutterMessageCodec> *HostTrivialApiGetCodec() {
+  static FlutterStandardMessageCodec *sSharedObject = nil;
+  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
+  return sSharedObject;
+}
+
+void HostTrivialApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+                         NSObject<HostTrivialApi> *api) {
+  {
+    FlutterBasicMessageChannel *channel =
+        [[FlutterBasicMessageChannel alloc] initWithName:@"dev.flutter.pigeon.HostTrivialApi.noop"
+                                         binaryMessenger:binaryMessenger
+                                                   codec:HostTrivialApiGetCodec()];
+    if (api) {
+      NSCAssert([api respondsToSelector:@selector(noopWithError:)],
+                @"HostTrivialApi api (%@) doesn't respond to @selector(noopWithError:)", api);
+      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+        FlutterError *error;
+        [api noopWithError:&error];
+        callback(wrapResult(nil, error));
+      }];
+    } else {
+      [channel setMessageHandler:nil];
+    }
+  }
+}
diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore
index c69837a..a870aa1 100644
--- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore
+++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/.gitignore
@@ -3,3 +3,4 @@
 # such as a flag to suppress version stamp generation.
 *.kt
 !TestPlugin.kt
+!CoreTests.gen.kt
\ No newline at end of file
diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt
new file mode 100644
index 0000000..bcd41b0
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt
@@ -0,0 +1,793 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// 
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+package com.example.test_plugin
+
+import android.util.Log
+import io.flutter.plugin.common.BasicMessageChannel
+import io.flutter.plugin.common.BinaryMessenger
+import io.flutter.plugin.common.MessageCodec
+import io.flutter.plugin.common.StandardMessageCodec
+import java.io.ByteArrayOutputStream
+import java.nio.ByteBuffer
+
+/** Generated class from Pigeon. */
+
+enum class AnEnum(val raw: Int) {
+  ONE(0),
+  TWO(1),
+  THREE(2);
+
+  companion object {
+    fun ofRaw(raw: Int): AnEnum? {
+      return values().firstOrNull { it.raw == raw }
+    }
+  }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class AllTypes (
+  val aBool: Boolean,
+  val anInt: Long,
+  val aDouble: Double,
+  val aString: String,
+  val aByteArray: ByteArray,
+  val a4ByteArray: IntArray,
+  val a8ByteArray: LongArray,
+  val aFloatArray: DoubleArray,
+  val aList: List<Any?>,
+  val aMap: Map<Any, Any?>,
+  val anEnum: AnEnum
+
+) {
+  companion object {
+    @Suppress("UNCHECKED_CAST")
+    fun fromList(list: List<Any?>): AllTypes {
+      val aBool = list[0] as Boolean
+      val anInt = list[1] as Long
+      val aDouble = list[2] as Double
+      val aString = list[3] as String
+      val aByteArray = list[4] as ByteArray
+      val a4ByteArray = list[5] as IntArray
+      val a8ByteArray = list[6] as LongArray
+      val aFloatArray = list[7] as DoubleArray
+      val aList = list[8] as List<Any?>
+      val aMap = list[9] as Map<Any, Any?>
+      val anEnum = AnEnum.ofRaw(list[10] as Int)!!
+      return AllTypes(aBool, anInt, aDouble, aString, aByteArray, a4ByteArray, a8ByteArray, aFloatArray, aList, aMap, anEnum)
+    }
+  }
+  fun toList(): List<Any?> {
+    return listOf<Any?>(
+      aBool,
+      anInt,
+      aDouble,
+      aString,
+      aByteArray,
+      a4ByteArray,
+      a8ByteArray,
+      aFloatArray,
+      aList,
+      aMap,
+      anEnum?.raw,
+    )
+  }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class AllNullableTypes (
+  val aNullableBool: Boolean? = null,
+  val aNullableInt: Long? = null,
+  val aNullableDouble: Double? = null,
+  val aNullableString: String? = null,
+  val aNullableByteArray: ByteArray? = null,
+  val aNullable4ByteArray: IntArray? = null,
+  val aNullable8ByteArray: LongArray? = null,
+  val aNullableFloatArray: DoubleArray? = null,
+  val aNullableList: List<Any?>? = null,
+  val aNullableMap: Map<Any, Any?>? = null,
+  val nullableNestedList: List<List<Boolean?>?>? = null,
+  val nullableMapWithAnnotations: Map<String?, String?>? = null,
+  val nullableMapWithObject: Map<String?, Any?>? = null,
+  val aNullableEnum: AnEnum? = null
+
+) {
+  companion object {
+    @Suppress("UNCHECKED_CAST")
+    fun fromList(list: List<Any?>): AllNullableTypes {
+      val aNullableBool = list[0] as? Boolean
+      val aNullableInt = list[1].let { if (it is Int) it.toLong() else it as? Long }
+      val aNullableDouble = list[2] as? Double
+      val aNullableString = list[3] as? String
+      val aNullableByteArray = list[4] as? ByteArray
+      val aNullable4ByteArray = list[5] as? IntArray
+      val aNullable8ByteArray = list[6] as? LongArray
+      val aNullableFloatArray = list[7] as? DoubleArray
+      val aNullableList = list[8] as? List<Any?>
+      val aNullableMap = list[9] as? Map<Any, Any?>
+      val nullableNestedList = list[10] as? List<List<Boolean?>?>
+      val nullableMapWithAnnotations = list[11] as? Map<String?, String?>
+      val nullableMapWithObject = list[12] as? Map<String?, Any?>
+      val aNullableEnum: AnEnum? = (list[13] as? Int)?.let {
+        AnEnum.ofRaw(it)
+      }
+
+      return AllNullableTypes(aNullableBool, aNullableInt, aNullableDouble, aNullableString, aNullableByteArray, aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, aNullableList, aNullableMap, nullableNestedList, nullableMapWithAnnotations, nullableMapWithObject, aNullableEnum)
+    }
+  }
+  fun toList(): List<Any?> {
+    return listOf<Any?>(
+      aNullableBool,
+      aNullableInt,
+      aNullableDouble,
+      aNullableString,
+      aNullableByteArray,
+      aNullable4ByteArray,
+      aNullable8ByteArray,
+      aNullableFloatArray,
+      aNullableList,
+      aNullableMap,
+      nullableNestedList,
+      nullableMapWithAnnotations,
+      nullableMapWithObject,
+      aNullableEnum?.raw,
+    )
+  }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class AllNullableTypesWrapper (
+  val values: AllNullableTypes
+
+) {
+  companion object {
+    @Suppress("UNCHECKED_CAST")
+    fun fromList(list: List<Any?>): AllNullableTypesWrapper {
+      val values = AllNullableTypes.fromList(list[0] as List<Any?>)
+
+      return AllNullableTypesWrapper(values)
+    }
+  }
+  fun toList(): List<Any?> {
+    return listOf<Any?>(
+      values?.toList(),
+    )
+  }
+}
+
+@Suppress("UNCHECKED_CAST")
+private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
+  override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
+    return when (type) {
+      128.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
+          AllNullableTypes.fromList(it)
+        }
+      }
+      129.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
+          AllNullableTypes.fromList(it)
+        }
+      }
+      130.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
+          AllNullableTypesWrapper.fromList(it)
+        }
+      }
+      131.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
+          AllTypes.fromList(it)
+        }
+      }
+      else -> super.readValueOfType(type, buffer)
+    }
+  }
+  override fun writeValue(stream: ByteArrayOutputStream, value: Any?)   {
+    when (value) {
+      is AllNullableTypes -> {
+        stream.write(128)
+        writeValue(stream, value.toList())
+      }
+      is AllNullableTypes -> {
+        stream.write(129)
+        writeValue(stream, value.toList())
+      }
+      is AllNullableTypesWrapper -> {
+        stream.write(130)
+        writeValue(stream, value.toList())
+      }
+      is AllTypes -> {
+        stream.write(131)
+        writeValue(stream, value.toList())
+      }
+      else -> super.writeValue(stream, value)
+    }
+  }
+}
+
+/**
+ * The core interface that each host language plugin must implement in
+ * platform_test integration tests.
+ *
+ * Generated interface from Pigeon that represents a handler of messages from Flutter.
+ */
+interface HostIntegrationCoreApi {
+  /**
+   * A no-op function taking no arguments and returning no value, to sanity
+   * test basic calling.
+   */
+  fun noop()
+  /** Returns the passed object, to test serialization and deserialization. */
+  fun echoAllTypes(everything: AllTypes): AllTypes
+  /** Returns the passed object, to test serialization and deserialization. */
+  fun echoAllNullableTypes(everything: AllNullableTypes?): AllNullableTypes?
+  /** Returns an error, to test error handling. */
+  fun throwError()
+  /** Returns passed in int. */
+  fun echoInt(anInt: Long): Long
+  /** Returns passed in double. */
+  fun echoDouble(aDouble: Double): Double
+  /** Returns the passed in boolean. */
+  fun echoBool(aBool: Boolean): Boolean
+  /** Returns the passed in string. */
+  fun echoString(aString: String): String
+  /** Returns the passed in Uint8List. */
+  fun echoUint8List(aUint8List: ByteArray): ByteArray
+  /**
+   * Returns the inner `aString` value from the wrapped object, to test
+   * sending of nested objects.
+   */
+  fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String?
+  /**
+   * Returns the inner `aString` value from the wrapped object, to test
+   * sending of nested objects.
+   */
+  fun createNestedNullableString(nullableString: String?): AllNullableTypesWrapper
+  /** Returns passed in arguments of multiple types. */
+  fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes
+  /** Returns passed in int. */
+  fun echoNullableInt(aNullableInt: Long?): Long?
+  /** Returns passed in double. */
+  fun echoNullableDouble(aNullableDouble: Double?): Double?
+  /** Returns the passed in boolean. */
+  fun echoNullableBool(aNullableBool: Boolean?): Boolean?
+  /** Returns the passed in string. */
+  fun echoNullableString(aNullableString: String?): String?
+  /** Returns the passed in Uint8List. */
+  fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray?
+  /**
+   * A no-op function taking no arguments and returning no value, to sanity
+   * test basic asynchronous calling.
+   */
+  fun noopAsync(callback: () -> Unit)
+  /** Returns the passed string asynchronously. */
+  fun echoAsyncString(aString: String, callback: (String) -> Unit)
+  fun callFlutterNoop(callback: () -> Unit)
+  fun callFlutterEchoString(aString: String, callback: (String) -> Unit)
+
+  companion object {
+    /** The codec used by HostIntegrationCoreApi. */
+    val codec: MessageCodec<Any?> by lazy {
+      HostIntegrationCoreApiCodec
+    }
+    /** Sets up an instance of `HostIntegrationCoreApi` to handle messages through the `binaryMessenger`. */
+    @Suppress("UNCHECKED_CAST")
+    fun setUp(binaryMessenger: BinaryMessenger, api: HostIntegrationCoreApi?) {
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop", codec)
+        if (api != null) {
+          channel.setMessageHandler { _, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              api.noop()
+              wrapped = listOf<Any?>(null)
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val everythingArg = args[0] as AllTypes
+              wrapped = listOf<Any?>(api.echoAllTypes(everythingArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val everythingArg = args[0] as? AllNullableTypes
+              wrapped = listOf<Any?>(api.echoAllNullableTypes(everythingArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", codec)
+        if (api != null) {
+          channel.setMessageHandler { _, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              api.throwError()
+              wrapped = listOf<Any?>(null)
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val anIntArg = args[0].let { if (it is Int) it.toLong() else it as Long }
+              wrapped = listOf<Any?>(api.echoInt(anIntArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aDoubleArg = args[0] as Double
+              wrapped = listOf<Any?>(api.echoDouble(aDoubleArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aBoolArg = args[0] as Boolean
+              wrapped = listOf<Any?>(api.echoBool(aBoolArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aStringArg = args[0] as String
+              wrapped = listOf<Any?>(api.echoString(aStringArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aUint8ListArg = args[0] as ByteArray
+              wrapped = listOf<Any?>(api.echoUint8List(aUint8ListArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val wrapperArg = args[0] as AllNullableTypesWrapper
+              wrapped = listOf<Any?>(api.extractNestedNullableString(wrapperArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val nullableStringArg = args[0] as? String
+              wrapped = listOf<Any?>(api.createNestedNullableString(nullableStringArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aNullableBoolArg = args[0] as? Boolean
+              val aNullableIntArg = args[1].let { if (it is Int) it.toLong() else it as? Long }
+              val aNullableStringArg = args[2] as? String
+              wrapped = listOf<Any?>(api.sendMultipleNullableTypes(aNullableBoolArg, aNullableIntArg, aNullableStringArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aNullableIntArg = args[0].let { if (it is Int) it.toLong() else it as? Long }
+              wrapped = listOf<Any?>(api.echoNullableInt(aNullableIntArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aNullableDoubleArg = args[0] as? Double
+              wrapped = listOf<Any?>(api.echoNullableDouble(aNullableDoubleArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aNullableBoolArg = args[0] as? Boolean
+              wrapped = listOf<Any?>(api.echoNullableBool(aNullableBoolArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aNullableStringArg = args[0] as? String
+              wrapped = listOf<Any?>(api.echoNullableString(aNullableStringArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aNullableUint8ListArg = args[0] as? ByteArray
+              wrapped = listOf<Any?>(api.echoNullableUint8List(aNullableUint8ListArg))
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", codec)
+        if (api != null) {
+          channel.setMessageHandler { _, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              api.noopAsync() {
+                reply.reply(wrapResult(null))
+              }
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+              reply.reply(wrapped)
+            }
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aStringArg = args[0] as String
+              api.echoAsyncString(aStringArg) {
+                reply.reply(wrapResult(it))
+              }
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+              reply.reply(wrapped)
+            }
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop", codec)
+        if (api != null) {
+          channel.setMessageHandler { _, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              api.callFlutterNoop() {
+                reply.reply(wrapResult(null))
+              }
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+              reply.reply(wrapped)
+            }
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString", codec)
+        if (api != null) {
+          channel.setMessageHandler { message, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              val args = message as List<Any?>
+              val aStringArg = args[0] as String
+              api.callFlutterEchoString(aStringArg) {
+                reply.reply(wrapResult(it))
+              }
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+              reply.reply(wrapped)
+            }
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+    }
+  }
+}
+@Suppress("UNCHECKED_CAST")
+private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() {
+  override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
+    return when (type) {
+      128.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
+          AllNullableTypes.fromList(it)
+        }
+      }
+      129.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
+          AllTypes.fromList(it)
+        }
+      }
+      else -> super.readValueOfType(type, buffer)
+    }
+  }
+  override fun writeValue(stream: ByteArrayOutputStream, value: Any?)   {
+    when (value) {
+      is AllNullableTypes -> {
+        stream.write(128)
+        writeValue(stream, value.toList())
+      }
+      is AllTypes -> {
+        stream.write(129)
+        writeValue(stream, value.toList())
+      }
+      else -> super.writeValue(stream, value)
+    }
+  }
+}
+
+/**
+ * The core interface that the Dart platform_test code implements for host
+ * integration tests to call into.
+ *
+ * Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.
+ */
+@Suppress("UNCHECKED_CAST")
+class FlutterIntegrationCoreApi(private val binaryMessenger: BinaryMessenger) {
+  companion object {
+    /** The codec used by FlutterIntegrationCoreApi. */
+    val codec: MessageCodec<Any?> by lazy {
+      FlutterIntegrationCoreApiCodec
+    }
+  }
+  /**
+   * A no-op function taking no arguments and returning no value, to sanity
+   * test basic calling.
+   */
+  fun noop(callback: () -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", codec)
+    channel.send(null) {
+      callback()
+    }
+  }
+  /** Returns the passed object, to test serialization and deserialization. */
+  fun echoAllTypes(everythingArg: AllTypes, callback: (AllTypes) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", codec)
+    channel.send(listOf(everythingArg)) {
+      val result = it as AllTypes
+      callback(result)
+    }
+  }
+  /** Returns the passed object, to test serialization and deserialization. */
+  fun echoAllNullableTypes(everythingArg: AllNullableTypes, callback: (AllNullableTypes) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes", codec)
+    channel.send(listOf(everythingArg)) {
+      val result = it as AllNullableTypes
+      callback(result)
+    }
+  }
+  /** Returns the passed string, to test serialization and deserialization. */
+  fun echoString(aStringArg: String, callback: (String) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", codec)
+    channel.send(listOf(aStringArg)) {
+      val result = it as String
+      callback(result)
+    }
+  }
+}
+/**
+ * An API that can be implemented for minimal, compile-only tests.
+ *
+ * Generated interface from Pigeon that represents a handler of messages from Flutter.
+ */
+interface HostTrivialApi {
+  fun noop()
+
+  companion object {
+    /** The codec used by HostTrivialApi. */
+    val codec: MessageCodec<Any?> by lazy {
+      StandardMessageCodec()
+    }
+    /** Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`. */
+    @Suppress("UNCHECKED_CAST")
+    fun setUp(binaryMessenger: BinaryMessenger, api: HostTrivialApi?) {
+      run {
+        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostTrivialApi.noop", codec)
+        if (api != null) {
+          channel.setMessageHandler { _, reply ->
+            var wrapped = listOf<Any?>()
+            try {
+              api.noop()
+              wrapped = listOf<Any?>(null)
+            } catch (exception: Error) {
+              wrapped = wrapError(exception)
+            }
+            reply.reply(wrapped)
+          }
+        } else {
+          channel.setMessageHandler(null)
+        }
+      }
+    }
+  }
+}
+
+private fun wrapResult(result: Any?): List<Any?> {
+  return listOf(result)
+}
+
+private fun wrapError(exception: Throwable): List<Any> {
+  return listOf<Any>(
+    exception.javaClass.simpleName,
+    exception.toString(),
+    "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
+  )
+}
diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore b/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore
index ebbbb45..65eaa14 100644
--- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore
+++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/.gitignore
@@ -2,3 +2,4 @@
 # changes on generated files. This will need a way to avoid unnecessary churn,
 # such as a flag to suppress version stamp generation.
 *.gen.swift
+!CoreTests.gen.swift
\ No newline at end of file
diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift
new file mode 100644
index 0000000..385b507
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift
@@ -0,0 +1,657 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// 
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+import Foundation
+#if os(iOS)
+import Flutter
+#elseif os(macOS)
+import FlutterMacOS
+#else
+#error("Unsupported platform.")
+#endif
+
+
+/// Generated class from Pigeon.
+
+enum AnEnum: Int {
+  case one = 0
+  case two = 1
+  case three = 2
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct AllTypes {
+  var aBool: Bool
+  var anInt: Int32
+  var aDouble: Double
+  var aString: String
+  var aByteArray: FlutterStandardTypedData
+  var a4ByteArray: FlutterStandardTypedData
+  var a8ByteArray: FlutterStandardTypedData
+  var aFloatArray: FlutterStandardTypedData
+  var aList: [Any?]
+  var aMap: [AnyHashable: Any?]
+  var anEnum: AnEnum
+
+  static func fromList(_ list: [Any?]) -> AllTypes? {
+    let aBool = list[0] as! Bool
+    let anInt = list[1] as! Int32
+    let aDouble = list[2] as! Double
+    let aString = list[3] as! String
+    let aByteArray = list[4] as! FlutterStandardTypedData
+    let a4ByteArray = list[5] as! FlutterStandardTypedData
+    let a8ByteArray = list[6] as! FlutterStandardTypedData
+    let aFloatArray = list[7] as! FlutterStandardTypedData
+    let aList = list[8] as! [Any?]
+    let aMap = list[9] as! [AnyHashable: Any?]
+    let anEnum = AnEnum(rawValue: list[10] as! Int)!
+
+    return AllTypes(
+      aBool: aBool,
+      anInt: anInt,
+      aDouble: aDouble,
+      aString: aString,
+      aByteArray: aByteArray,
+      a4ByteArray: a4ByteArray,
+      a8ByteArray: a8ByteArray,
+      aFloatArray: aFloatArray,
+      aList: aList,
+      aMap: aMap,
+      anEnum: anEnum
+    )
+  }
+  func toList() -> [Any?] {
+    return [
+      aBool,
+      anInt,
+      aDouble,
+      aString,
+      aByteArray,
+      a4ByteArray,
+      a8ByteArray,
+      aFloatArray,
+      aList,
+      aMap,
+      anEnum.rawValue,
+    ]
+  }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct AllNullableTypes {
+  var aNullableBool: Bool? = nil
+  var aNullableInt: Int32? = nil
+  var aNullableDouble: Double? = nil
+  var aNullableString: String? = nil
+  var aNullableByteArray: FlutterStandardTypedData? = nil
+  var aNullable4ByteArray: FlutterStandardTypedData? = nil
+  var aNullable8ByteArray: FlutterStandardTypedData? = nil
+  var aNullableFloatArray: FlutterStandardTypedData? = nil
+  var aNullableList: [Any?]? = nil
+  var aNullableMap: [AnyHashable: Any?]? = nil
+  var nullableNestedList: [[Bool?]?]? = nil
+  var nullableMapWithAnnotations: [String?: String?]? = nil
+  var nullableMapWithObject: [String?: Any?]? = nil
+  var aNullableEnum: AnEnum? = nil
+
+  static func fromList(_ list: [Any?]) -> AllNullableTypes? {
+    let aNullableBool = list[0] as? Bool 
+    let aNullableInt = list[1] as? Int32 
+    let aNullableDouble = list[2] as? Double 
+    let aNullableString = list[3] as? String 
+    let aNullableByteArray = list[4] as? FlutterStandardTypedData 
+    let aNullable4ByteArray = list[5] as? FlutterStandardTypedData 
+    let aNullable8ByteArray = list[6] as? FlutterStandardTypedData 
+    let aNullableFloatArray = list[7] as? FlutterStandardTypedData 
+    let aNullableList = list[8] as? [Any?] 
+    let aNullableMap = list[9] as? [AnyHashable: Any?] 
+    let nullableNestedList = list[10] as? [[Bool?]?] 
+    let nullableMapWithAnnotations = list[11] as? [String?: String?] 
+    let nullableMapWithObject = list[12] as? [String?: Any?] 
+    var aNullableEnum: AnEnum? = nil
+    if let aNullableEnumRawValue = list[13] as? Int {
+      aNullableEnum = AnEnum(rawValue: aNullableEnumRawValue)
+    }
+
+    return AllNullableTypes(
+      aNullableBool: aNullableBool,
+      aNullableInt: aNullableInt,
+      aNullableDouble: aNullableDouble,
+      aNullableString: aNullableString,
+      aNullableByteArray: aNullableByteArray,
+      aNullable4ByteArray: aNullable4ByteArray,
+      aNullable8ByteArray: aNullable8ByteArray,
+      aNullableFloatArray: aNullableFloatArray,
+      aNullableList: aNullableList,
+      aNullableMap: aNullableMap,
+      nullableNestedList: nullableNestedList,
+      nullableMapWithAnnotations: nullableMapWithAnnotations,
+      nullableMapWithObject: nullableMapWithObject,
+      aNullableEnum: aNullableEnum
+    )
+  }
+  func toList() -> [Any?] {
+    return [
+      aNullableBool,
+      aNullableInt,
+      aNullableDouble,
+      aNullableString,
+      aNullableByteArray,
+      aNullable4ByteArray,
+      aNullable8ByteArray,
+      aNullableFloatArray,
+      aNullableList,
+      aNullableMap,
+      nullableNestedList,
+      nullableMapWithAnnotations,
+      nullableMapWithObject,
+      aNullableEnum?.rawValue,
+    ]
+  }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct AllNullableTypesWrapper {
+  var values: AllNullableTypes
+
+  static func fromList(_ list: [Any?]) -> AllNullableTypesWrapper? {
+    let values = AllNullableTypes.fromList(list[0] as! [Any?])!
+
+    return AllNullableTypesWrapper(
+      values: values
+    )
+  }
+  func toList() -> [Any?] {
+    return [
+      values.toList(),
+    ]
+  }
+}
+
+private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
+  override func readValue(ofType type: UInt8) -> Any? {
+    switch type {
+      case 128:
+        return AllNullableTypes.fromList(self.readValue() as! [Any])      
+      case 129:
+        return AllNullableTypes.fromList(self.readValue() as! [Any])      
+      case 130:
+        return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])      
+      case 131:
+        return AllTypes.fromList(self.readValue() as! [Any])      
+      default:
+        return super.readValue(ofType: type)
+      
+    }
+  }
+}
+private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
+  override func writeValue(_ value: Any) {
+    if let value = value as? AllNullableTypes {
+      super.writeByte(128)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllNullableTypes {
+      super.writeByte(129)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllNullableTypesWrapper {
+      super.writeByte(130)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllTypes {
+      super.writeByte(131)
+      super.writeValue(value.toList())
+    } else {
+      super.writeValue(value)
+    }
+  }
+}
+
+private class HostIntegrationCoreApiCodecReaderWriter: FlutterStandardReaderWriter {
+  override func reader(with data: Data) -> FlutterStandardReader {
+    return HostIntegrationCoreApiCodecReader(data: data)
+  }
+
+  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
+    return HostIntegrationCoreApiCodecWriter(data: data)
+  }
+}
+
+class HostIntegrationCoreApiCodec: FlutterStandardMessageCodec {
+  static let shared = HostIntegrationCoreApiCodec(readerWriter: HostIntegrationCoreApiCodecReaderWriter())
+}
+
+/// The core interface that each host language plugin must implement in
+/// platform_test integration tests.
+///
+/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
+protocol HostIntegrationCoreApi {
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic calling.
+  func noop()
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllTypes(everything: AllTypes) -> AllTypes
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllNullableTypes(everything: AllNullableTypes?) -> AllNullableTypes?
+  /// Returns an error, to test error handling.
+  func throwError()
+  /// Returns passed in int.
+  func echoInt(anInt: Int32) -> Int32
+  /// Returns passed in double.
+  func echoDouble(aDouble: Double) -> Double
+  /// Returns the passed in boolean.
+  func echoBool(aBool: Bool) -> Bool
+  /// Returns the passed in string.
+  func echoString(aString: String) -> String
+  /// Returns the passed in Uint8List.
+  func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData
+  /// Returns the inner `aString` value from the wrapped object, to test
+  /// sending of nested objects.
+  func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String?
+  /// Returns the inner `aString` value from the wrapped object, to test
+  /// sending of nested objects.
+  func createNestedNullableString(nullableString: String?) -> AllNullableTypesWrapper
+  /// Returns passed in arguments of multiple types.
+  func sendMultipleNullableTypes(aNullableBool: Bool?, aNullableInt: Int32?, aNullableString: String?) -> AllNullableTypes
+  /// Returns passed in int.
+  func echoNullableInt(aNullableInt: Int32?) -> Int32?
+  /// Returns passed in double.
+  func echoNullableDouble(aNullableDouble: Double?) -> Double?
+  /// Returns the passed in boolean.
+  func echoNullableBool(aNullableBool: Bool?) -> Bool?
+  /// Returns the passed in string.
+  func echoNullableString(aNullableString: String?) -> String?
+  /// Returns the passed in Uint8List.
+  func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData?
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic asynchronous calling.
+  func noopAsync(completion: @escaping () -> Void)
+  /// Returns the passed string asynchronously.
+  func echoAsyncString(aString: String, completion: @escaping (String) -> Void)
+  func callFlutterNoop(completion: @escaping () -> Void)
+  func callFlutterEchoString(aString: String, completion: @escaping (String) -> Void)
+}
+
+/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
+class HostIntegrationCoreApiSetup {
+  /// The codec used by HostIntegrationCoreApi.
+  static var codec: FlutterStandardMessageCodec { HostIntegrationCoreApiCodec.shared }
+  /// Sets up an instance of `HostIntegrationCoreApi` to handle messages through the `binaryMessenger`.
+  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostIntegrationCoreApi?) {
+    /// A no-op function taking no arguments and returning no value, to sanity
+    /// test basic calling.
+    let noopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      noopChannel.setMessageHandler { _, reply in
+        api.noop()
+        reply(wrapResult(nil))
+      }
+    } else {
+      noopChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed object, to test serialization and deserialization.
+    let echoAllTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoAllTypesChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let everythingArg = args[0] as! AllTypes
+        let result = api.echoAllTypes(everything: everythingArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoAllTypesChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed object, to test serialization and deserialization.
+    let echoAllNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoAllNullableTypesChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let everythingArg = args[0] as? AllNullableTypes
+        let result = api.echoAllNullableTypes(everything: everythingArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoAllNullableTypesChannel.setMessageHandler(nil)
+    }
+    /// Returns an error, to test error handling.
+    let throwErrorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      throwErrorChannel.setMessageHandler { _, reply in
+        api.throwError()
+        reply(wrapResult(nil))
+      }
+    } else {
+      throwErrorChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in int.
+    let echoIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoIntChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let anIntArg = args[0] as! Int32
+        let result = api.echoInt(anInt: anIntArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoIntChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in double.
+    let echoDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoDoubleChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aDoubleArg = args[0] as! Double
+        let result = api.echoDouble(aDouble: aDoubleArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoDoubleChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in boolean.
+    let echoBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoBoolChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aBoolArg = args[0] as! Bool
+        let result = api.echoBool(aBool: aBoolArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoBoolChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in string.
+    let echoStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aStringArg = args[0] as! String
+        let result = api.echoString(aString: aStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoStringChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in Uint8List.
+    let echoUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoUint8ListChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aUint8ListArg = args[0] as! FlutterStandardTypedData
+        let result = api.echoUint8List(aUint8List: aUint8ListArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoUint8ListChannel.setMessageHandler(nil)
+    }
+    /// Returns the inner `aString` value from the wrapped object, to test
+    /// sending of nested objects.
+    let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      extractNestedNullableStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let wrapperArg = args[0] as! AllNullableTypesWrapper
+        let result = api.extractNestedNullableString(wrapper: wrapperArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      extractNestedNullableStringChannel.setMessageHandler(nil)
+    }
+    /// Returns the inner `aString` value from the wrapped object, to test
+    /// sending of nested objects.
+    let createNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      createNestedNullableStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let nullableStringArg = args[0] as? String
+        let result = api.createNestedNullableString(nullableString: nullableStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      createNestedNullableStringChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in arguments of multiple types.
+    let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      sendMultipleNullableTypesChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableBoolArg = args[0] as? Bool
+        let aNullableIntArg = args[1] as? Int32
+        let aNullableStringArg = args[2] as? String
+        let result = api.sendMultipleNullableTypes(aNullableBool: aNullableBoolArg, aNullableInt: aNullableIntArg, aNullableString: aNullableStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      sendMultipleNullableTypesChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in int.
+    let echoNullableIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableIntChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableIntArg = args[0] as? Int32
+        let result = api.echoNullableInt(aNullableInt: aNullableIntArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableIntChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in double.
+    let echoNullableDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableDoubleChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableDoubleArg = args[0] as? Double
+        let result = api.echoNullableDouble(aNullableDouble: aNullableDoubleArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableDoubleChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in boolean.
+    let echoNullableBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableBoolChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableBoolArg = args[0] as? Bool
+        let result = api.echoNullableBool(aNullableBool: aNullableBoolArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableBoolChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in string.
+    let echoNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableStringArg = args[0] as? String
+        let result = api.echoNullableString(aNullableString: aNullableStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableStringChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in Uint8List.
+    let echoNullableUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableUint8ListChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableUint8ListArg = args[0] as? FlutterStandardTypedData
+        let result = api.echoNullableUint8List(aNullableUint8List: aNullableUint8ListArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableUint8ListChannel.setMessageHandler(nil)
+    }
+    /// A no-op function taking no arguments and returning no value, to sanity
+    /// test basic asynchronous calling.
+    let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      noopAsyncChannel.setMessageHandler { _, reply in
+        api.noopAsync() {
+          reply(wrapResult(nil))
+        }
+      }
+    } else {
+      noopAsyncChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed string asynchronously.
+    let echoAsyncStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoAsyncStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aStringArg = args[0] as! String
+        api.echoAsyncString(aString: aStringArg) { result in
+          reply(wrapResult(result))
+        }
+      }
+    } else {
+      echoAsyncStringChannel.setMessageHandler(nil)
+    }
+    let callFlutterNoopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      callFlutterNoopChannel.setMessageHandler { _, reply in
+        api.callFlutterNoop() {
+          reply(wrapResult(nil))
+        }
+      }
+    } else {
+      callFlutterNoopChannel.setMessageHandler(nil)
+    }
+    let callFlutterEchoStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      callFlutterEchoStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aStringArg = args[0] as! String
+        api.callFlutterEchoString(aString: aStringArg) { result in
+          reply(wrapResult(result))
+        }
+      }
+    } else {
+      callFlutterEchoStringChannel.setMessageHandler(nil)
+    }
+  }
+}
+private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader {
+  override func readValue(ofType type: UInt8) -> Any? {
+    switch type {
+      case 128:
+        return AllNullableTypes.fromList(self.readValue() as! [Any])      
+      case 129:
+        return AllTypes.fromList(self.readValue() as! [Any])      
+      default:
+        return super.readValue(ofType: type)
+      
+    }
+  }
+}
+private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter {
+  override func writeValue(_ value: Any) {
+    if let value = value as? AllNullableTypes {
+      super.writeByte(128)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllTypes {
+      super.writeByte(129)
+      super.writeValue(value.toList())
+    } else {
+      super.writeValue(value)
+    }
+  }
+}
+
+private class FlutterIntegrationCoreApiCodecReaderWriter: FlutterStandardReaderWriter {
+  override func reader(with data: Data) -> FlutterStandardReader {
+    return FlutterIntegrationCoreApiCodecReader(data: data)
+  }
+
+  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
+    return FlutterIntegrationCoreApiCodecWriter(data: data)
+  }
+}
+
+class FlutterIntegrationCoreApiCodec: FlutterStandardMessageCodec {
+  static let shared = FlutterIntegrationCoreApiCodec(readerWriter: FlutterIntegrationCoreApiCodecReaderWriter())
+}
+
+/// The core interface that the Dart platform_test code implements for host
+/// integration tests to call into.
+///
+/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.
+class FlutterIntegrationCoreApi {
+  private let binaryMessenger: FlutterBinaryMessenger
+  init(binaryMessenger: FlutterBinaryMessenger){
+    self.binaryMessenger = binaryMessenger
+  }
+  var codec: FlutterStandardMessageCodec {
+    return FlutterIntegrationCoreApiCodec.shared
+  }
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic calling.
+  func noop(completion: @escaping () -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage(nil) { _ in
+      completion()
+    }
+  }
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllTypes(everything everythingArg: AllTypes, completion: @escaping (AllTypes) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([everythingArg]) { response in
+      let result = response as! AllTypes
+      completion(result)
+    }
+  }
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllNullableTypes(everything everythingArg: AllNullableTypes, completion: @escaping (AllNullableTypes) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([everythingArg]) { response in
+      let result = response as! AllNullableTypes
+      completion(result)
+    }
+  }
+  /// Returns the passed string, to test serialization and deserialization.
+  func echoString(aString aStringArg: String, completion: @escaping (String) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aStringArg]) { response in
+      let result = response as! String
+      completion(result)
+    }
+  }
+}
+/// An API that can be implemented for minimal, compile-only tests.
+///
+/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
+protocol HostTrivialApi {
+  func noop()
+}
+
+/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
+class HostTrivialApiSetup {
+  /// The codec used by HostTrivialApi.
+  /// Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`.
+  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostTrivialApi?) {
+    let noopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostTrivialApi.noop", binaryMessenger: binaryMessenger)
+    if let api = api {
+      noopChannel.setMessageHandler { _, reply in
+        api.noop()
+        reply(wrapResult(nil))
+      }
+    } else {
+      noopChannel.setMessageHandler(nil)
+    }
+  }
+}
+
+private func wrapResult(_ result: Any?) -> [Any?] {
+  return [result]
+}
+
+private func wrapError(_ error: FlutterError) -> [Any?] {
+  return [
+    error.code,
+    error.message,
+    error.details
+  ]
+}
diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore b/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore
index ebbbb45..65eaa14 100644
--- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore
+++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/.gitignore
@@ -2,3 +2,4 @@
 # changes on generated files. This will need a way to avoid unnecessary churn,
 # such as a flag to suppress version stamp generation.
 *.gen.swift
+!CoreTests.gen.swift
\ No newline at end of file
diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift
new file mode 100644
index 0000000..385b507
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift
@@ -0,0 +1,657 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// 
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+import Foundation
+#if os(iOS)
+import Flutter
+#elseif os(macOS)
+import FlutterMacOS
+#else
+#error("Unsupported platform.")
+#endif
+
+
+/// Generated class from Pigeon.
+
+enum AnEnum: Int {
+  case one = 0
+  case two = 1
+  case three = 2
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct AllTypes {
+  var aBool: Bool
+  var anInt: Int32
+  var aDouble: Double
+  var aString: String
+  var aByteArray: FlutterStandardTypedData
+  var a4ByteArray: FlutterStandardTypedData
+  var a8ByteArray: FlutterStandardTypedData
+  var aFloatArray: FlutterStandardTypedData
+  var aList: [Any?]
+  var aMap: [AnyHashable: Any?]
+  var anEnum: AnEnum
+
+  static func fromList(_ list: [Any?]) -> AllTypes? {
+    let aBool = list[0] as! Bool
+    let anInt = list[1] as! Int32
+    let aDouble = list[2] as! Double
+    let aString = list[3] as! String
+    let aByteArray = list[4] as! FlutterStandardTypedData
+    let a4ByteArray = list[5] as! FlutterStandardTypedData
+    let a8ByteArray = list[6] as! FlutterStandardTypedData
+    let aFloatArray = list[7] as! FlutterStandardTypedData
+    let aList = list[8] as! [Any?]
+    let aMap = list[9] as! [AnyHashable: Any?]
+    let anEnum = AnEnum(rawValue: list[10] as! Int)!
+
+    return AllTypes(
+      aBool: aBool,
+      anInt: anInt,
+      aDouble: aDouble,
+      aString: aString,
+      aByteArray: aByteArray,
+      a4ByteArray: a4ByteArray,
+      a8ByteArray: a8ByteArray,
+      aFloatArray: aFloatArray,
+      aList: aList,
+      aMap: aMap,
+      anEnum: anEnum
+    )
+  }
+  func toList() -> [Any?] {
+    return [
+      aBool,
+      anInt,
+      aDouble,
+      aString,
+      aByteArray,
+      a4ByteArray,
+      a8ByteArray,
+      aFloatArray,
+      aList,
+      aMap,
+      anEnum.rawValue,
+    ]
+  }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct AllNullableTypes {
+  var aNullableBool: Bool? = nil
+  var aNullableInt: Int32? = nil
+  var aNullableDouble: Double? = nil
+  var aNullableString: String? = nil
+  var aNullableByteArray: FlutterStandardTypedData? = nil
+  var aNullable4ByteArray: FlutterStandardTypedData? = nil
+  var aNullable8ByteArray: FlutterStandardTypedData? = nil
+  var aNullableFloatArray: FlutterStandardTypedData? = nil
+  var aNullableList: [Any?]? = nil
+  var aNullableMap: [AnyHashable: Any?]? = nil
+  var nullableNestedList: [[Bool?]?]? = nil
+  var nullableMapWithAnnotations: [String?: String?]? = nil
+  var nullableMapWithObject: [String?: Any?]? = nil
+  var aNullableEnum: AnEnum? = nil
+
+  static func fromList(_ list: [Any?]) -> AllNullableTypes? {
+    let aNullableBool = list[0] as? Bool 
+    let aNullableInt = list[1] as? Int32 
+    let aNullableDouble = list[2] as? Double 
+    let aNullableString = list[3] as? String 
+    let aNullableByteArray = list[4] as? FlutterStandardTypedData 
+    let aNullable4ByteArray = list[5] as? FlutterStandardTypedData 
+    let aNullable8ByteArray = list[6] as? FlutterStandardTypedData 
+    let aNullableFloatArray = list[7] as? FlutterStandardTypedData 
+    let aNullableList = list[8] as? [Any?] 
+    let aNullableMap = list[9] as? [AnyHashable: Any?] 
+    let nullableNestedList = list[10] as? [[Bool?]?] 
+    let nullableMapWithAnnotations = list[11] as? [String?: String?] 
+    let nullableMapWithObject = list[12] as? [String?: Any?] 
+    var aNullableEnum: AnEnum? = nil
+    if let aNullableEnumRawValue = list[13] as? Int {
+      aNullableEnum = AnEnum(rawValue: aNullableEnumRawValue)
+    }
+
+    return AllNullableTypes(
+      aNullableBool: aNullableBool,
+      aNullableInt: aNullableInt,
+      aNullableDouble: aNullableDouble,
+      aNullableString: aNullableString,
+      aNullableByteArray: aNullableByteArray,
+      aNullable4ByteArray: aNullable4ByteArray,
+      aNullable8ByteArray: aNullable8ByteArray,
+      aNullableFloatArray: aNullableFloatArray,
+      aNullableList: aNullableList,
+      aNullableMap: aNullableMap,
+      nullableNestedList: nullableNestedList,
+      nullableMapWithAnnotations: nullableMapWithAnnotations,
+      nullableMapWithObject: nullableMapWithObject,
+      aNullableEnum: aNullableEnum
+    )
+  }
+  func toList() -> [Any?] {
+    return [
+      aNullableBool,
+      aNullableInt,
+      aNullableDouble,
+      aNullableString,
+      aNullableByteArray,
+      aNullable4ByteArray,
+      aNullable8ByteArray,
+      aNullableFloatArray,
+      aNullableList,
+      aNullableMap,
+      nullableNestedList,
+      nullableMapWithAnnotations,
+      nullableMapWithObject,
+      aNullableEnum?.rawValue,
+    ]
+  }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct AllNullableTypesWrapper {
+  var values: AllNullableTypes
+
+  static func fromList(_ list: [Any?]) -> AllNullableTypesWrapper? {
+    let values = AllNullableTypes.fromList(list[0] as! [Any?])!
+
+    return AllNullableTypesWrapper(
+      values: values
+    )
+  }
+  func toList() -> [Any?] {
+    return [
+      values.toList(),
+    ]
+  }
+}
+
+private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
+  override func readValue(ofType type: UInt8) -> Any? {
+    switch type {
+      case 128:
+        return AllNullableTypes.fromList(self.readValue() as! [Any])      
+      case 129:
+        return AllNullableTypes.fromList(self.readValue() as! [Any])      
+      case 130:
+        return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])      
+      case 131:
+        return AllTypes.fromList(self.readValue() as! [Any])      
+      default:
+        return super.readValue(ofType: type)
+      
+    }
+  }
+}
+private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
+  override func writeValue(_ value: Any) {
+    if let value = value as? AllNullableTypes {
+      super.writeByte(128)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllNullableTypes {
+      super.writeByte(129)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllNullableTypesWrapper {
+      super.writeByte(130)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllTypes {
+      super.writeByte(131)
+      super.writeValue(value.toList())
+    } else {
+      super.writeValue(value)
+    }
+  }
+}
+
+private class HostIntegrationCoreApiCodecReaderWriter: FlutterStandardReaderWriter {
+  override func reader(with data: Data) -> FlutterStandardReader {
+    return HostIntegrationCoreApiCodecReader(data: data)
+  }
+
+  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
+    return HostIntegrationCoreApiCodecWriter(data: data)
+  }
+}
+
+class HostIntegrationCoreApiCodec: FlutterStandardMessageCodec {
+  static let shared = HostIntegrationCoreApiCodec(readerWriter: HostIntegrationCoreApiCodecReaderWriter())
+}
+
+/// The core interface that each host language plugin must implement in
+/// platform_test integration tests.
+///
+/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
+protocol HostIntegrationCoreApi {
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic calling.
+  func noop()
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllTypes(everything: AllTypes) -> AllTypes
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllNullableTypes(everything: AllNullableTypes?) -> AllNullableTypes?
+  /// Returns an error, to test error handling.
+  func throwError()
+  /// Returns passed in int.
+  func echoInt(anInt: Int32) -> Int32
+  /// Returns passed in double.
+  func echoDouble(aDouble: Double) -> Double
+  /// Returns the passed in boolean.
+  func echoBool(aBool: Bool) -> Bool
+  /// Returns the passed in string.
+  func echoString(aString: String) -> String
+  /// Returns the passed in Uint8List.
+  func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData
+  /// Returns the inner `aString` value from the wrapped object, to test
+  /// sending of nested objects.
+  func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String?
+  /// Returns the inner `aString` value from the wrapped object, to test
+  /// sending of nested objects.
+  func createNestedNullableString(nullableString: String?) -> AllNullableTypesWrapper
+  /// Returns passed in arguments of multiple types.
+  func sendMultipleNullableTypes(aNullableBool: Bool?, aNullableInt: Int32?, aNullableString: String?) -> AllNullableTypes
+  /// Returns passed in int.
+  func echoNullableInt(aNullableInt: Int32?) -> Int32?
+  /// Returns passed in double.
+  func echoNullableDouble(aNullableDouble: Double?) -> Double?
+  /// Returns the passed in boolean.
+  func echoNullableBool(aNullableBool: Bool?) -> Bool?
+  /// Returns the passed in string.
+  func echoNullableString(aNullableString: String?) -> String?
+  /// Returns the passed in Uint8List.
+  func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData?
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic asynchronous calling.
+  func noopAsync(completion: @escaping () -> Void)
+  /// Returns the passed string asynchronously.
+  func echoAsyncString(aString: String, completion: @escaping (String) -> Void)
+  func callFlutterNoop(completion: @escaping () -> Void)
+  func callFlutterEchoString(aString: String, completion: @escaping (String) -> Void)
+}
+
+/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
+class HostIntegrationCoreApiSetup {
+  /// The codec used by HostIntegrationCoreApi.
+  static var codec: FlutterStandardMessageCodec { HostIntegrationCoreApiCodec.shared }
+  /// Sets up an instance of `HostIntegrationCoreApi` to handle messages through the `binaryMessenger`.
+  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostIntegrationCoreApi?) {
+    /// A no-op function taking no arguments and returning no value, to sanity
+    /// test basic calling.
+    let noopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      noopChannel.setMessageHandler { _, reply in
+        api.noop()
+        reply(wrapResult(nil))
+      }
+    } else {
+      noopChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed object, to test serialization and deserialization.
+    let echoAllTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoAllTypesChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let everythingArg = args[0] as! AllTypes
+        let result = api.echoAllTypes(everything: everythingArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoAllTypesChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed object, to test serialization and deserialization.
+    let echoAllNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoAllNullableTypesChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let everythingArg = args[0] as? AllNullableTypes
+        let result = api.echoAllNullableTypes(everything: everythingArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoAllNullableTypesChannel.setMessageHandler(nil)
+    }
+    /// Returns an error, to test error handling.
+    let throwErrorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      throwErrorChannel.setMessageHandler { _, reply in
+        api.throwError()
+        reply(wrapResult(nil))
+      }
+    } else {
+      throwErrorChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in int.
+    let echoIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoIntChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let anIntArg = args[0] as! Int32
+        let result = api.echoInt(anInt: anIntArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoIntChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in double.
+    let echoDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoDoubleChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aDoubleArg = args[0] as! Double
+        let result = api.echoDouble(aDouble: aDoubleArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoDoubleChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in boolean.
+    let echoBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoBoolChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aBoolArg = args[0] as! Bool
+        let result = api.echoBool(aBool: aBoolArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoBoolChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in string.
+    let echoStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aStringArg = args[0] as! String
+        let result = api.echoString(aString: aStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoStringChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in Uint8List.
+    let echoUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoUint8ListChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aUint8ListArg = args[0] as! FlutterStandardTypedData
+        let result = api.echoUint8List(aUint8List: aUint8ListArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoUint8ListChannel.setMessageHandler(nil)
+    }
+    /// Returns the inner `aString` value from the wrapped object, to test
+    /// sending of nested objects.
+    let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      extractNestedNullableStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let wrapperArg = args[0] as! AllNullableTypesWrapper
+        let result = api.extractNestedNullableString(wrapper: wrapperArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      extractNestedNullableStringChannel.setMessageHandler(nil)
+    }
+    /// Returns the inner `aString` value from the wrapped object, to test
+    /// sending of nested objects.
+    let createNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      createNestedNullableStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let nullableStringArg = args[0] as? String
+        let result = api.createNestedNullableString(nullableString: nullableStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      createNestedNullableStringChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in arguments of multiple types.
+    let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      sendMultipleNullableTypesChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableBoolArg = args[0] as? Bool
+        let aNullableIntArg = args[1] as? Int32
+        let aNullableStringArg = args[2] as? String
+        let result = api.sendMultipleNullableTypes(aNullableBool: aNullableBoolArg, aNullableInt: aNullableIntArg, aNullableString: aNullableStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      sendMultipleNullableTypesChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in int.
+    let echoNullableIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableIntChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableIntArg = args[0] as? Int32
+        let result = api.echoNullableInt(aNullableInt: aNullableIntArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableIntChannel.setMessageHandler(nil)
+    }
+    /// Returns passed in double.
+    let echoNullableDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableDoubleChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableDoubleArg = args[0] as? Double
+        let result = api.echoNullableDouble(aNullableDouble: aNullableDoubleArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableDoubleChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in boolean.
+    let echoNullableBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableBoolChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableBoolArg = args[0] as? Bool
+        let result = api.echoNullableBool(aNullableBool: aNullableBoolArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableBoolChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in string.
+    let echoNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableStringArg = args[0] as? String
+        let result = api.echoNullableString(aNullableString: aNullableStringArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableStringChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed in Uint8List.
+    let echoNullableUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoNullableUint8ListChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aNullableUint8ListArg = args[0] as? FlutterStandardTypedData
+        let result = api.echoNullableUint8List(aNullableUint8List: aNullableUint8ListArg)
+        reply(wrapResult(result))
+      }
+    } else {
+      echoNullableUint8ListChannel.setMessageHandler(nil)
+    }
+    /// A no-op function taking no arguments and returning no value, to sanity
+    /// test basic asynchronous calling.
+    let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      noopAsyncChannel.setMessageHandler { _, reply in
+        api.noopAsync() {
+          reply(wrapResult(nil))
+        }
+      }
+    } else {
+      noopAsyncChannel.setMessageHandler(nil)
+    }
+    /// Returns the passed string asynchronously.
+    let echoAsyncStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      echoAsyncStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aStringArg = args[0] as! String
+        api.echoAsyncString(aString: aStringArg) { result in
+          reply(wrapResult(result))
+        }
+      }
+    } else {
+      echoAsyncStringChannel.setMessageHandler(nil)
+    }
+    let callFlutterNoopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      callFlutterNoopChannel.setMessageHandler { _, reply in
+        api.callFlutterNoop() {
+          reply(wrapResult(nil))
+        }
+      }
+    } else {
+      callFlutterNoopChannel.setMessageHandler(nil)
+    }
+    let callFlutterEchoStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString", binaryMessenger: binaryMessenger, codec: codec)
+    if let api = api {
+      callFlutterEchoStringChannel.setMessageHandler { message, reply in
+        let args = message as! [Any?]
+        let aStringArg = args[0] as! String
+        api.callFlutterEchoString(aString: aStringArg) { result in
+          reply(wrapResult(result))
+        }
+      }
+    } else {
+      callFlutterEchoStringChannel.setMessageHandler(nil)
+    }
+  }
+}
+private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader {
+  override func readValue(ofType type: UInt8) -> Any? {
+    switch type {
+      case 128:
+        return AllNullableTypes.fromList(self.readValue() as! [Any])      
+      case 129:
+        return AllTypes.fromList(self.readValue() as! [Any])      
+      default:
+        return super.readValue(ofType: type)
+      
+    }
+  }
+}
+private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter {
+  override func writeValue(_ value: Any) {
+    if let value = value as? AllNullableTypes {
+      super.writeByte(128)
+      super.writeValue(value.toList())
+    } else if let value = value as? AllTypes {
+      super.writeByte(129)
+      super.writeValue(value.toList())
+    } else {
+      super.writeValue(value)
+    }
+  }
+}
+
+private class FlutterIntegrationCoreApiCodecReaderWriter: FlutterStandardReaderWriter {
+  override func reader(with data: Data) -> FlutterStandardReader {
+    return FlutterIntegrationCoreApiCodecReader(data: data)
+  }
+
+  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
+    return FlutterIntegrationCoreApiCodecWriter(data: data)
+  }
+}
+
+class FlutterIntegrationCoreApiCodec: FlutterStandardMessageCodec {
+  static let shared = FlutterIntegrationCoreApiCodec(readerWriter: FlutterIntegrationCoreApiCodecReaderWriter())
+}
+
+/// The core interface that the Dart platform_test code implements for host
+/// integration tests to call into.
+///
+/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.
+class FlutterIntegrationCoreApi {
+  private let binaryMessenger: FlutterBinaryMessenger
+  init(binaryMessenger: FlutterBinaryMessenger){
+    self.binaryMessenger = binaryMessenger
+  }
+  var codec: FlutterStandardMessageCodec {
+    return FlutterIntegrationCoreApiCodec.shared
+  }
+  /// A no-op function taking no arguments and returning no value, to sanity
+  /// test basic calling.
+  func noop(completion: @escaping () -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage(nil) { _ in
+      completion()
+    }
+  }
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllTypes(everything everythingArg: AllTypes, completion: @escaping (AllTypes) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([everythingArg]) { response in
+      let result = response as! AllTypes
+      completion(result)
+    }
+  }
+  /// Returns the passed object, to test serialization and deserialization.
+  func echoAllNullableTypes(everything everythingArg: AllNullableTypes, completion: @escaping (AllNullableTypes) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([everythingArg]) { response in
+      let result = response as! AllNullableTypes
+      completion(result)
+    }
+  }
+  /// Returns the passed string, to test serialization and deserialization.
+  func echoString(aString aStringArg: String, completion: @escaping (String) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aStringArg]) { response in
+      let result = response as! String
+      completion(result)
+    }
+  }
+}
+/// An API that can be implemented for minimal, compile-only tests.
+///
+/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
+protocol HostTrivialApi {
+  func noop()
+}
+
+/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
+class HostTrivialApiSetup {
+  /// The codec used by HostTrivialApi.
+  /// Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`.
+  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostTrivialApi?) {
+    let noopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostTrivialApi.noop", binaryMessenger: binaryMessenger)
+    if let api = api {
+      noopChannel.setMessageHandler { _, reply in
+        api.noop()
+        reply(wrapResult(nil))
+      }
+    } else {
+      noopChannel.setMessageHandler(nil)
+    }
+  }
+}
+
+private func wrapResult(_ result: Any?) -> [Any?] {
+  return [result]
+}
+
+private func wrapError(_ error: FlutterError) -> [Any?] {
+  return [
+    error.code,
+    error.message,
+    error.details
+  ]
+}
diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/.gitignore b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/.gitignore
index 12c56aa..250e84e 100644
--- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/.gitignore
+++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/.gitignore
@@ -3,3 +3,4 @@
 # such as a flag to suppress version stamp generation.
 *.gen.h
 *.gen.cpp
+!core_tests.gen*
\ No newline at end of file
diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp
new file mode 100644
index 0000000..990732c
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp
@@ -0,0 +1,1523 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+#undef _HAS_EXCEPTIONS
+
+#include "core_tests.gen.h"
+
+#include <flutter/basic_message_channel.h>
+#include <flutter/binary_messenger.h>
+#include <flutter/encodable_value.h>
+#include <flutter/standard_message_codec.h>
+
+#include <map>
+#include <optional>
+#include <string>
+
+namespace core_tests_pigeontest {
+
+// AllTypes
+
+bool AllTypes::a_bool() const { return a_bool_; }
+void AllTypes::set_a_bool(bool value_arg) { a_bool_ = value_arg; }
+
+int64_t AllTypes::an_int() const { return an_int_; }
+void AllTypes::set_an_int(int64_t value_arg) { an_int_ = value_arg; }
+
+double AllTypes::a_double() const { return a_double_; }
+void AllTypes::set_a_double(double value_arg) { a_double_ = value_arg; }
+
+const std::string& AllTypes::a_string() const { return a_string_; }
+void AllTypes::set_a_string(std::string_view value_arg) {
+  a_string_ = value_arg;
+}
+
+const std::vector<uint8_t>& AllTypes::a_byte_array() const {
+  return a_byte_array_;
+}
+void AllTypes::set_a_byte_array(const std::vector<uint8_t>& value_arg) {
+  a_byte_array_ = value_arg;
+}
+
+const std::vector<int32_t>& AllTypes::a4_byte_array() const {
+  return a4_byte_array_;
+}
+void AllTypes::set_a4_byte_array(const std::vector<int32_t>& value_arg) {
+  a4_byte_array_ = value_arg;
+}
+
+const std::vector<int64_t>& AllTypes::a8_byte_array() const {
+  return a8_byte_array_;
+}
+void AllTypes::set_a8_byte_array(const std::vector<int64_t>& value_arg) {
+  a8_byte_array_ = value_arg;
+}
+
+const std::vector<double>& AllTypes::a_float_array() const {
+  return a_float_array_;
+}
+void AllTypes::set_a_float_array(const std::vector<double>& value_arg) {
+  a_float_array_ = value_arg;
+}
+
+const flutter::EncodableList& AllTypes::a_list() const { return a_list_; }
+void AllTypes::set_a_list(const flutter::EncodableList& value_arg) {
+  a_list_ = value_arg;
+}
+
+const flutter::EncodableMap& AllTypes::a_map() const { return a_map_; }
+void AllTypes::set_a_map(const flutter::EncodableMap& value_arg) {
+  a_map_ = value_arg;
+}
+
+const AnEnum& AllTypes::an_enum() const { return an_enum_; }
+void AllTypes::set_an_enum(const AnEnum& value_arg) { an_enum_ = value_arg; }
+
+flutter::EncodableList AllTypes::ToEncodableList() const {
+  return flutter::EncodableList{
+      flutter::EncodableValue(a_bool_),
+      flutter::EncodableValue(an_int_),
+      flutter::EncodableValue(a_double_),
+      flutter::EncodableValue(a_string_),
+      flutter::EncodableValue(a_byte_array_),
+      flutter::EncodableValue(a4_byte_array_),
+      flutter::EncodableValue(a8_byte_array_),
+      flutter::EncodableValue(a_float_array_),
+      flutter::EncodableValue(a_list_),
+      flutter::EncodableValue(a_map_),
+      flutter::EncodableValue((int)an_enum_),
+  };
+}
+
+AllTypes::AllTypes() {}
+
+AllTypes::AllTypes(const flutter::EncodableList& list) {
+  auto& encodable_a_bool = list[0];
+  if (const bool* pointer_a_bool = std::get_if<bool>(&encodable_a_bool)) {
+    a_bool_ = *pointer_a_bool;
+  }
+  auto& encodable_an_int = list[1];
+  if (const int32_t* pointer_an_int = std::get_if<int32_t>(&encodable_an_int))
+    an_int_ = *pointer_an_int;
+  else if (const int64_t* pointer_an_int_64 =
+               std::get_if<int64_t>(&encodable_an_int))
+    an_int_ = *pointer_an_int_64;
+  auto& encodable_a_double = list[2];
+  if (const double* pointer_a_double =
+          std::get_if<double>(&encodable_a_double)) {
+    a_double_ = *pointer_a_double;
+  }
+  auto& encodable_a_string = list[3];
+  if (const std::string* pointer_a_string =
+          std::get_if<std::string>(&encodable_a_string)) {
+    a_string_ = *pointer_a_string;
+  }
+  auto& encodable_a_byte_array = list[4];
+  if (const std::vector<uint8_t>* pointer_a_byte_array =
+          std::get_if<std::vector<uint8_t>>(&encodable_a_byte_array)) {
+    a_byte_array_ = *pointer_a_byte_array;
+  }
+  auto& encodable_a4_byte_array = list[5];
+  if (const std::vector<int32_t>* pointer_a4_byte_array =
+          std::get_if<std::vector<int32_t>>(&encodable_a4_byte_array)) {
+    a4_byte_array_ = *pointer_a4_byte_array;
+  }
+  auto& encodable_a8_byte_array = list[6];
+  if (const std::vector<int64_t>* pointer_a8_byte_array =
+          std::get_if<std::vector<int64_t>>(&encodable_a8_byte_array)) {
+    a8_byte_array_ = *pointer_a8_byte_array;
+  }
+  auto& encodable_a_float_array = list[7];
+  if (const std::vector<double>* pointer_a_float_array =
+          std::get_if<std::vector<double>>(&encodable_a_float_array)) {
+    a_float_array_ = *pointer_a_float_array;
+  }
+  auto& encodable_a_list = list[8];
+  if (const flutter::EncodableList* pointer_a_list =
+          std::get_if<flutter::EncodableList>(&encodable_a_list)) {
+    a_list_ = *pointer_a_list;
+  }
+  auto& encodable_a_map = list[9];
+  if (const flutter::EncodableMap* pointer_a_map =
+          std::get_if<flutter::EncodableMap>(&encodable_a_map)) {
+    a_map_ = *pointer_a_map;
+  }
+  auto& encodable_an_enum = list[10];
+  if (const int32_t* pointer_an_enum = std::get_if<int32_t>(&encodable_an_enum))
+    an_enum_ = (AnEnum)*pointer_an_enum;
+}
+
+// AllNullableTypes
+
+const bool* AllNullableTypes::a_nullable_bool() const {
+  return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_bool(const bool* value_arg) {
+  a_nullable_bool_ = value_arg ? std::optional<bool>(*value_arg) : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_bool(bool value_arg) {
+  a_nullable_bool_ = value_arg;
+}
+
+const int64_t* AllNullableTypes::a_nullable_int() const {
+  return a_nullable_int_ ? &(*a_nullable_int_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_int(const int64_t* value_arg) {
+  a_nullable_int_ =
+      value_arg ? std::optional<int64_t>(*value_arg) : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_int(int64_t value_arg) {
+  a_nullable_int_ = value_arg;
+}
+
+const double* AllNullableTypes::a_nullable_double() const {
+  return a_nullable_double_ ? &(*a_nullable_double_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_double(const double* value_arg) {
+  a_nullable_double_ =
+      value_arg ? std::optional<double>(*value_arg) : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_double(double value_arg) {
+  a_nullable_double_ = value_arg;
+}
+
+const std::string* AllNullableTypes::a_nullable_string() const {
+  return a_nullable_string_ ? &(*a_nullable_string_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_string(
+    const std::string_view* value_arg) {
+  a_nullable_string_ =
+      value_arg ? std::optional<std::string>(*value_arg) : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_string(std::string_view value_arg) {
+  a_nullable_string_ = value_arg;
+}
+
+const std::vector<uint8_t>* AllNullableTypes::a_nullable_byte_array() const {
+  return a_nullable_byte_array_ ? &(*a_nullable_byte_array_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_byte_array(
+    const std::vector<uint8_t>* value_arg) {
+  a_nullable_byte_array_ = value_arg
+                               ? std::optional<std::vector<uint8_t>>(*value_arg)
+                               : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_byte_array(
+    const std::vector<uint8_t>& value_arg) {
+  a_nullable_byte_array_ = value_arg;
+}
+
+const std::vector<int32_t>* AllNullableTypes::a_nullable4_byte_array() const {
+  return a_nullable4_byte_array_ ? &(*a_nullable4_byte_array_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable4_byte_array(
+    const std::vector<int32_t>* value_arg) {
+  a_nullable4_byte_array_ =
+      value_arg ? std::optional<std::vector<int32_t>>(*value_arg)
+                : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable4_byte_array(
+    const std::vector<int32_t>& value_arg) {
+  a_nullable4_byte_array_ = value_arg;
+}
+
+const std::vector<int64_t>* AllNullableTypes::a_nullable8_byte_array() const {
+  return a_nullable8_byte_array_ ? &(*a_nullable8_byte_array_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable8_byte_array(
+    const std::vector<int64_t>* value_arg) {
+  a_nullable8_byte_array_ =
+      value_arg ? std::optional<std::vector<int64_t>>(*value_arg)
+                : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable8_byte_array(
+    const std::vector<int64_t>& value_arg) {
+  a_nullable8_byte_array_ = value_arg;
+}
+
+const std::vector<double>* AllNullableTypes::a_nullable_float_array() const {
+  return a_nullable_float_array_ ? &(*a_nullable_float_array_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_float_array(
+    const std::vector<double>* value_arg) {
+  a_nullable_float_array_ =
+      value_arg ? std::optional<std::vector<double>>(*value_arg) : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_float_array(
+    const std::vector<double>& value_arg) {
+  a_nullable_float_array_ = value_arg;
+}
+
+const flutter::EncodableList* AllNullableTypes::a_nullable_list() const {
+  return a_nullable_list_ ? &(*a_nullable_list_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_list(
+    const flutter::EncodableList* value_arg) {
+  a_nullable_list_ = value_arg
+                         ? std::optional<flutter::EncodableList>(*value_arg)
+                         : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_list(
+    const flutter::EncodableList& value_arg) {
+  a_nullable_list_ = value_arg;
+}
+
+const flutter::EncodableMap* AllNullableTypes::a_nullable_map() const {
+  return a_nullable_map_ ? &(*a_nullable_map_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_map(
+    const flutter::EncodableMap* value_arg) {
+  a_nullable_map_ = value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
+                              : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_map(
+    const flutter::EncodableMap& value_arg) {
+  a_nullable_map_ = value_arg;
+}
+
+const flutter::EncodableList* AllNullableTypes::nullable_nested_list() const {
+  return nullable_nested_list_ ? &(*nullable_nested_list_) : nullptr;
+}
+void AllNullableTypes::set_nullable_nested_list(
+    const flutter::EncodableList* value_arg) {
+  nullable_nested_list_ =
+      value_arg ? std::optional<flutter::EncodableList>(*value_arg)
+                : std::nullopt;
+}
+void AllNullableTypes::set_nullable_nested_list(
+    const flutter::EncodableList& value_arg) {
+  nullable_nested_list_ = value_arg;
+}
+
+const flutter::EncodableMap* AllNullableTypes::nullable_map_with_annotations()
+    const {
+  return nullable_map_with_annotations_ ? &(*nullable_map_with_annotations_)
+                                        : nullptr;
+}
+void AllNullableTypes::set_nullable_map_with_annotations(
+    const flutter::EncodableMap* value_arg) {
+  nullable_map_with_annotations_ =
+      value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
+                : std::nullopt;
+}
+void AllNullableTypes::set_nullable_map_with_annotations(
+    const flutter::EncodableMap& value_arg) {
+  nullable_map_with_annotations_ = value_arg;
+}
+
+const flutter::EncodableMap* AllNullableTypes::nullable_map_with_object()
+    const {
+  return nullable_map_with_object_ ? &(*nullable_map_with_object_) : nullptr;
+}
+void AllNullableTypes::set_nullable_map_with_object(
+    const flutter::EncodableMap* value_arg) {
+  nullable_map_with_object_ =
+      value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
+                : std::nullopt;
+}
+void AllNullableTypes::set_nullable_map_with_object(
+    const flutter::EncodableMap& value_arg) {
+  nullable_map_with_object_ = value_arg;
+}
+
+const AnEnum* AllNullableTypes::a_nullable_enum() const {
+  return a_nullable_enum_ ? &(*a_nullable_enum_) : nullptr;
+}
+void AllNullableTypes::set_a_nullable_enum(const AnEnum* value_arg) {
+  a_nullable_enum_ =
+      value_arg ? std::optional<AnEnum>(*value_arg) : std::nullopt;
+}
+void AllNullableTypes::set_a_nullable_enum(const AnEnum& value_arg) {
+  a_nullable_enum_ = value_arg;
+}
+
+flutter::EncodableList AllNullableTypes::ToEncodableList() const {
+  return flutter::EncodableList{
+      a_nullable_bool_ ? flutter::EncodableValue(*a_nullable_bool_)
+                       : flutter::EncodableValue(),
+      a_nullable_int_ ? flutter::EncodableValue(*a_nullable_int_)
+                      : flutter::EncodableValue(),
+      a_nullable_double_ ? flutter::EncodableValue(*a_nullable_double_)
+                         : flutter::EncodableValue(),
+      a_nullable_string_ ? flutter::EncodableValue(*a_nullable_string_)
+                         : flutter::EncodableValue(),
+      a_nullable_byte_array_ ? flutter::EncodableValue(*a_nullable_byte_array_)
+                             : flutter::EncodableValue(),
+      a_nullable4_byte_array_
+          ? flutter::EncodableValue(*a_nullable4_byte_array_)
+          : flutter::EncodableValue(),
+      a_nullable8_byte_array_
+          ? flutter::EncodableValue(*a_nullable8_byte_array_)
+          : flutter::EncodableValue(),
+      a_nullable_float_array_
+          ? flutter::EncodableValue(*a_nullable_float_array_)
+          : flutter::EncodableValue(),
+      a_nullable_list_ ? flutter::EncodableValue(*a_nullable_list_)
+                       : flutter::EncodableValue(),
+      a_nullable_map_ ? flutter::EncodableValue(*a_nullable_map_)
+                      : flutter::EncodableValue(),
+      nullable_nested_list_ ? flutter::EncodableValue(*nullable_nested_list_)
+                            : flutter::EncodableValue(),
+      nullable_map_with_annotations_
+          ? flutter::EncodableValue(*nullable_map_with_annotations_)
+          : flutter::EncodableValue(),
+      nullable_map_with_object_
+          ? flutter::EncodableValue(*nullable_map_with_object_)
+          : flutter::EncodableValue(),
+      a_nullable_enum_ ? flutter::EncodableValue((int)(*a_nullable_enum_))
+                       : flutter::EncodableValue(),
+  };
+}
+
+AllNullableTypes::AllNullableTypes() {}
+
+AllNullableTypes::AllNullableTypes(const flutter::EncodableList& list) {
+  auto& encodable_a_nullable_bool = list[0];
+  if (const bool* pointer_a_nullable_bool =
+          std::get_if<bool>(&encodable_a_nullable_bool)) {
+    a_nullable_bool_ = *pointer_a_nullable_bool;
+  }
+  auto& encodable_a_nullable_int = list[1];
+  if (const int32_t* pointer_a_nullable_int =
+          std::get_if<int32_t>(&encodable_a_nullable_int))
+    a_nullable_int_ = *pointer_a_nullable_int;
+  else if (const int64_t* pointer_a_nullable_int_64 =
+               std::get_if<int64_t>(&encodable_a_nullable_int))
+    a_nullable_int_ = *pointer_a_nullable_int_64;
+  auto& encodable_a_nullable_double = list[2];
+  if (const double* pointer_a_nullable_double =
+          std::get_if<double>(&encodable_a_nullable_double)) {
+    a_nullable_double_ = *pointer_a_nullable_double;
+  }
+  auto& encodable_a_nullable_string = list[3];
+  if (const std::string* pointer_a_nullable_string =
+          std::get_if<std::string>(&encodable_a_nullable_string)) {
+    a_nullable_string_ = *pointer_a_nullable_string;
+  }
+  auto& encodable_a_nullable_byte_array = list[4];
+  if (const std::vector<uint8_t>* pointer_a_nullable_byte_array =
+          std::get_if<std::vector<uint8_t>>(&encodable_a_nullable_byte_array)) {
+    a_nullable_byte_array_ = *pointer_a_nullable_byte_array;
+  }
+  auto& encodable_a_nullable4_byte_array = list[5];
+  if (const std::vector<int32_t>* pointer_a_nullable4_byte_array =
+          std::get_if<std::vector<int32_t>>(
+              &encodable_a_nullable4_byte_array)) {
+    a_nullable4_byte_array_ = *pointer_a_nullable4_byte_array;
+  }
+  auto& encodable_a_nullable8_byte_array = list[6];
+  if (const std::vector<int64_t>* pointer_a_nullable8_byte_array =
+          std::get_if<std::vector<int64_t>>(
+              &encodable_a_nullable8_byte_array)) {
+    a_nullable8_byte_array_ = *pointer_a_nullable8_byte_array;
+  }
+  auto& encodable_a_nullable_float_array = list[7];
+  if (const std::vector<double>* pointer_a_nullable_float_array =
+          std::get_if<std::vector<double>>(&encodable_a_nullable_float_array)) {
+    a_nullable_float_array_ = *pointer_a_nullable_float_array;
+  }
+  auto& encodable_a_nullable_list = list[8];
+  if (const flutter::EncodableList* pointer_a_nullable_list =
+          std::get_if<flutter::EncodableList>(&encodable_a_nullable_list)) {
+    a_nullable_list_ = *pointer_a_nullable_list;
+  }
+  auto& encodable_a_nullable_map = list[9];
+  if (const flutter::EncodableMap* pointer_a_nullable_map =
+          std::get_if<flutter::EncodableMap>(&encodable_a_nullable_map)) {
+    a_nullable_map_ = *pointer_a_nullable_map;
+  }
+  auto& encodable_nullable_nested_list = list[10];
+  if (const flutter::EncodableList* pointer_nullable_nested_list =
+          std::get_if<flutter::EncodableList>(
+              &encodable_nullable_nested_list)) {
+    nullable_nested_list_ = *pointer_nullable_nested_list;
+  }
+  auto& encodable_nullable_map_with_annotations = list[11];
+  if (const flutter::EncodableMap* pointer_nullable_map_with_annotations =
+          std::get_if<flutter::EncodableMap>(
+              &encodable_nullable_map_with_annotations)) {
+    nullable_map_with_annotations_ = *pointer_nullable_map_with_annotations;
+  }
+  auto& encodable_nullable_map_with_object = list[12];
+  if (const flutter::EncodableMap* pointer_nullable_map_with_object =
+          std::get_if<flutter::EncodableMap>(
+              &encodable_nullable_map_with_object)) {
+    nullable_map_with_object_ = *pointer_nullable_map_with_object;
+  }
+  auto& encodable_a_nullable_enum = list[13];
+  if (const int32_t* pointer_a_nullable_enum =
+          std::get_if<int32_t>(&encodable_a_nullable_enum))
+    a_nullable_enum_ = (AnEnum)*pointer_a_nullable_enum;
+}
+
+// AllNullableTypesWrapper
+
+const AllNullableTypes& AllNullableTypesWrapper::values() const {
+  return values_;
+}
+void AllNullableTypesWrapper::set_values(const AllNullableTypes& value_arg) {
+  values_ = value_arg;
+}
+
+flutter::EncodableList AllNullableTypesWrapper::ToEncodableList() const {
+  return flutter::EncodableList{
+      flutter::EncodableValue(values_.ToEncodableList()),
+  };
+}
+
+AllNullableTypesWrapper::AllNullableTypesWrapper() {}
+
+AllNullableTypesWrapper::AllNullableTypesWrapper(
+    const flutter::EncodableList& list) {
+  auto& encodable_values = list[0];
+  if (const flutter::EncodableList* pointer_values =
+          std::get_if<flutter::EncodableList>(&encodable_values)) {
+    values_ = AllNullableTypes(*pointer_values);
+  }
+}
+
+HostIntegrationCoreApiCodecSerializer::HostIntegrationCoreApiCodecSerializer() {
+}
+flutter::EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType(
+    uint8_t type, flutter::ByteStreamReader* stream) const {
+  switch (type) {
+    case 128:
+      return flutter::CustomEncodableValue(AllNullableTypes(
+          std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    case 129:
+      return flutter::CustomEncodableValue(AllNullableTypes(
+          std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    case 130:
+      return flutter::CustomEncodableValue(AllNullableTypesWrapper(
+          std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    case 131:
+      return flutter::CustomEncodableValue(
+          AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    default:
+      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
+  }
+}
+
+void HostIntegrationCoreApiCodecSerializer::WriteValue(
+    const flutter::EncodableValue& value,
+    flutter::ByteStreamWriter* stream) const {
+  if (const flutter::CustomEncodableValue* custom_value =
+          std::get_if<flutter::CustomEncodableValue>(&value)) {
+    if (custom_value->type() == typeid(AllNullableTypes)) {
+      stream->WriteByte(128);
+      WriteValue(
+          flutter::EncodableValue(
+              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
+          stream);
+      return;
+    }
+    if (custom_value->type() == typeid(AllNullableTypes)) {
+      stream->WriteByte(129);
+      WriteValue(
+          flutter::EncodableValue(
+              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
+          stream);
+      return;
+    }
+    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
+      stream->WriteByte(130);
+      WriteValue(flutter::EncodableValue(
+                     std::any_cast<AllNullableTypesWrapper>(*custom_value)
+                         .ToEncodableList()),
+                 stream);
+      return;
+    }
+    if (custom_value->type() == typeid(AllTypes)) {
+      stream->WriteByte(131);
+      WriteValue(flutter::EncodableValue(
+                     std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
+                 stream);
+      return;
+    }
+  }
+  flutter::StandardCodecSerializer::WriteValue(value, stream);
+}
+
+/// The codec used by HostIntegrationCoreApi.
+const flutter::StandardMessageCodec& HostIntegrationCoreApi::GetCodec() {
+  return flutter::StandardMessageCodec::GetInstance(
+      &HostIntegrationCoreApiCodecSerializer::GetInstance());
+}
+
+// Sets up an instance of `HostIntegrationCoreApi` to handle messages through
+// the `binary_messenger`.
+void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger,
+                                   HostIntegrationCoreApi* api) {
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              std::optional<FlutterError> output = api->Noop();
+              if (output.has_value()) {
+                wrapped = WrapError(output.value());
+              } else {
+                wrapped.push_back(flutter::EncodableValue());
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_everything_arg = args.at(0);
+              if (encodable_everything_arg.IsNull()) {
+                reply(WrapError("everything_arg unexpectedly null."));
+                return;
+              }
+              const auto& everything_arg = std::any_cast<const AllTypes&>(
+                  std::get<flutter::CustomEncodableValue>(
+                      encodable_everything_arg));
+              ErrorOr<AllTypes> output = api->EchoAllTypes(everything_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(flutter::CustomEncodableValue(
+                    std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_everything_arg = args.at(0);
+              const auto* everything_arg =
+                  &(std::any_cast<const AllNullableTypes&>(
+                      std::get<flutter::CustomEncodableValue>(
+                          encodable_everything_arg)));
+              ErrorOr<std::optional<AllNullableTypes>> output =
+                  api->EchoAllNullableTypes(everything_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::CustomEncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.throwError",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              std::optional<FlutterError> output = api->ThrowError();
+              if (output.has_value()) {
+                wrapped = WrapError(output.value());
+              } else {
+                wrapped.push_back(flutter::EncodableValue());
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_an_int_arg = args.at(0);
+              if (encodable_an_int_arg.IsNull()) {
+                reply(WrapError("an_int_arg unexpectedly null."));
+                return;
+              }
+              const int64_t an_int_arg = encodable_an_int_arg.LongValue();
+              ErrorOr<int64_t> output = api->EchoInt(an_int_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(
+                    flutter::EncodableValue(std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_double_arg = args.at(0);
+              if (encodable_a_double_arg.IsNull()) {
+                reply(WrapError("a_double_arg unexpectedly null."));
+                return;
+              }
+              const auto& a_double_arg =
+                  std::get<double>(encodable_a_double_arg);
+              ErrorOr<double> output = api->EchoDouble(a_double_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(
+                    flutter::EncodableValue(std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_bool_arg = args.at(0);
+              if (encodable_a_bool_arg.IsNull()) {
+                reply(WrapError("a_bool_arg unexpectedly null."));
+                return;
+              }
+              const auto& a_bool_arg = std::get<bool>(encodable_a_bool_arg);
+              ErrorOr<bool> output = api->EchoBool(a_bool_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(
+                    flutter::EncodableValue(std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoString",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_string_arg = args.at(0);
+              if (encodable_a_string_arg.IsNull()) {
+                reply(WrapError("a_string_arg unexpectedly null."));
+                return;
+              }
+              const auto& a_string_arg =
+                  std::get<std::string>(encodable_a_string_arg);
+              ErrorOr<std::string> output = api->EchoString(a_string_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(
+                    flutter::EncodableValue(std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_uint8_list_arg = args.at(0);
+              if (encodable_a_uint8_list_arg.IsNull()) {
+                reply(WrapError("a_uint8_list_arg unexpectedly null."));
+                return;
+              }
+              const auto& a_uint8_list_arg =
+                  std::get<std::vector<uint8_t>>(encodable_a_uint8_list_arg);
+              ErrorOr<std::vector<uint8_t>> output =
+                  api->EchoUint8List(a_uint8_list_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(
+                    flutter::EncodableValue(std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel = std::make_unique<
+        flutter::BasicMessageChannel<flutter::EncodableValue>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
+        &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_wrapper_arg = args.at(0);
+              if (encodable_wrapper_arg.IsNull()) {
+                reply(WrapError("wrapper_arg unexpectedly null."));
+                return;
+              }
+              const auto& wrapper_arg =
+                  std::any_cast<const AllNullableTypesWrapper&>(
+                      std::get<flutter::CustomEncodableValue>(
+                          encodable_wrapper_arg));
+              ErrorOr<std::optional<std::string>> output =
+                  api->ExtractNestedNullableString(wrapper_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::EncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel = std::make_unique<
+        flutter::BasicMessageChannel<flutter::EncodableValue>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
+        &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_nullable_string_arg = args.at(0);
+              const auto* nullable_string_arg =
+                  std::get_if<std::string>(&encodable_nullable_string_arg);
+              ErrorOr<AllNullableTypesWrapper> output =
+                  api->CreateNestedNullableString(nullable_string_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(flutter::CustomEncodableValue(
+                    std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel = std::make_unique<
+        flutter::BasicMessageChannel<flutter::EncodableValue>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
+        &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_nullable_bool_arg = args.at(0);
+              const auto* a_nullable_bool_arg =
+                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
+              const auto& encodable_a_nullable_int_arg = args.at(1);
+              const int64_t a_nullable_int_arg_value =
+                  encodable_a_nullable_int_arg.IsNull()
+                      ? 0
+                      : encodable_a_nullable_int_arg.LongValue();
+              const auto* a_nullable_int_arg =
+                  encodable_a_nullable_int_arg.IsNull()
+                      ? nullptr
+                      : &a_nullable_int_arg_value;
+              const auto& encodable_a_nullable_string_arg = args.at(2);
+              const auto* a_nullable_string_arg =
+                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
+              ErrorOr<AllNullableTypes> output = api->SendMultipleNullableTypes(
+                  a_nullable_bool_arg, a_nullable_int_arg,
+                  a_nullable_string_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                wrapped.push_back(flutter::CustomEncodableValue(
+                    std::move(output).TakeValue()));
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_nullable_int_arg = args.at(0);
+              const int64_t a_nullable_int_arg_value =
+                  encodable_a_nullable_int_arg.IsNull()
+                      ? 0
+                      : encodable_a_nullable_int_arg.LongValue();
+              const auto* a_nullable_int_arg =
+                  encodable_a_nullable_int_arg.IsNull()
+                      ? nullptr
+                      : &a_nullable_int_arg_value;
+              ErrorOr<std::optional<int64_t>> output =
+                  api->EchoNullableInt(a_nullable_int_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::EncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_nullable_double_arg = args.at(0);
+              const auto* a_nullable_double_arg =
+                  std::get_if<double>(&encodable_a_nullable_double_arg);
+              ErrorOr<std::optional<double>> output =
+                  api->EchoNullableDouble(a_nullable_double_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::EncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_nullable_bool_arg = args.at(0);
+              const auto* a_nullable_bool_arg =
+                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
+              ErrorOr<std::optional<bool>> output =
+                  api->EchoNullableBool(a_nullable_bool_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::EncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_nullable_string_arg = args.at(0);
+              const auto* a_nullable_string_arg =
+                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
+              ErrorOr<std::optional<std::string>> output =
+                  api->EchoNullableString(a_nullable_string_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::EncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_nullable_uint8_list_arg = args.at(0);
+              const auto* a_nullable_uint8_list_arg =
+                  std::get_if<std::vector<uint8_t>>(
+                      &encodable_a_nullable_uint8_list_arg);
+              ErrorOr<std::optional<std::vector<uint8_t>>> output =
+                  api->EchoNullableUint8List(a_nullable_uint8_list_arg);
+              if (output.has_error()) {
+                wrapped = WrapError(output.error());
+              } else {
+                auto output_optional = std::move(output).TakeValue();
+                if (output_optional) {
+                  wrapped.push_back(flutter::EncodableValue(
+                      std::move(output_optional).value()));
+                } else {
+                  wrapped.push_back(flutter::EncodableValue());
+                }
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              api->NoopAsync(
+                  [&wrapped, &reply](std::optional<FlutterError>&& output) {
+                    if (output.has_value()) {
+                      wrapped = WrapError(output.value());
+                    } else {
+                      wrapped.push_back(flutter::EncodableValue());
+                    }
+                    reply(wrapped);
+                  });
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+              reply(wrapped);
+            }
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_string_arg = args.at(0);
+              if (encodable_a_string_arg.IsNull()) {
+                reply(WrapError("a_string_arg unexpectedly null."));
+                return;
+              }
+              const auto& a_string_arg =
+                  std::get<std::string>(encodable_a_string_arg);
+              api->EchoAsyncString(
+                  a_string_arg,
+                  [&wrapped, &reply](ErrorOr<std::string>&& output) {
+                    if (output.has_error()) {
+                      wrapped = WrapError(output.error());
+                    } else {
+                      wrapped.push_back(flutter::EncodableValue(
+                          std::move(output).TakeValue()));
+                    }
+                    reply(wrapped);
+                  });
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+              reply(wrapped);
+            }
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              api->CallFlutterNoop(
+                  [&wrapped, &reply](std::optional<FlutterError>&& output) {
+                    if (output.has_value()) {
+                      wrapped = WrapError(output.value());
+                    } else {
+                      wrapped.push_back(flutter::EncodableValue());
+                    }
+                    reply(wrapped);
+                  });
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+              reply(wrapped);
+            }
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger,
+            "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              const auto& args = std::get<flutter::EncodableList>(message);
+              const auto& encodable_a_string_arg = args.at(0);
+              if (encodable_a_string_arg.IsNull()) {
+                reply(WrapError("a_string_arg unexpectedly null."));
+                return;
+              }
+              const auto& a_string_arg =
+                  std::get<std::string>(encodable_a_string_arg);
+              api->CallFlutterEchoString(
+                  a_string_arg,
+                  [&wrapped, &reply](ErrorOr<std::string>&& output) {
+                    if (output.has_error()) {
+                      wrapped = WrapError(output.error());
+                    } else {
+                      wrapped.push_back(flutter::EncodableValue(
+                          std::move(output).TakeValue()));
+                    }
+                    reply(wrapped);
+                  });
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+              reply(wrapped);
+            }
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+}
+
+flutter::EncodableList HostIntegrationCoreApi::WrapError(
+    std::string_view error_message) {
+  return flutter::EncodableList(
+      {flutter::EncodableValue(std::string(error_message)),
+       flutter::EncodableValue("Error"), flutter::EncodableValue()});
+}
+flutter::EncodableList HostIntegrationCoreApi::WrapError(
+    const FlutterError& error) {
+  return flutter::EncodableList({flutter::EncodableValue(error.message()),
+                                 flutter::EncodableValue(error.code()),
+                                 error.details()});
+}
+
+FlutterIntegrationCoreApiCodecSerializer::
+    FlutterIntegrationCoreApiCodecSerializer() {}
+flutter::EncodableValue
+FlutterIntegrationCoreApiCodecSerializer::ReadValueOfType(
+    uint8_t type, flutter::ByteStreamReader* stream) const {
+  switch (type) {
+    case 128:
+      return flutter::CustomEncodableValue(AllNullableTypes(
+          std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    case 129:
+      return flutter::CustomEncodableValue(
+          AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    default:
+      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
+  }
+}
+
+void FlutterIntegrationCoreApiCodecSerializer::WriteValue(
+    const flutter::EncodableValue& value,
+    flutter::ByteStreamWriter* stream) const {
+  if (const flutter::CustomEncodableValue* custom_value =
+          std::get_if<flutter::CustomEncodableValue>(&value)) {
+    if (custom_value->type() == typeid(AllNullableTypes)) {
+      stream->WriteByte(128);
+      WriteValue(
+          flutter::EncodableValue(
+              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
+          stream);
+      return;
+    }
+    if (custom_value->type() == typeid(AllTypes)) {
+      stream->WriteByte(129);
+      WriteValue(flutter::EncodableValue(
+                     std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
+                 stream);
+      return;
+    }
+  }
+  flutter::StandardCodecSerializer::WriteValue(value, stream);
+}
+
+// Generated class from Pigeon that represents Flutter messages that can be
+// called from C++.
+FlutterIntegrationCoreApi::FlutterIntegrationCoreApi(
+    flutter::BinaryMessenger* binary_messenger) {
+  this->binary_messenger_ = binary_messenger;
+}
+
+const flutter::StandardMessageCodec& FlutterIntegrationCoreApi::GetCodec() {
+  return flutter::StandardMessageCodec::GetInstance(
+      &FlutterIntegrationCoreApiCodecSerializer::GetInstance());
+}
+
+void FlutterIntegrationCoreApi::noop(std::function<void(void)>&& callback) {
+  auto channel =
+      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+          binary_messenger_,
+          "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", &GetCodec());
+  channel->Send(
+      flutter::EncodableValue(),
+      [callback](const uint8_t* reply, size_t reply_size) { callback(); });
+}
+void FlutterIntegrationCoreApi::echoAllTypes(
+    const AllTypes& everything_arg,
+    std::function<void(const AllTypes&)>&& callback) {
+  auto channel =
+      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+          binary_messenger_,
+          "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes",
+          &GetCodec());
+  channel->Send(
+      flutter::EncodableList{flutter::CustomEncodableValue(everything_arg)},
+      [callback](const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> decoded_reply =
+            GetCodec().DecodeMessage(reply, reply_size);
+        flutter::EncodableValue args =
+            *(flutter::EncodableValue*)(decoded_reply.release());
+        AllTypes output{};
+        if (const flutter::EncodableList* pointer_output =
+                std::get_if<flutter::EncodableList>(&args)) {
+          output = AllTypes(*pointer_output);
+        }
+        callback(output);
+      });
+}
+void FlutterIntegrationCoreApi::echoAllNullableTypes(
+    const AllNullableTypes& everything_arg,
+    std::function<void(const AllNullableTypes&)>&& callback) {
+  auto channel =
+      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+          binary_messenger_,
+          "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
+          &GetCodec());
+  channel->Send(
+      flutter::EncodableList{flutter::CustomEncodableValue(everything_arg)},
+      [callback](const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> decoded_reply =
+            GetCodec().DecodeMessage(reply, reply_size);
+        flutter::EncodableValue args =
+            *(flutter::EncodableValue*)(decoded_reply.release());
+        AllNullableTypes output{};
+        if (const flutter::EncodableList* pointer_output =
+                std::get_if<flutter::EncodableList>(&args)) {
+          output = AllNullableTypes(*pointer_output);
+        }
+        callback(output);
+      });
+}
+void FlutterIntegrationCoreApi::echoString(
+    const std::string& a_string_arg,
+    std::function<void(const std::string&)>&& callback) {
+  auto channel =
+      std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+          binary_messenger_,
+          "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString",
+          &GetCodec());
+  channel->Send(
+      flutter::EncodableList{flutter::CustomEncodableValue(a_string_arg)},
+      [callback](const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> decoded_reply =
+            GetCodec().DecodeMessage(reply, reply_size);
+        flutter::EncodableValue args =
+            *(flutter::EncodableValue*)(decoded_reply.release());
+        std::string output{};
+        if (const std::string* pointer_output =
+                std::get_if<std::string>(&args)) {
+          output = *pointer_output;
+        }
+        callback(output);
+      });
+}
+/// The codec used by HostTrivialApi.
+const flutter::StandardMessageCodec& HostTrivialApi::GetCodec() {
+  return flutter::StandardMessageCodec::GetInstance(
+      &flutter::StandardCodecSerializer::GetInstance());
+}
+
+// Sets up an instance of `HostTrivialApi` to handle messages through the
+// `binary_messenger`.
+void HostTrivialApi::SetUp(flutter::BinaryMessenger* binary_messenger,
+                           HostTrivialApi* api) {
+  {
+    auto channel =
+        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
+            binary_messenger, "dev.flutter.pigeon.HostTrivialApi.noop",
+            &GetCodec());
+    if (api != nullptr) {
+      channel->SetMessageHandler(
+          [api](const flutter::EncodableValue& message,
+                const flutter::MessageReply<flutter::EncodableValue>& reply) {
+            flutter::EncodableList wrapped;
+            try {
+              std::optional<FlutterError> output = api->Noop();
+              if (output.has_value()) {
+                wrapped = WrapError(output.value());
+              } else {
+                wrapped.push_back(flutter::EncodableValue());
+              }
+            } catch (const std::exception& exception) {
+              wrapped = WrapError(exception.what());
+            }
+            reply(wrapped);
+          });
+    } else {
+      channel->SetMessageHandler(nullptr);
+    }
+  }
+}
+
+flutter::EncodableList HostTrivialApi::WrapError(
+    std::string_view error_message) {
+  return flutter::EncodableList(
+      {flutter::EncodableValue(std::string(error_message)),
+       flutter::EncodableValue("Error"), flutter::EncodableValue()});
+}
+flutter::EncodableList HostTrivialApi::WrapError(const FlutterError& error) {
+  return flutter::EncodableList({flutter::EncodableValue(error.message()),
+                                 flutter::EncodableValue(error.code()),
+                                 error.details()});
+}
+
+}  // namespace core_tests_pigeontest
diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h
new file mode 100644
index 0000000..5100fdb
--- /dev/null
+++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h
@@ -0,0 +1,409 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Autogenerated from Pigeon (v4.2.12), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+
+#ifndef PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_
+#define PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_
+#include <flutter/basic_message_channel.h>
+#include <flutter/binary_messenger.h>
+#include <flutter/encodable_value.h>
+#include <flutter/standard_message_codec.h>
+
+#include <map>
+#include <optional>
+#include <string>
+
+namespace core_tests_pigeontest {
+class CoreTestsTest;
+
+// Generated class from Pigeon.
+
+enum class AnEnum { one = 0, two = 1, three = 2 };
+
+class FlutterError {
+ public:
+  explicit FlutterError(const std::string& code) : code_(code) {}
+  explicit FlutterError(const std::string& code, const std::string& message)
+      : code_(code), message_(message) {}
+  explicit FlutterError(const std::string& code, const std::string& message,
+                        const flutter::EncodableValue& details)
+      : code_(code), message_(message), details_(details) {}
+
+  const std::string& code() const { return code_; }
+  const std::string& message() const { return message_; }
+  const flutter::EncodableValue& details() const { return details_; }
+
+ private:
+  std::string code_;
+  std::string message_;
+  flutter::EncodableValue details_;
+};
+
+template <class T>
+class ErrorOr {
+ public:
+  ErrorOr(const T& rhs) { new (&v_) T(rhs); }
+  ErrorOr(const T&& rhs) { v_ = std::move(rhs); }
+  ErrorOr(const FlutterError& rhs) { new (&v_) FlutterError(rhs); }
+  ErrorOr(const FlutterError&& rhs) { v_ = std::move(rhs); }
+
+  bool has_error() const { return std::holds_alternative<FlutterError>(v_); }
+  const T& value() const { return std::get<T>(v_); };
+  const FlutterError& error() const { return std::get<FlutterError>(v_); };
+
+ private:
+  friend class HostIntegrationCoreApi;
+  friend class FlutterIntegrationCoreApi;
+  friend class HostTrivialApi;
+  ErrorOr() = default;
+  T TakeValue() && { return std::get<T>(std::move(v_)); }
+
+  std::variant<T, FlutterError> v_;
+};
+
+// Generated class from Pigeon that represents data sent in messages.
+class AllTypes {
+ public:
+  AllTypes();
+  bool a_bool() const;
+  void set_a_bool(bool value_arg);
+
+  int64_t an_int() const;
+  void set_an_int(int64_t value_arg);
+
+  double a_double() const;
+  void set_a_double(double value_arg);
+
+  const std::string& a_string() const;
+  void set_a_string(std::string_view value_arg);
+
+  const std::vector<uint8_t>& a_byte_array() const;
+  void set_a_byte_array(const std::vector<uint8_t>& value_arg);
+
+  const std::vector<int32_t>& a4_byte_array() const;
+  void set_a4_byte_array(const std::vector<int32_t>& value_arg);
+
+  const std::vector<int64_t>& a8_byte_array() const;
+  void set_a8_byte_array(const std::vector<int64_t>& value_arg);
+
+  const std::vector<double>& a_float_array() const;
+  void set_a_float_array(const std::vector<double>& value_arg);
+
+  const flutter::EncodableList& a_list() const;
+  void set_a_list(const flutter::EncodableList& value_arg);
+
+  const flutter::EncodableMap& a_map() const;
+  void set_a_map(const flutter::EncodableMap& value_arg);
+
+  const AnEnum& an_enum() const;
+  void set_an_enum(const AnEnum& value_arg);
+
+ private:
+  AllTypes(const flutter::EncodableList& list);
+  flutter::EncodableList ToEncodableList() const;
+  friend class HostIntegrationCoreApi;
+  friend class HostIntegrationCoreApiCodecSerializer;
+  friend class FlutterIntegrationCoreApi;
+  friend class FlutterIntegrationCoreApiCodecSerializer;
+  friend class HostTrivialApi;
+  friend class HostTrivialApiCodecSerializer;
+  friend class CoreTestsTest;
+  bool a_bool_;
+  int64_t an_int_;
+  double a_double_;
+  std::string a_string_;
+  std::vector<uint8_t> a_byte_array_;
+  std::vector<int32_t> a4_byte_array_;
+  std::vector<int64_t> a8_byte_array_;
+  std::vector<double> a_float_array_;
+  flutter::EncodableList a_list_;
+  flutter::EncodableMap a_map_;
+  AnEnum an_enum_;
+};
+
+// Generated class from Pigeon that represents data sent in messages.
+class AllNullableTypes {
+ public:
+  AllNullableTypes();
+  const bool* a_nullable_bool() const;
+  void set_a_nullable_bool(const bool* value_arg);
+  void set_a_nullable_bool(bool value_arg);
+
+  const int64_t* a_nullable_int() const;
+  void set_a_nullable_int(const int64_t* value_arg);
+  void set_a_nullable_int(int64_t value_arg);
+
+  const double* a_nullable_double() const;
+  void set_a_nullable_double(const double* value_arg);
+  void set_a_nullable_double(double value_arg);
+
+  const std::string* a_nullable_string() const;
+  void set_a_nullable_string(const std::string_view* value_arg);
+  void set_a_nullable_string(std::string_view value_arg);
+
+  const std::vector<uint8_t>* a_nullable_byte_array() const;
+  void set_a_nullable_byte_array(const std::vector<uint8_t>* value_arg);
+  void set_a_nullable_byte_array(const std::vector<uint8_t>& value_arg);
+
+  const std::vector<int32_t>* a_nullable4_byte_array() const;
+  void set_a_nullable4_byte_array(const std::vector<int32_t>* value_arg);
+  void set_a_nullable4_byte_array(const std::vector<int32_t>& value_arg);
+
+  const std::vector<int64_t>* a_nullable8_byte_array() const;
+  void set_a_nullable8_byte_array(const std::vector<int64_t>* value_arg);
+  void set_a_nullable8_byte_array(const std::vector<int64_t>& value_arg);
+
+  const std::vector<double>* a_nullable_float_array() const;
+  void set_a_nullable_float_array(const std::vector<double>* value_arg);
+  void set_a_nullable_float_array(const std::vector<double>& value_arg);
+
+  const flutter::EncodableList* a_nullable_list() const;
+  void set_a_nullable_list(const flutter::EncodableList* value_arg);
+  void set_a_nullable_list(const flutter::EncodableList& value_arg);
+
+  const flutter::EncodableMap* a_nullable_map() const;
+  void set_a_nullable_map(const flutter::EncodableMap* value_arg);
+  void set_a_nullable_map(const flutter::EncodableMap& value_arg);
+
+  const flutter::EncodableList* nullable_nested_list() const;
+  void set_nullable_nested_list(const flutter::EncodableList* value_arg);
+  void set_nullable_nested_list(const flutter::EncodableList& value_arg);
+
+  const flutter::EncodableMap* nullable_map_with_annotations() const;
+  void set_nullable_map_with_annotations(
+      const flutter::EncodableMap* value_arg);
+  void set_nullable_map_with_annotations(
+      const flutter::EncodableMap& value_arg);
+
+  const flutter::EncodableMap* nullable_map_with_object() const;
+  void set_nullable_map_with_object(const flutter::EncodableMap* value_arg);
+  void set_nullable_map_with_object(const flutter::EncodableMap& value_arg);
+
+  const AnEnum* a_nullable_enum() const;
+  void set_a_nullable_enum(const AnEnum* value_arg);
+  void set_a_nullable_enum(const AnEnum& value_arg);
+
+ private:
+  AllNullableTypes(const flutter::EncodableList& list);
+  flutter::EncodableList ToEncodableList() const;
+  friend class AllNullableTypesWrapper;
+  friend class HostIntegrationCoreApi;
+  friend class HostIntegrationCoreApiCodecSerializer;
+  friend class FlutterIntegrationCoreApi;
+  friend class FlutterIntegrationCoreApiCodecSerializer;
+  friend class HostTrivialApi;
+  friend class HostTrivialApiCodecSerializer;
+  friend class CoreTestsTest;
+  std::optional<bool> a_nullable_bool_;
+  std::optional<int64_t> a_nullable_int_;
+  std::optional<double> a_nullable_double_;
+  std::optional<std::string> a_nullable_string_;
+  std::optional<std::vector<uint8_t>> a_nullable_byte_array_;
+  std::optional<std::vector<int32_t>> a_nullable4_byte_array_;
+  std::optional<std::vector<int64_t>> a_nullable8_byte_array_;
+  std::optional<std::vector<double>> a_nullable_float_array_;
+  std::optional<flutter::EncodableList> a_nullable_list_;
+  std::optional<flutter::EncodableMap> a_nullable_map_;
+  std::optional<flutter::EncodableList> nullable_nested_list_;
+  std::optional<flutter::EncodableMap> nullable_map_with_annotations_;
+  std::optional<flutter::EncodableMap> nullable_map_with_object_;
+  std::optional<AnEnum> a_nullable_enum_;
+};
+
+// Generated class from Pigeon that represents data sent in messages.
+class AllNullableTypesWrapper {
+ public:
+  AllNullableTypesWrapper();
+  const AllNullableTypes& values() const;
+  void set_values(const AllNullableTypes& value_arg);
+
+ private:
+  AllNullableTypesWrapper(const flutter::EncodableList& list);
+  flutter::EncodableList ToEncodableList() const;
+  friend class HostIntegrationCoreApi;
+  friend class HostIntegrationCoreApiCodecSerializer;
+  friend class FlutterIntegrationCoreApi;
+  friend class FlutterIntegrationCoreApiCodecSerializer;
+  friend class HostTrivialApi;
+  friend class HostTrivialApiCodecSerializer;
+  friend class CoreTestsTest;
+  AllNullableTypes values_;
+};
+
+class HostIntegrationCoreApiCodecSerializer
+    : public flutter::StandardCodecSerializer {
+ public:
+  inline static HostIntegrationCoreApiCodecSerializer& GetInstance() {
+    static HostIntegrationCoreApiCodecSerializer sInstance;
+    return sInstance;
+  }
+
+  HostIntegrationCoreApiCodecSerializer();
+
+ public:
+  void WriteValue(const flutter::EncodableValue& value,
+                  flutter::ByteStreamWriter* stream) const override;
+
+ protected:
+  flutter::EncodableValue ReadValueOfType(
+      uint8_t type, flutter::ByteStreamReader* stream) const override;
+};
+
+// The core interface that each host language plugin must implement in
+// platform_test integration tests.
+//
+// Generated interface from Pigeon that represents a handler of messages from
+// Flutter.
+class HostIntegrationCoreApi {
+ public:
+  HostIntegrationCoreApi(const HostIntegrationCoreApi&) = delete;
+  HostIntegrationCoreApi& operator=(const HostIntegrationCoreApi&) = delete;
+  virtual ~HostIntegrationCoreApi(){};
+  // A no-op function taking no arguments and returning no value, to sanity
+  // test basic calling.
+  virtual std::optional<FlutterError> Noop() = 0;
+  // Returns the passed object, to test serialization and deserialization.
+  virtual ErrorOr<AllTypes> EchoAllTypes(const AllTypes& everything) = 0;
+  // Returns the passed object, to test serialization and deserialization.
+  virtual ErrorOr<std::optional<AllNullableTypes>> EchoAllNullableTypes(
+      const AllNullableTypes* everything) = 0;
+  // Returns an error, to test error handling.
+  virtual std::optional<FlutterError> ThrowError() = 0;
+  // Returns passed in int.
+  virtual ErrorOr<int64_t> EchoInt(int64_t an_int) = 0;
+  // Returns passed in double.
+  virtual ErrorOr<double> EchoDouble(double a_double) = 0;
+  // Returns the passed in boolean.
+  virtual ErrorOr<bool> EchoBool(bool a_bool) = 0;
+  // Returns the passed in string.
+  virtual ErrorOr<std::string> EchoString(const std::string& a_string) = 0;
+  // Returns the passed in Uint8List.
+  virtual ErrorOr<std::vector<uint8_t>> EchoUint8List(
+      const std::vector<uint8_t>& a_uint8_list) = 0;
+  // Returns the inner `aString` value from the wrapped object, to test
+  // sending of nested objects.
+  virtual ErrorOr<std::optional<std::string>> ExtractNestedNullableString(
+      const AllNullableTypesWrapper& wrapper) = 0;
+  // Returns the inner `aString` value from the wrapped object, to test
+  // sending of nested objects.
+  virtual ErrorOr<AllNullableTypesWrapper> CreateNestedNullableString(
+      const std::string* nullable_string) = 0;
+  // Returns passed in arguments of multiple types.
+  virtual ErrorOr<AllNullableTypes> SendMultipleNullableTypes(
+      const bool* a_nullable_bool, const int64_t* a_nullable_int,
+      const std::string* a_nullable_string) = 0;
+  // Returns passed in int.
+  virtual ErrorOr<std::optional<int64_t>> EchoNullableInt(
+      const int64_t* a_nullable_int) = 0;
+  // Returns passed in double.
+  virtual ErrorOr<std::optional<double>> EchoNullableDouble(
+      const double* a_nullable_double) = 0;
+  // Returns the passed in boolean.
+  virtual ErrorOr<std::optional<bool>> EchoNullableBool(
+      const bool* a_nullable_bool) = 0;
+  // Returns the passed in string.
+  virtual ErrorOr<std::optional<std::string>> EchoNullableString(
+      const std::string* a_nullable_string) = 0;
+  // Returns the passed in Uint8List.
+  virtual ErrorOr<std::optional<std::vector<uint8_t>>> EchoNullableUint8List(
+      const std::vector<uint8_t>* a_nullable_uint8_list) = 0;
+  // A no-op function taking no arguments and returning no value, to sanity
+  // test basic asynchronous calling.
+  virtual void NoopAsync(
+      std::function<void(std::optional<FlutterError> reply)> result) = 0;
+  // Returns the passed string asynchronously.
+  virtual void EchoAsyncString(
+      const std::string& a_string,
+      std::function<void(ErrorOr<std::string> reply)> result) = 0;
+  virtual void CallFlutterNoop(
+      std::function<void(std::optional<FlutterError> reply)> result) = 0;
+  virtual void CallFlutterEchoString(
+      const std::string& a_string,
+      std::function<void(ErrorOr<std::string> reply)> result) = 0;
+
+  // The codec used by HostIntegrationCoreApi.
+  static const flutter::StandardMessageCodec& GetCodec();
+  // Sets up an instance of `HostIntegrationCoreApi` to handle messages through
+  // the `binary_messenger`.
+  static void SetUp(flutter::BinaryMessenger* binary_messenger,
+                    HostIntegrationCoreApi* api);
+  static flutter::EncodableList WrapError(std::string_view error_message);
+  static flutter::EncodableList WrapError(const FlutterError& error);
+
+ protected:
+  HostIntegrationCoreApi() = default;
+};
+class FlutterIntegrationCoreApiCodecSerializer
+    : public flutter::StandardCodecSerializer {
+ public:
+  inline static FlutterIntegrationCoreApiCodecSerializer& GetInstance() {
+    static FlutterIntegrationCoreApiCodecSerializer sInstance;
+    return sInstance;
+  }
+
+  FlutterIntegrationCoreApiCodecSerializer();
+
+ public:
+  void WriteValue(const flutter::EncodableValue& value,
+                  flutter::ByteStreamWriter* stream) const override;
+
+ protected:
+  flutter::EncodableValue ReadValueOfType(
+      uint8_t type, flutter::ByteStreamReader* stream) const override;
+};
+
+// The core interface that the Dart platform_test code implements for host
+// integration tests to call into.
+//
+// Generated class from Pigeon that represents Flutter messages that can be
+// called from C++.
+class FlutterIntegrationCoreApi {
+ private:
+  flutter::BinaryMessenger* binary_messenger_;
+
+ public:
+  FlutterIntegrationCoreApi(flutter::BinaryMessenger* binary_messenger);
+  static const flutter::StandardMessageCodec& GetCodec();
+  // A no-op function taking no arguments and returning no value, to sanity
+  // test basic calling.
+  void noop(std::function<void(void)>&& callback);
+  // Returns the passed object, to test serialization and deserialization.
+  void echoAllTypes(const AllTypes& everything_arg,
+                    std::function<void(const AllTypes&)>&& callback);
+  // Returns the passed object, to test serialization and deserialization.
+  void echoAllNullableTypes(
+      const AllNullableTypes& everything_arg,
+      std::function<void(const AllNullableTypes&)>&& callback);
+  // Returns the passed string, to test serialization and deserialization.
+  void echoString(const std::string& a_string_arg,
+                  std::function<void(const std::string&)>&& callback);
+};
+
+// An API that can be implemented for minimal, compile-only tests.
+//
+// Generated interface from Pigeon that represents a handler of messages from
+// Flutter.
+class HostTrivialApi {
+ public:
+  HostTrivialApi(const HostTrivialApi&) = delete;
+  HostTrivialApi& operator=(const HostTrivialApi&) = delete;
+  virtual ~HostTrivialApi(){};
+  virtual std::optional<FlutterError> Noop() = 0;
+
+  // The codec used by HostTrivialApi.
+  static const flutter::StandardMessageCodec& GetCodec();
+  // Sets up an instance of `HostTrivialApi` to handle messages through the
+  // `binary_messenger`.
+  static void SetUp(flutter::BinaryMessenger* binary_messenger,
+                    HostTrivialApi* api);
+  static flutter::EncodableList WrapError(std::string_view error_message);
+  static flutter::EncodableList WrapError(const FlutterError& error);
+
+ protected:
+  HostTrivialApi() = default;
+};
+}  // namespace core_tests_pigeontest
+#endif  // PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_
