[pigeon] Fix C++ generator's handling of Flutter APIs (#3042)

* Add new APIs, unimplemented and unused

* Add Dart implementation

* Add multiple arity FlutterApi

* Add Dart unit tests for desired output format

* Enable the existing integration test

* Add units tests for callback format

* Adjust unit test expectations for error callback

* First-pass implementation; mostly untested

* Comment fix

* Add todo

* Minor fixes

* Fix compilation error in Swift from new pigeons

* Make new Maps string-keyed to avoid Swift error

* Update generation

* Update unit test for change

* Update C++ test plugin for API changes

* Fix type regression

* missing ;

* Drop string_view in Flutter API

* Unwind incorrect 'simplification' of custom classes

* Fix merge mistake

* Merge mistake

* Version bump

* Address review comments

* Fix Dart unit test compilation
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 2bf8a72..9c62479 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.0.1
+
+* [c++] Fixes most non-class arguments and return values in Flutter APIs. The
+  types of arguments and return values have changed, so this may require updates
+  to existing code.
+
 ## 6.0.0
 
 * Creates StructuredGenerator class and implements it on all platforms.
diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart
index 105f6bd..71a3a24 100644
--- a/packages/pigeon/lib/cpp_generator.dart
+++ b/packages/pigeon/lib/cpp_generator.dart
@@ -191,10 +191,7 @@
           addDocumentationComments(
               indent, field.documentationComments, _docCommentSpec);
           final HostDatatype baseDatatype = getFieldHostDatatype(
-              field,
-              root.classes,
-              root.enums,
-              (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
+              field, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
           indent.writeln(
               '${_getterReturnType(baseDatatype)} ${_makeGetterName(field)}() const;');
           indent.writeln(
@@ -233,10 +230,7 @@
 
         for (final NamedType field in getFieldsInSerializationOrder(klass)) {
           final HostDatatype hostDatatype = getFieldHostDatatype(
-              field,
-              root.classes,
-              root.enums,
-              (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
+              field, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
           indent.writeln(
               '${_valueType(hostDatatype)} ${_makeInstanceVariableName(field)};');
         }
@@ -273,24 +267,24 @@
         indent
             .writeln('static const flutter::StandardMessageCodec& GetCodec();');
         for (final Method func in api.methods) {
-          final String returnType = func.returnType.isVoid
-              ? 'void'
-              : _nullSafeCppTypeForDartType(func.returnType);
-          final String callback = 'std::function<void($returnType)>&& callback';
+          final HostDatatype returnType = getHostDatatype(func.returnType,
+              root.classes, root.enums, _baseCppTypeForBuiltinDartType);
           addDocumentationComments(
               indent, func.documentationComments, _docCommentSpec);
-          if (func.arguments.isEmpty) {
-            indent.writeln('void ${func.name}($callback);');
-          } else {
-            final Iterable<String> argTypes = func.arguments
-                .map((NamedType e) => _nullSafeCppTypeForDartType(e.type));
-            final Iterable<String> argNames =
-                indexMap(func.arguments, _getSafeArgumentName);
-            final String argsSignature =
-                map2(argTypes, argNames, (String x, String y) => '$x $y')
-                    .join(', ');
-            indent.writeln('void ${func.name}($argsSignature, $callback);');
-          }
+
+          final Iterable<String> argTypes = func.arguments.map((NamedType arg) {
+            final HostDatatype hostType = getFieldHostDatatype(
+                arg, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
+            return _flutterApiArgumentType(hostType);
+          });
+          final Iterable<String> argNames =
+              indexMap(func.arguments, _getArgumentName);
+          final List<String> parameters = <String>[
+            ...map2(argTypes, argNames, (String x, String y) => '$x $y'),
+            ..._flutterApiCallbackParameters(returnType),
+          ];
+          indent.writeln(
+              'void ${_makeMethodName(func)}(${parameters.join(', ')});');
         }
       });
     }, nestCount: 0);
@@ -320,22 +314,16 @@
         indent.writeln('${api.name}& operator=(const ${api.name}&) = delete;');
         indent.writeln('virtual ~${api.name}() { };');
         for (final Method method in api.methods) {
-          final HostDatatype returnType = getHostDatatype(
-              method.returnType,
-              root.classes,
-              root.enums,
-              (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
-          final String returnTypeName = _apiReturnType(returnType);
+          final HostDatatype returnType = getHostDatatype(method.returnType,
+              root.classes, root.enums, _baseCppTypeForBuiltinDartType);
+          final String returnTypeName = _hostApiReturnType(returnType);
 
           final List<String> argSignature = <String>[];
           if (method.arguments.isNotEmpty) {
             final Iterable<String> argTypes =
                 method.arguments.map((NamedType arg) {
-              final HostDatatype hostType = getFieldHostDatatype(
-                  arg,
-                  root.classes,
-                  root.enums,
-                  (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
+              final HostDatatype hostType = getFieldHostDatatype(arg,
+                  root.classes, root.enums, _baseCppTypeForBuiltinDartType);
               return _hostApiArgumentType(hostType);
             });
             final Iterable<String> argNames =
@@ -557,36 +545,9 @@
       indent.scoped('return flutter::EncodableList{', '};', () {
         for (final NamedType field in getFieldsInSerializationOrder(klass)) {
           final HostDatatype hostDatatype = getFieldHostDatatype(
-              field,
-              root.classes,
-              root.enums,
-              (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
-
-          final String instanceVariable = _makeInstanceVariableName(field);
-
-          String encodableValue = '';
-          if (!hostDatatype.isBuiltin &&
-              customClassNames.contains(field.type.baseName)) {
-            final String operator = field.type.isNullable ? '->' : '.';
-            encodableValue =
-                'flutter::EncodableValue($instanceVariable${operator}ToEncodableList())';
-          } else if (!hostDatatype.isBuiltin &&
-              customEnumNames.contains(field.type.baseName)) {
-            final String nonNullValue = field.type.isNullable
-                ? '(*$instanceVariable)'
-                : instanceVariable;
-            encodableValue = 'flutter::EncodableValue((int)$nonNullValue)';
-          } else {
-            final String operator = field.type.isNullable ? '*' : '';
-            encodableValue =
-                'flutter::EncodableValue($operator$instanceVariable)';
-          }
-
-          if (field.type.isNullable) {
-            encodableValue =
-                '$instanceVariable ? $encodableValue : flutter::EncodableValue()';
-          }
-
+              field, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
+          final String encodableValue = _wrappedHostApiArgumentExpression(
+              root, _makeInstanceVariableName(field), field.type, hostDatatype);
           indent.writeln('$encodableValue,');
         }
       });
@@ -619,10 +580,7 @@
               'if (const int32_t* $pointerFieldName = std::get_if<int32_t>(&$encodableFieldName))\t$instanceVariableName = (${field.type.baseName})*$pointerFieldName;');
         } else {
           final HostDatatype hostDatatype = getFieldHostDatatype(
-              field,
-              root.classes,
-              root.enums,
-              (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
+              field, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
           if (field.type.baseName == 'int') {
             indent.format('''
 if (const int32_t* $pointerFieldName = std::get_if<int32_t>(&$encodableFieldName))
@@ -681,80 +639,66 @@
 ''');
     for (final Method func in api.methods) {
       final String channelName = makeChannelName(api, func);
-      final String returnType = func.returnType.isVoid
-          ? 'void'
-          : _nullSafeCppTypeForDartType(func.returnType);
-      String sendArgument;
-      final String callback = 'std::function<void($returnType)>&& callback';
-      if (func.arguments.isEmpty) {
-        indent.write('void ${api.name}::${func.name}($callback) ');
-        sendArgument = 'flutter::EncodableValue()';
-      } else {
-        final Iterable<String> argTypes = func.arguments
-            .map((NamedType e) => _nullSafeCppTypeForDartType(e.type));
-        final Iterable<String> argNames =
-            indexMap(func.arguments, _getSafeArgumentName);
-        sendArgument =
-            'flutter::EncodableList { ${argNames.map((String arg) => 'flutter::CustomEncodableValue($arg)').join(', ')} }';
-        final String argsSignature =
-            map2(argTypes, argNames, (String x, String y) => '$x $y')
-                .join(', ');
-        indent.write(
-            'void ${api.name}::${func.name}($argsSignature, $callback) ');
-      }
+      final HostDatatype returnType = getHostDatatype(func.returnType,
+          root.classes, root.enums, _baseCppTypeForBuiltinDartType);
+
+      // Determine the input paramater list, saved in a structured form for later
+      // use as platform channel call arguments.
+      final Iterable<_HostNamedType> hostParameters =
+          indexMap(func.arguments, (int i, NamedType arg) {
+        final HostDatatype hostType = getFieldHostDatatype(
+            arg, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
+        return _HostNamedType(_getSafeArgumentName(i, arg), hostType, arg.type);
+      });
+      final List<String> parameters = <String>[
+        ...hostParameters.map((_HostNamedType arg) =>
+            '${_flutterApiArgumentType(arg.hostType)} ${arg.name}'),
+        ..._flutterApiCallbackParameters(returnType),
+      ];
+      indent.write(
+          'void ${api.name}::${_makeMethodName(func)}(${parameters.join(', ')}) ');
       indent.scoped('{', '}', () {
         const String channel = 'channel';
         indent.writeln(
-            'auto channel = std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(');
-        indent.inc();
-        indent.inc();
-        indent.writeln('binary_messenger_, "$channelName", &GetCodec());');
-        indent.dec();
-        indent.dec();
-        indent.write(
-            '$channel->Send($sendArgument, [callback](const uint8_t* reply, size_t reply_size) ');
+            'auto channel = std::make_unique<flutter::BasicMessageChannel<>>(binary_messenger_, '
+            '"$channelName", &GetCodec());');
+
+        // Convert arguments to EncodableValue versions.
+        const String argumentListVariableName = 'encoded_api_arguments';
+        indent.write('flutter::EncodableValue $argumentListVariableName = ');
+        if (func.arguments.isEmpty) {
+          indent.addln('flutter::EncodableValue();');
+        } else {
+          indent.scoped(
+              'flutter::EncodableValue(flutter::EncodableList{', '});', () {
+            for (final _HostNamedType param in hostParameters) {
+              final String encodedArgument = _wrappedHostApiArgumentExpression(
+                  root, param.name, param.originalType, param.hostType);
+              indent.writeln('$encodedArgument,');
+            }
+          });
+        }
+
+        indent.write('$channel->Send($argumentListVariableName, '
+            // ignore: missing_whitespace_between_adjacent_strings
+            '[on_success = std::move(on_success), on_error = std::move(on_error)]'
+            '(const uint8_t* reply, size_t reply_size) ');
         indent.scoped('{', '});', () {
+          final String successCallbackArgument;
           if (func.returnType.isVoid) {
-            indent.writeln('callback();');
+            successCallbackArgument = '';
           } else {
+            successCallbackArgument = 'return_value';
+            final String encodedReplyName =
+                'encodable_$successCallbackArgument';
             indent.writeln(
-                'std::unique_ptr<flutter::EncodableValue> decoded_reply = GetCodec().DecodeMessage(reply, reply_size);');
-            indent.writeln(
-                'flutter::EncodableValue args = *(flutter::EncodableValue*)(decoded_reply.release());');
-            const String output = 'output';
-
-            final bool isBuiltin =
-                _baseCppTypeForBuiltinDartType(func.returnType) != null;
-            final String returnTypeName =
-                _baseCppTypeForDartType(func.returnType);
-            if (func.returnType.isNullable) {
-              indent.writeln('$returnType $output{};');
-            } else {
-              indent.writeln('$returnTypeName $output{};');
-            }
-            const String pointerVariable = '${_pointerPrefix}_$output';
-            if (func.returnType.baseName == 'int') {
-              indent.format('''
-if (const int32_t* $pointerVariable = std::get_if<int32_t>(&args))
-\t$output = *$pointerVariable;
-else if (const int64_t* ${pointerVariable}_64 = std::get_if<int64_t>(&args))
-\t$output = *${pointerVariable}_64;''');
-            } else if (!isBuiltin) {
-              indent.write(
-                  'if (const flutter::EncodableList* $pointerVariable = std::get_if<flutter::EncodableList>(&args)) ');
-              indent.scoped('{', '}', () {
-                indent.writeln('$output = $returnTypeName(*$pointerVariable);');
-              });
-            } else {
-              indent.write(
-                  'if (const $returnTypeName* $pointerVariable = std::get_if<$returnTypeName>(&args)) ');
-              indent.scoped('{', '}', () {
-                indent.writeln('$output = *$pointerVariable;');
-              });
-            }
-
-            indent.writeln('callback($output);');
+                'std::unique_ptr<flutter::EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);');
+            indent.writeln('const auto& $encodedReplyName = *response;');
+            _writeEncodableValueArgumentUnwrapping(indent, returnType,
+                argName: successCallbackArgument,
+                encodableArgName: encodedReplyName);
           }
+          indent.writeln('on_success($successCallbackArgument);');
         });
       });
     }
@@ -787,12 +731,8 @@
         indent.write('');
         indent.scoped('{', '}', () {
           indent.writeln(
-              'auto channel = std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(');
-          indent.inc();
-          indent.inc();
-          indent.writeln('binary_messenger, "$channelName", &GetCodec());');
-          indent.dec();
-          indent.dec();
+              'auto channel = std::make_unique<flutter::BasicMessageChannel<>>(binary_messenger, '
+              '"$channelName", &GetCodec());');
           indent.write('if (api != nullptr) ');
           indent.scoped('{', '} else {', () {
             indent.write(
@@ -805,70 +745,6 @@
                   indent.writeln(
                       'const auto& args = std::get<flutter::EncodableList>(message);');
 
-                  // Writes the code to declare and populate a variable called
-                  // [argName] to use as a parameter to an API method call from
-                  // an existing EncodablValue variable called [encodableArgName]
-                  // which corresponds to [arg] in the API definition.
-                  void extractEncodedArgument(
-                      String argName,
-                      String encodableArgName,
-                      NamedType arg,
-                      HostDatatype hostType) {
-                    if (arg.type.isNullable) {
-                      // Nullable arguments are always pointers, with nullptr
-                      // corresponding to null.
-                      if (hostType.datatype == 'int64_t') {
-                        // The EncodableValue will either be an int32_t or an
-                        // int64_t depending on the value, but the generated API
-                        // requires an int64_t so that it can handle any case.
-                        // Create a local variable for the 64-bit value...
-                        final String valueVarName = '${argName}_value';
-                        indent.writeln(
-                            'const int64_t $valueVarName = $encodableArgName.IsNull() ? 0 : $encodableArgName.LongValue();');
-                        // ... then declare the arg as a reference to that local.
-                        indent.writeln(
-                            'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;');
-                      } else if (hostType.datatype ==
-                          'flutter::EncodableValue') {
-                        // Generic objects just pass the EncodableValue through
-                        // directly.
-                        indent.writeln(
-                            'const auto* $argName = &$encodableArgName;');
-                      } else if (hostType.isBuiltin) {
-                        indent.writeln(
-                            'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);');
-                      } else {
-                        indent.writeln(
-                            'const auto* $argName = &(std::any_cast<const ${hostType.datatype}&>(std::get<flutter::CustomEncodableValue>($encodableArgName)));');
-                      }
-                    } else {
-                      // Non-nullable arguments are either passed by value or
-                      // reference, but the extraction doesn't need to distinguish
-                      // since those are the same at the call site.
-                      if (hostType.datatype == 'int64_t') {
-                        // The EncodableValue will either be an int32_t or an
-                        // int64_t depending on the value, but the generated API
-                        // requires an int64_t so that it can handle any case.
-                        indent.writeln(
-                            'const int64_t $argName = $encodableArgName.LongValue();');
-                      } else if (hostType.datatype ==
-                          'flutter::EncodableValue') {
-                        // Generic objects just pass the EncodableValue through
-                        // directly. This creates an alias just to avoid having to
-                        // special-case the argName/encodableArgName distinction
-                        // at a higher level.
-                        indent.writeln(
-                            'const auto& $argName = $encodableArgName;');
-                      } else if (hostType.isBuiltin) {
-                        indent.writeln(
-                            'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);');
-                      } else {
-                        indent.writeln(
-                            'const auto& $argName = std::any_cast<const ${hostType.datatype}&>(std::get<flutter::CustomEncodableValue>($encodableArgName));');
-                      }
-                    }
-                  }
-
                   enumerate(method.arguments, (int index, NamedType arg) {
                     final HostDatatype hostType = getHostDatatype(
                         arg.type,
@@ -890,8 +766,8 @@
                         indent.writeln('return;');
                       });
                     }
-                    extractEncodedArgument(
-                        argName, encodableArgName, arg, hostType);
+                    _writeEncodableValueArgumentUnwrapping(indent, hostType,
+                        argName: argName, encodableArgName: encodableArgName);
                     methodArgument.add(argName);
                   });
                 }
@@ -900,8 +776,8 @@
                     method.returnType,
                     root.classes,
                     root.enums,
-                    (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
-                final String returnTypeName = _apiReturnType(returnType);
+                    _baseCppTypeForBuiltinDartType);
+                final String returnTypeName = _hostApiReturnType(returnType);
                 if (method.isAsynchronous) {
                   methodArgument.add(
                     '[reply]($returnTypeName&& output) {${indent.newline}'
@@ -1011,8 +887,8 @@
 
   void _writeCppSourceClassField(CppOptions generatorOptions, Root root,
       Indent indent, Class klass, NamedType field) {
-    final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes,
-        root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
+    final HostDatatype hostDatatype = getFieldHostDatatype(
+        field, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
     final String instanceVariableName = _makeInstanceVariableName(field);
     final String qualifiedGetterName =
         '${klass.name}::${_makeGetterName(field)}';
@@ -1058,8 +934,8 @@
       errorCondition = 'output.has_value()';
       errorGetter = 'value';
     } else {
-      final HostDatatype hostType = getHostDatatype(returnType, root.classes,
-          root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x));
+      final HostDatatype hostType = getHostDatatype(
+          returnType, root.classes, root.enums, _baseCppTypeForBuiltinDartType);
       const String extractedValue = 'std::move(output).TakeValue()';
       final String wrapperType = hostType.isBuiltin
           ? 'flutter::EncodableValue'
@@ -1104,6 +980,18 @@
   }
 }
 
+/// Contains information about a host function argument.
+///
+/// This is comparable to a [NamedType], but has already gone through host type
+/// and variable name mapping, and it tracks the original [NamedType] that it
+/// was created from.
+class _HostNamedType {
+  const _HostNamedType(this.name, this.hostType, this.originalType);
+  final String name;
+  final HostDatatype hostType;
+  final TypeDeclaration originalType;
+}
+
 String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer';
 
 const String _pointerPrefix = 'pointer';
@@ -1162,6 +1050,15 @@
   }
 }
 
+/// Returns the parameters to use for the success and error callbacks in a
+/// Flutter API function signature.
+List<String> _flutterApiCallbackParameters(HostDatatype returnType) {
+  return <String>[
+    'std::function<void(${_flutterApiReturnType(returnType)})>&& on_success',
+    'std::function<void(const FlutterError&)>&& on_error',
+  ];
+}
+
 /// Returns true if [type] corresponds to a plain-old-data type (i.e., one that
 /// should generally be passed by value rather than pointer/reference) in C++.
 bool _isPodType(HostDatatype type) {
@@ -1190,12 +1087,6 @@
   }
 }
 
-/// Returns the base C++ type (without pointer, reference, optional, etc.) for
-/// the given [type].
-String _baseCppTypeForDartType(TypeDeclaration type) {
-  return _baseCppTypeForBuiltinDartType(type) ?? type.baseName;
-}
-
 /// Returns the C++ type to use in a value context (variable declaration,
 /// pass-by-value, etc.) for the given C++ base type.
 String _valueType(HostDatatype type) {
@@ -1228,6 +1119,19 @@
   return type.isNullable ? 'const $baseType*' : 'const $baseType&';
 }
 
+/// Returns the C++ type to use for arguments to a Flutter API.
+String _flutterApiArgumentType(HostDatatype type) {
+  // Nullable strings use std::string* rather than std::string_view*
+  // since there's no implicit conversion for the pointer types, making them
+  // more awkward to use. For consistency, and since EncodableValue will end
+  // up making a std::string internally anyway, std::string is used for the
+  // non-nullable case as well.
+  if (type.datatype == 'std::string') {
+    return type.isNullable ? 'const std::string*' : 'const std::string&';
+  }
+  return _unownedArgumentType(type);
+}
+
 /// Returns the C++ type to use for the return of a getter for a field of type
 /// [type].
 String _getterReturnType(HostDatatype type) {
@@ -1241,9 +1145,9 @@
   return type.isNullable ? 'const $baseType*' : 'const $baseType&';
 }
 
-/// Returns the C++ type to use for the return of an API method retutrning
+/// Returns the C++ type to use for the return of a host API method returning
 /// [type].
-String _apiReturnType(HostDatatype type) {
+String _hostApiReturnType(HostDatatype type) {
   if (type.datatype == 'void') {
     return 'std::optional<FlutterError>';
   }
@@ -1254,31 +1158,25 @@
   return 'ErrorOr<$valueType>';
 }
 
-// TODO(stuartmorgan): Audit all uses of this and convert them to context-based
-// methods like those above. Code still using this method may well have bugs.
-String _nullSafeCppTypeForDartType(TypeDeclaration type,
-    {bool considerReference = true}) {
-  if (type.isNullable) {
-    return 'std::optional<${_baseCppTypeForDartType(type)}>';
-  } else {
-    String typeName = _baseCppTypeForDartType(type);
-    if (_isReferenceType(typeName)) {
-      if (considerReference) {
-        typeName = 'const $typeName&';
-      } else {
-        typeName = 'std::unique_ptr<$typeName>';
-      }
-    }
-    return typeName;
+/// Returns the C++ type to use for the paramer to the asyncronous "return"
+/// callback of a Flutter API method returning [type].
+String _flutterApiReturnType(HostDatatype type) {
+  if (type.datatype == 'void') {
+    return 'void';
   }
+  // For anything other than void, handle it the same way as a host API argument
+  // since it has the same basic structure of being a function defined by the
+  // client, being called by the generated code.
+  return _hostApiArgumentType(type);
 }
 
 String _getGuardName(String? headerFileName) {
-  String guardName = 'PIGEON_';
+  const String prefix = 'PIGEON_';
   if (headerFileName != null) {
-    guardName += '${headerFileName.replaceAll('.', '_').toUpperCase()}_';
+    return '$prefix${headerFileName.replaceAll('.', '_').toUpperCase()}_';
+  } else {
+    return '${prefix}H_';
   }
-  return '${guardName}H_';
 }
 
 void _writeSystemHeaderIncludeBlock(Indent indent, List<String> headers) {
@@ -1288,6 +1186,88 @@
   }
 }
 
+/// Returns the expression to create an EncodableValue from a host API argument
+/// with the given [variableName] and types.
+String _wrappedHostApiArgumentExpression(Root root, String variableName,
+    TypeDeclaration dartType, HostDatatype hostType) {
+  final String encodableValue;
+  if (!hostType.isBuiltin &&
+      root.classes.any((Class c) => c.name == dartType.baseName)) {
+    final String operator = hostType.isNullable ? '->' : '.';
+    encodableValue =
+        'flutter::EncodableValue($variableName${operator}ToEncodableList())';
+  } else if (!hostType.isBuiltin &&
+      root.enums.any((Enum e) => e.name == dartType.baseName)) {
+    final String nonNullValue =
+        hostType.isNullable ? '(*$variableName)' : variableName;
+    encodableValue = 'flutter::EncodableValue((int)$nonNullValue)';
+  } else {
+    final String operator = hostType.isNullable ? '*' : '';
+    encodableValue = 'flutter::EncodableValue($operator$variableName)';
+  }
+
+  if (hostType.isNullable) {
+    return '$variableName ? $encodableValue : flutter::EncodableValue()';
+  }
+  return encodableValue;
+}
+
+// Writes the code to declare and populate a variable of type [hostType] called
+// [argName] to use as a parameter to an API method call, from an existing
+// EncodableValue variable called [encodableArgName].
+void _writeEncodableValueArgumentUnwrapping(
+  Indent indent,
+  HostDatatype hostType, {
+  required String argName,
+  required String encodableArgName,
+}) {
+  if (hostType.isNullable) {
+    // Nullable arguments are always pointers, with nullptr corresponding to
+    // null.
+    if (hostType.datatype == 'int64_t') {
+      // The EncodableValue will either be an int32_t or an int64_t depending
+      // on the value, but the generated API requires an int64_t so that it can
+      // handle any case. Create a local variable for the 64-bit value...
+      final String valueVarName = '${argName}_value';
+      indent.writeln(
+          'const int64_t $valueVarName = $encodableArgName.IsNull() ? 0 : $encodableArgName.LongValue();');
+      // ... then declare the arg as a reference to that local.
+      indent.writeln(
+          'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;');
+    } else if (hostType.datatype == 'flutter::EncodableValue') {
+      // Generic objects just pass the EncodableValue through directly.
+      indent.writeln('const auto* $argName = &$encodableArgName;');
+    } else if (hostType.isBuiltin) {
+      indent.writeln(
+          'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);');
+    } else {
+      indent.writeln(
+          'const auto* $argName = &(std::any_cast<const ${hostType.datatype}&>(std::get<flutter::CustomEncodableValue>($encodableArgName)));');
+    }
+  } else {
+    // Non-nullable arguments are either passed by value or reference, but the
+    // extraction doesn't need to distinguish since those are the same at the
+    // call site.
+    if (hostType.datatype == 'int64_t') {
+      // The EncodableValue will either be an int32_t or an int64_t depending
+      // on the value, but the generated API requires an int64_t so that it can
+      // handle any case.
+      indent.writeln('const int64_t $argName = $encodableArgName.LongValue();');
+    } else if (hostType.datatype == 'flutter::EncodableValue') {
+      // Generic objects just pass the EncodableValue through directly. This
+      // creates an alias just to avoid having to special-case the
+      // argName/encodableArgName distinction at a higher level.
+      indent.writeln('const auto& $argName = $encodableArgName;');
+    } else if (hostType.isBuiltin) {
+      indent.writeln(
+          'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);');
+    } else {
+      indent.writeln(
+          'const auto& $argName = std::any_cast<const ${hostType.datatype}&>(std::get<flutter::CustomEncodableValue>($encodableArgName));');
+    }
+  }
+}
+
 /// Validates an AST to make sure the cpp generator supports everything.
 List<Error> validateCpp(CppOptions options, Root root) {
   final List<Error> result = <Error>[];
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 3dc1df4..40f2f5b 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -9,7 +9,7 @@
 import 'ast.dart';
 
 /// The current version of pigeon. This must match the version in pubspec.yaml.
-const String pigeonVersion = '6.0.0';
+const String pigeonVersion = '6.0.1';
 
 /// Read all the content from [stdin] to a String.
 String readStdin() {
diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart
index 46e1400..d8f5b1a 100644
--- a/packages/pigeon/lib/swift_generator.dart
+++ b/packages/pigeon/lib/swift_generator.dart
@@ -313,7 +313,7 @@
               indexMap(func.arguments, _getArgumentName);
           final Iterable<String> argNames =
               indexMap(func.arguments, _getSafeArgumentName);
-          sendArgument = '[${argNames.join(', ')}]';
+          sendArgument = '[${argNames.join(', ')}] as [Any?]';
           final String argsSignature = map3(
               argTypes,
               argLabels,
diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart
index bf02b40..0afd305 100644
--- a/packages/pigeon/mock_handler_tester/test/message.dart
+++ b/packages/pigeon/mock_handler_tester/test/message.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/mock_handler_tester/test/test.dart b/packages/pigeon/mock_handler_tester/test/test.dart
index 5cc8473..25f5d73 100644
--- a/packages/pigeon/mock_handler_tester/test/test.dart
+++ b/packages/pigeon/mock_handler_tester/test/test.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import
 // ignore_for_file: avoid_relative_lib_imports
diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart
index ed4ba3a..1699b0f 100644
--- a/packages/pigeon/pigeons/core_tests.dart
+++ b/packages/pigeon/pigeons/core_tests.dart
@@ -191,10 +191,12 @@
   @ObjCSelector('callFlutterEchoString:')
   String callFlutterEchoString(String aString);
 
-  // TODO(stuartmorgan): Add callFlutterEchoString and the associated test once
-  // either https://github.com/flutter/flutter/issues/116117 is fixed, or the
-  // problematic type is moved out of AllTypes and into its own test, since
+  // TODO(stuartmorgan): Add callFlutterEchoAllTypes and the associated test
+  // once either https://github.com/flutter/flutter/issues/116117 is fixed, or
+  // the problematic type is moved out of AllTypes and into its own test, since
   // the type mismatch breaks the second `encode` round.
+
+  // TODO(stuartmorgan): Fill in the rest of the callFlutterEcho* tests.
 }
 
 /// The core interface that the Dart platform_test code implements for host
@@ -213,9 +215,72 @@
   @ObjCSelector('echoAllNullableTypes:')
   AllNullableTypes echoAllNullableTypes(AllNullableTypes everything);
 
+  /// Returns passed in arguments of multiple types.
+  ///
+  /// Tests multiple-arity FlutterApi handling.
+  @ObjCSelector('sendMultipleNullableTypesABool:anInt:aString:')
+  AllNullableTypes sendMultipleNullableTypes(
+      bool? aNullableBool, int? aNullableInt, String? aNullableString);
+
+  // ========== Non-nullable argument/return type tests ==========
+
+  /// Returns the passed boolean, to test serialization and deserialization.
+  @ObjCSelector('echoBool:')
+  bool echoBool(bool aBool);
+
+  /// Returns the passed int, to test serialization and deserialization.
+  @ObjCSelector('echoInt:')
+  int echoInt(int anInt);
+
+  /// Returns the passed double, to test serialization and deserialization.
+  @ObjCSelector('echoDouble:')
+  double echoDouble(double aDouble);
+
   /// Returns the passed string, to test serialization and deserialization.
   @ObjCSelector('echoString:')
   String echoString(String aString);
+
+  /// Returns the passed byte list, to test serialization and deserialization.
+  @ObjCSelector('echoUint8List:')
+  Uint8List echoUint8List(Uint8List aList);
+
+  /// Returns the passed list, to test serialization and deserialization.
+  @ObjCSelector('echoList:')
+  List<Object?> echoList(List<Object?> aList);
+
+  /// Returns the passed map, to test serialization and deserialization.
+  @ObjCSelector('echoMap:')
+  Map<String?, Object?> echoMap(Map<String?, Object?> aMap);
+
+  // ========== Nullable argument/return type tests ==========
+
+  /// Returns the passed boolean, to test serialization and deserialization.
+  @ObjCSelector('echoNullableBool:')
+  bool? echoNullableBool(bool? aBool);
+
+  /// Returns the passed int, to test serialization and deserialization.
+  @ObjCSelector('echoNullableInt:')
+  int? echoNullableInt(int? anInt);
+
+  /// Returns the passed double, to test serialization and deserialization.
+  @ObjCSelector('echoNullableDouble:')
+  double? echoNullableDouble(double? aDouble);
+
+  /// Returns the passed string, to test serialization and deserialization.
+  @ObjCSelector('echoNullableString:')
+  String? echoNullableString(String? aString);
+
+  /// Returns the passed byte list, to test serialization and deserialization.
+  @ObjCSelector('echoNullableUint8List:')
+  Uint8List? echoNullableUint8List(Uint8List? aList);
+
+  /// Returns the passed list, to test serialization and deserialization.
+  @ObjCSelector('echoNullableList:')
+  List<Object?>? echoNullableList(List<Object?>? aList);
+
+  /// Returns the passed map, to test serialization and deserialization.
+  @ObjCSelector('echoNullableMap:')
+  Map<String?, Object?> echoNullableMap(Map<String?, Object?> aMap);
 }
 
 /// An API that can be implemented for minimal, compile-only tests.
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
index d97d0cc..13367f2 100644
--- 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
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 package com.example.alternate_language_test_plugin;
@@ -17,6 +17,7 @@
 import java.io.ByteArrayOutputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -1518,6 +1519,9 @@
           return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
 
         case (byte) 129:
+          return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));
+
+        case (byte) 130:
           return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
 
         default:
@@ -1530,8 +1534,11 @@
       if (value instanceof AllNullableTypes) {
         stream.write(128);
         writeValue(stream, ((AllNullableTypes) value).toList());
-      } else if (value instanceof AllTypes) {
+      } else if (value instanceof AllNullableTypesWrapper) {
         stream.write(129);
+        writeValue(stream, ((AllNullableTypesWrapper) value).toList());
+      } else if (value instanceof AllTypes) {
+        stream.write(130);
         writeValue(stream, ((AllTypes) value).toList());
       } else {
         super.writeValue(stream, value);
@@ -1603,6 +1610,71 @@
             callback.reply(output);
           });
     }
+    /**
+     * Returns passed in arguments of multiple types.
+     *
+     * <p>Tests multiple-arity FlutterApi handling.
+     */
+    public void sendMultipleNullableTypes(
+        @Nullable Boolean aNullableBoolArg,
+        @Nullable Long aNullableIntArg,
+        @Nullable String aNullableStringArg,
+        Reply<AllNullableTypes> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(
+              Arrays.asList(aNullableBoolArg, aNullableIntArg, aNullableStringArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            AllNullableTypes output = (AllNullableTypes) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed boolean, to test serialization and deserialization. */
+    public void echoBool(@NonNull Boolean aBoolArg, Reply<Boolean> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aBoolArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Boolean output = (Boolean) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed int, to test serialization and deserialization. */
+    public void echoInt(@NonNull Long anIntArg, Reply<Long> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt", getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(anIntArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Long output = channelReply == null ? null : ((Number) channelReply).longValue();
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed double, to test serialization and deserialization. */
+    public void echoDouble(@NonNull Double aDoubleArg, Reply<Double> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aDoubleArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Double output = (Double) 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 =
@@ -1618,6 +1690,153 @@
             callback.reply(output);
           });
     }
+    /** Returns the passed byte list, to test serialization and deserialization. */
+    public void echoUint8List(@NonNull byte[] aListArg, Reply<byte[]> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aListArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            byte[] output = (byte[]) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed list, to test serialization and deserialization. */
+    public void echoList(@NonNull List<Object> aListArg, Reply<List<Object>> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aListArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            List<Object> output = (List<Object>) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed map, to test serialization and deserialization. */
+    public void echoMap(@NonNull Map<String, Object> aMapArg, Reply<Map<String, Object>> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap", getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aMapArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Map<String, Object> output = (Map<String, Object>) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed boolean, to test serialization and deserialization. */
+    public void echoNullableBool(@Nullable Boolean aBoolArg, Reply<Boolean> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aBoolArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Boolean output = (Boolean) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed int, to test serialization and deserialization. */
+    public void echoNullableInt(@Nullable Long anIntArg, Reply<Long> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(anIntArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Long output = channelReply == null ? null : ((Number) channelReply).longValue();
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed double, to test serialization and deserialization. */
+    public void echoNullableDouble(@Nullable Double aDoubleArg, Reply<Double> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aDoubleArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Double output = (Double) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed string, to test serialization and deserialization. */
+    public void echoNullableString(@Nullable String aStringArg, Reply<String> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aStringArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            String output = (String) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed byte list, to test serialization and deserialization. */
+    public void echoNullableUint8List(@Nullable byte[] aListArg, Reply<byte[]> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aListArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            byte[] output = (byte[]) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed list, to test serialization and deserialization. */
+    public void echoNullableList(@Nullable List<Object> aListArg, Reply<List<Object>> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aListArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            List<Object> output = (List<Object>) channelReply;
+            callback.reply(output);
+          });
+    }
+    /** Returns the passed map, to test serialization and deserialization. */
+    public void echoNullableMap(
+        @NonNull Map<String, Object> aMapArg, Reply<Map<String, Object>> callback) {
+      BasicMessageChannel<Object> channel =
+          new BasicMessageChannel<>(
+              binaryMessenger,
+              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap",
+              getCodec());
+      channel.send(
+          new ArrayList<Object>(Collections.singletonList(aMapArg)),
+          channelReply -> {
+            @SuppressWarnings("ConstantConditions")
+            Map<String, Object> output = (Map<String, Object>) channelReply;
+            callback.reply(output);
+          });
+    }
   }
   /**
    * An API that can be implemented for minimal, compile-only tests.
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
index bfab566..a5c55a3 100644
--- 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
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 #import <Foundation/Foundation.h>
@@ -205,9 +205,58 @@
 /// Returns the passed object, to test serialization and deserialization.
 - (void)echoAllNullableTypes:(AllNullableTypes *)everything
                   completion:(void (^)(AllNullableTypes *_Nullable, NSError *_Nullable))completion;
+/// Returns passed in arguments of multiple types.
+///
+/// Tests multiple-arity FlutterApi handling.
+- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool
+                                 anInt:(nullable NSNumber *)aNullableInt
+                               aString:(nullable NSString *)aNullableString
+                            completion:(void (^)(AllNullableTypes *_Nullable,
+                                                 NSError *_Nullable))completion;
+/// Returns the passed boolean, to test serialization and deserialization.
+- (void)echoBool:(NSNumber *)aBool
+      completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed int, to test serialization and deserialization.
+- (void)echoInt:(NSNumber *)anInt
+     completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed double, to test serialization and deserialization.
+- (void)echoDouble:(NSNumber *)aDouble
+        completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;
 /// Returns the passed string, to test serialization and deserialization.
 - (void)echoString:(NSString *)aString
         completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed byte list, to test serialization and deserialization.
+- (void)echoUint8List:(FlutterStandardTypedData *)aList
+           completion:(void (^)(FlutterStandardTypedData *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed list, to test serialization and deserialization.
+- (void)echoList:(NSArray<id> *)aList
+      completion:(void (^)(NSArray<id> *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed map, to test serialization and deserialization.
+- (void)echoMap:(NSDictionary<NSString *, id> *)aMap
+     completion:(void (^)(NSDictionary<NSString *, id> *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed boolean, to test serialization and deserialization.
+- (void)echoNullableBool:(nullable NSNumber *)aBool
+              completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed int, to test serialization and deserialization.
+- (void)echoNullableInt:(nullable NSNumber *)anInt
+             completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed double, to test serialization and deserialization.
+- (void)echoNullableDouble:(nullable NSNumber *)aDouble
+                completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed string, to test serialization and deserialization.
+- (void)echoNullableString:(nullable NSString *)aString
+                completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed byte list, to test serialization and deserialization.
+- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)aList
+                   completion:(void (^)(FlutterStandardTypedData *_Nullable,
+                                        NSError *_Nullable))completion;
+/// Returns the passed list, to test serialization and deserialization.
+- (void)echoNullableList:(nullable NSArray<id> *)aList
+              completion:(void (^)(NSArray<id> *_Nullable, NSError *_Nullable))completion;
+/// Returns the passed map, to test serialization and deserialization.
+- (void)echoNullableMap:(NSDictionary<NSString *, id> *)aMap
+             completion:
+                 (void (^)(NSDictionary<NSString *, id> *_Nullable, NSError *_Nullable))completion;
 @end
 
 /// The codec used by HostTrivialApi.
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
index 7f73cf6..c8fa7d8 100644
--- 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
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 #import "CoreTests.gen.h"
@@ -791,6 +791,9 @@
       return [AllNullableTypes fromList:[self readValue]];
 
     case 129:
+      return [AllNullableTypesWrapper fromList:[self readValue]];
+
+    case 130:
       return [AllTypes fromList:[self readValue]];
 
     default:
@@ -806,9 +809,12 @@
   if ([value isKindOfClass:[AllNullableTypes class]]) {
     [self writeByte:128];
     [self writeValue:[value toList]];
-  } else if ([value isKindOfClass:[AllTypes class]]) {
+  } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) {
     [self writeByte:129];
     [self writeValue:[value toList]];
+  } else if ([value isKindOfClass:[AllTypes class]]) {
+    [self writeByte:130];
+    [self writeValue:[value toList]];
   } else {
     [super writeValue:value];
   }
@@ -884,6 +890,61 @@
                    completion(output, nil);
                  }];
 }
+- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool
+                                 anInt:(nullable NSNumber *)arg_aNullableInt
+                               aString:(nullable NSString *)arg_aNullableString
+                            completion:(void (^)(AllNullableTypes *_Nullable,
+                                                 NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:
+          @"dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[
+    arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null],
+    arg_aNullableString ?: [NSNull null]
+  ]
+                 reply:^(id reply) {
+                   AllNullableTypes *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoBool:(NSNumber *)arg_aBool
+      completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aBool ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSNumber *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoInt:(NSNumber *)arg_anInt
+     completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_anInt ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSNumber *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoDouble:(NSNumber *)arg_aDouble
+        completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSNumber *output = reply;
+                   completion(output, nil);
+                 }];
+}
 - (void)echoString:(NSString *)arg_aString
         completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion {
   FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
@@ -896,6 +957,129 @@
                    completion(output, nil);
                  }];
 }
+- (void)echoUint8List:(FlutterStandardTypedData *)arg_aList
+           completion:
+               (void (^)(FlutterStandardTypedData *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   FlutterStandardTypedData *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoList:(NSArray<id> *)arg_aList
+      completion:(void (^)(NSArray<id> *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSArray<id> *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoMap:(NSDictionary<NSString *, id> *)arg_aMap
+     completion:(void (^)(NSDictionary<NSString *, id> *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aMap ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSDictionary<NSString *, id> *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableBool:(nullable NSNumber *)arg_aBool
+              completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aBool ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSNumber *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableInt:(nullable NSNumber *)arg_anInt
+             completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_anInt ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSNumber *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble
+                completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSNumber *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableString:(nullable NSString *)arg_aString
+                completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aString ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSString *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_aList
+                   completion:(void (^)(FlutterStandardTypedData *_Nullable,
+                                        NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   FlutterStandardTypedData *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableList:(nullable NSArray<id> *)arg_aList
+              completion:(void (^)(NSArray<id> *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSArray<id> *output = reply;
+                   completion(output, nil);
+                 }];
+}
+- (void)echoNullableMap:(NSDictionary<NSString *, id> *)arg_aMap
+             completion:
+                 (void (^)(NSDictionary<NSString *, id> *_Nullable, NSError *_Nullable))completion {
+  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap"
+             binaryMessenger:self.binaryMessenger
+                       codec:FlutterIntegrationCoreApiGetCodec()];
+  [channel sendMessage:@[ arg_aMap ?: [NSNull null] ]
+                 reply:^(id reply) {
+                   NSDictionary<NSString *, id> *output = reply;
+                   completion(output, nil);
+                 }];
+}
 @end
 
 NSObject<FlutterMessageCodec> *HostTrivialApiGetCodec() {
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart
index 1040f61..203f02b 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
@@ -848,9 +848,12 @@
     if (value is AllNullableTypes) {
       buffer.putUint8(128);
       writeValue(buffer, value.encode());
-    } else if (value is AllTypes) {
+    } else if (value is AllNullableTypesWrapper) {
       buffer.putUint8(129);
       writeValue(buffer, value.encode());
+    } else if (value is AllTypes) {
+      buffer.putUint8(130);
+      writeValue(buffer, value.encode());
     } else {
       super.writeValue(buffer, value);
     }
@@ -863,6 +866,9 @@
         return AllNullableTypes.decode(readValue(buffer)!);
 
       case 129:
+        return AllNullableTypesWrapper.decode(readValue(buffer)!);
+
+      case 130:
         return AllTypes.decode(readValue(buffer)!);
 
       default:
@@ -886,9 +892,54 @@
   /// Returns the passed object, to test serialization and deserialization.
   AllNullableTypes echoAllNullableTypes(AllNullableTypes everything);
 
+  /// Returns passed in arguments of multiple types.
+  ///
+  /// Tests multiple-arity FlutterApi handling.
+  AllNullableTypes sendMultipleNullableTypes(
+      bool? aNullableBool, int? aNullableInt, String? aNullableString);
+
+  /// Returns the passed boolean, to test serialization and deserialization.
+  bool echoBool(bool aBool);
+
+  /// Returns the passed int, to test serialization and deserialization.
+  int echoInt(int anInt);
+
+  /// Returns the passed double, to test serialization and deserialization.
+  double echoDouble(double aDouble);
+
   /// Returns the passed string, to test serialization and deserialization.
   String echoString(String aString);
 
+  /// Returns the passed byte list, to test serialization and deserialization.
+  Uint8List echoUint8List(Uint8List aList);
+
+  /// Returns the passed list, to test serialization and deserialization.
+  List<Object?> echoList(List<Object?> aList);
+
+  /// Returns the passed map, to test serialization and deserialization.
+  Map<String?, Object?> echoMap(Map<String?, Object?> aMap);
+
+  /// Returns the passed boolean, to test serialization and deserialization.
+  bool? echoNullableBool(bool? aBool);
+
+  /// Returns the passed int, to test serialization and deserialization.
+  int? echoNullableInt(int? anInt);
+
+  /// Returns the passed double, to test serialization and deserialization.
+  double? echoNullableDouble(double? aDouble);
+
+  /// Returns the passed string, to test serialization and deserialization.
+  String? echoNullableString(String? aString);
+
+  /// Returns the passed byte list, to test serialization and deserialization.
+  Uint8List? echoNullableUint8List(Uint8List? aList);
+
+  /// Returns the passed list, to test serialization and deserialization.
+  List<Object?>? echoNullableList(List<Object?>? aList);
+
+  /// Returns the passed map, to test serialization and deserialization.
+  Map<String?, Object?> echoNullableMap(Map<String?, Object?> aMap);
+
   static void setup(FlutterIntegrationCoreApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -948,6 +999,84 @@
     }
     {
       final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final bool? arg_aNullableBool = (args[0] as bool?);
+          final int? arg_aNullableInt = (args[1] as int?);
+          final String? arg_aNullableString = (args[2] as String?);
+          final AllNullableTypes output = api.sendMultipleNullableTypes(
+              arg_aNullableBool, arg_aNullableInt, arg_aNullableString);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final bool? arg_aBool = (args[0] as bool?);
+          assert(arg_aBool != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool was null, expected non-null bool.');
+          final bool output = api.echoBool(arg_aBool!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final int? arg_anInt = (args[0] as int?);
+          assert(arg_anInt != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt was null, expected non-null int.');
+          final int output = api.echoInt(arg_anInt!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final double? arg_aDouble = (args[0] as double?);
+          assert(arg_aDouble != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble was null, expected non-null double.');
+          final double output = api.echoDouble(arg_aDouble!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
           'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString', codec,
           binaryMessenger: binaryMessenger);
       if (api == null) {
@@ -965,6 +1094,193 @@
         });
       }
     }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Uint8List? arg_aList = (args[0] as Uint8List?);
+          assert(arg_aList != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List was null, expected non-null Uint8List.');
+          final Uint8List output = api.echoUint8List(arg_aList!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final List<Object?>? arg_aList =
+              (args[0] as List<Object?>?)?.cast<Object?>();
+          assert(arg_aList != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList was null, expected non-null List<Object?>.');
+          final List<Object?> output = api.echoList(arg_aList!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Map<String?, Object?>? arg_aMap =
+              (args[0] as Map<Object?, Object?>?)?.cast<String?, Object?>();
+          assert(arg_aMap != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap was null, expected non-null Map<String?, Object?>.');
+          final Map<String?, Object?> output = api.echoMap(arg_aMap!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final bool? arg_aBool = (args[0] as bool?);
+          final bool? output = api.echoNullableBool(arg_aBool);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final int? arg_anInt = (args[0] as int?);
+          final int? output = api.echoNullableInt(arg_anInt);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final double? arg_aDouble = (args[0] as double?);
+          final double? output = api.echoNullableDouble(arg_aDouble);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final String? arg_aString = (args[0] as String?);
+          final String? output = api.echoNullableString(arg_aString);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Uint8List? arg_aList = (args[0] as Uint8List?);
+          final Uint8List? output = api.echoNullableUint8List(arg_aList);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final List<Object?>? arg_aList =
+              (args[0] as List<Object?>?)?.cast<Object?>();
+          final List<Object?>? output = api.echoNullableList(arg_aList);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Map<String?, Object?>? arg_aMap =
+              (args[0] as Map<Object?, Object?>?)?.cast<String?, Object?>();
+          assert(arg_aMap != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap was null, expected non-null Map<String?, Object?>.');
+          final Map<String?, Object?> output = api.echoNullableMap(arg_aMap!);
+          return output;
+        });
+      }
+    }
   }
 }
 
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart
index c3b44b0..76a6a34 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart
index 3bf1fa5..f316971 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart
index 82bfce2..60f9dc4 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
index a4a52e6..5d7f772 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart
index 51af74c..d29b2eb 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart
index f9855f6..72c9ea2 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart
index 23a46ac..a47622b 100644
--- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart
+++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart
@@ -527,10 +527,7 @@
       final String echoObject = await api.callFlutterEchoString(sentObject);
       expect(echoObject, sentObject);
     });
-  },
-      // TODO(stuartmorgan): Enable when FlutterApi generation is fixed for
-      // C++. See https://github.com/flutter/flutter/issues/108682.
-      skip: targetGenerator == TargetGenerator.cpp);
+  });
 }
 
 class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi {
@@ -545,10 +542,56 @@
   }
 
   @override
-  String echoString(String aString) {
-    return aString;
+  void noop() {}
+
+  @override
+  AllNullableTypes sendMultipleNullableTypes(
+      bool? aNullableBool, int? aNullableInt, String? aNullableString) {
+    return AllNullableTypes(
+        aNullableBool: aNullableBool,
+        aNullableInt: aNullableInt,
+        aNullableString: aNullableString);
   }
 
   @override
-  void noop() {}
+  bool echoBool(bool aBool) => aBool;
+
+  @override
+  double echoDouble(double aDouble) => aDouble;
+
+  @override
+  int echoInt(int anInt) => anInt;
+
+  @override
+  String echoString(String aString) => aString;
+
+  @override
+  Uint8List echoUint8List(Uint8List aList) => aList;
+
+  @override
+  List<Object?> echoList(List<Object?> aList) => aList;
+
+  @override
+  Map<String?, Object?> echoMap(Map<String?, Object?> aMap) => aMap;
+
+  @override
+  bool? echoNullableBool(bool? aBool) => aBool;
+
+  @override
+  double? echoNullableDouble(double? aDouble) => aDouble;
+
+  @override
+  int? echoNullableInt(int? anInt) => anInt;
+
+  @override
+  List<Object?>? echoNullableList(List<Object?>? aList) => aList;
+
+  @override
+  Map<String?, Object?> echoNullableMap(Map<String?, Object?> aMap) => aMap;
+
+  @override
+  String? echoNullableString(String? aString) => aString;
+
+  @override
+  Uint8List? echoNullableUint8List(Uint8List? aList) => aList;
 }
diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart
index 1040f61..203f02b 100644
--- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart
+++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 
@@ -848,9 +848,12 @@
     if (value is AllNullableTypes) {
       buffer.putUint8(128);
       writeValue(buffer, value.encode());
-    } else if (value is AllTypes) {
+    } else if (value is AllNullableTypesWrapper) {
       buffer.putUint8(129);
       writeValue(buffer, value.encode());
+    } else if (value is AllTypes) {
+      buffer.putUint8(130);
+      writeValue(buffer, value.encode());
     } else {
       super.writeValue(buffer, value);
     }
@@ -863,6 +866,9 @@
         return AllNullableTypes.decode(readValue(buffer)!);
 
       case 129:
+        return AllNullableTypesWrapper.decode(readValue(buffer)!);
+
+      case 130:
         return AllTypes.decode(readValue(buffer)!);
 
       default:
@@ -886,9 +892,54 @@
   /// Returns the passed object, to test serialization and deserialization.
   AllNullableTypes echoAllNullableTypes(AllNullableTypes everything);
 
+  /// Returns passed in arguments of multiple types.
+  ///
+  /// Tests multiple-arity FlutterApi handling.
+  AllNullableTypes sendMultipleNullableTypes(
+      bool? aNullableBool, int? aNullableInt, String? aNullableString);
+
+  /// Returns the passed boolean, to test serialization and deserialization.
+  bool echoBool(bool aBool);
+
+  /// Returns the passed int, to test serialization and deserialization.
+  int echoInt(int anInt);
+
+  /// Returns the passed double, to test serialization and deserialization.
+  double echoDouble(double aDouble);
+
   /// Returns the passed string, to test serialization and deserialization.
   String echoString(String aString);
 
+  /// Returns the passed byte list, to test serialization and deserialization.
+  Uint8List echoUint8List(Uint8List aList);
+
+  /// Returns the passed list, to test serialization and deserialization.
+  List<Object?> echoList(List<Object?> aList);
+
+  /// Returns the passed map, to test serialization and deserialization.
+  Map<String?, Object?> echoMap(Map<String?, Object?> aMap);
+
+  /// Returns the passed boolean, to test serialization and deserialization.
+  bool? echoNullableBool(bool? aBool);
+
+  /// Returns the passed int, to test serialization and deserialization.
+  int? echoNullableInt(int? anInt);
+
+  /// Returns the passed double, to test serialization and deserialization.
+  double? echoNullableDouble(double? aDouble);
+
+  /// Returns the passed string, to test serialization and deserialization.
+  String? echoNullableString(String? aString);
+
+  /// Returns the passed byte list, to test serialization and deserialization.
+  Uint8List? echoNullableUint8List(Uint8List? aList);
+
+  /// Returns the passed list, to test serialization and deserialization.
+  List<Object?>? echoNullableList(List<Object?>? aList);
+
+  /// Returns the passed map, to test serialization and deserialization.
+  Map<String?, Object?> echoNullableMap(Map<String?, Object?> aMap);
+
   static void setup(FlutterIntegrationCoreApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -948,6 +999,84 @@
     }
     {
       final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final bool? arg_aNullableBool = (args[0] as bool?);
+          final int? arg_aNullableInt = (args[1] as int?);
+          final String? arg_aNullableString = (args[2] as String?);
+          final AllNullableTypes output = api.sendMultipleNullableTypes(
+              arg_aNullableBool, arg_aNullableInt, arg_aNullableString);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final bool? arg_aBool = (args[0] as bool?);
+          assert(arg_aBool != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool was null, expected non-null bool.');
+          final bool output = api.echoBool(arg_aBool!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final int? arg_anInt = (args[0] as int?);
+          assert(arg_anInt != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt was null, expected non-null int.');
+          final int output = api.echoInt(arg_anInt!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final double? arg_aDouble = (args[0] as double?);
+          assert(arg_aDouble != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble was null, expected non-null double.');
+          final double output = api.echoDouble(arg_aDouble!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
           'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString', codec,
           binaryMessenger: binaryMessenger);
       if (api == null) {
@@ -965,6 +1094,193 @@
         });
       }
     }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Uint8List? arg_aList = (args[0] as Uint8List?);
+          assert(arg_aList != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List was null, expected non-null Uint8List.');
+          final Uint8List output = api.echoUint8List(arg_aList!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final List<Object?>? arg_aList =
+              (args[0] as List<Object?>?)?.cast<Object?>();
+          assert(arg_aList != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList was null, expected non-null List<Object?>.');
+          final List<Object?> output = api.echoList(arg_aList!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Map<String?, Object?>? arg_aMap =
+              (args[0] as Map<Object?, Object?>?)?.cast<String?, Object?>();
+          assert(arg_aMap != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap was null, expected non-null Map<String?, Object?>.');
+          final Map<String?, Object?> output = api.echoMap(arg_aMap!);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final bool? arg_aBool = (args[0] as bool?);
+          final bool? output = api.echoNullableBool(arg_aBool);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final int? arg_anInt = (args[0] as int?);
+          final int? output = api.echoNullableInt(arg_anInt);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final double? arg_aDouble = (args[0] as double?);
+          final double? output = api.echoNullableDouble(arg_aDouble);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final String? arg_aString = (args[0] as String?);
+          final String? output = api.echoNullableString(arg_aString);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Uint8List? arg_aList = (args[0] as Uint8List?);
+          final Uint8List? output = api.echoNullableUint8List(arg_aList);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final List<Object?>? arg_aList =
+              (args[0] as List<Object?>?)?.cast<Object?>();
+          final List<Object?>? output = api.echoNullableList(arg_aList);
+          return output;
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap', codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMessageHandler(null);
+      } else {
+        channel.setMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final Map<String?, Object?>? arg_aMap =
+              (args[0] as Map<Object?, Object?>?)?.cast<String?, Object?>();
+          assert(arg_aMap != null,
+              'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap was null, expected non-null Map<String?, Object?>.');
+          final Map<String?, Object?> output = api.echoNullableMap(arg_aMap!);
+          return output;
+        });
+      }
+    }
   }
 }
 
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
index c2c0390..c5f0ee0 100644
--- 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
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 // 
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 package com.example.test_plugin
@@ -714,6 +714,11 @@
       }
       129.toByte() -> {
         return (readValue(buffer) as? List<Any?>)?.let {
+          AllNullableTypesWrapper.fromList(it)
+        }
+      }
+      130.toByte() -> {
+        return (readValue(buffer) as? List<Any?>)?.let {
           AllTypes.fromList(it)
         }
       }
@@ -726,10 +731,14 @@
         stream.write(128)
         writeValue(stream, value.toList())
       }
-      is AllTypes -> {
+      is AllNullableTypesWrapper -> {
         stream.write(129)
         writeValue(stream, value.toList())
       }
+      is AllTypes -> {
+        stream.write(130)
+        writeValue(stream, value.toList())
+      }
       else -> super.writeValue(stream, value)
     }
   }
@@ -775,6 +784,42 @@
       callback(result)
     }
   }
+  /**
+   * Returns passed in arguments of multiple types.
+   *
+   * Tests multiple-arity FlutterApi handling.
+   */
+  fun sendMultipleNullableTypes(aNullableBoolArg: Boolean?, aNullableIntArg: Long?, aNullableStringArg: String?, callback: (AllNullableTypes) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes", codec)
+    channel.send(listOf(aNullableBoolArg, aNullableIntArg, aNullableStringArg)) {
+      val result = it as AllNullableTypes
+      callback(result)
+    }
+  }
+  /** Returns the passed boolean, to test serialization and deserialization. */
+  fun echoBool(aBoolArg: Boolean, callback: (Boolean) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", codec)
+    channel.send(listOf(aBoolArg)) {
+      val result = it as Boolean
+      callback(result)
+    }
+  }
+  /** Returns the passed int, to test serialization and deserialization. */
+  fun echoInt(anIntArg: Long, callback: (Long) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt", codec)
+    channel.send(listOf(anIntArg)) {
+      val result = it as Long
+      callback(result)
+    }
+  }
+  /** Returns the passed double, to test serialization and deserialization. */
+  fun echoDouble(aDoubleArg: Double, callback: (Double) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", codec)
+    channel.send(listOf(aDoubleArg)) {
+      val result = it as Double
+      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)
@@ -783,6 +828,86 @@
       callback(result)
     }
   }
+  /** Returns the passed byte list, to test serialization and deserialization. */
+  fun echoUint8List(aListArg: ByteArray, callback: (ByteArray) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List", codec)
+    channel.send(listOf(aListArg)) {
+      val result = it as ByteArray
+      callback(result)
+    }
+  }
+  /** Returns the passed list, to test serialization and deserialization. */
+  fun echoList(aListArg: List<Any?>, callback: (List<Any?>) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", codec)
+    channel.send(listOf(aListArg)) {
+      val result = it as List<Any?>
+      callback(result)
+    }
+  }
+  /** Returns the passed map, to test serialization and deserialization. */
+  fun echoMap(aMapArg: Map<String?, Any?>, callback: (Map<String?, Any?>) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap", codec)
+    channel.send(listOf(aMapArg)) {
+      val result = it as Map<String?, Any?>
+      callback(result)
+    }
+  }
+  /** Returns the passed boolean, to test serialization and deserialization. */
+  fun echoNullableBool(aBoolArg: Boolean?, callback: (Boolean?) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool", codec)
+    channel.send(listOf(aBoolArg)) {
+      val result = it as? Boolean?
+      callback(result)
+    }
+  }
+  /** Returns the passed int, to test serialization and deserialization. */
+  fun echoNullableInt(anIntArg: Long?, callback: (Long?) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt", codec)
+    channel.send(listOf(anIntArg)) {
+      val result = it as? Long?
+      callback(result)
+    }
+  }
+  /** Returns the passed double, to test serialization and deserialization. */
+  fun echoNullableDouble(aDoubleArg: Double?, callback: (Double?) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble", codec)
+    channel.send(listOf(aDoubleArg)) {
+      val result = it as? Double?
+      callback(result)
+    }
+  }
+  /** Returns the passed string, to test serialization and deserialization. */
+  fun echoNullableString(aStringArg: String?, callback: (String?) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString", codec)
+    channel.send(listOf(aStringArg)) {
+      val result = it as? String?
+      callback(result)
+    }
+  }
+  /** Returns the passed byte list, to test serialization and deserialization. */
+  fun echoNullableUint8List(aListArg: ByteArray?, callback: (ByteArray?) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List", codec)
+    channel.send(listOf(aListArg)) {
+      val result = it as? ByteArray?
+      callback(result)
+    }
+  }
+  /** Returns the passed list, to test serialization and deserialization. */
+  fun echoNullableList(aListArg: List<Any?>?, callback: (List<Any?>?) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList", codec)
+    channel.send(listOf(aListArg)) {
+      val result = it as? List<Any?>?
+      callback(result)
+    }
+  }
+  /** Returns the passed map, to test serialization and deserialization. */
+  fun echoNullableMap(aMapArg: Map<String?, Any?>, callback: (Map<String?, Any?>) -> Unit) {
+    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap", codec)
+    channel.send(listOf(aMapArg)) {
+      val result = it as Map<String?, Any?>
+      callback(result)
+    }
+  }
 }
 /**
  * An API that can be implemented for minimal, compile-only tests.
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
index 407ee69..522a9d7 100644
--- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift
+++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 // 
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 import Foundation
@@ -574,6 +574,8 @@
       case 128:
         return AllNullableTypes.fromList(self.readValue() as! [Any])      
       case 129:
+        return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])      
+      case 130:
         return AllTypes.fromList(self.readValue() as! [Any])      
       default:
         return super.readValue(ofType: type)
@@ -586,9 +588,12 @@
     if let value = value as? AllNullableTypes {
       super.writeByte(128)
       super.writeValue(value.toList())
-    } else if let value = value as? AllTypes {
+    } else if let value = value as? AllNullableTypesWrapper {
       super.writeByte(129)
       super.writeValue(value.toList())
+    } else if let value = value as? AllTypes {
+      super.writeByte(130)
+      super.writeValue(value.toList())
     } else {
       super.writeValue(value)
     }
@@ -632,7 +637,7 @@
   /// 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
+    channel.sendMessage([everythingArg] as [Any?]) { response in
       let result = response as! AllTypes
       completion(result)
     }
@@ -640,19 +645,133 @@
   /// 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
+    channel.sendMessage([everythingArg] as [Any?]) { response in
       let result = response as! AllNullableTypes
       completion(result)
     }
   }
+  /// Returns passed in arguments of multiple types.
+  ///
+  /// Tests multiple-arity FlutterApi handling.
+  func sendMultipleNullableTypes(aNullableBool aNullableBoolArg: Bool?, aNullableInt aNullableIntArg: Int32?, aNullableString aNullableStringArg: String?, completion: @escaping (AllNullableTypes) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { response in
+      let result = response as! AllNullableTypes
+      completion(result)
+    }
+  }
+  /// Returns the passed boolean, to test serialization and deserialization.
+  func echoBool(aBool aBoolArg: Bool, completion: @escaping (Bool) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aBoolArg] as [Any?]) { response in
+      let result = response as! Bool
+      completion(result)
+    }
+  }
+  /// Returns the passed int, to test serialization and deserialization.
+  func echoInt(anInt anIntArg: Int32, completion: @escaping (Int32) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([anIntArg] as [Any?]) { response in
+      let result = response as! Int32
+      completion(result)
+    }
+  }
+  /// Returns the passed double, to test serialization and deserialization.
+  func echoDouble(aDouble aDoubleArg: Double, completion: @escaping (Double) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aDoubleArg] as [Any?]) { response in
+      let result = response as! Double
+      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
+    channel.sendMessage([aStringArg] as [Any?]) { response in
       let result = response as! String
       completion(result)
     }
   }
+  /// Returns the passed byte list, to test serialization and deserialization.
+  func echoUint8List(aList aListArg: FlutterStandardTypedData, completion: @escaping (FlutterStandardTypedData) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as! FlutterStandardTypedData
+      completion(result)
+    }
+  }
+  /// Returns the passed list, to test serialization and deserialization.
+  func echoList(aList aListArg: [Any?], completion: @escaping ([Any?]) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as! [Any?]
+      completion(result)
+    }
+  }
+  /// Returns the passed map, to test serialization and deserialization.
+  func echoMap(aMap aMapArg: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aMapArg] as [Any?]) { response in
+      let result = response as! [String?: Any?]
+      completion(result)
+    }
+  }
+  /// Returns the passed boolean, to test serialization and deserialization.
+  func echoNullableBool(aBool aBoolArg: Bool?, completion: @escaping (Bool?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aBoolArg] as [Any?]) { response in
+      let result = response as? Bool
+      completion(result)
+    }
+  }
+  /// Returns the passed int, to test serialization and deserialization.
+  func echoNullableInt(anInt anIntArg: Int32?, completion: @escaping (Int32?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([anIntArg] as [Any?]) { response in
+      let result = response as? Int32
+      completion(result)
+    }
+  }
+  /// Returns the passed double, to test serialization and deserialization.
+  func echoNullableDouble(aDouble aDoubleArg: Double?, completion: @escaping (Double?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aDoubleArg] as [Any?]) { response in
+      let result = response as? Double
+      completion(result)
+    }
+  }
+  /// Returns the passed string, to test serialization and deserialization.
+  func echoNullableString(aString aStringArg: String?, completion: @escaping (String?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aStringArg] as [Any?]) { response in
+      let result = response as? String
+      completion(result)
+    }
+  }
+  /// Returns the passed byte list, to test serialization and deserialization.
+  func echoNullableUint8List(aList aListArg: FlutterStandardTypedData?, completion: @escaping (FlutterStandardTypedData?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as? FlutterStandardTypedData
+      completion(result)
+    }
+  }
+  /// Returns the passed list, to test serialization and deserialization.
+  func echoNullableList(aList aListArg: [Any?]?, completion: @escaping ([Any?]?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as? [Any?]
+      completion(result)
+    }
+  }
+  /// Returns the passed map, to test serialization and deserialization.
+  func echoNullableMap(aMap aMapArg: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aMapArg] as [Any?]) { response in
+      let result = response as! [String?: Any?]
+      completion(result)
+    }
+  }
 }
 /// An API that can be implemented for minimal, compile-only tests.
 ///
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
index 407ee69..522a9d7 100644
--- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift
+++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 // 
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 import Foundation
@@ -574,6 +574,8 @@
       case 128:
         return AllNullableTypes.fromList(self.readValue() as! [Any])      
       case 129:
+        return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])      
+      case 130:
         return AllTypes.fromList(self.readValue() as! [Any])      
       default:
         return super.readValue(ofType: type)
@@ -586,9 +588,12 @@
     if let value = value as? AllNullableTypes {
       super.writeByte(128)
       super.writeValue(value.toList())
-    } else if let value = value as? AllTypes {
+    } else if let value = value as? AllNullableTypesWrapper {
       super.writeByte(129)
       super.writeValue(value.toList())
+    } else if let value = value as? AllTypes {
+      super.writeByte(130)
+      super.writeValue(value.toList())
     } else {
       super.writeValue(value)
     }
@@ -632,7 +637,7 @@
   /// 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
+    channel.sendMessage([everythingArg] as [Any?]) { response in
       let result = response as! AllTypes
       completion(result)
     }
@@ -640,19 +645,133 @@
   /// 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
+    channel.sendMessage([everythingArg] as [Any?]) { response in
       let result = response as! AllNullableTypes
       completion(result)
     }
   }
+  /// Returns passed in arguments of multiple types.
+  ///
+  /// Tests multiple-arity FlutterApi handling.
+  func sendMultipleNullableTypes(aNullableBool aNullableBoolArg: Bool?, aNullableInt aNullableIntArg: Int32?, aNullableString aNullableStringArg: String?, completion: @escaping (AllNullableTypes) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { response in
+      let result = response as! AllNullableTypes
+      completion(result)
+    }
+  }
+  /// Returns the passed boolean, to test serialization and deserialization.
+  func echoBool(aBool aBoolArg: Bool, completion: @escaping (Bool) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aBoolArg] as [Any?]) { response in
+      let result = response as! Bool
+      completion(result)
+    }
+  }
+  /// Returns the passed int, to test serialization and deserialization.
+  func echoInt(anInt anIntArg: Int32, completion: @escaping (Int32) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([anIntArg] as [Any?]) { response in
+      let result = response as! Int32
+      completion(result)
+    }
+  }
+  /// Returns the passed double, to test serialization and deserialization.
+  func echoDouble(aDouble aDoubleArg: Double, completion: @escaping (Double) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aDoubleArg] as [Any?]) { response in
+      let result = response as! Double
+      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
+    channel.sendMessage([aStringArg] as [Any?]) { response in
       let result = response as! String
       completion(result)
     }
   }
+  /// Returns the passed byte list, to test serialization and deserialization.
+  func echoUint8List(aList aListArg: FlutterStandardTypedData, completion: @escaping (FlutterStandardTypedData) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as! FlutterStandardTypedData
+      completion(result)
+    }
+  }
+  /// Returns the passed list, to test serialization and deserialization.
+  func echoList(aList aListArg: [Any?], completion: @escaping ([Any?]) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as! [Any?]
+      completion(result)
+    }
+  }
+  /// Returns the passed map, to test serialization and deserialization.
+  func echoMap(aMap aMapArg: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aMapArg] as [Any?]) { response in
+      let result = response as! [String?: Any?]
+      completion(result)
+    }
+  }
+  /// Returns the passed boolean, to test serialization and deserialization.
+  func echoNullableBool(aBool aBoolArg: Bool?, completion: @escaping (Bool?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aBoolArg] as [Any?]) { response in
+      let result = response as? Bool
+      completion(result)
+    }
+  }
+  /// Returns the passed int, to test serialization and deserialization.
+  func echoNullableInt(anInt anIntArg: Int32?, completion: @escaping (Int32?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([anIntArg] as [Any?]) { response in
+      let result = response as? Int32
+      completion(result)
+    }
+  }
+  /// Returns the passed double, to test serialization and deserialization.
+  func echoNullableDouble(aDouble aDoubleArg: Double?, completion: @escaping (Double?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aDoubleArg] as [Any?]) { response in
+      let result = response as? Double
+      completion(result)
+    }
+  }
+  /// Returns the passed string, to test serialization and deserialization.
+  func echoNullableString(aString aStringArg: String?, completion: @escaping (String?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aStringArg] as [Any?]) { response in
+      let result = response as? String
+      completion(result)
+    }
+  }
+  /// Returns the passed byte list, to test serialization and deserialization.
+  func echoNullableUint8List(aList aListArg: FlutterStandardTypedData?, completion: @escaping (FlutterStandardTypedData?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as? FlutterStandardTypedData
+      completion(result)
+    }
+  }
+  /// Returns the passed list, to test serialization and deserialization.
+  func echoNullableList(aList aListArg: [Any?]?, completion: @escaping ([Any?]?) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aListArg] as [Any?]) { response in
+      let result = response as? [Any?]
+      completion(result)
+    }
+  }
+  /// Returns the passed map, to test serialization and deserialization.
+  func echoNullableMap(aMap aMapArg: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void) {
+    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap", binaryMessenger: binaryMessenger, codec: codec)
+    channel.sendMessage([aMapArg] as [Any?]) { response in
+      let result = response as! [String?: Any?]
+      completion(result)
+    }
+  }
 }
 /// An API that can be implemented for minimal, compile-only tests.
 ///
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
index 6c39bce..d205dbb 100644
--- 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
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 #undef _HAS_EXCEPTIONS
@@ -545,10 +545,9 @@
 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());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -571,11 +570,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -608,11 +605,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -648,11 +644,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.throwError",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -675,10 +669,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -709,11 +702,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -745,10 +736,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -779,11 +769,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoString",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -815,11 +803,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -852,11 +838,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -888,8 +872,7 @@
     }
   }
   {
-    auto channel = std::make_unique<
-        flutter::BasicMessageChannel<flutter::EncodableValue>>(
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
         binary_messenger,
         "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
         &GetCodec());
@@ -932,8 +915,7 @@
     }
   }
   {
-    auto channel = std::make_unique<
-        flutter::BasicMessageChannel<flutter::EncodableValue>>(
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
         binary_messenger,
         "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
         &GetCodec());
@@ -965,8 +947,7 @@
     }
   }
   {
-    auto channel = std::make_unique<
-        flutter::BasicMessageChannel<flutter::EncodableValue>>(
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
         binary_messenger,
         "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
         &GetCodec());
@@ -1011,11 +992,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1055,11 +1035,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1093,11 +1072,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1131,11 +1109,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1169,11 +1146,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1208,11 +1184,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1246,10 +1221,9 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1273,11 +1247,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1311,11 +1284,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1340,11 +1312,10 @@
     }
   }
   {
-    auto channel =
-        std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
-            binary_messenger,
-            "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
-            &GetCodec());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger,
+        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
@@ -1403,6 +1374,10 @@
           std::get<flutter::EncodableList>(ReadValue(stream))));
 
     case 129:
+      return flutter::CustomEncodableValue(AllNullableTypesWrapper(
+          std::get<flutter::EncodableList>(ReadValue(stream))));
+
+    case 130:
       return flutter::CustomEncodableValue(
           AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));
 
@@ -1424,9 +1399,17 @@
           stream);
       return;
     }
-    if (custom_value->type() == typeid(AllTypes)) {
+    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
       stream->WriteByte(129);
       WriteValue(flutter::EncodableValue(
+                     std::any_cast<AllNullableTypesWrapper>(*custom_value)
+                         .ToEncodableList()),
+                 stream);
+      return;
+    }
+    if (custom_value->type() == typeid(AllTypes)) {
+      stream->WriteByte(130);
+      WriteValue(flutter::EncodableValue(
                      std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
                  stream);
       return;
@@ -1447,82 +1430,423 @@
       &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());
+void FlutterIntegrationCoreApi::Noop(
+    std::function<void(void)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments = flutter::EncodableValue();
   channel->Send(
-      flutter::EncodableValue(),
-      [callback](const uint8_t* reply, size_t reply_size) { callback(); });
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) { on_success(); });
 }
-void FlutterIntegrationCoreApi::echoAllTypes(
+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());
+    std::function<void(const AllTypes&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(everything_arg.ToEncodableList()),
+      });
   channel->Send(
-      flutter::EncodableList{flutter::CustomEncodableValue(everything_arg)},
-      [callback](const uint8_t* reply, size_t reply_size) {
-        std::unique_ptr<flutter::EncodableValue> decoded_reply =
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
             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);
+        const auto& encodable_return_value = *response;
+        const auto& return_value = std::any_cast<const AllTypes&>(
+            std::get<flutter::CustomEncodableValue>(encodable_return_value));
+        on_success(return_value);
       });
 }
-void FlutterIntegrationCoreApi::echoAllNullableTypes(
+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());
+    std::function<void(const AllNullableTypes&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(everything_arg.ToEncodableList()),
+      });
   channel->Send(
-      flutter::EncodableList{flutter::CustomEncodableValue(everything_arg)},
-      [callback](const uint8_t* reply, size_t reply_size) {
-        std::unique_ptr<flutter::EncodableValue> decoded_reply =
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
             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);
+        const auto& encodable_return_value = *response;
+        const auto& return_value = std::any_cast<const AllNullableTypes&>(
+            std::get<flutter::CustomEncodableValue>(encodable_return_value));
+        on_success(return_value);
       });
 }
-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());
+void FlutterIntegrationCoreApi::SendMultipleNullableTypes(
+    const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg,
+    const std::string* a_nullable_string_arg,
+    std::function<void(const AllNullableTypes&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          a_nullable_bool_arg ? flutter::EncodableValue(*a_nullable_bool_arg)
+                              : flutter::EncodableValue(),
+          a_nullable_int_arg ? flutter::EncodableValue(*a_nullable_int_arg)
+                             : flutter::EncodableValue(),
+          a_nullable_string_arg
+              ? flutter::EncodableValue(*a_nullable_string_arg)
+              : flutter::EncodableValue(),
+      });
   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 =
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
             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);
+        const auto& encodable_return_value = *response;
+        const auto& return_value = std::any_cast<const AllNullableTypes&>(
+            std::get<flutter::CustomEncodableValue>(encodable_return_value));
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoBool(
+    bool a_bool_arg, std::function<void(bool)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_bool_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value = std::get<bool>(encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoInt(
+    int64_t an_int_arg, std::function<void(int64_t)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(an_int_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const int64_t return_value = encodable_return_value.LongValue();
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoDouble(
+    double a_double_arg, std::function<void(double)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_double_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value = std::get<double>(encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoString(
+    const std::string& a_string_arg,
+    std::function<void(const std::string&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_string_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value =
+            std::get<std::string>(encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoUint8List(
+    const std::vector<uint8_t>& a_list_arg,
+    std::function<void(const std::vector<uint8_t>&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_list_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value =
+            std::get<std::vector<uint8_t>>(encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoList(
+    const flutter::EncodableList& a_list_arg,
+    std::function<void(const flutter::EncodableList&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_list_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value =
+            std::get<flutter::EncodableList>(encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoMap(
+    const flutter::EncodableMap& a_map_arg,
+    std::function<void(const flutter::EncodableMap&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_map_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value =
+            std::get<flutter::EncodableMap>(encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableBool(
+    const bool* a_bool_arg, std::function<void(const bool*)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          a_bool_arg ? flutter::EncodableValue(*a_bool_arg)
+                     : flutter::EncodableValue(),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto* return_value = std::get_if<bool>(&encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableInt(
+    const int64_t* an_int_arg, std::function<void(const int64_t*)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          an_int_arg ? flutter::EncodableValue(*an_int_arg)
+                     : flutter::EncodableValue(),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const int64_t return_value_value =
+            encodable_return_value.IsNull()
+                ? 0
+                : encodable_return_value.LongValue();
+        const auto* return_value =
+            encodable_return_value.IsNull() ? nullptr : &return_value_value;
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableDouble(
+    const double* a_double_arg, std::function<void(const double*)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          a_double_arg ? flutter::EncodableValue(*a_double_arg)
+                       : flutter::EncodableValue(),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto* return_value = std::get_if<double>(&encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableString(
+    const std::string* a_string_arg,
+    std::function<void(const std::string*)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          a_string_arg ? flutter::EncodableValue(*a_string_arg)
+                       : flutter::EncodableValue(),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto* return_value =
+            std::get_if<std::string>(&encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableUint8List(
+    const std::vector<uint8_t>* a_list_arg,
+    std::function<void(const std::vector<uint8_t>*)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          a_list_arg ? flutter::EncodableValue(*a_list_arg)
+                     : flutter::EncodableValue(),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto* return_value =
+            std::get_if<std::vector<uint8_t>>(&encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableList(
+    const flutter::EncodableList* a_list_arg,
+    std::function<void(const flutter::EncodableList*)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          a_list_arg ? flutter::EncodableValue(*a_list_arg)
+                     : flutter::EncodableValue(),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto* return_value =
+            std::get_if<flutter::EncodableList>(&encodable_return_value);
+        on_success(return_value);
+      });
+}
+void FlutterIntegrationCoreApi::EchoNullableMap(
+    const flutter::EncodableMap& a_map_arg,
+    std::function<void(const flutter::EncodableMap&)>&& on_success,
+    std::function<void(const FlutterError&)>&& on_error) {
+  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+      binary_messenger_,
+      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap",
+      &GetCodec());
+  flutter::EncodableValue encoded_api_arguments =
+      flutter::EncodableValue(flutter::EncodableList{
+          flutter::EncodableValue(a_map_arg),
+      });
+  channel->Send(
+      encoded_api_arguments,
+      [on_success = std::move(on_success), on_error = std::move(on_error)](
+          const uint8_t* reply, size_t reply_size) {
+        std::unique_ptr<flutter::EncodableValue> response =
+            GetCodec().DecodeMessage(reply, reply_size);
+        const auto& encodable_return_value = *response;
+        const auto& return_value =
+            std::get<flutter::EncodableMap>(encodable_return_value);
+        on_success(return_value);
       });
 }
 /// The codec used by HostTrivialApi.
@@ -1536,10 +1860,9 @@
 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());
+    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
+        binary_messenger, "dev.flutter.pigeon.HostTrivialApi.noop",
+        &GetCodec());
     if (api != nullptr) {
       channel->SetMessageHandler(
           [api](const flutter::EncodableValue& message,
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
index c752a5a..545a050 100644
--- 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
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Autogenerated from Pigeon (v6.0.0), do not edit directly.
+// Autogenerated from Pigeon (v6.0.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
-#ifndef PIGEON_CORE_TESTS_GEN_H_H_
-#define PIGEON_CORE_TESTS_GEN_H_H_
+#ifndef PIGEON_CORE_TESTS_GEN_H_
+#define PIGEON_CORE_TESTS_GEN_H_
 #include <flutter/basic_message_channel.h>
 #include <flutter/binary_messenger.h>
 #include <flutter/encodable_value.h>
@@ -376,17 +376,82 @@
   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);
+  void Noop(std::function<void(void)>&& on_success,
+            std::function<void(const FlutterError&)>&& on_error);
   // Returns the passed object, to test serialization and deserialization.
-  void echoAllTypes(const AllTypes& everything_arg,
-                    std::function<void(const AllTypes&)>&& callback);
+  void EchoAllTypes(const AllTypes& everything,
+                    std::function<void(const AllTypes&)>&& on_success,
+                    std::function<void(const FlutterError&)>&& on_error);
   // Returns the passed object, to test serialization and deserialization.
-  void echoAllNullableTypes(
-      const AllNullableTypes& everything_arg,
-      std::function<void(const AllNullableTypes&)>&& callback);
+  void EchoAllNullableTypes(
+      const AllNullableTypes& everything,
+      std::function<void(const AllNullableTypes&)>&& on_success,
+      std::function<void(const FlutterError&)>&& on_error);
+  // Returns passed in arguments of multiple types.
+  //
+  // Tests multiple-arity FlutterApi handling.
+  void SendMultipleNullableTypes(
+      const bool* a_nullable_bool, const int64_t* a_nullable_int,
+      const std::string* a_nullable_string,
+      std::function<void(const AllNullableTypes&)>&& on_success,
+      std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed boolean, to test serialization and deserialization.
+  void EchoBool(bool a_bool, std::function<void(bool)>&& on_success,
+                std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed int, to test serialization and deserialization.
+  void EchoInt(int64_t an_int, std::function<void(int64_t)>&& on_success,
+               std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed double, to test serialization and deserialization.
+  void EchoDouble(double a_double, std::function<void(double)>&& on_success,
+                  std::function<void(const FlutterError&)>&& on_error);
   // Returns the passed string, to test serialization and deserialization.
-  void echoString(const std::string& a_string_arg,
-                  std::function<void(const std::string&)>&& callback);
+  void EchoString(const std::string& a_string,
+                  std::function<void(const std::string&)>&& on_success,
+                  std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed byte list, to test serialization and deserialization.
+  void EchoUint8List(
+      const std::vector<uint8_t>& a_list,
+      std::function<void(const std::vector<uint8_t>&)>&& on_success,
+      std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed list, to test serialization and deserialization.
+  void EchoList(const flutter::EncodableList& a_list,
+                std::function<void(const flutter::EncodableList&)>&& on_success,
+                std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed map, to test serialization and deserialization.
+  void EchoMap(const flutter::EncodableMap& a_map,
+               std::function<void(const flutter::EncodableMap&)>&& on_success,
+               std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed boolean, to test serialization and deserialization.
+  void EchoNullableBool(const bool* a_bool,
+                        std::function<void(const bool*)>&& on_success,
+                        std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed int, to test serialization and deserialization.
+  void EchoNullableInt(const int64_t* an_int,
+                       std::function<void(const int64_t*)>&& on_success,
+                       std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed double, to test serialization and deserialization.
+  void EchoNullableDouble(const double* a_double,
+                          std::function<void(const double*)>&& on_success,
+                          std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed string, to test serialization and deserialization.
+  void EchoNullableString(const std::string* a_string,
+                          std::function<void(const std::string*)>&& on_success,
+                          std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed byte list, to test serialization and deserialization.
+  void EchoNullableUint8List(
+      const std::vector<uint8_t>* a_list,
+      std::function<void(const std::vector<uint8_t>*)>&& on_success,
+      std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed list, to test serialization and deserialization.
+  void EchoNullableList(
+      const flutter::EncodableList* a_list,
+      std::function<void(const flutter::EncodableList*)>&& on_success,
+      std::function<void(const FlutterError&)>&& on_error);
+  // Returns the passed map, to test serialization and deserialization.
+  void EchoNullableMap(
+      const flutter::EncodableMap& a_map,
+      std::function<void(const flutter::EncodableMap&)>&& on_success,
+      std::function<void(const FlutterError&)>&& on_error);
 };
 
 // An API that can be implemented for minimal, compile-only tests.
@@ -413,4 +478,4 @@
   HostTrivialApi() = default;
 };
 }  // namespace core_tests_pigeontest
-#endif  // PIGEON_CORE_TESTS_GEN_H_H_
+#endif  // PIGEON_CORE_TESTS_GEN_H_
diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp
index 8c35994..b5477b4 100644
--- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp
+++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp
@@ -179,15 +179,17 @@
 
 void TestPlugin::CallFlutterNoop(
     std::function<void(std::optional<FlutterError> reply)> result) {
-  flutter_api_->noop([result]() { result(std::nullopt); });
+  flutter_api_->Noop([result]() { result(std::nullopt); },
+                     [result](const FlutterError& error) { result(error); });
 }
 
 void TestPlugin::CallFlutterEchoString(
     const std::string& a_string,
     std::function<void(ErrorOr<std::string> reply)> result) {
-  flutter_api_->echoString(
+  flutter_api_->EchoString(
       a_string,
-      [result](const std::string& flutter_string) { result(flutter_string); });
+      [result](const std::string& flutter_string) { result(flutter_string); },
+      [result](const FlutterError& error) { result(error); });
 }
 
 }  // namespace test_plugin
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index caa82a3..1f08613 100644
--- a/packages/pigeon/pubspec.yaml
+++ b/packages/pigeon/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
 repository: https://github.com/flutter/packages/tree/main/packages/pigeon
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon
-version: 6.0.0 # This must match the version in lib/generator_tools.dart
+version: 6.0.1 # This must match the version in lib/generator_tools.dart
 
 environment:
   sdk: ">=2.12.0 <3.0.0"
diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart
index 97dc129..9aa4784 100644
--- a/packages/pigeon/test/cpp_generator_test.dart
+++ b/packages/pigeon/test/cpp_generator_test.dart
@@ -1154,6 +1154,274 @@
     }
   });
 
+  test('flutter nullable arguments map correctly', () {
+    final Root root = Root(apis: <Api>[
+      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
+        Method(
+          name: 'doSomething',
+          arguments: <NamedType>[
+            NamedType(
+                name: 'aBool',
+                type: const TypeDeclaration(
+                  baseName: 'bool',
+                  isNullable: true,
+                )),
+            NamedType(
+                name: 'anInt',
+                type: const TypeDeclaration(
+                  baseName: 'int',
+                  isNullable: true,
+                )),
+            NamedType(
+                name: 'aString',
+                type: const TypeDeclaration(
+                  baseName: 'String',
+                  isNullable: true,
+                )),
+            NamedType(
+                name: 'aList',
+                type: const TypeDeclaration(
+                  baseName: 'List',
+                  typeArguments: <TypeDeclaration>[
+                    TypeDeclaration(baseName: 'Object', isNullable: true)
+                  ],
+                  isNullable: true,
+                )),
+            NamedType(
+                name: 'aMap',
+                type: const TypeDeclaration(
+                  baseName: 'Map',
+                  typeArguments: <TypeDeclaration>[
+                    TypeDeclaration(baseName: 'String', isNullable: true),
+                    TypeDeclaration(baseName: 'Object', isNullable: true),
+                  ],
+                  isNullable: true,
+                )),
+            NamedType(
+                name: 'anObject',
+                type: const TypeDeclaration(
+                  baseName: 'ParameterObject',
+                  isNullable: true,
+                )),
+            NamedType(
+                name: 'aGenericObject',
+                type: const TypeDeclaration(
+                  baseName: 'Object',
+                  isNullable: true,
+                )),
+          ],
+          returnType: const TypeDeclaration(
+            baseName: 'bool',
+            isNullable: true,
+          ),
+        ),
+      ])
+    ], classes: <Class>[
+      Class(name: 'ParameterObject', fields: <NamedType>[
+        NamedType(
+            type: const TypeDeclaration(
+              baseName: 'bool',
+              isNullable: false,
+            ),
+            name: 'aValue'),
+      ]),
+    ], enums: <Enum>[]);
+    {
+      final StringBuffer sink = StringBuffer();
+      const CppGenerator generator = CppGenerator();
+      final OutputFileOptions<CppOptions> generatorOptions =
+          OutputFileOptions<CppOptions>(
+        fileType: FileType.header,
+        languageOptions: const CppOptions(),
+      );
+      generator.generate(generatorOptions, root, sink);
+      final String code = sink.toString();
+      // Nullable arguments should all be pointers. This will make them somewhat
+      // awkward for some uses (literals, values that could be inlined) but
+      // unlike setters there's no way to provide reference-based alternatives
+      // since it's not always just one argument.
+      // TODO(stuartmorgan): Consider generating a second variant using
+      // `std::optional`s; that may be more ergonomic, but the perf implications
+      // would need to be considered.
+      expect(
+          code,
+          contains('DoSomething(const bool* a_bool, '
+              'const int64_t* an_int, '
+              // Nullable strings use std::string* rather than std::string_view*
+              // since there's no implicit conversion for pointer types.
+              'const std::string* a_string, '
+              'const flutter::EncodableList* a_list, '
+              'const flutter::EncodableMap* a_map, '
+              'const ParameterObject* an_object, '
+              'const flutter::EncodableValue* a_generic_object, '));
+      // The callback should pass a pointer as well.
+      expect(
+          code,
+          contains('std::function<void(const bool*)>&& on_success, '
+              'std::function<void(const FlutterError&)>&& on_error)'));
+    }
+    {
+      final StringBuffer sink = StringBuffer();
+      const CppGenerator generator = CppGenerator();
+      final OutputFileOptions<CppOptions> generatorOptions =
+          OutputFileOptions<CppOptions>(
+        fileType: FileType.source,
+        languageOptions: const CppOptions(),
+      );
+      generator.generate(generatorOptions, root, sink);
+      final String code = sink.toString();
+      // All types pass nulls values when the pointer is null.
+      // Standard types are wrapped an EncodableValues.
+      expect(
+          code,
+          contains(
+              'a_bool_arg ? flutter::EncodableValue(*a_bool_arg) : flutter::EncodableValue()'));
+      expect(
+          code,
+          contains(
+              'an_int_arg ? flutter::EncodableValue(*an_int_arg) : flutter::EncodableValue()'));
+      expect(
+          code,
+          contains(
+              'a_string_arg ? flutter::EncodableValue(*a_string_arg) : flutter::EncodableValue()'));
+      expect(
+          code,
+          contains(
+              'a_list_arg ? flutter::EncodableValue(*a_list_arg) : flutter::EncodableValue()'));
+      expect(
+          code,
+          contains(
+              'a_map_arg ? flutter::EncodableValue(*a_map_arg) : flutter::EncodableValue()'));
+      // Class types use ToEncodableList.
+      expect(
+          code,
+          contains(
+              'an_object_arg ? flutter::EncodableValue(an_object_arg->ToEncodableList()) : flutter::EncodableValue()'));
+    }
+  });
+
+  test('flutter non-nullable arguments map correctly', () {
+    final Root root = Root(apis: <Api>[
+      Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
+        Method(
+          name: 'doSomething',
+          arguments: <NamedType>[
+            NamedType(
+                name: 'aBool',
+                type: const TypeDeclaration(
+                  baseName: 'bool',
+                  isNullable: false,
+                )),
+            NamedType(
+                name: 'anInt',
+                type: const TypeDeclaration(
+                  baseName: 'int',
+                  isNullable: false,
+                )),
+            NamedType(
+                name: 'aString',
+                type: const TypeDeclaration(
+                  baseName: 'String',
+                  isNullable: false,
+                )),
+            NamedType(
+                name: 'aList',
+                type: const TypeDeclaration(
+                  baseName: 'List',
+                  typeArguments: <TypeDeclaration>[
+                    TypeDeclaration(baseName: 'Object', isNullable: true)
+                  ],
+                  isNullable: false,
+                )),
+            NamedType(
+                name: 'aMap',
+                type: const TypeDeclaration(
+                  baseName: 'Map',
+                  typeArguments: <TypeDeclaration>[
+                    TypeDeclaration(baseName: 'String', isNullable: true),
+                    TypeDeclaration(baseName: 'Object', isNullable: true),
+                  ],
+                  isNullable: false,
+                )),
+            NamedType(
+                name: 'anObject',
+                type: const TypeDeclaration(
+                  baseName: 'ParameterObject',
+                  isNullable: false,
+                )),
+            NamedType(
+                name: 'aGenericObject',
+                type: const TypeDeclaration(
+                  baseName: 'Object',
+                  isNullable: false,
+                )),
+          ],
+          returnType: const TypeDeclaration(
+            baseName: 'bool',
+            isNullable: false,
+          ),
+        ),
+      ])
+    ], classes: <Class>[
+      Class(name: 'ParameterObject', fields: <NamedType>[
+        NamedType(
+            type: const TypeDeclaration(
+              baseName: 'bool',
+              isNullable: false,
+            ),
+            name: 'aValue'),
+      ]),
+    ], enums: <Enum>[]);
+    {
+      final StringBuffer sink = StringBuffer();
+      const CppGenerator generator = CppGenerator();
+      final OutputFileOptions<CppOptions> generatorOptions =
+          OutputFileOptions<CppOptions>(
+        fileType: FileType.header,
+        languageOptions: const CppOptions(),
+      );
+      generator.generate(generatorOptions, root, sink);
+      final String code = sink.toString();
+      expect(
+          code,
+          contains('DoSomething(bool a_bool, '
+              'int64_t an_int, '
+              // Non-nullable strings use std::string for consistency with
+              // nullable strings.
+              'const std::string& a_string, '
+              // Non-POD types use const references.
+              'const flutter::EncodableList& a_list, '
+              'const flutter::EncodableMap& a_map, '
+              'const ParameterObject& an_object, '
+              'const flutter::EncodableValue& a_generic_object, '));
+      // The callback should pass a value.
+      expect(
+          code,
+          contains('std::function<void(bool)>&& on_success, '
+              'std::function<void(const FlutterError&)>&& on_error)'));
+    }
+    {
+      final StringBuffer sink = StringBuffer();
+      const CppGenerator generator = CppGenerator();
+      final OutputFileOptions<CppOptions> generatorOptions =
+          OutputFileOptions<CppOptions>(
+        fileType: FileType.source,
+        languageOptions: const CppOptions(),
+      );
+      generator.generate(generatorOptions, root, sink);
+      final String code = sink.toString();
+      // Standard types are wrapped an EncodableValues.
+      expect(code, contains('flutter::EncodableValue(a_bool_arg)'));
+      expect(code, contains('flutter::EncodableValue(an_int_arg)'));
+      expect(code, contains('flutter::EncodableValue(a_string_arg)'));
+      expect(code, contains('flutter::EncodableValue(a_list_arg)'));
+      expect(code, contains('flutter::EncodableValue(a_map_arg)'));
+      // Class types use ToEncodableList.
+      expect(code,
+          contains('flutter::EncodableValue(an_object_arg.ToEncodableList())'));
+    }
+  });
+
   test('host API argument extraction uses references', () {
     final Root root = Root(apis: <Api>[
       Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart
index dfd2dfb..1bf8594 100644
--- a/packages/pigeon/test/swift_generator_test.dart
+++ b/packages/pigeon/test/swift_generator_test.dart
@@ -834,7 +834,8 @@
         code,
         contains(
             'func add(x xArg: Int32, y yArg: Int32, completion: @escaping (Int32) -> Void)'));
-    expect(code, contains('channel.sendMessage([xArg, yArg]) { response in'));
+    expect(code,
+        contains('channel.sendMessage([xArg, yArg] as [Any?]) { response in'));
   });
 
   test('return nullable host', () {