// 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 (v5.0.1), do not edit directly.
// See also: https://pub.dev/packages/pigeon

package com.example.alternate_language_test_plugin;

import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.plugin.common.BasicMessageChannel;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.common.StandardMessageCodec;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/** Generated class from Pigeon. */
@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})
public class CoreTests {

  public enum AnEnum {
    ONE(0),
    TWO(1),
    THREE(2);

    private final int index;

    private AnEnum(final int index) {
      this.index = index;
    }
  }

  /** Generated class from Pigeon that represents data sent in messages. */
  public static class AllTypes {
    private @NonNull Boolean aBool;

    public @NonNull Boolean getABool() {
      return aBool;
    }

    public void setABool(@NonNull Boolean setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aBool\" is null.");
      }
      this.aBool = setterArg;
    }

    private @NonNull Long anInt;

    public @NonNull Long getAnInt() {
      return anInt;
    }

    public void setAnInt(@NonNull Long setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"anInt\" is null.");
      }
      this.anInt = setterArg;
    }

    private @NonNull Double aDouble;

    public @NonNull Double getADouble() {
      return aDouble;
    }

    public void setADouble(@NonNull Double setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aDouble\" is null.");
      }
      this.aDouble = setterArg;
    }

    private @NonNull String aString;

    public @NonNull String getAString() {
      return aString;
    }

    public void setAString(@NonNull String setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aString\" is null.");
      }
      this.aString = setterArg;
    }

    private @NonNull byte[] aByteArray;

    public @NonNull byte[] getAByteArray() {
      return aByteArray;
    }

    public void setAByteArray(@NonNull byte[] setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aByteArray\" is null.");
      }
      this.aByteArray = setterArg;
    }

    private @NonNull int[] a4ByteArray;

    public @NonNull int[] getA4ByteArray() {
      return a4ByteArray;
    }

    public void setA4ByteArray(@NonNull int[] setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"a4ByteArray\" is null.");
      }
      this.a4ByteArray = setterArg;
    }

    private @NonNull long[] a8ByteArray;

    public @NonNull long[] getA8ByteArray() {
      return a8ByteArray;
    }

    public void setA8ByteArray(@NonNull long[] setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"a8ByteArray\" is null.");
      }
      this.a8ByteArray = setterArg;
    }

    private @NonNull double[] aFloatArray;

    public @NonNull double[] getAFloatArray() {
      return aFloatArray;
    }

    public void setAFloatArray(@NonNull double[] setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aFloatArray\" is null.");
      }
      this.aFloatArray = setterArg;
    }

    private @NonNull List<Object> aList;

    public @NonNull List<Object> getAList() {
      return aList;
    }

    public void setAList(@NonNull List<Object> setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aList\" is null.");
      }
      this.aList = setterArg;
    }

    private @NonNull Map<Object, Object> aMap;

    public @NonNull Map<Object, Object> getAMap() {
      return aMap;
    }

    public void setAMap(@NonNull Map<Object, Object> setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"aMap\" is null.");
      }
      this.aMap = setterArg;
    }

    private @NonNull AnEnum anEnum;

    public @NonNull AnEnum getAnEnum() {
      return anEnum;
    }

    public void setAnEnum(@NonNull AnEnum setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"anEnum\" is null.");
      }
      this.anEnum = setterArg;
    }

    /** Constructor is private to enforce null safety; use Builder. */
    private AllTypes() {}

    public static final class Builder {
      private @Nullable Boolean aBool;

      public @NonNull Builder setABool(@NonNull Boolean setterArg) {
        this.aBool = setterArg;
        return this;
      }

      private @Nullable Long anInt;

      public @NonNull Builder setAnInt(@NonNull Long setterArg) {
        this.anInt = setterArg;
        return this;
      }

      private @Nullable Double aDouble;

      public @NonNull Builder setADouble(@NonNull Double setterArg) {
        this.aDouble = setterArg;
        return this;
      }

      private @Nullable String aString;

      public @NonNull Builder setAString(@NonNull String setterArg) {
        this.aString = setterArg;
        return this;
      }

      private @Nullable byte[] aByteArray;

      public @NonNull Builder setAByteArray(@NonNull byte[] setterArg) {
        this.aByteArray = setterArg;
        return this;
      }

      private @Nullable int[] a4ByteArray;

      public @NonNull Builder setA4ByteArray(@NonNull int[] setterArg) {
        this.a4ByteArray = setterArg;
        return this;
      }

      private @Nullable long[] a8ByteArray;

      public @NonNull Builder setA8ByteArray(@NonNull long[] setterArg) {
        this.a8ByteArray = setterArg;
        return this;
      }

      private @Nullable double[] aFloatArray;

      public @NonNull Builder setAFloatArray(@NonNull double[] setterArg) {
        this.aFloatArray = setterArg;
        return this;
      }

      private @Nullable List<Object> aList;

      public @NonNull Builder setAList(@NonNull List<Object> setterArg) {
        this.aList = setterArg;
        return this;
      }

      private @Nullable Map<Object, Object> aMap;

      public @NonNull Builder setAMap(@NonNull Map<Object, Object> setterArg) {
        this.aMap = setterArg;
        return this;
      }

      private @Nullable AnEnum anEnum;

      public @NonNull Builder setAnEnum(@NonNull AnEnum setterArg) {
        this.anEnum = setterArg;
        return this;
      }

      public @NonNull AllTypes build() {
        AllTypes pigeonReturn = new AllTypes();
        pigeonReturn.setABool(aBool);
        pigeonReturn.setAnInt(anInt);
        pigeonReturn.setADouble(aDouble);
        pigeonReturn.setAString(aString);
        pigeonReturn.setAByteArray(aByteArray);
        pigeonReturn.setA4ByteArray(a4ByteArray);
        pigeonReturn.setA8ByteArray(a8ByteArray);
        pigeonReturn.setAFloatArray(aFloatArray);
        pigeonReturn.setAList(aList);
        pigeonReturn.setAMap(aMap);
        pigeonReturn.setAnEnum(anEnum);
        return pigeonReturn;
      }
    }

    @NonNull
    ArrayList<Object> toList() {
      ArrayList<Object> toListResult = new ArrayList<Object>(11);
      toListResult.add(aBool);
      toListResult.add(anInt);
      toListResult.add(aDouble);
      toListResult.add(aString);
      toListResult.add(aByteArray);
      toListResult.add(a4ByteArray);
      toListResult.add(a8ByteArray);
      toListResult.add(aFloatArray);
      toListResult.add(aList);
      toListResult.add(aMap);
      toListResult.add(anEnum == null ? null : anEnum.index);
      return toListResult;
    }

    static @NonNull AllTypes fromList(@NonNull ArrayList<Object> list) {
      AllTypes pigeonResult = new AllTypes();
      Object aBool = list.get(0);
      pigeonResult.setABool((Boolean) aBool);
      Object anInt = list.get(1);
      pigeonResult.setAnInt(
          (anInt == null) ? null : ((anInt instanceof Integer) ? (Integer) anInt : (Long) anInt));
      Object aDouble = list.get(2);
      pigeonResult.setADouble((Double) aDouble);
      Object aString = list.get(3);
      pigeonResult.setAString((String) aString);
      Object aByteArray = list.get(4);
      pigeonResult.setAByteArray((byte[]) aByteArray);
      Object a4ByteArray = list.get(5);
      pigeonResult.setA4ByteArray((int[]) a4ByteArray);
      Object a8ByteArray = list.get(6);
      pigeonResult.setA8ByteArray((long[]) a8ByteArray);
      Object aFloatArray = list.get(7);
      pigeonResult.setAFloatArray((double[]) aFloatArray);
      Object aList = list.get(8);
      pigeonResult.setAList((List<Object>) aList);
      Object aMap = list.get(9);
      pigeonResult.setAMap((Map<Object, Object>) aMap);
      Object anEnum = list.get(10);
      pigeonResult.setAnEnum(anEnum == null ? null : AnEnum.values()[(int) anEnum]);
      return pigeonResult;
    }
  }

  /** Generated class from Pigeon that represents data sent in messages. */
  public static class AllNullableTypes {
    private @Nullable Boolean aNullableBool;

    public @Nullable Boolean getANullableBool() {
      return aNullableBool;
    }

    public void setANullableBool(@Nullable Boolean setterArg) {
      this.aNullableBool = setterArg;
    }

    private @Nullable Long aNullableInt;

    public @Nullable Long getANullableInt() {
      return aNullableInt;
    }

    public void setANullableInt(@Nullable Long setterArg) {
      this.aNullableInt = setterArg;
    }

    private @Nullable Double aNullableDouble;

    public @Nullable Double getANullableDouble() {
      return aNullableDouble;
    }

    public void setANullableDouble(@Nullable Double setterArg) {
      this.aNullableDouble = setterArg;
    }

    private @Nullable String aNullableString;

    public @Nullable String getANullableString() {
      return aNullableString;
    }

    public void setANullableString(@Nullable String setterArg) {
      this.aNullableString = setterArg;
    }

    private @Nullable byte[] aNullableByteArray;

    public @Nullable byte[] getANullableByteArray() {
      return aNullableByteArray;
    }

    public void setANullableByteArray(@Nullable byte[] setterArg) {
      this.aNullableByteArray = setterArg;
    }

    private @Nullable int[] aNullable4ByteArray;

    public @Nullable int[] getANullable4ByteArray() {
      return aNullable4ByteArray;
    }

    public void setANullable4ByteArray(@Nullable int[] setterArg) {
      this.aNullable4ByteArray = setterArg;
    }

    private @Nullable long[] aNullable8ByteArray;

    public @Nullable long[] getANullable8ByteArray() {
      return aNullable8ByteArray;
    }

    public void setANullable8ByteArray(@Nullable long[] setterArg) {
      this.aNullable8ByteArray = setterArg;
    }

    private @Nullable double[] aNullableFloatArray;

    public @Nullable double[] getANullableFloatArray() {
      return aNullableFloatArray;
    }

    public void setANullableFloatArray(@Nullable double[] setterArg) {
      this.aNullableFloatArray = setterArg;
    }

    private @Nullable List<Object> aNullableList;

    public @Nullable List<Object> getANullableList() {
      return aNullableList;
    }

    public void setANullableList(@Nullable List<Object> setterArg) {
      this.aNullableList = setterArg;
    }

    private @Nullable Map<Object, Object> aNullableMap;

    public @Nullable Map<Object, Object> getANullableMap() {
      return aNullableMap;
    }

    public void setANullableMap(@Nullable Map<Object, Object> setterArg) {
      this.aNullableMap = setterArg;
    }

    private @Nullable List<List<Boolean>> nullableNestedList;

    public @Nullable List<List<Boolean>> getNullableNestedList() {
      return nullableNestedList;
    }

    public void setNullableNestedList(@Nullable List<List<Boolean>> setterArg) {
      this.nullableNestedList = setterArg;
    }

    private @Nullable Map<String, String> nullableMapWithAnnotations;

    public @Nullable Map<String, String> getNullableMapWithAnnotations() {
      return nullableMapWithAnnotations;
    }

    public void setNullableMapWithAnnotations(@Nullable Map<String, String> setterArg) {
      this.nullableMapWithAnnotations = setterArg;
    }

    private @Nullable Map<String, Object> nullableMapWithObject;

    public @Nullable Map<String, Object> getNullableMapWithObject() {
      return nullableMapWithObject;
    }

    public void setNullableMapWithObject(@Nullable Map<String, Object> setterArg) {
      this.nullableMapWithObject = setterArg;
    }

    private @Nullable AnEnum aNullableEnum;

    public @Nullable AnEnum getANullableEnum() {
      return aNullableEnum;
    }

    public void setANullableEnum(@Nullable AnEnum setterArg) {
      this.aNullableEnum = setterArg;
    }

    public static final class Builder {
      private @Nullable Boolean aNullableBool;

      public @NonNull Builder setANullableBool(@Nullable Boolean setterArg) {
        this.aNullableBool = setterArg;
        return this;
      }

      private @Nullable Long aNullableInt;

      public @NonNull Builder setANullableInt(@Nullable Long setterArg) {
        this.aNullableInt = setterArg;
        return this;
      }

      private @Nullable Double aNullableDouble;

      public @NonNull Builder setANullableDouble(@Nullable Double setterArg) {
        this.aNullableDouble = setterArg;
        return this;
      }

      private @Nullable String aNullableString;

      public @NonNull Builder setANullableString(@Nullable String setterArg) {
        this.aNullableString = setterArg;
        return this;
      }

      private @Nullable byte[] aNullableByteArray;

      public @NonNull Builder setANullableByteArray(@Nullable byte[] setterArg) {
        this.aNullableByteArray = setterArg;
        return this;
      }

      private @Nullable int[] aNullable4ByteArray;

      public @NonNull Builder setANullable4ByteArray(@Nullable int[] setterArg) {
        this.aNullable4ByteArray = setterArg;
        return this;
      }

      private @Nullable long[] aNullable8ByteArray;

      public @NonNull Builder setANullable8ByteArray(@Nullable long[] setterArg) {
        this.aNullable8ByteArray = setterArg;
        return this;
      }

      private @Nullable double[] aNullableFloatArray;

      public @NonNull Builder setANullableFloatArray(@Nullable double[] setterArg) {
        this.aNullableFloatArray = setterArg;
        return this;
      }

      private @Nullable List<Object> aNullableList;

      public @NonNull Builder setANullableList(@Nullable List<Object> setterArg) {
        this.aNullableList = setterArg;
        return this;
      }

      private @Nullable Map<Object, Object> aNullableMap;

      public @NonNull Builder setANullableMap(@Nullable Map<Object, Object> setterArg) {
        this.aNullableMap = setterArg;
        return this;
      }

      private @Nullable List<List<Boolean>> nullableNestedList;

      public @NonNull Builder setNullableNestedList(@Nullable List<List<Boolean>> setterArg) {
        this.nullableNestedList = setterArg;
        return this;
      }

      private @Nullable Map<String, String> nullableMapWithAnnotations;

      public @NonNull Builder setNullableMapWithAnnotations(
          @Nullable Map<String, String> setterArg) {
        this.nullableMapWithAnnotations = setterArg;
        return this;
      }

      private @Nullable Map<String, Object> nullableMapWithObject;

      public @NonNull Builder setNullableMapWithObject(@Nullable Map<String, Object> setterArg) {
        this.nullableMapWithObject = setterArg;
        return this;
      }

      private @Nullable AnEnum aNullableEnum;

      public @NonNull Builder setANullableEnum(@Nullable AnEnum setterArg) {
        this.aNullableEnum = setterArg;
        return this;
      }

      public @NonNull AllNullableTypes build() {
        AllNullableTypes pigeonReturn = new AllNullableTypes();
        pigeonReturn.setANullableBool(aNullableBool);
        pigeonReturn.setANullableInt(aNullableInt);
        pigeonReturn.setANullableDouble(aNullableDouble);
        pigeonReturn.setANullableString(aNullableString);
        pigeonReturn.setANullableByteArray(aNullableByteArray);
        pigeonReturn.setANullable4ByteArray(aNullable4ByteArray);
        pigeonReturn.setANullable8ByteArray(aNullable8ByteArray);
        pigeonReturn.setANullableFloatArray(aNullableFloatArray);
        pigeonReturn.setANullableList(aNullableList);
        pigeonReturn.setANullableMap(aNullableMap);
        pigeonReturn.setNullableNestedList(nullableNestedList);
        pigeonReturn.setNullableMapWithAnnotations(nullableMapWithAnnotations);
        pigeonReturn.setNullableMapWithObject(nullableMapWithObject);
        pigeonReturn.setANullableEnum(aNullableEnum);
        return pigeonReturn;
      }
    }

    @NonNull
    ArrayList<Object> toList() {
      ArrayList<Object> toListResult = new ArrayList<Object>(14);
      toListResult.add(aNullableBool);
      toListResult.add(aNullableInt);
      toListResult.add(aNullableDouble);
      toListResult.add(aNullableString);
      toListResult.add(aNullableByteArray);
      toListResult.add(aNullable4ByteArray);
      toListResult.add(aNullable8ByteArray);
      toListResult.add(aNullableFloatArray);
      toListResult.add(aNullableList);
      toListResult.add(aNullableMap);
      toListResult.add(nullableNestedList);
      toListResult.add(nullableMapWithAnnotations);
      toListResult.add(nullableMapWithObject);
      toListResult.add(aNullableEnum == null ? null : aNullableEnum.index);
      return toListResult;
    }

    static @NonNull AllNullableTypes fromList(@NonNull ArrayList<Object> list) {
      AllNullableTypes pigeonResult = new AllNullableTypes();
      Object aNullableBool = list.get(0);
      pigeonResult.setANullableBool((Boolean) aNullableBool);
      Object aNullableInt = list.get(1);
      pigeonResult.setANullableInt(
          (aNullableInt == null)
              ? null
              : ((aNullableInt instanceof Integer) ? (Integer) aNullableInt : (Long) aNullableInt));
      Object aNullableDouble = list.get(2);
      pigeonResult.setANullableDouble((Double) aNullableDouble);
      Object aNullableString = list.get(3);
      pigeonResult.setANullableString((String) aNullableString);
      Object aNullableByteArray = list.get(4);
      pigeonResult.setANullableByteArray((byte[]) aNullableByteArray);
      Object aNullable4ByteArray = list.get(5);
      pigeonResult.setANullable4ByteArray((int[]) aNullable4ByteArray);
      Object aNullable8ByteArray = list.get(6);
      pigeonResult.setANullable8ByteArray((long[]) aNullable8ByteArray);
      Object aNullableFloatArray = list.get(7);
      pigeonResult.setANullableFloatArray((double[]) aNullableFloatArray);
      Object aNullableList = list.get(8);
      pigeonResult.setANullableList((List<Object>) aNullableList);
      Object aNullableMap = list.get(9);
      pigeonResult.setANullableMap((Map<Object, Object>) aNullableMap);
      Object nullableNestedList = list.get(10);
      pigeonResult.setNullableNestedList((List<List<Boolean>>) nullableNestedList);
      Object nullableMapWithAnnotations = list.get(11);
      pigeonResult.setNullableMapWithAnnotations((Map<String, String>) nullableMapWithAnnotations);
      Object nullableMapWithObject = list.get(12);
      pigeonResult.setNullableMapWithObject((Map<String, Object>) nullableMapWithObject);
      Object aNullableEnum = list.get(13);
      pigeonResult.setANullableEnum(
          aNullableEnum == null ? null : AnEnum.values()[(int) aNullableEnum]);
      return pigeonResult;
    }
  }

  /** Generated class from Pigeon that represents data sent in messages. */
  public static class AllNullableTypesWrapper {
    private @NonNull AllNullableTypes values;

    public @NonNull AllNullableTypes getValues() {
      return values;
    }

    public void setValues(@NonNull AllNullableTypes setterArg) {
      if (setterArg == null) {
        throw new IllegalStateException("Nonnull field \"values\" is null.");
      }
      this.values = setterArg;
    }

    /** Constructor is private to enforce null safety; use Builder. */
    private AllNullableTypesWrapper() {}

    public static final class Builder {
      private @Nullable AllNullableTypes values;

      public @NonNull Builder setValues(@NonNull AllNullableTypes setterArg) {
        this.values = setterArg;
        return this;
      }

      public @NonNull AllNullableTypesWrapper build() {
        AllNullableTypesWrapper pigeonReturn = new AllNullableTypesWrapper();
        pigeonReturn.setValues(values);
        return pigeonReturn;
      }
    }

    @NonNull
    ArrayList<Object> toList() {
      ArrayList<Object> toListResult = new ArrayList<Object>(1);
      toListResult.add((values == null) ? null : values.toList());
      return toListResult;
    }

    static @NonNull AllNullableTypesWrapper fromList(@NonNull ArrayList<Object> list) {
      AllNullableTypesWrapper pigeonResult = new AllNullableTypesWrapper();
      Object values = list.get(0);
      pigeonResult.setValues(
          (values == null) ? null : AllNullableTypes.fromList((ArrayList<Object>) values));
      return pigeonResult;
    }
  }

  public interface Result<T> {
    void success(T result);

    void error(Throwable error);
  }

  private static class HostIntegrationCoreApiCodec extends StandardMessageCodec {
    public static final HostIntegrationCoreApiCodec INSTANCE = new HostIntegrationCoreApiCodec();

    private HostIntegrationCoreApiCodec() {}

    @Override
    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
      switch (type) {
        case (byte) 128:
          return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));

        case (byte) 129:
          return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));

        case (byte) 130:
          return AllTypes.fromList((ArrayList<Object>) readValue(buffer));

        default:
          return super.readValueOfType(type, buffer);
      }
    }

    @Override
    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
      if (value instanceof AllNullableTypes) {
        stream.write(128);
        writeValue(stream, ((AllNullableTypes) value).toList());
      } else if (value instanceof 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);
      }
    }
  }

  /**
   * The core interface that each host language plugin must implement in platform_test integration
   * tests.
   *
   * <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
   */
  public interface HostIntegrationCoreApi {
    /**
     * A no-op function taking no arguments and returning no value, to sanity test basic calling.
     */
    void noop();
    /** Returns the passed object, to test serialization and deserialization. */
    @NonNull
    AllTypes echoAllTypes(@NonNull AllTypes everything);
    /** Returns the passed object, to test serialization and deserialization. */
    @Nullable
    AllNullableTypes echoAllNullableTypes(@Nullable AllNullableTypes everything);
    /** Returns an error, to test error handling. */
    void throwError();
    /** Returns passed in int. */
    @NonNull
    Long echoInt(@NonNull Long anInt);
    /** Returns passed in double. */
    @NonNull
    Double echoDouble(@NonNull Double aDouble);
    /** Returns the passed in boolean. */
    @NonNull
    Boolean echoBool(@NonNull Boolean aBool);
    /** Returns the passed in string. */
    @NonNull
    String echoString(@NonNull String aString);
    /** Returns the passed in Uint8List. */
    @NonNull
    byte[] echoUint8List(@NonNull byte[] aUint8List);
    /** Returns the passed in generic Object. */
    @NonNull
    Object echoObject(@NonNull Object anObject);
    /**
     * Returns the inner `aString` value from the wrapped object, to test sending of nested objects.
     */
    @Nullable
    String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper);
    /**
     * Returns the inner `aString` value from the wrapped object, to test sending of nested objects.
     */
    @NonNull
    AllNullableTypesWrapper createNestedNullableString(@Nullable String nullableString);
    /** Returns passed in arguments of multiple types. */
    @NonNull
    AllNullableTypes sendMultipleNullableTypes(
        @Nullable Boolean aNullableBool,
        @Nullable Long aNullableInt,
        @Nullable String aNullableString);
    /** Returns passed in int. */
    @Nullable
    Long echoNullableInt(@Nullable Long aNullableInt);
    /** Returns passed in double. */
    @Nullable
    Double echoNullableDouble(@Nullable Double aNullableDouble);
    /** Returns the passed in boolean. */
    @Nullable
    Boolean echoNullableBool(@Nullable Boolean aNullableBool);
    /** Returns the passed in string. */
    @Nullable
    String echoNullableString(@Nullable String aNullableString);
    /** Returns the passed in Uint8List. */
    @Nullable
    byte[] echoNullableUint8List(@Nullable byte[] aNullableUint8List);
    /** Returns the passed in generic Object. */
    @Nullable
    Object echoNullableObject(@Nullable Object aNullableObject);
    /**
     * A no-op function taking no arguments and returning no value, to sanity test basic
     * asynchronous calling.
     */
    void noopAsync(Result<Void> result);
    /** Returns the passed string asynchronously. */
    void echoAsyncString(@NonNull String aString, Result<String> result);

    void callFlutterNoop(Result<Void> result);

    void callFlutterEchoString(@NonNull String aString, Result<String> result);

    /** The codec used by HostIntegrationCoreApi. */
    static MessageCodec<Object> getCodec() {
      return HostIntegrationCoreApiCodec.INSTANCE;
    }
    /**
     * Sets up an instance of `HostIntegrationCoreApi` to handle messages through the
     * `binaryMessenger`.
     */
    static void setup(BinaryMessenger binaryMessenger, HostIntegrationCoreApi api) {
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop", getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  api.noop();
                  wrapped.add(0, null);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  AllTypes everythingArg = (AllTypes) args.get(0);
                  if (everythingArg == null) {
                    throw new NullPointerException("everythingArg unexpectedly null.");
                  }
                  AllTypes output = api.echoAllTypes(everythingArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  AllNullableTypes everythingArg = (AllNullableTypes) args.get(0);
                  AllNullableTypes output = api.echoAllNullableTypes(everythingArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.throwError",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  api.throwError();
                  wrapped.add(0, null);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Number anIntArg = (Number) args.get(0);
                  if (anIntArg == null) {
                    throw new NullPointerException("anIntArg unexpectedly null.");
                  }
                  Long output = api.echoInt((anIntArg == null) ? null : anIntArg.longValue());
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Double aDoubleArg = (Double) args.get(0);
                  if (aDoubleArg == null) {
                    throw new NullPointerException("aDoubleArg unexpectedly null.");
                  }
                  Double output = api.echoDouble(aDoubleArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Boolean aBoolArg = (Boolean) args.get(0);
                  if (aBoolArg == null) {
                    throw new NullPointerException("aBoolArg unexpectedly null.");
                  }
                  Boolean output = api.echoBool(aBoolArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoString",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  String aStringArg = (String) args.get(0);
                  if (aStringArg == null) {
                    throw new NullPointerException("aStringArg unexpectedly null.");
                  }
                  String output = api.echoString(aStringArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  byte[] aUint8ListArg = (byte[]) args.get(0);
                  if (aUint8ListArg == null) {
                    throw new NullPointerException("aUint8ListArg unexpectedly null.");
                  }
                  byte[] output = api.echoUint8List(aUint8ListArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Object anObjectArg = args.get(0);
                  if (anObjectArg == null) {
                    throw new NullPointerException("anObjectArg unexpectedly null.");
                  }
                  Object output = api.echoObject(anObjectArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  AllNullableTypesWrapper wrapperArg = (AllNullableTypesWrapper) args.get(0);
                  if (wrapperArg == null) {
                    throw new NullPointerException("wrapperArg unexpectedly null.");
                  }
                  String output = api.extractNestedNullableString(wrapperArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  String nullableStringArg = (String) args.get(0);
                  AllNullableTypesWrapper output =
                      api.createNestedNullableString(nullableStringArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Boolean aNullableBoolArg = (Boolean) args.get(0);
                  Number aNullableIntArg = (Number) args.get(1);
                  String aNullableStringArg = (String) args.get(2);
                  AllNullableTypes output =
                      api.sendMultipleNullableTypes(
                          aNullableBoolArg,
                          (aNullableIntArg == null) ? null : aNullableIntArg.longValue(),
                          aNullableStringArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Number aNullableIntArg = (Number) args.get(0);
                  Long output =
                      api.echoNullableInt(
                          (aNullableIntArg == null) ? null : aNullableIntArg.longValue());
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Double aNullableDoubleArg = (Double) args.get(0);
                  Double output = api.echoNullableDouble(aNullableDoubleArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Boolean aNullableBoolArg = (Boolean) args.get(0);
                  Boolean output = api.echoNullableBool(aNullableBoolArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  String aNullableStringArg = (String) args.get(0);
                  String output = api.echoNullableString(aNullableStringArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  byte[] aNullableUint8ListArg = (byte[]) args.get(0);
                  byte[] output = api.echoNullableUint8List(aNullableUint8ListArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  Object aNullableObjectArg = args.get(0);
                  Object output = api.echoNullableObject(aNullableObjectArg);
                  wrapped.add(0, output);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  Result<Void> resultCallback =
                      new Result<Void>() {
                        public void success(Void result) {
                          wrapped.add(0, null);
                          reply.reply(wrapped);
                        }

                        public void error(Throwable error) {
                          ArrayList<Object> wrappedError = wrapError(error);
                          reply.reply(wrappedError);
                        }
                      };

                  api.noopAsync(resultCallback);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  reply.reply(wrappedError);
                }
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  String aStringArg = (String) args.get(0);
                  if (aStringArg == null) {
                    throw new NullPointerException("aStringArg unexpectedly null.");
                  }
                  Result<String> resultCallback =
                      new Result<String>() {
                        public void success(String result) {
                          wrapped.add(0, result);
                          reply.reply(wrapped);
                        }

                        public void error(Throwable error) {
                          ArrayList<Object> wrappedError = wrapError(error);
                          reply.reply(wrappedError);
                        }
                      };

                  api.echoAsyncString(aStringArg, resultCallback);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  reply.reply(wrappedError);
                }
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  Result<Void> resultCallback =
                      new Result<Void>() {
                        public void success(Void result) {
                          wrapped.add(0, null);
                          reply.reply(wrapped);
                        }

                        public void error(Throwable error) {
                          ArrayList<Object> wrappedError = wrapError(error);
                          reply.reply(wrappedError);
                        }
                      };

                  api.callFlutterNoop(resultCallback);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  reply.reply(wrappedError);
                }
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger,
                "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
                getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  ArrayList<Object> args = (ArrayList<Object>) message;
                  assert args != null;
                  String aStringArg = (String) args.get(0);
                  if (aStringArg == null) {
                    throw new NullPointerException("aStringArg unexpectedly null.");
                  }
                  Result<String> resultCallback =
                      new Result<String>() {
                        public void success(String result) {
                          wrapped.add(0, result);
                          reply.reply(wrapped);
                        }

                        public void error(Throwable error) {
                          ArrayList<Object> wrappedError = wrapError(error);
                          reply.reply(wrappedError);
                        }
                      };

                  api.callFlutterEchoString(aStringArg, resultCallback);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  reply.reply(wrappedError);
                }
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
    }
  }

  private static class FlutterIntegrationCoreApiCodec extends StandardMessageCodec {
    public static final FlutterIntegrationCoreApiCodec INSTANCE =
        new FlutterIntegrationCoreApiCodec();

    private FlutterIntegrationCoreApiCodec() {}

    @Override
    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
      switch (type) {
        case (byte) 128:
          return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));

        case (byte) 129:
          return AllTypes.fromList((ArrayList<Object>) readValue(buffer));

        default:
          return super.readValueOfType(type, buffer);
      }
    }

    @Override
    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
      if (value instanceof AllNullableTypes) {
        stream.write(128);
        writeValue(stream, ((AllNullableTypes) value).toList());
      } else if (value instanceof AllTypes) {
        stream.write(129);
        writeValue(stream, ((AllTypes) value).toList());
      } else {
        super.writeValue(stream, value);
      }
    }
  }

  /**
   * The core interface that the Dart platform_test code implements for host integration tests to
   * call into.
   *
   * <p>Generated class from Pigeon that represents Flutter messages that can be called from Java.
   */
  public static class FlutterIntegrationCoreApi {
    private final BinaryMessenger binaryMessenger;

    public FlutterIntegrationCoreApi(BinaryMessenger argBinaryMessenger) {
      this.binaryMessenger = argBinaryMessenger;
    }

    public interface Reply<T> {
      void reply(T reply);
    }
    /** The codec used by FlutterIntegrationCoreApi. */
    static MessageCodec<Object> getCodec() {
      return FlutterIntegrationCoreApiCodec.INSTANCE;
    }
    /**
     * A no-op function taking no arguments and returning no value, to sanity test basic calling.
     */
    public void noop(Reply<Void> callback) {
      BasicMessageChannel<Object> channel =
          new BasicMessageChannel<>(
              binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", getCodec());
      channel.send(
          null,
          channelReply -> {
            callback.reply(null);
          });
    }
    /** Returns the passed object, to test serialization and deserialization. */
    public void echoAllTypes(@NonNull AllTypes everythingArg, Reply<AllTypes> callback) {
      BasicMessageChannel<Object> channel =
          new BasicMessageChannel<>(
              binaryMessenger,
              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes",
              getCodec());
      channel.send(
          new ArrayList<Object>(Collections.singletonList(everythingArg)),
          channelReply -> {
            @SuppressWarnings("ConstantConditions")
            AllTypes output = (AllTypes) channelReply;
            callback.reply(output);
          });
    }
    /** Returns the passed object, to test serialization and deserialization. */
    public void echoAllNullableTypes(
        @NonNull AllNullableTypes everythingArg, Reply<AllNullableTypes> callback) {
      BasicMessageChannel<Object> channel =
          new BasicMessageChannel<>(
              binaryMessenger,
              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
              getCodec());
      channel.send(
          new ArrayList<Object>(Collections.singletonList(everythingArg)),
          channelReply -> {
            @SuppressWarnings("ConstantConditions")
            AllNullableTypes output = (AllNullableTypes) channelReply;
            callback.reply(output);
          });
    }
    /** Returns the passed string, to test serialization and deserialization. */
    public void echoString(@NonNull String aStringArg, Reply<String> callback) {
      BasicMessageChannel<Object> channel =
          new BasicMessageChannel<>(
              binaryMessenger,
              "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString",
              getCodec());
      channel.send(
          new ArrayList<Object>(Collections.singletonList(aStringArg)),
          channelReply -> {
            @SuppressWarnings("ConstantConditions")
            String output = (String) channelReply;
            callback.reply(output);
          });
    }
  }
  /**
   * An API that can be implemented for minimal, compile-only tests.
   *
   * <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
   */
  public interface HostTrivialApi {
    void noop();

    /** The codec used by HostTrivialApi. */
    static MessageCodec<Object> getCodec() {
      return new StandardMessageCodec();
    }
    /** Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`. */
    static void setup(BinaryMessenger binaryMessenger, HostTrivialApi api) {
      {
        BasicMessageChannel<Object> channel =
            new BasicMessageChannel<>(
                binaryMessenger, "dev.flutter.pigeon.HostTrivialApi.noop", getCodec());
        if (api != null) {
          channel.setMessageHandler(
              (message, reply) -> {
                ArrayList wrapped = new ArrayList<>();
                try {
                  api.noop();
                  wrapped.add(0, null);
                } catch (Error | RuntimeException exception) {
                  ArrayList<Object> wrappedError = wrapError(exception);
                  wrapped = wrappedError;
                }
                reply.reply(wrapped);
              });
        } else {
          channel.setMessageHandler(null);
        }
      }
    }
  }

  @NonNull
  private static ArrayList<Object> wrapError(@NonNull Throwable exception) {
    ArrayList<Object> errorList = new ArrayList<>(3);
    errorList.add(exception.toString());
    errorList.add(exception.getClass().getSimpleName());
    errorList.add(
        "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception));
    return errorList;
  }
}
