// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// 
// Autogenerated from Pigeon (v7.0.1), do not edit directly.
// See also: https://pub.dev/packages/pigeon

package com.example.test_plugin

import android.util.Log
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MessageCodec
import io.flutter.plugin.common.StandardMessageCodec
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer

private fun wrapResult(result: Any?): List<Any?> {
  return listOf(result)
}

private fun wrapError(exception: Throwable): List<Any> {
  return listOf<Any>(
    exception.javaClass.simpleName,
    exception.toString(),
    "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
  )
}

enum class AnEnum(val raw: Int) {
  ONE(0),
  TWO(1),
  THREE(2);

  companion object {
    fun ofRaw(raw: Int): AnEnum? {
      return values().firstOrNull { it.raw == raw }
    }
  }
}

/** Generated class from Pigeon that represents data sent in messages. */
data class AllTypes (
  val aBool: Boolean,
  val anInt: Long,
  val aDouble: Double,
  val aByteArray: ByteArray,
  val a4ByteArray: IntArray,
  val a8ByteArray: LongArray,
  val aFloatArray: DoubleArray,
  val aList: List<Any?>,
  val aMap: Map<Any, Any?>,
  val anEnum: AnEnum,
  val aString: String

) {
  companion object {
    @Suppress("UNCHECKED_CAST")
    fun fromList(list: List<Any?>): AllTypes {
      val aBool = list[0] as Boolean
      val anInt = list[1] as Long
      val aDouble = list[2] as Double
      val aByteArray = list[3] as ByteArray
      val a4ByteArray = list[4] as IntArray
      val a8ByteArray = list[5] as LongArray
      val aFloatArray = list[6] as DoubleArray
      val aList = list[7] as List<Any?>
      val aMap = list[8] as Map<Any, Any?>
      val anEnum = AnEnum.ofRaw(list[9] as Int)!!
      val aString = list[10] as String
      return AllTypes(aBool, anInt, aDouble, aByteArray, a4ByteArray, a8ByteArray, aFloatArray, aList, aMap, anEnum, aString)
    }
  }
  fun toList(): List<Any?> {
    return listOf<Any?>(
      aBool,
      anInt,
      aDouble,
      aByteArray,
      a4ByteArray,
      a8ByteArray,
      aFloatArray,
      aList,
      aMap,
      anEnum?.raw,
      aString,
    )
  }
}

/** Generated class from Pigeon that represents data sent in messages. */
data class AllNullableTypes (
  val aNullableBool: Boolean? = null,
  val aNullableInt: Long? = null,
  val aNullableDouble: Double? = null,
  val aNullableByteArray: ByteArray? = null,
  val aNullable4ByteArray: IntArray? = null,
  val aNullable8ByteArray: LongArray? = null,
  val aNullableFloatArray: DoubleArray? = null,
  val aNullableList: List<Any?>? = null,
  val aNullableMap: Map<Any, Any?>? = null,
  val nullableNestedList: List<List<Boolean?>?>? = null,
  val nullableMapWithAnnotations: Map<String?, String?>? = null,
  val nullableMapWithObject: Map<String?, Any?>? = null,
  val aNullableEnum: AnEnum? = null,
  val aNullableString: String? = null

) {
  companion object {
    @Suppress("UNCHECKED_CAST")
    fun fromList(list: List<Any?>): AllNullableTypes {
      val aNullableBool = list[0] as? Boolean
      val aNullableInt = list[1].let { if (it is Int) it.toLong() else it as? Long }
      val aNullableDouble = list[2] as? Double
      val aNullableByteArray = list[3] as? ByteArray
      val aNullable4ByteArray = list[4] as? IntArray
      val aNullable8ByteArray = list[5] as? LongArray
      val aNullableFloatArray = list[6] as? DoubleArray
      val aNullableList = list[7] as? List<Any?>
      val aNullableMap = list[8] as? Map<Any, Any?>
      val nullableNestedList = list[9] as? List<List<Boolean?>?>
      val nullableMapWithAnnotations = list[10] as? Map<String?, String?>
      val nullableMapWithObject = list[11] as? Map<String?, Any?>
      val aNullableEnum: AnEnum? = (list[12] as? Int)?.let {
        AnEnum.ofRaw(it)
      }
      val aNullableString = list[13] as? String
      return AllNullableTypes(aNullableBool, aNullableInt, aNullableDouble, aNullableByteArray, aNullable4ByteArray, aNullable8ByteArray, aNullableFloatArray, aNullableList, aNullableMap, nullableNestedList, nullableMapWithAnnotations, nullableMapWithObject, aNullableEnum, aNullableString)
    }
  }
  fun toList(): List<Any?> {
    return listOf<Any?>(
      aNullableBool,
      aNullableInt,
      aNullableDouble,
      aNullableByteArray,
      aNullable4ByteArray,
      aNullable8ByteArray,
      aNullableFloatArray,
      aNullableList,
      aNullableMap,
      nullableNestedList,
      nullableMapWithAnnotations,
      nullableMapWithObject,
      aNullableEnum?.raw,
      aNullableString,
    )
  }
}

/** Generated class from Pigeon that represents data sent in messages. */
data class AllNullableTypesWrapper (
  val values: AllNullableTypes

) {
  companion object {
    @Suppress("UNCHECKED_CAST")
    fun fromList(list: List<Any?>): AllNullableTypesWrapper {
      val values = AllNullableTypes.fromList(list[0] as List<Any?>)
      return AllNullableTypesWrapper(values)
    }
  }
  fun toList(): List<Any?> {
    return listOf<Any?>(
      values?.toList(),
    )
  }
}

@Suppress("UNCHECKED_CAST")
private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
  override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
    return when (type) {
      128.toByte() -> {
        return (readValue(buffer) as? List<Any?>)?.let {
          AllNullableTypes.fromList(it)
        }
      }
      129.toByte() -> {
        return (readValue(buffer) as? List<Any?>)?.let {
          AllNullableTypesWrapper.fromList(it)
        }
      }
      130.toByte() -> {
        return (readValue(buffer) as? List<Any?>)?.let {
          AllTypes.fromList(it)
        }
      }
      else -> super.readValueOfType(type, buffer)
    }
  }
  override fun writeValue(stream: ByteArrayOutputStream, value: Any?)   {
    when (value) {
      is AllNullableTypes -> {
        stream.write(128)
        writeValue(stream, value.toList())
      }
      is AllNullableTypesWrapper -> {
        stream.write(129)
        writeValue(stream, value.toList())
      }
      is AllTypes -> {
        stream.write(130)
        writeValue(stream, value.toList())
      }
      else -> super.writeValue(stream, value)
    }
  }
}

/**
 * The core interface that each host language plugin must implement in
 * platform_test integration tests.
 *
 * Generated interface from Pigeon that represents a handler of messages from Flutter.
 */
interface HostIntegrationCoreApi {
  /**
   * A no-op function taking no arguments and returning no value, to sanity
   * test basic calling.
   */
  fun noop()
  /** Returns the passed object, to test serialization and deserialization. */
  fun echoAllTypes(everything: AllTypes): AllTypes
  /** Returns the passed object, to test serialization and deserialization. */
  fun echoAllNullableTypes(everything: AllNullableTypes?): AllNullableTypes?
  /** Returns an error, to test error handling. */
  fun throwError()
  /** Returns passed in int. */
  fun echoInt(anInt: Long): Long
  /** Returns passed in double. */
  fun echoDouble(aDouble: Double): Double
  /** Returns the passed in boolean. */
  fun echoBool(aBool: Boolean): Boolean
  /** Returns the passed in string. */
  fun echoString(aString: String): String
  /** Returns the passed in Uint8List. */
  fun echoUint8List(aUint8List: ByteArray): ByteArray
  /** Returns the passed in generic Object. */
  fun echoObject(anObject: Any): Any
  /**
   * Returns the inner `aString` value from the wrapped object, to test
   * sending of nested objects.
   */
  fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String?
  /**
   * Returns the inner `aString` value from the wrapped object, to test
   * sending of nested objects.
   */
  fun createNestedNullableString(nullableString: String?): AllNullableTypesWrapper
  /** Returns passed in arguments of multiple types. */
  fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes
  /** Returns passed in int. */
  fun echoNullableInt(aNullableInt: Long?): Long?
  /** Returns passed in double. */
  fun echoNullableDouble(aNullableDouble: Double?): Double?
  /** Returns the passed in boolean. */
  fun echoNullableBool(aNullableBool: Boolean?): Boolean?
  /** Returns the passed in string. */
  fun echoNullableString(aNullableString: String?): String?
  /** Returns the passed in Uint8List. */
  fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray?
  /** Returns the passed in generic Object. */
  fun echoNullableObject(aNullableObject: Any?): Any?
  /**
   * A no-op function taking no arguments and returning no value, to sanity
   * test basic asynchronous calling.
   */
  fun noopAsync(callback: () -> Unit)
  /** Returns the passed string asynchronously. */
  fun echoAsyncString(aString: String, callback: (String) -> Unit)
  fun callFlutterNoop(callback: () -> Unit)
  fun callFlutterEchoAllTypes(everything: AllTypes, callback: (AllTypes) -> Unit)
  fun callFlutterSendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?, callback: (AllNullableTypes) -> Unit)
  fun callFlutterEchoBool(aBool: Boolean, callback: (Boolean) -> Unit)
  fun callFlutterEchoInt(anInt: Long, callback: (Long) -> Unit)
  fun callFlutterEchoDouble(aDouble: Double, callback: (Double) -> Unit)
  fun callFlutterEchoString(aString: String, callback: (String) -> Unit)
  fun callFlutterEchoUint8List(aList: ByteArray, callback: (ByteArray) -> Unit)
  fun callFlutterEchoList(aList: List<Any?>, callback: (List<Any?>) -> Unit)
  fun callFlutterEchoMap(aMap: Map<String?, Any?>, callback: (Map<String?, Any?>) -> Unit)
  fun callFlutterEchoNullableBool(aBool: Boolean?, callback: (Boolean?) -> Unit)
  fun callFlutterEchoNullableInt(anInt: Long?, callback: (Long?) -> Unit)
  fun callFlutterEchoNullableDouble(aDouble: Double?, callback: (Double?) -> Unit)
  fun callFlutterEchoNullableString(aString: String?, callback: (String?) -> Unit)
  fun callFlutterEchoNullableUint8List(aList: ByteArray?, callback: (ByteArray?) -> Unit)
  fun callFlutterEchoNullableList(aList: List<Any?>?, callback: (List<Any?>?) -> Unit)
  fun callFlutterEchoNullableMap(aMap: Map<String?, Any?>?, callback: (Map<String?, Any?>?) -> Unit)

  companion object {
    /** The codec used by HostIntegrationCoreApi. */
    val codec: MessageCodec<Any?> by lazy {
      HostIntegrationCoreApiCodec
    }
    /** Sets up an instance of `HostIntegrationCoreApi` to handle messages through the `binaryMessenger`. */
    @Suppress("UNCHECKED_CAST")
    fun setUp(binaryMessenger: BinaryMessenger, api: HostIntegrationCoreApi?) {
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop", codec)
        if (api != null) {
          channel.setMessageHandler { _, reply ->
            var wrapped = listOf<Any?>()
            try {
              api.noop()
              wrapped = listOf<Any?>(null)
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val everythingArg = args[0] as AllTypes
              wrapped = listOf<Any?>(api.echoAllTypes(everythingArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val everythingArg = args[0] as? AllNullableTypes
              wrapped = listOf<Any?>(api.echoAllNullableTypes(everythingArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", codec)
        if (api != null) {
          channel.setMessageHandler { _, reply ->
            var wrapped = listOf<Any?>()
            try {
              api.throwError()
              wrapped = listOf<Any?>(null)
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val anIntArg = args[0].let { if (it is Int) it.toLong() else it as Long }
              wrapped = listOf<Any?>(api.echoInt(anIntArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aDoubleArg = args[0] as Double
              wrapped = listOf<Any?>(api.echoDouble(aDoubleArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aBoolArg = args[0] as Boolean
              wrapped = listOf<Any?>(api.echoBool(aBoolArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aStringArg = args[0] as String
              wrapped = listOf<Any?>(api.echoString(aStringArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aUint8ListArg = args[0] as ByteArray
              wrapped = listOf<Any?>(api.echoUint8List(aUint8ListArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val anObjectArg = args[0] as Any
              wrapped = listOf<Any?>(api.echoObject(anObjectArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val wrapperArg = args[0] as AllNullableTypesWrapper
              wrapped = listOf<Any?>(api.extractNestedNullableString(wrapperArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val nullableStringArg = args[0] as? String
              wrapped = listOf<Any?>(api.createNestedNullableString(nullableStringArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableBoolArg = args[0] as? Boolean
              val aNullableIntArg = args[1].let { if (it is Int) it.toLong() else it as? Long }
              val aNullableStringArg = args[2] as? String
              wrapped = listOf<Any?>(api.sendMultipleNullableTypes(aNullableBoolArg, aNullableIntArg, aNullableStringArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableIntArg = args[0].let { if (it is Int) it.toLong() else it as? Long }
              wrapped = listOf<Any?>(api.echoNullableInt(aNullableIntArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableDoubleArg = args[0] as? Double
              wrapped = listOf<Any?>(api.echoNullableDouble(aNullableDoubleArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableBoolArg = args[0] as? Boolean
              wrapped = listOf<Any?>(api.echoNullableBool(aNullableBoolArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableStringArg = args[0] as? String
              wrapped = listOf<Any?>(api.echoNullableString(aNullableStringArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableUint8ListArg = args[0] as? ByteArray
              wrapped = listOf<Any?>(api.echoNullableUint8List(aNullableUint8ListArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableObjectArg = args[0] as? Any
              wrapped = listOf<Any?>(api.echoNullableObject(aNullableObjectArg))
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", codec)
        if (api != null) {
          channel.setMessageHandler { _, reply ->
            var wrapped = listOf<Any?>()
            try {
              api.noopAsync() {
                reply.reply(wrapResult(null))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aStringArg = args[0] as String
              api.echoAsyncString(aStringArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop", codec)
        if (api != null) {
          channel.setMessageHandler { _, reply ->
            var wrapped = listOf<Any?>()
            try {
              api.callFlutterNoop() {
                reply.reply(wrapResult(null))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoAllTypes", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val everythingArg = args[0] as AllTypes
              api.callFlutterEchoAllTypes(everythingArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aNullableBoolArg = args[0] as? Boolean
              val aNullableIntArg = args[1].let { if (it is Int) it.toLong() else it as? Long }
              val aNullableStringArg = args[2] as? String
              api.callFlutterSendMultipleNullableTypes(aNullableBoolArg, aNullableIntArg, aNullableStringArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoBool", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aBoolArg = args[0] as Boolean
              api.callFlutterEchoBool(aBoolArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoInt", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val anIntArg = args[0].let { if (it is Int) it.toLong() else it as Long }
              api.callFlutterEchoInt(anIntArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoDouble", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aDoubleArg = args[0] as Double
              api.callFlutterEchoDouble(aDoubleArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aStringArg = args[0] as String
              api.callFlutterEchoString(aStringArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoUint8List", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aListArg = args[0] as ByteArray
              api.callFlutterEchoUint8List(aListArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoList", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aListArg = args[0] as List<Any?>
              api.callFlutterEchoList(aListArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoMap", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aMapArg = args[0] as Map<String?, Any?>
              api.callFlutterEchoMap(aMapArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableBool", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aBoolArg = args[0] as? Boolean
              api.callFlutterEchoNullableBool(aBoolArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableInt", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val anIntArg = args[0].let { if (it is Int) it.toLong() else it as? Long }
              api.callFlutterEchoNullableInt(anIntArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableDouble", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aDoubleArg = args[0] as? Double
              api.callFlutterEchoNullableDouble(aDoubleArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableString", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aStringArg = args[0] as? String
              api.callFlutterEchoNullableString(aStringArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableUint8List", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aListArg = args[0] as? ByteArray
              api.callFlutterEchoNullableUint8List(aListArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableList", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aListArg = args[0] as? List<Any?>
              api.callFlutterEchoNullableList(aListArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableMap", codec)
        if (api != null) {
          channel.setMessageHandler { message, reply ->
            var wrapped = listOf<Any?>()
            try {
              val args = message as List<Any?>
              val aMapArg = args[0] as? Map<String?, Any?>
              api.callFlutterEchoNullableMap(aMapArg) {
                reply.reply(wrapResult(it))
              }
            } catch (exception: Error) {
              wrapped = wrapError(exception)
              reply.reply(wrapped)
            }
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
    }
  }
}
@Suppress("UNCHECKED_CAST")
private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() {
  override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
    return when (type) {
      128.toByte() -> {
        return (readValue(buffer) as? List<Any?>)?.let {
          AllNullableTypes.fromList(it)
        }
      }
      129.toByte() -> {
        return (readValue(buffer) as? List<Any?>)?.let {
          AllNullableTypesWrapper.fromList(it)
        }
      }
      130.toByte() -> {
        return (readValue(buffer) as? List<Any?>)?.let {
          AllTypes.fromList(it)
        }
      }
      else -> super.readValueOfType(type, buffer)
    }
  }
  override fun writeValue(stream: ByteArrayOutputStream, value: Any?)   {
    when (value) {
      is AllNullableTypes -> {
        stream.write(128)
        writeValue(stream, value.toList())
      }
      is AllNullableTypesWrapper -> {
        stream.write(129)
        writeValue(stream, value.toList())
      }
      is AllTypes -> {
        stream.write(130)
        writeValue(stream, value.toList())
      }
      else -> super.writeValue(stream, value)
    }
  }
}

/**
 * The core interface that the Dart platform_test code implements for host
 * integration tests to call into.
 *
 * Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.
 */
@Suppress("UNCHECKED_CAST")
class FlutterIntegrationCoreApi(private val binaryMessenger: BinaryMessenger) {
  companion object {
    /** The codec used by FlutterIntegrationCoreApi. */
    val codec: MessageCodec<Any?> by lazy {
      FlutterIntegrationCoreApiCodec
    }
  }
  /**
   * A no-op function taking no arguments and returning no value, to sanity
   * test basic calling.
   */
  fun noop(callback: () -> Unit) {
    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", codec)
    channel.send(null) {
      callback()
    }
  }
  /** Returns the passed object, to test serialization and deserialization. */
  fun echoAllTypes(everythingArg: AllTypes, callback: (AllTypes) -> Unit) {
    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", codec)
    channel.send(listOf(everythingArg)) {
      val result = it as AllTypes
      callback(result)
    }
  }
  /** Returns the passed object, to test serialization and deserialization. */
  fun echoAllNullableTypes(everythingArg: AllNullableTypes, callback: (AllNullableTypes) -> Unit) {
    val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes", codec)
    channel.send(listOf(everythingArg)) {
      val result = it as AllNullableTypes
      callback(result)
    }
  }
  /**
   * Returns 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)
    channel.send(listOf(aStringArg)) {
      val result = it as String
      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.
 *
 * Generated interface from Pigeon that represents a handler of messages from Flutter.
 */
interface HostTrivialApi {
  fun noop()

  companion object {
    /** The codec used by HostTrivialApi. */
    val codec: MessageCodec<Any?> by lazy {
      StandardMessageCodec()
    }
    /** Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`. */
    @Suppress("UNCHECKED_CAST")
    fun setUp(binaryMessenger: BinaryMessenger, api: HostTrivialApi?) {
      run {
        val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostTrivialApi.noop", codec)
        if (api != null) {
          channel.setMessageHandler { _, reply ->
            var wrapped = listOf<Any?>()
            try {
              api.noop()
              wrapped = listOf<Any?>(null)
            } catch (exception: Error) {
              wrapped = wrapError(exception)
            }
            reply.reply(wrapped)
          }
        } else {
          channel.setMessageHandler(null)
        }
      }
    }
  }
}
